Migrate output schema to V2 (#14311)
Previous refacto was creating output schema V2 which has more specific schemas based on the step type. Before we were using one common schema, which was too complex when searching for variable informations. This PR migrate the deprecated schemas and remove the old code: - mark previous `BaseOutputSchema` as deprecated - remove other previous schemas - use V2 everywhere - icon should not be stored in schema. Instead it should be generated based on the fieldmetadata or the item type
This commit is contained in:
+7
-13
@@ -4,13 +4,12 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { type InputSchemaPropertyType } from '@/workflow/types/InputSchema';
|
||||
import { WorkflowVariablesDropdownAllItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownAllItems';
|
||||
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
|
||||
import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems';
|
||||
import { WorkflowVariablesDropdownStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownStepItems';
|
||||
import { WorkflowVariablesDropdownSteps } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownSteps';
|
||||
import { SEARCH_VARIABLES_DROPDOWN_ID } from '@/workflow/workflow-variables/constants/SearchVariablesDropdownId';
|
||||
|
||||
import { useAvailableVariablesInWorkflowStep } from '@/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep';
|
||||
import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { type StepOutputSchemaV2 } from '@/workflow/workflow-variables/types/StepOutputSchemaV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
@@ -73,7 +72,7 @@ export const WorkflowVariablesDropdown = ({
|
||||
: undefined;
|
||||
|
||||
const [selectedStep, setSelectedStep] = useState<
|
||||
StepOutputSchema | undefined
|
||||
StepOutputSchemaV2 | undefined
|
||||
>(initialStep);
|
||||
|
||||
const handleStepSelect = (stepId: string) => {
|
||||
@@ -122,22 +121,17 @@ export const WorkflowVariablesDropdown = ({
|
||||
}
|
||||
dropdownComponents={
|
||||
!isDefined(selectedStep) ? (
|
||||
<WorkflowVariablesDropdownWorkflowStepItems
|
||||
<WorkflowVariablesDropdownSteps
|
||||
dropdownId={dropdownId}
|
||||
steps={availableVariablesInWorkflowStep}
|
||||
onSelect={handleStepSelect}
|
||||
/>
|
||||
) : shouldDisplayRecordObjects ? (
|
||||
<WorkflowVariablesDropdownAllItems
|
||||
step={selectedStep}
|
||||
onSelect={handleSubItemSelect}
|
||||
onBack={handleBack}
|
||||
/>
|
||||
) : (
|
||||
<WorkflowVariablesDropdownFieldItems
|
||||
<WorkflowVariablesDropdownStepItems
|
||||
step={selectedStep}
|
||||
onSelect={handleSubItemSelect}
|
||||
onBack={handleBack}
|
||||
shouldDisplayRecordObjects={shouldDisplayRecordObjects}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||
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 { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
OverflowingTextWithTooltip,
|
||||
useIcons,
|
||||
} from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { useVariableDropdown } from '../hooks/useVariableDropdown';
|
||||
|
||||
type WorkflowVariablesDropdownFieldItemsProps = {
|
||||
step: StepOutputSchema;
|
||||
onSelect: (value: string) => void;
|
||||
onBack: () => void;
|
||||
};
|
||||
|
||||
export const WorkflowVariablesDropdownFieldItems = ({
|
||||
step,
|
||||
onSelect,
|
||||
onBack,
|
||||
}: WorkflowVariablesDropdownFieldItemsProps) => {
|
||||
const { getIcon } = useIcons();
|
||||
const {
|
||||
searchInputValue,
|
||||
setSearchInputValue,
|
||||
handleSelectField,
|
||||
goBack,
|
||||
filteredOptions,
|
||||
currentPath,
|
||||
} = useVariableDropdown({
|
||||
step,
|
||||
onSelect,
|
||||
onBack,
|
||||
});
|
||||
|
||||
return (
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={goBack}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<OverflowingTextWithTooltip
|
||||
text={getStepHeaderLabel(step, currentPath)}
|
||||
/>
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
value={searchInputValue}
|
||||
onChange={(event) => setSearchInputValue(event.target.value)}
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredOptions.map(([key, option]) => (
|
||||
<MenuItemSelect
|
||||
key={key}
|
||||
selected={false}
|
||||
focused={false}
|
||||
onClick={() => handleSelectField(key)}
|
||||
text={option.label || key}
|
||||
hasSubMenu={!option.isLeaf}
|
||||
LeftIcon={option.icon ? getIcon(option.icon) : undefined}
|
||||
contextualText={
|
||||
option.isLeaf ? option?.value?.toString() : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
);
|
||||
};
|
||||
+44
-22
@@ -2,16 +2,19 @@ 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 { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { isRecordOutputSchemaV2 } from '@/workflow/workflow-variables/types/guards/isRecordOutputSchemaV2';
|
||||
import { type StepOutputSchemaV2 } from '@/workflow/workflow-variables/types/StepOutputSchemaV2';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
import { getStepItemIcon } from '@/workflow/workflow-variables/utils/getStepItemIcon';
|
||||
import { getVariableTemplateFromPath } from '@/workflow/workflow-variables/utils/getVariableTemplateFromPath';
|
||||
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
OverflowingTextWithTooltip,
|
||||
@@ -20,17 +23,19 @@ import {
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { useVariableDropdown } from '../hooks/useVariableDropdown';
|
||||
|
||||
type WorkflowVariablesDropdownAllItemsProps = {
|
||||
step: StepOutputSchema;
|
||||
type WorkflowVariablesDropdownStepItemsProps = {
|
||||
step: StepOutputSchemaV2;
|
||||
onSelect: (value: string) => void;
|
||||
onBack: () => void;
|
||||
shouldDisplayRecordObjects: boolean;
|
||||
};
|
||||
|
||||
export const WorkflowVariablesDropdownAllItems = ({
|
||||
export const WorkflowVariablesDropdownStepItems = ({
|
||||
step,
|
||||
onSelect,
|
||||
onBack,
|
||||
}: WorkflowVariablesDropdownAllItemsProps) => {
|
||||
shouldDisplayRecordObjects,
|
||||
}: WorkflowVariablesDropdownStepItemsProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const {
|
||||
@@ -46,10 +51,12 @@ export const WorkflowVariablesDropdownAllItems = ({
|
||||
onBack,
|
||||
});
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const getDisplayedSubStepObject = () => {
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
if (!isRecordOutputSchemaV2(currentSubStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,30 +66,37 @@ export const WorkflowVariablesDropdownAllItems = ({
|
||||
const handleSelectObject = () => {
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
if (!isRecordOutputSchemaV2(currentSubStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
onSelect(
|
||||
getVariableTemplateFromPath({
|
||||
stepId: step.id,
|
||||
path: [...currentPath, currentSubStep.object.fieldIdName],
|
||||
path: [...currentPath, 'id'],
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const displayedSubStepObject = getDisplayedSubStepObject();
|
||||
|
||||
const shouldDisplaySubStepObject = searchInputValue
|
||||
? displayedSubStepObject?.label &&
|
||||
displayedSubStepObject.label
|
||||
const displayedSubStepObjectMetadata = isDefined(displayedSubStepObject)
|
||||
? objectMetadataItems.find(
|
||||
(item) => item.id === displayedSubStepObject?.objectMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const isObjectFoundThroughSearch = isDefined(searchInputValue)
|
||||
? isDefined(displayedSubStepObject?.label) &&
|
||||
displayedSubStepObject?.label
|
||||
.toLowerCase()
|
||||
.includes(searchInputValue.toLowerCase())
|
||||
: true;
|
||||
|
||||
const shouldDisplayObject =
|
||||
shouldDisplaySubStepObject && displayedSubStepObject?.label;
|
||||
const nameSingular = displayedSubStepObject?.nameSingular;
|
||||
const shouldDisplaySubStepObject =
|
||||
shouldDisplayRecordObjects && isObjectFoundThroughSearch;
|
||||
|
||||
const objectLabel = displayedSubStepObjectMetadata?.labelSingular;
|
||||
|
||||
return (
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
|
||||
@@ -105,22 +119,22 @@ export const WorkflowVariablesDropdownAllItems = ({
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{shouldDisplayObject && (
|
||||
{shouldDisplaySubStepObject && (
|
||||
<MenuItemSelect
|
||||
selected={false}
|
||||
focused={false}
|
||||
onClick={handleSelectObject}
|
||||
text={displayedSubStepObject?.label || ''}
|
||||
text={objectLabel || ''}
|
||||
hasSubMenu={false}
|
||||
LeftIcon={
|
||||
displayedSubStepObject.icon
|
||||
? getIcon(displayedSubStepObject.icon)
|
||||
displayedSubStepObjectMetadata?.icon
|
||||
? getIcon(displayedSubStepObjectMetadata.icon)
|
||||
: undefined
|
||||
}
|
||||
contextualText={t`Pick a ${nameSingular} record`}
|
||||
contextualText={t`Pick a ${objectLabel} record`}
|
||||
/>
|
||||
)}
|
||||
{filteredOptions.length > 0 && shouldDisplayObject && (
|
||||
{filteredOptions.length > 0 && shouldDisplaySubStepObject && (
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
{filteredOptions.map(([key, subStep]) => (
|
||||
@@ -131,7 +145,15 @@ export const WorkflowVariablesDropdownAllItems = ({
|
||||
onClick={() => handleSelectField(key)}
|
||||
text={subStep.label || key}
|
||||
hasSubMenu={!subStep.isLeaf}
|
||||
LeftIcon={subStep.icon ? getIcon(subStep.icon) : undefined}
|
||||
LeftIcon={
|
||||
subStep.icon
|
||||
? getIcon(subStep.icon)
|
||||
: getIcon(
|
||||
getStepItemIcon({
|
||||
itemType: subStep.type,
|
||||
}),
|
||||
)
|
||||
}
|
||||
contextualText={
|
||||
subStep.isLeaf ? subStep?.value?.toString() : undefined
|
||||
}
|
||||
+5
-5
@@ -6,22 +6,22 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { type StepOutputSchemaV2 } from '@/workflow/workflow-variables/types/StepOutputSchemaV2';
|
||||
import { useState } from 'react';
|
||||
import { IconX, OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
|
||||
|
||||
type WorkflowVariablesDropdownWorkflowStepItemsProps = {
|
||||
type WorkflowVariablesDropdownStepsProps = {
|
||||
dropdownId: string;
|
||||
steps: StepOutputSchema[];
|
||||
steps: StepOutputSchemaV2[];
|
||||
onSelect: (value: string) => void;
|
||||
};
|
||||
|
||||
export const WorkflowVariablesDropdownWorkflowStepItems = ({
|
||||
export const WorkflowVariablesDropdownSteps = ({
|
||||
dropdownId,
|
||||
steps,
|
||||
onSelect,
|
||||
}: WorkflowVariablesDropdownWorkflowStepItemsProps) => {
|
||||
}: WorkflowVariablesDropdownStepsProps) => {
|
||||
const { getIcon } = useIcons();
|
||||
const [searchInputValue, setSearchInputValue] = useState('');
|
||||
|
||||
Reference in New Issue
Block a user