Remove before-after + fix header label (#9932)
- Fix header label on step Before <img width="224" alt="Capture d’écran 2025-01-30 à 12 11 27" src="https://github.com/user-attachments/assets/e04e2d83-2414-4a92-a307-159e1ca16c64" /> <img width="224" alt="Capture d’écran 2025-01-30 à 13 27 40" src="https://github.com/user-attachments/assets/72e2c567-7ee0-43ff-9ae2-898e46d677c1" /> After <img width="224" alt="Capture d’écran 2025-01-30 à 13 29 00" src="https://github.com/user-attachments/assets/e7e458ab-458d-4e84-98a2-63596f44e0e7" /> <img width="224" alt="Capture d’écran 2025-01-30 à 13 29 25" src="https://github.com/user-attachments/assets/df1b0cbd-c8f2-44f6-b2f6-944e5ec8e14f" /> - Remove before - after when there is only one of them
This commit is contained in:
@ -5,7 +5,6 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import {
|
||||
BaseOutputSchema,
|
||||
LinkOutputSchema,
|
||||
OutputSchema,
|
||||
StepOutputSchema,
|
||||
} from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
|
||||
@ -15,6 +14,8 @@ import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { workflowDiagramTriggerNodeSelectionState } from '@/workflow/workflow-diagram/states/workflowDiagramTriggerNodeSelectionState';
|
||||
import { workflowSelectedNodeState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeState';
|
||||
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/constants/WorkflowServerlessFunctionTabListComponentId';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
import { isLinkOutputSchema } from '@/workflow/workflow-variables/utils/isLinkOutputSchema';
|
||||
import { useState } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
@ -48,22 +49,8 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
workflowDiagramTriggerNodeSelectionState,
|
||||
);
|
||||
|
||||
const getCurrentSubStep = (): OutputSchema => {
|
||||
let currentSubStep = step.outputSchema;
|
||||
|
||||
for (const key of currentPath) {
|
||||
if (isRecordOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep.fields[key]?.value;
|
||||
} else if (isBaseOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep[key]?.value;
|
||||
}
|
||||
}
|
||||
|
||||
return currentSubStep;
|
||||
};
|
||||
|
||||
const getDisplayedSubStepFields = () => {
|
||||
const currentSubStep = getCurrentSubStep();
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (isLinkOutputSchema(currentSubStep)) {
|
||||
return { link: currentSubStep.link };
|
||||
@ -75,7 +62,7 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
};
|
||||
|
||||
const handleSelectField = (key: string) => {
|
||||
const currentSubStep = getCurrentSubStep();
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
const handleSelectBaseOutputSchema = (
|
||||
baseOutputSchema: BaseOutputSchema,
|
||||
@ -115,20 +102,6 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
}
|
||||
};
|
||||
|
||||
const getHeaderLabel = () => {
|
||||
if (currentPath.length === 0) {
|
||||
return step.name;
|
||||
}
|
||||
|
||||
const subStepName = currentPath.at(-1);
|
||||
|
||||
if (isDefined(subStepName) && isRecordOutputSchema(step.outputSchema)) {
|
||||
return step.outputSchema.fields[subStepName].label;
|
||||
}
|
||||
|
||||
return subStepName;
|
||||
};
|
||||
|
||||
const displayedObject = getDisplayedSubStepFields();
|
||||
const options = displayedObject ? Object.entries(displayedObject) : [];
|
||||
|
||||
@ -147,7 +120,9 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
onClick={goBack}
|
||||
style={{ position: 'fixed' }}
|
||||
>
|
||||
<OverflowingTextWithTooltip text={getHeaderLabel()} />
|
||||
<OverflowingTextWithTooltip
|
||||
text={getStepHeaderLabel(step, currentPath)}
|
||||
/>
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
|
||||
@ -2,10 +2,9 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import {
|
||||
OutputSchema,
|
||||
StepOutputSchema,
|
||||
} from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
|
||||
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
|
||||
|
||||
@ -32,22 +31,8 @@ export const WorkflowVariablesDropdownObjectItems = ({
|
||||
const [searchInputValue, setSearchInputValue] = useState('');
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const getCurrentSubStep = (): OutputSchema => {
|
||||
let currentSubStep = step.outputSchema;
|
||||
|
||||
for (const key of currentPath) {
|
||||
if (isRecordOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep.fields[key]?.value;
|
||||
} else if (isBaseOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep[key]?.value;
|
||||
}
|
||||
}
|
||||
|
||||
return currentSubStep;
|
||||
};
|
||||
|
||||
const getDisplayedSubStepFields = () => {
|
||||
const currentSubStep = getCurrentSubStep();
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (isRecordOutputSchema(currentSubStep)) {
|
||||
return currentSubStep.fields;
|
||||
@ -57,7 +42,7 @@ export const WorkflowVariablesDropdownObjectItems = ({
|
||||
};
|
||||
|
||||
const getDisplayedSubStepObject = () => {
|
||||
const currentSubStep = getCurrentSubStep();
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
return;
|
||||
@ -67,7 +52,7 @@ export const WorkflowVariablesDropdownObjectItems = ({
|
||||
};
|
||||
|
||||
const handleSelectObject = () => {
|
||||
const currentSubStep = getCurrentSubStep();
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
return;
|
||||
@ -91,8 +76,6 @@ export const WorkflowVariablesDropdownObjectItems = ({
|
||||
}
|
||||
};
|
||||
|
||||
const headerLabel = currentPath.length === 0 ? step.name : currentPath.at(-1);
|
||||
|
||||
const displayedSubStepObject = getDisplayedSubStepObject();
|
||||
|
||||
const shouldDisplaySubStepObject = searchInputValue
|
||||
@ -116,7 +99,9 @@ export const WorkflowVariablesDropdownObjectItems = ({
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
|
||||
<OverflowingTextWithTooltip text={headerLabel} />
|
||||
<OverflowingTextWithTooltip
|
||||
text={getStepHeaderLabel(step, currentPath)}
|
||||
/>
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
|
||||
const mockStep = {
|
||||
id: 'step-1',
|
||||
name: 'Step 1',
|
||||
outputSchema: {
|
||||
company: {
|
||||
isLeaf: false,
|
||||
icon: 'company',
|
||||
label: 'Company',
|
||||
value: {
|
||||
object: {
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'id',
|
||||
label: 'Company',
|
||||
value: 'John',
|
||||
isLeaf: true,
|
||||
},
|
||||
fields: {
|
||||
name: { label: 'Name', value: 'Twenty', isLeaf: true },
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies StepOutputSchema;
|
||||
|
||||
describe('getCurrentSubStepFromPath', () => {
|
||||
it('should return the current sub step from the path', () => {
|
||||
const path = ['company', 'name'];
|
||||
expect(getCurrentSubStepFromPath(mockStep, path)).toBe('Twenty');
|
||||
});
|
||||
|
||||
it('should return undefined when the path is not valid', () => {
|
||||
const path = ['company', 'unknown'];
|
||||
expect(getCurrentSubStepFromPath(mockStep, path)).toBe(undefined);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,54 @@
|
||||
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
|
||||
const mockStep = {
|
||||
id: 'step-1',
|
||||
name: 'Step 1',
|
||||
outputSchema: {
|
||||
company: {
|
||||
isLeaf: false,
|
||||
icon: 'company',
|
||||
label: 'Company',
|
||||
value: {
|
||||
object: {
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'id',
|
||||
label: 'Company',
|
||||
value: 'John',
|
||||
isLeaf: true,
|
||||
},
|
||||
fields: {
|
||||
name: { label: 'Name', value: 'Twenty', isLeaf: true },
|
||||
address: {
|
||||
label: 'Address',
|
||||
value: {
|
||||
street: { label: 'Street', value: '123 Main St', isLeaf: true },
|
||||
city: { label: 'City', value: 'New York', isLeaf: true },
|
||||
state: { label: 'State', value: 'NY', isLeaf: true },
|
||||
zip: { label: 'Zip', value: '10001', isLeaf: true },
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies StepOutputSchema;
|
||||
|
||||
describe('getStepHeaderLabel', () => {
|
||||
it('should return the step name when the path is empty', () => {
|
||||
const currentPath: string[] = [];
|
||||
expect(getStepHeaderLabel(mockStep, currentPath)).toBe('Step 1');
|
||||
});
|
||||
|
||||
it('should return the field label when the path is not empty', () => {
|
||||
const currentPath: string[] = ['company'];
|
||||
expect(getStepHeaderLabel(mockStep, currentPath)).toBe('Company');
|
||||
});
|
||||
|
||||
it('should return the nested field label when the path is not empty', () => {
|
||||
const currentPath: string[] = ['company', 'address'];
|
||||
expect(getStepHeaderLabel(mockStep, currentPath)).toBe('Address');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,23 @@
|
||||
import {
|
||||
OutputSchema,
|
||||
StepOutputSchema,
|
||||
} from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
|
||||
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
|
||||
|
||||
export const getCurrentSubStepFromPath = (
|
||||
step: StepOutputSchema,
|
||||
path: string[],
|
||||
): OutputSchema => {
|
||||
let currentSubStep = step.outputSchema;
|
||||
|
||||
for (const key of path) {
|
||||
if (isRecordOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep.fields[key]?.value;
|
||||
} else if (isBaseOutputSchema(currentSubStep)) {
|
||||
currentSubStep = currentSubStep[key]?.value;
|
||||
}
|
||||
}
|
||||
|
||||
return currentSubStep;
|
||||
};
|
||||
@ -0,0 +1,40 @@
|
||||
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
|
||||
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const getStepHeaderLabel = (
|
||||
step: StepOutputSchema,
|
||||
currentPath: string[],
|
||||
) => {
|
||||
if (currentPath.length === 0) {
|
||||
return step.name;
|
||||
}
|
||||
|
||||
const subStepName = currentPath.at(-1);
|
||||
const previousSubStep = getCurrentSubStepFromPath(
|
||||
step,
|
||||
currentPath.slice(0, -1),
|
||||
);
|
||||
|
||||
if (!subStepName) {
|
||||
return step.name;
|
||||
}
|
||||
|
||||
if (
|
||||
isRecordOutputSchema(previousSubStep) &&
|
||||
isDefined(previousSubStep.fields[subStepName]?.label)
|
||||
) {
|
||||
return previousSubStep.fields[subStepName].label;
|
||||
}
|
||||
|
||||
if (
|
||||
isBaseOutputSchema(previousSubStep) &&
|
||||
isDefined(previousSubStep[subStepName]?.label)
|
||||
) {
|
||||
return previousSubStep[subStepName].label;
|
||||
}
|
||||
|
||||
return subStepName;
|
||||
};
|
||||
@ -46,11 +46,9 @@ export const generateFakeObjectRecordEvent = (
|
||||
if (action === DatabaseEventAction.CREATED) {
|
||||
return {
|
||||
...baseResult,
|
||||
properties: {
|
||||
'properties.after': {
|
||||
isLeaf: false,
|
||||
value: {
|
||||
after: { isLeaf: false, value: after, label: 'After Creation' },
|
||||
},
|
||||
value: after,
|
||||
label: 'Record Fields',
|
||||
},
|
||||
};
|
||||
@ -75,11 +73,9 @@ export const generateFakeObjectRecordEvent = (
|
||||
if (action === DatabaseEventAction.DELETED) {
|
||||
return {
|
||||
...baseResult,
|
||||
properties: {
|
||||
'properties.before': {
|
||||
isLeaf: false,
|
||||
value: {
|
||||
before: { isLeaf: false, value: before, label: 'Before Deletion' },
|
||||
},
|
||||
value: before,
|
||||
label: 'Record Fields',
|
||||
},
|
||||
};
|
||||
@ -88,15 +84,9 @@ export const generateFakeObjectRecordEvent = (
|
||||
if (action === DatabaseEventAction.DESTROYED) {
|
||||
return {
|
||||
...baseResult,
|
||||
properties: {
|
||||
'properties.before': {
|
||||
isLeaf: false,
|
||||
value: {
|
||||
before: {
|
||||
isLeaf: false,
|
||||
value: before,
|
||||
label: 'Before Permanent Deletion',
|
||||
},
|
||||
},
|
||||
value: before,
|
||||
label: 'Record Fields',
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user