Thomas Trompette
2025-09-10 17:25:40 +02:00
committed by GitHub
parent bcf1bba302
commit 3bfb5bbd86
34 changed files with 642 additions and 118 deletions
@@ -0,0 +1,71 @@
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { useDuplicateStep } from '@/workflow/workflow-steps/hooks/useDuplicateStep';
import { useTheme } from '@emotion/react';
import { useId } from 'react';
import { Button } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
import { getOsControlSymbol } from 'twenty-ui/utilities';
export const WorkflowActionFooter = ({
stepId,
additionalActions,
}: {
stepId: string;
additionalActions?: React.ReactNode[];
}) => {
const dropdownId = useId();
const theme = useTheme();
const { duplicateStep } = useDuplicateStep();
const { closeDropdown } = useCloseDropdown();
const OptionsDropdown = () => {
return (
<Dropdown
dropdownId={dropdownId}
data-select-disable
clickableComponent={
<Button title="Options" hotkeys={[getOsControlSymbol(), 'O']} />
}
dropdownPlacement="top-end"
dropdownOffset={{ y: parseInt(theme.spacing(2), 10) }}
globalHotkeysConfig={{
enableGlobalHotkeysWithModifiers: true,
enableGlobalHotkeysConflictingWithKeyboard: false,
}}
dropdownComponents={
<DropdownContent>
<DropdownMenuItemsContainer>
<SelectableList
selectableListInstanceId={dropdownId}
focusId={dropdownId}
selectableItemIdArray={['duplicate']}
>
<MenuItem
onClick={() => {
closeDropdown(dropdownId);
duplicateStep({ stepId });
}}
text="Duplicate"
/>
</SelectableList>
</DropdownMenuItemsContainer>
</DropdownContent>
}
/>
);
};
return (
<RightDrawerFooter
actions={[
<OptionsDropdown key="options" />,
...(additionalActions ?? []),
]}
/>
);
};
@@ -1,4 +1,3 @@
import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { WorkflowVisualizerComponentInstanceContext } from '../../../workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
@@ -44,17 +43,6 @@ const wrapper = ({ children }: { children: React.ReactNode }) => {
};
describe('useCreateStep', () => {
const mockWorkflow = {
id: '123',
currentVersion: {
id: '456',
status: 'DRAFT',
steps: [],
trigger: { type: 'manual' },
},
versions: [],
};
beforeEach(() => {
jest.clearAllMocks();
});
@@ -63,15 +51,9 @@ describe('useCreateStep', () => {
const mockWorkflowVersionId = 'version-123';
mockGetUpdatableWorkflowVersion.mockResolvedValue(mockWorkflowVersionId);
const { result } = renderHook(
() =>
useCreateStep({
workflow: mockWorkflow as unknown as WorkflowWithCurrentVersion,
}),
{
wrapper,
},
);
const { result } = renderHook(() => useCreateStep(), {
wrapper,
});
await act(async () => {
await result.current.createStep({
@@ -6,11 +6,14 @@ const mockGetUpdatableWorkflowVersion = jest.fn();
const mockDeleteStepsOutputSchema = jest.fn();
const mockCloseCommandMenu = jest.fn();
jest.mock('@/workflow/hooks/useDeleteWorkflowVersionStep', () => ({
useDeleteWorkflowVersionStep: () => ({
deleteWorkflowVersionStep: mockDeleteWorkflowVersionStep,
jest.mock(
'@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionStep',
() => ({
useDeleteWorkflowVersionStep: () => ({
deleteWorkflowVersionStep: mockDeleteWorkflowVersionStep,
}),
}),
}));
);
jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
useGetUpdatableWorkflowVersionOrThrow: () => ({
@@ -0,0 +1,70 @@
import { useDuplicateStep } from '@/workflow/workflow-steps/hooks/useDuplicateStep';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { WorkflowVisualizerComponentInstanceContext } from '../../../workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
const mockGetUpdatableWorkflowVersion = jest.fn();
const mockDuplicateWorkflowVersionStep = jest.fn().mockResolvedValue({
data: {
duplicateWorkflowVersionStep: { createdStep: { id: '2', type: 'CODE' } },
},
});
jest.mock(
'@/workflow/workflow-steps/hooks/useDuplicateWorkflowVersionStep',
() => ({
useDuplicateWorkflowVersionStep: () => ({
duplicateWorkflowVersionStep: mockDuplicateWorkflowVersionStep,
}),
}),
);
jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
useGetUpdatableWorkflowVersionOrThrow: () => ({
getUpdatableWorkflowVersion: mockGetUpdatableWorkflowVersion,
}),
}));
const wrapper = ({ children }: { children: React.ReactNode }) => {
const workflowVisualizerComponentInstanceId =
'workflow-visualizer-instance-id';
return (
<RecoilRoot>
<WorkflowVisualizerComponentInstanceContext.Provider
value={{
instanceId: workflowVisualizerComponentInstanceId,
}}
>
{children}
</WorkflowVisualizerComponentInstanceContext.Provider>
</RecoilRoot>
);
};
describe('useDuplicateStep', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should create step in workflow version', async () => {
const mockWorkflowVersionId = 'version-123';
mockGetUpdatableWorkflowVersion.mockResolvedValue(mockWorkflowVersionId);
const { result } = renderHook(() => useDuplicateStep(), {
wrapper,
});
await act(async () => {
await result.current.duplicateStep({
stepId: 'step-1',
});
});
expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalled();
expect(mockDuplicateWorkflowVersionStep).toHaveBeenCalledWith({
stepId: 'step-1',
workflowVersionId: mockWorkflowVersionId,
});
});
});
@@ -1,20 +1,13 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import {
type WorkflowStepType,
type WorkflowWithCurrentVersion,
} from '@/workflow/types/Workflow';
import { type WorkflowStepType } from '@/workflow/types/Workflow';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { useCreateWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/useCreateWorkflowVersionStep';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useCreateStep = ({
workflow,
}: {
workflow: WorkflowWithCurrentVersion | undefined;
}) => {
export const useCreateStep = () => {
const [isLoading, setIsLoading] = useState(false);
const { createWorkflowVersionStep } = useCreateWorkflowVersionStep();
const setWorkflowSelectedNode = useSetRecoilComponentState(
@@ -27,12 +20,6 @@ export const useCreateStep = ({
const { getUpdatableWorkflowVersion } =
useGetUpdatableWorkflowVersionOrThrow();
if (!isDefined(workflow)) {
return {
createStep: async () => undefined,
};
}
const createStep = async ({
newStepType,
parentStepId,
@@ -1,7 +1,7 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { useDeleteWorkflowVersionStep } from '@/workflow/hooks/useDeleteWorkflowVersionStep';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema';
import { useDeleteWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionStep';
export const useDeleteStep = () => {
const { deleteWorkflowVersionStep } = useDeleteWorkflowVersionStep();
@@ -0,0 +1,39 @@
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
import { DELETE_WORKFLOW_VERSION_STEP } from '@/workflow/graphql/mutations/deleteWorkflowVersionStep';
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
import { useMutation } from '@apollo/client';
import {
type DeleteWorkflowVersionStepInput,
type DeleteWorkflowVersionStepMutation,
type DeleteWorkflowVersionStepMutationVariables,
} from '~/generated-metadata/graphql';
export const useDeleteWorkflowVersionStep = () => {
const apolloCoreClient = useApolloCoreClient();
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
const [mutate] = useMutation<
DeleteWorkflowVersionStepMutation,
DeleteWorkflowVersionStepMutationVariables
>(DELETE_WORKFLOW_VERSION_STEP, {
client: apolloCoreClient,
});
const deleteWorkflowVersionStep = async (
input: DeleteWorkflowVersionStepInput,
) => {
const result = await mutate({ variables: { input } });
const workflowVersionStepChanges = result?.data?.deleteWorkflowVersionStep;
updateWorkflowVersionCache({
workflowVersionStepChanges,
workflowVersionId: input.workflowVersionId,
});
return workflowVersionStepChanges;
};
return { deleteWorkflowVersionStep };
};
@@ -0,0 +1,57 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { useDuplicateWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/useDuplicateWorkflowVersionStep';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useDuplicateStep = () => {
const [isLoading, setIsLoading] = useState(false);
const { duplicateWorkflowVersionStep } = useDuplicateWorkflowVersionStep();
const setWorkflowSelectedNode = useSetRecoilComponentState(
workflowSelectedNodeComponentState,
);
const setWorkflowLastCreatedStepId = useSetRecoilComponentState(
workflowLastCreatedStepIdComponentState,
);
const { getUpdatableWorkflowVersion } =
useGetUpdatableWorkflowVersionOrThrow();
const duplicateStep = async ({ stepId }: { stepId: string }) => {
if (isLoading === true) {
return;
}
setIsLoading(true);
try {
const workflowVersionId = await getUpdatableWorkflowVersion();
const workflowVersionStepChanges = (
await duplicateWorkflowVersionStep({
workflowVersionId,
stepId,
})
)?.data?.duplicateWorkflowVersionStep;
const createdStep = workflowVersionStepChanges?.createdStep;
if (!isDefined(createdStep)) {
throw new Error("Couldn't duplicate step");
}
setWorkflowSelectedNode(createdStep.id);
setWorkflowLastCreatedStepId(createdStep.id);
return createdStep;
} finally {
setIsLoading(false);
}
};
return {
duplicateStep,
};
};
@@ -0,0 +1,55 @@
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { DUPLICATE_WORKFLOW_VERSION_STEP } from '@/workflow/graphql/mutations/duplicateWorkflowVersionStep';
import { flowComponentState } from '@/workflow/states/flowComponentState';
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
import { useMutation } from '@apollo/client';
import { isDefined } from 'twenty-shared/utils';
import {
type DuplicateWorkflowVersionStepInput,
type DuplicateWorkflowVersionStepMutation,
type DuplicateWorkflowVersionStepMutationVariables,
} from '~/generated-metadata/graphql';
export const useDuplicateWorkflowVersionStep = () => {
const apolloCoreClient = useApolloCoreClient();
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
const setFlow = useSetRecoilComponentState(flowComponentState);
const [mutate] = useMutation<
DuplicateWorkflowVersionStepMutation,
DuplicateWorkflowVersionStepMutationVariables
>(DUPLICATE_WORKFLOW_VERSION_STEP, {
client: apolloCoreClient,
});
const duplicateWorkflowVersionStep = async (
input: DuplicateWorkflowVersionStepInput,
) => {
const result = await mutate({
variables: { input },
});
const workflowVersionStepChanges =
result?.data?.duplicateWorkflowVersionStep;
const updatedWorkflowVersion = updateWorkflowVersionCache({
workflowVersionStepChanges,
workflowVersionId: input.workflowVersionId,
});
if (isDefined(updatedWorkflowVersion)) {
setFlow({
workflowVersionId: updatedWorkflowVersion.id,
trigger: updatedWorkflowVersion.trigger,
steps: updatedWorkflowVersion.steps,
});
}
return result;
};
return { duplicateWorkflowVersionStep };
};
@@ -3,6 +3,7 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/components/FormTextFieldInput';
import { Select } from '@/ui/input/components/Select';
import { type WorkflowAiAgentAction } from '@/workflow/types/Workflow';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
@@ -145,6 +146,7 @@ export const WorkflowEditActionAiAgent = ({
readonly={actionOptions.readonly}
/>
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -24,7 +24,6 @@ import { getFunctionOutputSchema } from '@/serverless-functions/utils/getFunctio
import { mergeDefaultFunctionInputAndFunctionInput } from '@/serverless-functions/utils/mergeDefaultFunctionInputAndFunctionInput';
import { InputLabel } from '@/ui/input/components/InputLabel';
import { TextArea } from '@/ui/input/components/TextArea';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
@@ -44,6 +43,7 @@ import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { type Monaco } from '@monaco-editor/react';
import { type editor } from 'monaco-editor';
import { AutoTypings } from 'monaco-editor-auto-typings';
@@ -515,15 +515,20 @@ export const WorkflowEditActionServerlessFunction = ({
</>
)}
</WorkflowStepBody>
{activeTabId === WorkflowServerlessFunctionTabId.TEST && (
<RightDrawerFooter
actions={[
<CmdEnterActionButton
title="Test"
onClick={handleRunFunction}
disabled={isTesting || actionOptions.readonly}
/>,
]}
{!actionOptions.readonly && (
<WorkflowActionFooter
stepId={action.id}
additionalActions={
activeTabId === WorkflowServerlessFunctionTabId.TEST
? [
<CmdEnterActionButton
title="Test"
onClick={handleRunFunction}
disabled={isTesting}
/>,
]
: []
}
/>
)}
{fullScreenOverlay}
@@ -7,6 +7,7 @@ import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useViewOrDefaultViewFromPrefetchedViews } from '@/views/hooks/useViewOrDefaultViewFromPrefetchedViews';
import { type WorkflowCreateRecordAction } from '@/workflow/types/Workflow';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
@@ -271,6 +272,7 @@ export const WorkflowEditActionCreateRecord = ({
);
})}
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -6,6 +6,7 @@ import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/Workflo
import { useEffect, useState } from 'react';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
@@ -179,6 +180,7 @@ export const WorkflowEditActionDeleteRecord = ({
/>
)}
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -11,6 +11,7 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { type WorkflowSendEmailAction } from '@/workflow/types/Workflow';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
@@ -294,6 +295,7 @@ export const WorkflowEditActionSendEmail = ({
multiline
/>
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
)
);
@@ -9,6 +9,7 @@ import { FormSingleRecordPicker } from '@/object-record/record-field/ui/form-typ
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { WorkflowFieldsMultiSelect } from '@/workflow/components/WorkflowEditUpdateEventFieldsMultiSelect';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
@@ -265,6 +266,7 @@ export const WorkflowEditActionUpdateRecord = ({
);
})}
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -13,6 +13,7 @@ import { type RecordFilter } from '@/object-record/record-filter/types/RecordFil
import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext';
import { useRecordIndexFieldMetadataDerivedStates } from '@/object-record/record-index/hooks/useRecordIndexFieldMetadataDerivedStates';
import { InputLabel } from '@/ui/input/components/InputLabel';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowFindRecordsFilters } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters';
import { WorkflowFindRecordsFiltersEffect } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFiltersEffect';
@@ -232,6 +233,7 @@ export const WorkflowEditActionFindRecords = ({
readonly
/>
</WorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -6,6 +6,7 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { type WorkflowFormAction } from '@/workflow/types/Workflow';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { WorkflowEditActionFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormFieldSettings';
@@ -398,6 +399,7 @@ export const WorkflowEditActionFormBuilder = ({
</StyledAddFieldButtonContainer>
)}
</StyledWorkflowStepBody>
{!actionOptions.readonly && <WorkflowActionFooter stepId={action.id} />}
</>
);
};
@@ -5,7 +5,9 @@ import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
import { FieldMetadataType } from 'twenty-shared/types';
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { WorkflowStepActionDrawerDecorator } from '~/testing/decorators/WorkflowStepActionDrawerDecorator';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { getWorkflowNodeIdMock } from '~/testing/mock-data/workflow';
@@ -56,9 +58,11 @@ const meta: Meta<typeof WorkflowEditActionFormBuilder> = {
},
decorators: [
WorkflowStepActionDrawerDecorator,
WorkflowStepDecorator,
ComponentDecorator,
RouterDecorator,
I18nFrontDecorator,
ObjectMetadataItemsDecorator,
],
};
@@ -8,10 +8,10 @@ import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-acti
import { CmdEnterActionButton } from '@/action-menu/components/CmdEnterActionButton';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter';
import { isMethodWithBody } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/isMethodWithBody';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
@@ -217,15 +217,20 @@ export const WorkflowEditActionHttpRequest = ({
</StyledTestTabContent>
)}
</WorkflowStepBody>
{activeTabId === WorkflowHttpRequestTabId.TEST && (
<RightDrawerFooter
actions={[
<CmdEnterActionButton
title="Test"
onClick={handleTestRequest}
disabled={isTesting || actionOptions.readonly}
/>,
]}
{!actionOptions.readonly && (
<WorkflowActionFooter
stepId={action.id}
additionalActions={
activeTabId === WorkflowHttpRequestTabId.TEST
? [
<CmdEnterActionButton
title="Test"
onClick={handleTestRequest}
disabled={isTesting}
/>,
]
: []
}
/>
)}
</>
@@ -3,6 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
import { expect, fn, waitFor, within } from '@storybook/test';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { WorkflowStepActionDrawerDecorator } from '~/testing/decorators/WorkflowStepActionDrawerDecorator';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
@@ -84,6 +85,7 @@ const meta: Meta<typeof WorkflowEditActionHttpRequest> = {
SnackBarDecorator,
WorkspaceDecorator,
I18nFrontDecorator,
ObjectMetadataItemsDecorator,
],
};