diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
index b7620d641..31f36eb58 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
@@ -4,6 +4,13 @@ import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hook
import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail';
import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep';
import { useUpdateWorkflowVersionTrigger } from '@/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger';
+import styled from '@emotion/styled';
+
+const StyledContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+`;
export const CommandMenuWorkflowEditStepContent = ({
workflow,
@@ -19,12 +26,14 @@ export const CommandMenuWorkflowEditStepContent = ({
});
return (
-
+
+
+
);
};
diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx
index 337cd439d..b288a5750 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx
@@ -20,17 +20,17 @@ import styled from '@emotion/styled';
import { IconLogin2, IconLogout, IconStepInto } from 'twenty-ui';
import { isDefined } from 'twenty-shared/utils';
-const StyledTabList = styled(TabList)`
- background-color: ${({ theme }) => theme.background.secondary};
- padding-left: ${({ theme }) => theme.spacing(2)};
-`;
-
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
height: 100%;
`;
+const StyledTabList = styled(TabList)`
+ background-color: ${({ theme }) => theme.background.secondary};
+ padding-left: ${({ theme }) => theme.spacing(2)};
+`;
+
type TabId = WorkflowRunTabIdType;
export const CommandMenuWorkflowRunViewStep = () => {
diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx
index 97825c9c1..659b17808 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx
@@ -2,20 +2,30 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext';
import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow';
import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail';
+import styled from '@emotion/styled';
+
+const StyledContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+`;
export const CommandMenuWorkflowViewStep = () => {
const flow = useFlowOrThrow();
const workflowSelectedNode = useWorkflowSelectedNodeOrThrow();
+
return (
-
+
+
+
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepInputDetail.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepInputDetail.tsx
index d56c6eeed..f86e36d55 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepInputDetail.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepInputDetail.tsx
@@ -1,27 +1,29 @@
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
+import { getStepDefinitionOrThrow } from '@/workflow/utils/getStepDefinitionOrThrow';
+import { WorkflowRunStepJsonContainer } from '@/workflow/workflow-steps/components/WorkflowRunStepJsonContainer';
+import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { getWorkflowPreviousStepId } from '@/workflow/workflow-steps/utils/getWorkflowPreviousStep';
import { getWorkflowRunStepContext } from '@/workflow/workflow-steps/utils/getWorkflowRunStepContext';
import { getWorkflowVariablesUsedInStep } from '@/workflow/workflow-steps/utils/getWorkflowVariablesUsedInStep';
-import styled from '@emotion/styled';
+import { getActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow';
+import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
+import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
+import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import {
IconBrackets,
JsonNestedNode,
JsonTreeContextProvider,
ShouldExpandNodeInitiallyProps,
+ useIcons,
} from 'twenty-ui';
import { isDefined } from 'twenty-shared/utils';
-const StyledContainer = styled.div`
- display: grid;
- overflow-x: auto;
- padding-block: ${({ theme }) => theme.spacing(4)};
- padding-inline: ${({ theme }) => theme.spacing(3)};
-`;
-
export const WorkflowRunStepInputDetail = ({ stepId }: { stepId: string }) => {
- const { t } = useLingui();
+ const { t, i18n } = useLingui();
+ const { getIcon } = useIcons();
+ const theme = useTheme();
const workflowRunId = useWorkflowRunIdOrThrow();
const workflowRun = useWorkflowRun({ workflowRunId });
@@ -49,6 +51,23 @@ export const WorkflowRunStepInputDetail = ({ stepId }: { stepId: string }) => {
return null;
}
+ const stepDefinition = getStepDefinitionOrThrow({
+ stepId,
+ trigger: workflowRun.output.flow.trigger,
+ steps: workflowRun.output.flow.steps,
+ });
+ if (stepDefinition?.type !== 'action') {
+ throw new Error('The input tab must be rendered with an action step.');
+ }
+
+ const headerTitle = stepDefinition.definition.name;
+ const headerIcon = getActionIcon(stepDefinition.definition.type);
+ const headerIconColor = getActionIconColorOrThrow({
+ theme,
+ actionType: stepDefinition.definition.type,
+ });
+ const headerType = getActionHeaderTypeOrThrow(stepDefinition.definition.type);
+
const variablesUsedInStep = getWorkflowVariablesUsedInStep({
step,
});
@@ -69,30 +88,40 @@ export const WorkflowRunStepInputDetail = ({ stepId }: { stepId: string }) => {
keyPath.startsWith(previousStepId) && depth < 2;
return (
-
- variablesUsedInStep.has(keyPath),
- shouldExpandNodeInitially: isFirstNodeDepthOfPreviousStep,
- }}
- >
- ({
- id,
- label: name,
- value: context,
- }))}
- Icon={IconBrackets}
- depth={0}
- keyPath=""
- emptyElementsText=""
- />
-
-
+ <>
+
+
+
+ variablesUsedInStep.has(keyPath),
+ shouldExpandNodeInitially: isFirstNodeDepthOfPreviousStep,
+ }}
+ >
+ ({
+ id,
+ label: name,
+ value: context,
+ }))}
+ Icon={IconBrackets}
+ depth={0}
+ keyPath=""
+ emptyElementsText=""
+ />
+
+
+ >
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepJsonContainer.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepJsonContainer.tsx
new file mode 100644
index 000000000..bd61776e4
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepJsonContainer.tsx
@@ -0,0 +1,11 @@
+import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
+import styled from '@emotion/styled';
+
+const StyledWorkflowRunStepJsonContainer = styled(WorkflowStepBody)`
+ grid-template-rows: max-content;
+ gap: 0;
+ display: grid;
+ overflow: auto;
+`;
+
+export { StyledWorkflowRunStepJsonContainer as WorkflowRunStepJsonContainer };
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepOutputDetail.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepOutputDetail.tsx
index c535bd24a..8009bae8e 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepOutputDetail.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowRunStepOutputDetail.tsx
@@ -1,40 +1,68 @@
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
-import styled from '@emotion/styled';
+import { getStepDefinitionOrThrow } from '@/workflow/utils/getStepDefinitionOrThrow';
+import { WorkflowRunStepJsonContainer } from '@/workflow/workflow-steps/components/WorkflowRunStepJsonContainer';
+import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
+import { getActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow';
+import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
+import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
+import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
-import { isTwoFirstDepths, JsonTree } from 'twenty-ui';
import { isDefined } from 'twenty-shared/utils';
-
-const StyledContainer = styled.div`
- display: grid;
- overflow-x: auto;
- padding-block: ${({ theme }) => theme.spacing(4)};
- padding-inline: ${({ theme }) => theme.spacing(3)};
-`;
+import { isTwoFirstDepths, JsonTree, useIcons } from 'twenty-ui';
export const WorkflowRunStepOutputDetail = ({ stepId }: { stepId: string }) => {
+ const { t, i18n } = useLingui();
+ const theme = useTheme();
+ const { getIcon } = useIcons();
+
const workflowRunId = useWorkflowRunIdOrThrow();
const workflowRun = useWorkflowRun({ workflowRunId });
- const { t } = useLingui();
-
if (!isDefined(workflowRun?.output?.stepsOutput)) {
return null;
}
const stepOutput = workflowRun.output.stepsOutput[stepId];
+ const stepDefinition = getStepDefinitionOrThrow({
+ stepId,
+ trigger: workflowRun.output.flow.trigger,
+ steps: workflowRun.output.flow.steps,
+ });
+ if (stepDefinition?.type !== 'action') {
+ throw new Error('The output tab must be rendered with an action step.');
+ }
+
+ const headerTitle = stepDefinition.definition.name;
+ const headerIcon = getActionIcon(stepDefinition.definition.type);
+ const headerIconColor = getActionIconColorOrThrow({
+ theme,
+ actionType: stepDefinition.definition.type,
+ });
+ const headerType = getActionHeaderTypeOrThrow(stepDefinition.definition.type);
+
return (
-
-
+
-
+
+
+
+
+ >
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepBody.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepBody.tsx
index 636f77d4e..59068a397 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepBody.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepBody.tsx
@@ -7,7 +7,8 @@ const StyledWorkflowStepBody = styled.div`
flex-direction: column;
height: 100%;
overflow-y: scroll;
- padding: ${({ theme }) => theme.spacing(4)};
+ padding-block: ${({ theme }) => theme.spacing(4)};
+ padding-inline: ${({ theme }) => theme.spacing(3)};
row-gap: ${({ theme }) => theme.spacing(6)};
`;
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
index 4b790f4dd..71c2dbd40 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
@@ -27,9 +27,10 @@ import { WorkflowEditActionServerlessFunctionFields } from '@/workflow/workflow-
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/code-action/constants/WorkflowServerlessFunctionTabListComponentId';
import { WorkflowServerlessFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowServerlessFunctionTabId';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
-import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Monaco } from '@monaco-editor/react';
import { editor } from 'monaco-editor';
@@ -40,12 +41,6 @@ import { CodeEditor, IconCode, IconPlayerPlay, useIcons } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
import { isDefined } from 'twenty-shared/utils';
-const StyledContainer = styled.div`
- display: flex;
- flex-direction: column;
- height: 100%;
-`;
-
const StyledCodeEditorContainer = styled.div`
display: flex;
flex-direction: column;
@@ -76,7 +71,6 @@ export const WorkflowEditActionServerlessFunction = ({
action,
actionOptions,
}: WorkflowEditActionServerlessFunctionProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const serverlessFunctionId = action.settings.input.serverlessFunctionId;
const activeTabId = useRecoilComponentValueV2(
@@ -287,10 +281,12 @@ export const WorkflowEditActionServerlessFunction = ({
? action.name
: 'Code - Serverless Function';
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
return (
!loading && (
-
+ <>
@@ -373,7 +369,7 @@ export const WorkflowEditActionServerlessFunction = ({
]}
/>
)}
-
+ >
)
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowReadonlyActionServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowReadonlyActionServerlessFunction.tsx
index f6855c3df..aeb241520 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowReadonlyActionServerlessFunction.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowReadonlyActionServerlessFunction.tsx
@@ -7,8 +7,9 @@ import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath'
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowEditActionServerlessFunctionFields } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunctionFields';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
-import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Monaco } from '@monaco-editor/react';
import { editor } from 'monaco-editor';
@@ -16,12 +17,6 @@ import { AutoTypings } from 'monaco-editor-auto-typings';
import { CodeEditor, useIcons } from 'twenty-ui';
import { isDefined } from 'twenty-shared/utils';
-const StyledContainer = styled.div`
- display: flex;
- flex-direction: column;
- height: 100%;
-`;
-
const StyledCodeEditorContainer = styled.div`
display: flex;
flex-direction: column;
@@ -34,7 +29,6 @@ type WorkflowReadonlyActionServerlessFunctionProps = {
export const WorkflowReadonlyActionServerlessFunction = ({
action,
}: WorkflowReadonlyActionServerlessFunctionProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const serverlessFunctionId = action.settings.input.serverlessFunctionId;
const serverlessFunctionVersion =
@@ -66,18 +60,20 @@ export const WorkflowReadonlyActionServerlessFunction = ({
? action.name
: 'Code - Serverless Function';
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
if (loading) {
return null;
}
return (
-
+ <>
@@ -99,6 +95,6 @@ export const WorkflowReadonlyActionServerlessFunction = ({
/>
-
+ >
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionCreateRecord.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionCreateRecord.tsx
index 8213a530a..4c2fc1f46 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionCreateRecord.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionCreateRecord.tsx
@@ -7,9 +7,10 @@ import { useViewOrDefaultViewFromPrefetchedViews } from '@/views/hooks/useViewOr
import { WorkflowCreateRecordAction } from '@/workflow/types/Workflow';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
-import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react';
import { HorizontalSeparator, useIcons } from 'twenty-ui';
import { JsonValue } from 'type-fest';
@@ -57,7 +58,6 @@ export const WorkflowEditActionCreateRecord = ({
action,
actionOptions,
}: WorkflowEditActionCreateRecordProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
@@ -159,6 +159,8 @@ export const WorkflowEditActionCreateRecord = ({
const headerTitle = isDefined(action.name) ? action.name : `Create Record`;
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
return (
<>
@@ -174,9 +176,9 @@ export const WorkflowEditActionCreateRecord = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.font.color.tertiary}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Action"
+ headerType={headerType}
disabled={isFormDisabled}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionDeleteRecord.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionDeleteRecord.tsx
index 38d24f452..c24d42756 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionDeleteRecord.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionDeleteRecord.tsx
@@ -3,10 +3,11 @@ import { Select, SelectOption } from '@/ui/input/components/Select';
import { WorkflowDeleteRecordAction } from '@/workflow/types/Workflow';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { WorkflowSingleRecordPicker } from '@/workflow/workflow-steps/workflow-actions/components/WorkflowSingleRecordPicker';
-import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { HorizontalSeparator, useIcons } from 'twenty-ui';
import { JsonValue } from 'type-fest';
@@ -34,7 +35,6 @@ export const WorkflowEditActionDeleteRecord = ({
action,
actionOptions,
}: WorkflowEditActionDeleteRecordProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
@@ -108,6 +108,8 @@ export const WorkflowEditActionDeleteRecord = ({
const headerTitle = isDefined(action.name) ? action.name : `Delete Record`;
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
return (
<>
@@ -123,9 +125,9 @@ export const WorkflowEditActionDeleteRecord = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.font.color.tertiary}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Action"
+ headerType={headerType}
disabled={isFormDisabled}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFindRecords.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFindRecords.tsx
index 96d970f0a..60bbe3069 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFindRecords.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFindRecords.tsx
@@ -2,11 +2,12 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
import { Select, SelectOption } from '@/ui/input/components/Select';
import { WorkflowFindRecordsAction } from '@/workflow/types/Workflow';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
-import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react';
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { HorizontalSeparator, useIcons } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
@@ -33,7 +34,6 @@ export const WorkflowEditActionFindRecords = ({
action,
actionOptions,
}: WorkflowEditActionFindRecordsProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
@@ -90,6 +90,8 @@ export const WorkflowEditActionFindRecords = ({
const headerTitle = isDefined(action.name) ? action.name : `Search Records`;
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
return (
<>
@@ -105,9 +107,9 @@ export const WorkflowEditActionFindRecords = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.font.color.tertiary}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Action"
+ headerType={headerType}
disabled={isFormDisabled}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
index ddd875dd2..bbbb1ba20 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
@@ -12,9 +12,10 @@ import { workflowIdState } from '@/workflow/states/workflowIdState';
import { WorkflowSendEmailAction } from '@/workflow/types/Workflow';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
-import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { IconPlus, useIcons } from 'twenty-ui';
@@ -47,7 +48,6 @@ export const WorkflowEditActionSendEmail = ({
action,
actionOptions,
}: WorkflowEditActionSendEmailProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const { triggerApisOAuth } = useTriggerApisOAuth();
@@ -188,6 +188,9 @@ export const WorkflowEditActionSendEmail = ({
const headerTitle = isDefined(action.name) ? action.name : 'Send Email';
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
+
const navigate = useNavigateSettings();
const { closeCommandMenu } = useCommandMenu();
@@ -206,9 +209,9 @@ export const WorkflowEditActionSendEmail = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.color.blue}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Email"
+ headerType={headerType}
disabled={actionOptions.readonly}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionUpdateRecord.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionUpdateRecord.tsx
index f1592e8d8..707a9b710 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionUpdateRecord.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionUpdateRecord.tsx
@@ -1,7 +1,6 @@
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { Select, SelectOption } from '@/ui/input/components/Select';
import { WorkflowUpdateRecordAction } from '@/workflow/types/Workflow';
-import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react';
import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition';
@@ -10,6 +9,8 @@ import { FormMultiSelectFieldInput } from '@/object-record/record-field/form-typ
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { WorkflowSingleRecordPicker } from '@/workflow/workflow-steps/workflow-actions/components/WorkflowSingleRecordPicker';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { HorizontalSeparator, useIcons } from 'twenty-ui';
@@ -59,7 +60,6 @@ export const WorkflowEditActionUpdateRecord = ({
action,
actionOptions,
}: WorkflowEditActionUpdateRecordProps) => {
- const theme = useTheme();
const { getIcon } = useIcons();
const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
@@ -160,6 +160,8 @@ export const WorkflowEditActionUpdateRecord = ({
const headerTitle = isDefined(action.name) ? action.name : `Update Record`;
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
return (
<>
@@ -175,9 +177,9 @@ export const WorkflowEditActionUpdateRecord = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.font.color.tertiary}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Action"
+ headerType={headerType}
disabled={isFormDisabled}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionFindRecords.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionFindRecords.stories.tsx
index ad054856e..d3e3f3bca 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionFindRecords.stories.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionFindRecords.stories.tsx
@@ -3,6 +3,7 @@ import { WorkflowEditActionFindRecords } from '@/workflow/workflow-steps/workflo
import { Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';
import { ComponentDecorator, RouterDecorator } from 'twenty-ui';
+import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { WorkflowStepActionDrawerDecorator } from '~/testing/decorators/WorkflowStepActionDrawerDecorator';
@@ -50,6 +51,7 @@ const meta: Meta = {
SnackBarDecorator,
RouterDecorator,
WorkspaceDecorator,
+ I18nFrontDecorator,
],
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/OtherActions.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/OtherActions.ts
index 45c6d6606..909c7b8fc 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/OtherActions.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/OtherActions.ts
@@ -1,8 +1,11 @@
-import { WorkflowStepType } from '@/workflow/types/Workflow';
+import { WorkflowActionType } from '@/workflow/types/Workflow';
export const OTHER_ACTIONS: Array<{
label: string;
- type: WorkflowStepType;
+ type: Exclude<
+ WorkflowActionType,
+ 'CREATE_RECORD' | 'UPDATE_RECORD' | 'DELETE_RECORD' | 'FIND_RECORDS'
+ >;
icon: string;
}> = [
{
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/RecordActions.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/RecordActions.ts
index f97eca306..2d27e9761 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/RecordActions.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/constants/RecordActions.ts
@@ -1,8 +1,11 @@
-import { WorkflowStepType } from '@/workflow/types/Workflow';
+import { WorkflowActionType } from '@/workflow/types/Workflow';
export const RECORD_ACTIONS: Array<{
label: string;
- type: WorkflowStepType;
+ type: Extract<
+ WorkflowActionType,
+ 'CREATE_RECORD' | 'UPDATE_RECORD' | 'DELETE_RECORD' | 'FIND_RECORDS'
+ >;
icon: string;
}> = [
{
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormBuilder.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormBuilder.tsx
index 88b61ef4f..87200657e 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormBuilder.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormBuilder.tsx
@@ -8,6 +8,8 @@ import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/Workflo
import { WorkflowEditActionFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormFieldSettings';
import { WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
+import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
+import { useActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow';
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
@@ -99,6 +101,9 @@ export const WorkflowEditActionFormBuilder = ({
const headerTitle = isDefined(action.name) ? action.name : `Form`;
const headerIcon = getActionIcon(action.type);
+ const headerIconColor = useActionIconColorOrThrow(action.type);
+ const headerType = useActionHeaderTypeOrThrow(action.type);
+
const [selectedField, setSelectedField] = useState(null);
const isFieldSelected = (fieldName: string) => selectedField === fieldName;
const handleFieldClick = (fieldName: string) => {
@@ -161,9 +166,9 @@ export const WorkflowEditActionFormBuilder = ({
});
}}
Icon={getIcon(headerIcon)}
- iconColor={theme.font.color.tertiary}
+ iconColor={headerIconColor}
initialTitle={headerTitle}
- headerType="Action"
+ headerType={headerType}
disabled={actionOptions.readonly}
/>
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow.ts
new file mode 100644
index 000000000..0c336898c
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow.ts
@@ -0,0 +1,9 @@
+import { WorkflowActionType } from '@/workflow/types/Workflow';
+import { getActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow';
+import { useLingui } from '@lingui/react';
+
+export const useActionHeaderTypeOrThrow = (actionType: WorkflowActionType) => {
+ const { _ } = useLingui();
+
+ return _(getActionHeaderTypeOrThrow(actionType));
+};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow.ts
new file mode 100644
index 000000000..c1246ce8c
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/hooks/useActionIconColorOrThrow.ts
@@ -0,0 +1,9 @@
+import { WorkflowActionType } from '@/workflow/types/Workflow';
+import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
+import { useTheme } from '@emotion/react';
+
+export const useActionIconColorOrThrow = (actionType: WorkflowActionType) => {
+ const theme = useTheme();
+
+ return getActionIconColorOrThrow({ theme, actionType });
+};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
new file mode 100644
index 000000000..692c6b1ad
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
@@ -0,0 +1,20 @@
+import { WorkflowActionType } from '@/workflow/types/Workflow';
+import { msg } from '@lingui/core/macro';
+import { assertUnreachable } from 'twenty-shared/utils';
+
+export const getActionHeaderTypeOrThrow = (actionType: WorkflowActionType) => {
+ switch (actionType) {
+ case 'CODE':
+ return msg`Code`;
+ case 'CREATE_RECORD':
+ case 'UPDATE_RECORD':
+ case 'DELETE_RECORD':
+ case 'FIND_RECORDS':
+ case 'FORM':
+ return msg`Action`;
+ case 'SEND_EMAIL':
+ return msg`Email`;
+ default:
+ assertUnreachable(actionType, `Unsupported action type: ${actionType}`);
+ }
+};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIcon.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIcon.ts
index a571fcbe7..7feb3fefe 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIcon.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIcon.ts
@@ -1,7 +1,8 @@
+import { WorkflowActionType } from '@/workflow/types/Workflow';
import { OTHER_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constants/OtherActions';
import { RECORD_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constants/RecordActions';
-export const getActionIcon = (actionType: string) => {
+export const getActionIcon = (actionType: WorkflowActionType) => {
switch (actionType) {
case 'CREATE_RECORD':
case 'UPDATE_RECORD':
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow.ts
new file mode 100644
index 000000000..348f49df8
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow.ts
@@ -0,0 +1,26 @@
+import { WorkflowActionType } from '@/workflow/types/Workflow';
+import { Theme } from '@emotion/react';
+import { assertUnreachable } from 'twenty-shared/utils';
+
+export const getActionIconColorOrThrow = ({
+ theme,
+ actionType,
+}: {
+ theme: Theme;
+ actionType: WorkflowActionType;
+}) => {
+ switch (actionType) {
+ case 'CODE':
+ return theme.color.orange;
+ case 'CREATE_RECORD':
+ case 'UPDATE_RECORD':
+ case 'DELETE_RECORD':
+ case 'FIND_RECORDS':
+ case 'FORM':
+ return theme.font.color.tertiary;
+ case 'SEND_EMAIL':
+ return theme.color.blue;
+ default:
+ assertUnreachable(actionType, `Unsupported action type: ${actionType}`);
+ }
+};