Add link on snack bar (#9873)
Add link to workflow execution <img width="639" alt="Capture d’écran 2025-01-27 à 18 15 34" src="https://github.com/user-attachments/assets/f2a1b3b5-7bf6-4b33-bba7-bf8907f6bcc6" />
This commit is contained in:
@ -26,7 +26,6 @@ export const useTestWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataI
|
||||
|
||||
runWorkflowVersion({
|
||||
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
||||
workflowName: workflowWithCurrentVersion.name,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -71,7 +71,6 @@ export const useWorkflowRunRecordActions = ({
|
||||
|
||||
await runWorkflowVersion({
|
||||
workflowVersionId: activeWorkflowVersion.id,
|
||||
workflowName: name,
|
||||
payload: selectedRecord,
|
||||
});
|
||||
},
|
||||
|
||||
@ -49,7 +49,6 @@ export const useWorkflowRunActions = () => {
|
||||
onClick: async () => {
|
||||
await runWorkflowVersion({
|
||||
workflowVersionId: activeWorkflowVersion.id,
|
||||
workflowName: name,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isUndefined } from '@sniptt/guards';
|
||||
import { ComponentPropsWithoutRef, ReactNode, useMemo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
IconAlertTriangle,
|
||||
IconInfoCircle,
|
||||
@ -31,6 +32,10 @@ export type SnackBarProps = Pick<ComponentPropsWithoutRef<'div'>, 'id'> & {
|
||||
duration?: number;
|
||||
icon?: ReactNode;
|
||||
message: string;
|
||||
link?: {
|
||||
href: string;
|
||||
text: string;
|
||||
};
|
||||
detailedMessage?: string;
|
||||
onCancel?: () => void;
|
||||
onClose?: () => void;
|
||||
@ -101,6 +106,20 @@ const StyledDescription = styled.div`
|
||||
width: 200px;
|
||||
`;
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
display: block;
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
padding-left: ${({ theme }) => theme.spacing(6)};
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 200px;
|
||||
&:hover {
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
}
|
||||
`;
|
||||
|
||||
const defaultAriaLabelByVariant: Record<SnackBarVariant, string> = {
|
||||
[SnackBarVariant.Default]: 'Alert',
|
||||
[SnackBarVariant.Error]: 'Error',
|
||||
@ -117,6 +136,7 @@ export const SnackBar = ({
|
||||
id,
|
||||
message,
|
||||
detailedMessage,
|
||||
link,
|
||||
onCancel,
|
||||
onClose,
|
||||
role = 'status',
|
||||
@ -205,6 +225,7 @@ export const SnackBar = ({
|
||||
{detailedMessage && (
|
||||
<StyledDescription>{detailedMessage}</StyledDescription>
|
||||
)}
|
||||
{link && <StyledLink to={link.href}>{link.text}</StyledLink>}
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -46,7 +46,15 @@ export const SnackBarProvider = ({ children }: React.PropsWithChildren) => {
|
||||
<StyledSnackBarContainer>
|
||||
<AnimatePresence>
|
||||
{snackBarInternal.queue.map(
|
||||
({ duration, icon, id, message, detailedMessage, variant }) => (
|
||||
({
|
||||
duration,
|
||||
icon,
|
||||
id,
|
||||
message,
|
||||
detailedMessage,
|
||||
variant,
|
||||
link,
|
||||
}) => (
|
||||
<motion.div
|
||||
key={id}
|
||||
variants={variants}
|
||||
@ -57,7 +65,14 @@ export const SnackBarProvider = ({ children }: React.PropsWithChildren) => {
|
||||
layout
|
||||
>
|
||||
<SnackBar
|
||||
{...{ duration, icon, message, detailedMessage, variant }}
|
||||
{...{
|
||||
duration,
|
||||
icon,
|
||||
message,
|
||||
detailedMessage,
|
||||
variant,
|
||||
link,
|
||||
}}
|
||||
onClose={() => handleSnackBarClose(id)}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@ -68,7 +68,6 @@ export const RecordShowPageWorkflowHeader = ({
|
||||
|
||||
await runWorkflowVersion({
|
||||
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
||||
workflowName: workflowWithCurrentVersion.name,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -3,7 +3,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { RUN_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/runWorkflowVersion';
|
||||
import { useApolloClient, useMutation } from '@apollo/client';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { capitalize } from 'twenty-shared';
|
||||
import { IconSettingsAutomation } from 'twenty-ui';
|
||||
import {
|
||||
RunWorkflowVersionMutation,
|
||||
@ -25,18 +24,27 @@ export const useRunWorkflowVersion = () => {
|
||||
|
||||
const runWorkflowVersion = async ({
|
||||
workflowVersionId,
|
||||
workflowName,
|
||||
payload,
|
||||
}: {
|
||||
workflowVersionId: string;
|
||||
workflowName: string;
|
||||
payload?: Record<string, any>;
|
||||
}) => {
|
||||
await mutate({
|
||||
const { data } = await mutate({
|
||||
variables: { input: { workflowVersionId, payload } },
|
||||
});
|
||||
|
||||
enqueueSnackBar(`${capitalize(workflowName)} starting...`, {
|
||||
const workflowRunId = data?.runWorkflowVersion?.workflowRunId;
|
||||
|
||||
if (!workflowRunId) {
|
||||
enqueueSnackBar('Workflow run failed', {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const link = `/object/workflowRun/${workflowRunId}`;
|
||||
|
||||
enqueueSnackBar('Workflow is running...', {
|
||||
variant: SnackBarVariant.Success,
|
||||
icon: (
|
||||
<IconSettingsAutomation
|
||||
@ -44,6 +52,10 @@ export const useRunWorkflowVersion = () => {
|
||||
color={theme.snackBar.success.color}
|
||||
/>
|
||||
),
|
||||
link: {
|
||||
href: link,
|
||||
text: 'View execution details',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user