diff --git a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx index 22ae9af78..00d3fb999 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx @@ -192,8 +192,8 @@ export const MatchColumnsStep = ({ if (columnIndex === index) { return setColumn(column, field, data); } else if (index === existingFieldIndex) { - enqueueSnackBar('Columns cannot duplicate', { - title: 'Another column unselected', + enqueueSnackBar('Another column unselected', { + detailedMessage: 'Columns cannot duplicate', variant: SnackBarVariant.Error, }); return setColumn(column); diff --git a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepper.tsx b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepper.tsx index e8c3d52df..bc93d4e38 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepper.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepper.tsx @@ -51,7 +51,6 @@ export const SpreadsheetImportStepper = ({ const handleError = useCallback( (description: string) => { enqueueSnackBar(description, { - title: 'Error', variant: SnackBarVariant.Error, }); }, diff --git a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx index e0d7ac6a2..57a16adac 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx @@ -109,8 +109,8 @@ export const DropZone = ({ onContinue, isLoading }: DropZoneProps) => { onDropRejected: (fileRejections) => { setLoading(false); fileRejections.forEach((fileRejection) => { - enqueueSnackBar(fileRejection.errors[0].message, { - title: `${fileRejection.file.name} upload rejected`, + enqueueSnackBar(`${fileRejection.file.name} upload rejected`, { + detailedMessage: fileRejection.errors[0].message, variant: SnackBarVariant.Error, }); }); diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx index 3c0cb5177..1ebc61329 100644 --- a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx +++ b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx @@ -24,15 +24,13 @@ export enum SnackBarVariant { Warning = 'warning', } -export type SnackBarProps = Pick< - ComponentPropsWithoutRef<'div'>, - 'id' | 'title' -> & { +export type SnackBarProps = Pick, 'id'> & { className?: string; progress?: number; duration?: number; icon?: ReactNode; - message?: string; + message: string; + detailedMessage?: string; onCancel?: () => void; onClose?: () => void; role?: 'alert' | 'status'; @@ -73,7 +71,17 @@ const StyledHeader = styled.div` display: flex; font-weight: ${({ theme }) => theme.font.weight.medium}; gap: ${({ theme }) => theme.spacing(2)}; - height: ${({ theme }) => theme.spacing(6)}; + margin-bottom: ${({ theme }) => theme.spacing(1)}; +`; + +const StyledMessage = styled.div` + color: ${({ theme }) => theme.font.color.secondary}; + font-size: ${({ theme }) => theme.font.size.sm}; +`; + +const StyledIcon = styled.div` + align-items: center; + display: flex; `; const StyledActions = styled.div` @@ -82,7 +90,16 @@ const StyledActions = styled.div` margin-left: auto; `; -const defaultTitleByVariant: Record = { +const StyledDescription = styled.div` + color: ${({ theme }) => theme.font.color.tertiary}; + font-size: ${({ theme }) => theme.font.size.sm}; + padding-left: ${({ theme }) => theme.spacing(6)}; + overflow: hidden; + text-overflow: ellipsis; + width: 200px; +`; + +const defaultAriaLabelByVariant: Record = { [SnackBarVariant.Default]: 'Alert', [SnackBarVariant.Error]: 'Error', [SnackBarVariant.Info]: 'Info', @@ -97,11 +114,11 @@ export const SnackBar = ({ icon: iconComponent, id, message, + detailedMessage, onCancel, onClose, role = 'status', variant = SnackBarVariant.Default, - title = defaultTitleByVariant[variant], }: SnackBarProps) => { const theme = useTheme(); const { animation: progressAnimation, value: progressValue } = @@ -119,7 +136,7 @@ export const SnackBar = ({ return iconComponent; } - const ariaLabel = defaultTitleByVariant[variant]; + const ariaLabel = defaultAriaLabelByVariant[variant]; const color = theme.snackBar[variant].color; const size = theme.icon.size.md; @@ -164,7 +181,7 @@ export const SnackBar = ({ aria-live={role === 'alert' ? 'assertive' : 'polite'} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} - title={message || title || defaultTitleByVariant[variant]} + title={message || defaultAriaLabelByVariant[variant]} {...{ className, id, role, variant }} > - {icon} - {message} + {icon} + {message} {!!onCancel && } @@ -182,6 +199,9 @@ export const SnackBar = ({ )} + {detailedMessage && ( + {detailedMessage} + )} ); }; diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBarProvider.tsx b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBarProvider.tsx index 529adbef6..db6383719 100644 --- a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBarProvider.tsx +++ b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBarProvider.tsx @@ -46,7 +46,7 @@ export const SnackBarProvider = ({ children }: React.PropsWithChildren) => { {snackBarInternal.queue.map( - ({ duration, icon, id, message, title, variant }) => ( + ({ duration, icon, id, message, detailedMessage, variant }) => ( { layout > handleSnackBarClose(id)} /> diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/__stories__/SnackBar.stories.tsx b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/__stories__/SnackBar.stories.tsx index 3d55b5f50..cb8f02b86 100644 --- a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/__stories__/SnackBar.stories.tsx +++ b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/__stories__/SnackBar.stories.tsx @@ -19,8 +19,8 @@ const meta: Meta = { icon: { control: false }, }, args: { - title: 'Lorem ipsum', - message: + message: 'Lorem ipsum', + detailedMessage: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec purus nec eros tincidunt lacinia.', onCancel: undefined, onClose: fn(), diff --git a/packages/twenty-front/src/modules/workflow/components/RecordShowPageWorkflowHeader.tsx b/packages/twenty-front/src/modules/workflow/components/RecordShowPageWorkflowHeader.tsx index c9c601e85..cb4017848 100644 --- a/packages/twenty-front/src/modules/workflow/components/RecordShowPageWorkflowHeader.tsx +++ b/packages/twenty-front/src/modules/workflow/components/RecordShowPageWorkflowHeader.tsx @@ -52,19 +52,17 @@ export const RecordShowPageWorkflowHeader = ({ assertWorkflowWithCurrentVersionIsDefined(workflowWithCurrentVersion); if (!canWorkflowBeTested) { - enqueueSnackBar( - 'Trigger type should be Manual - when no record(s) are selected', - { - variant: SnackBarVariant.Error, - title: 'Workflow cannot be tested', - icon: ( - - ), - }, - ); + enqueueSnackBar('Workflow cannot be tested', { + variant: SnackBarVariant.Error, + detailedMessage: + 'Trigger type should be Manual - when no record(s) are selected', + icon: ( + + ), + }); return; } diff --git a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx index a93cc7ac0..66b01377b 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx +++ b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx @@ -37,9 +37,8 @@ export const useRunWorkflowVersion = () => { variables: { input: { workflowVersionId, payload } }, }); - enqueueSnackBar('', { + enqueueSnackBar(`${capitalize(workflowName)} starting...`, { variant: SnackBarVariant.Success, - title: `${capitalize(workflowName)} starting...`, icon: (