mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-22 19:41:53 +03:00
Add fields to update in update record action (#9108)
- update backend action so it handles composite fields - add fields to update multiselect - generate form based on that field - add icons
This commit is contained in:
parent
b6508cc615
commit
94676215ad
@ -11,6 +11,7 @@ import { SelectOption } from '@/spreadsheet-import/types';
|
|||||||
import { MultiSelectDisplay } from '@/ui/field/display/components/MultiSelectDisplay';
|
import { MultiSelectDisplay } from '@/ui/field/display/components/MultiSelectDisplay';
|
||||||
import { MultiSelectInput } from '@/ui/field/input/components/MultiSelectInput';
|
import { MultiSelectInput } from '@/ui/field/input/components/MultiSelectInput';
|
||||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||||
|
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
|
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
|
||||||
import { useId, useState } from 'react';
|
import { useId, useState } from 'react';
|
||||||
@ -20,9 +21,9 @@ import { isDefined } from '~/utils/isDefined';
|
|||||||
type FormMultiSelectFieldInputProps = {
|
type FormMultiSelectFieldInputProps = {
|
||||||
label?: string;
|
label?: string;
|
||||||
defaultValue: FieldMultiSelectValue | string | undefined;
|
defaultValue: FieldMultiSelectValue | string | undefined;
|
||||||
|
options: SelectOption[];
|
||||||
onPersist: (value: FieldMultiSelectValue | string) => void;
|
onPersist: (value: FieldMultiSelectValue | string) => void;
|
||||||
VariablePicker?: VariablePickerComponent;
|
VariablePicker?: VariablePickerComponent;
|
||||||
options: SelectOption[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledDisplayModeContainer = styled.button`
|
const StyledDisplayModeContainer = styled.button`
|
||||||
@ -50,9 +51,9 @@ const StyledSelectInputContainer = styled.div`
|
|||||||
export const FormMultiSelectFieldInput = ({
|
export const FormMultiSelectFieldInput = ({
|
||||||
label,
|
label,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
|
options,
|
||||||
onPersist,
|
onPersist,
|
||||||
VariablePicker,
|
VariablePicker,
|
||||||
options,
|
|
||||||
}: FormMultiSelectFieldInputProps) => {
|
}: FormMultiSelectFieldInputProps) => {
|
||||||
const inputId = useId();
|
const inputId = useId();
|
||||||
|
|
||||||
@ -189,13 +190,15 @@ export const FormMultiSelectFieldInput = ({
|
|||||||
<StyledSelectInputContainer>
|
<StyledSelectInputContainer>
|
||||||
{draftValue.type === 'static' &&
|
{draftValue.type === 'static' &&
|
||||||
draftValue.editingMode === 'edit' && (
|
draftValue.editingMode === 'edit' && (
|
||||||
<MultiSelectInput
|
<OverlayContainer>
|
||||||
hotkeyScope={hotkeyScope}
|
<MultiSelectInput
|
||||||
options={options}
|
hotkeyScope={hotkeyScope}
|
||||||
onCancel={onCancel}
|
options={options}
|
||||||
onOptionSelected={onOptionSelected}
|
onCancel={onCancel}
|
||||||
values={draftValue.value}
|
onOptionSelected={onOptionSelected}
|
||||||
/>
|
values={draftValue.value}
|
||||||
|
/>
|
||||||
|
</OverlayContainer>
|
||||||
)}
|
)}
|
||||||
</StyledSelectInputContainer>
|
</StyledSelectInputContainer>
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ export const MultiSelectDisplay = ({
|
|||||||
key={index}
|
key={index}
|
||||||
color={selectedOption.color ?? 'transparent'}
|
color={selectedOption.color ?? 'transparent'}
|
||||||
text={selectedOption.label}
|
text={selectedOption.label}
|
||||||
|
Icon={selectedOption.icon ?? undefined}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
|
@ -127,6 +127,7 @@ export const MultiSelectInput = ({
|
|||||||
selected={values?.includes(option.value) || false}
|
selected={values?.includes(option.value) || false}
|
||||||
text={option.label}
|
text={option.label}
|
||||||
color={option.color ?? 'transparent'}
|
color={option.color ?? 'transparent'}
|
||||||
|
Icon={option.icon ?? undefined}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
onOptionSelected(formatNewSelectedOptions(option.value))
|
onOptionSelected(formatNewSelectedOptions(option.value))
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ export type WorkflowUpdateRecordActionSettings = BaseWorkflowActionSettings & {
|
|||||||
objectName: string;
|
objectName: string;
|
||||||
objectRecord: ObjectRecord;
|
objectRecord: ObjectRecord;
|
||||||
objectRecordId: string;
|
objectRecordId: string;
|
||||||
|
fieldsToUpdate: string[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,9 +12,14 @@ import {
|
|||||||
useIcons,
|
useIcons,
|
||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
|
|
||||||
|
import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition';
|
||||||
|
import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput';
|
||||||
|
import { FormMultiSelectFieldInput } from '@/object-record/record-field/form-types/components/FormMultiSelectFieldInput';
|
||||||
import { WorkflowStepBody } from '@/workflow/components/WorkflowStepBody';
|
import { WorkflowStepBody } from '@/workflow/components/WorkflowStepBody';
|
||||||
|
import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker';
|
||||||
import { JsonValue } from 'type-fest';
|
import { JsonValue } from 'type-fest';
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
type WorkflowEditActionFormUpdateRecordProps = {
|
type WorkflowEditActionFormUpdateRecordProps = {
|
||||||
action: WorkflowUpdateRecordAction;
|
action: WorkflowUpdateRecordAction;
|
||||||
@ -31,9 +36,23 @@ type WorkflowEditActionFormUpdateRecordProps = {
|
|||||||
type UpdateRecordFormData = {
|
type UpdateRecordFormData = {
|
||||||
objectName: string;
|
objectName: string;
|
||||||
objectRecordId: string;
|
objectRecordId: string;
|
||||||
|
fieldsToUpdate: string[];
|
||||||
[field: string]: unknown;
|
[field: string]: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AVAILABLE_FIELD_METADATA_TYPES = [
|
||||||
|
FieldMetadataType.Text,
|
||||||
|
FieldMetadataType.Number,
|
||||||
|
FieldMetadataType.Date,
|
||||||
|
FieldMetadataType.Boolean,
|
||||||
|
FieldMetadataType.Select,
|
||||||
|
FieldMetadataType.MultiSelect,
|
||||||
|
FieldMetadataType.Emails,
|
||||||
|
FieldMetadataType.Links,
|
||||||
|
FieldMetadataType.FullName,
|
||||||
|
FieldMetadataType.Address,
|
||||||
|
];
|
||||||
|
|
||||||
export const WorkflowEditActionFormUpdateRecord = ({
|
export const WorkflowEditActionFormUpdateRecord = ({
|
||||||
action,
|
action,
|
||||||
actionOptions,
|
actionOptions,
|
||||||
@ -53,6 +72,7 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
const [formData, setFormData] = useState<UpdateRecordFormData>({
|
const [formData, setFormData] = useState<UpdateRecordFormData>({
|
||||||
objectName: action.settings.input.objectName,
|
objectName: action.settings.input.objectName,
|
||||||
objectRecordId: action.settings.input.objectRecordId,
|
objectRecordId: action.settings.input.objectRecordId,
|
||||||
|
fieldsToUpdate: action.settings.input.fieldsToUpdate ?? [],
|
||||||
...action.settings.input.objectRecord,
|
...action.settings.input.objectRecord,
|
||||||
});
|
});
|
||||||
const isFormDisabled = actionOptions.readonly;
|
const isFormDisabled = actionOptions.readonly;
|
||||||
@ -75,6 +95,7 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
setFormData({
|
setFormData({
|
||||||
objectName: action.settings.input.objectName,
|
objectName: action.settings.input.objectName,
|
||||||
objectRecordId: action.settings.input.objectRecordId,
|
objectRecordId: action.settings.input.objectRecordId,
|
||||||
|
fieldsToUpdate: action.settings.input.fieldsToUpdate ?? [],
|
||||||
...action.settings.input.objectRecord,
|
...action.settings.input.objectRecord,
|
||||||
});
|
});
|
||||||
}, [action.settings.input]);
|
}, [action.settings.input]);
|
||||||
@ -88,6 +109,27 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
throw new Error('Should have found the metadata item');
|
throw new Error('Should have found the metadata item');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const inlineFieldMetadataItems = selectedObjectMetadataItem.fields
|
||||||
|
.filter(
|
||||||
|
(fieldMetadataItem) =>
|
||||||
|
!fieldMetadataItem.isSystem &&
|
||||||
|
fieldMetadataItem.isActive &&
|
||||||
|
AVAILABLE_FIELD_METADATA_TYPES.includes(fieldMetadataItem.type),
|
||||||
|
)
|
||||||
|
.sort((fieldMetadataItemA, fieldMetadataItemB) =>
|
||||||
|
fieldMetadataItemA.name.localeCompare(fieldMetadataItemB.name),
|
||||||
|
);
|
||||||
|
|
||||||
|
const inlineFieldDefinitions = inlineFieldMetadataItems.map(
|
||||||
|
(fieldMetadataItem) =>
|
||||||
|
formatFieldMetadataItemAsFieldDefinition({
|
||||||
|
field: fieldMetadataItem,
|
||||||
|
objectMetadataItem: selectedObjectMetadataItem,
|
||||||
|
showLabel: true,
|
||||||
|
labelWidth: 90,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const saveAction = useDebouncedCallback(
|
const saveAction = useDebouncedCallback(
|
||||||
async (formData: UpdateRecordFormData) => {
|
async (formData: UpdateRecordFormData) => {
|
||||||
if (actionOptions.readonly === true) {
|
if (actionOptions.readonly === true) {
|
||||||
@ -97,6 +139,7 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
const {
|
const {
|
||||||
objectName: updatedObjectName,
|
objectName: updatedObjectName,
|
||||||
objectRecordId: updatedObjectRecordId,
|
objectRecordId: updatedObjectRecordId,
|
||||||
|
fieldsToUpdate: updatedFieldsToUpdate,
|
||||||
...updatedOtherFields
|
...updatedOtherFields
|
||||||
} = formData;
|
} = formData;
|
||||||
|
|
||||||
@ -108,6 +151,7 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
objectName: updatedObjectName,
|
objectName: updatedObjectName,
|
||||||
objectRecordId: updatedObjectRecordId ?? '',
|
objectRecordId: updatedObjectRecordId ?? '',
|
||||||
objectRecord: updatedOtherFields,
|
objectRecord: updatedOtherFields,
|
||||||
|
fieldsToUpdate: updatedFieldsToUpdate ?? [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -154,6 +198,7 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
const newFormData: UpdateRecordFormData = {
|
const newFormData: UpdateRecordFormData = {
|
||||||
objectName: updatedObjectName,
|
objectName: updatedObjectName,
|
||||||
objectRecordId: '',
|
objectRecordId: '',
|
||||||
|
fieldsToUpdate: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
setFormData(newFormData);
|
setFormData(newFormData);
|
||||||
@ -172,6 +217,48 @@ export const WorkflowEditActionFormUpdateRecord = ({
|
|||||||
objectNameSingular={formData.objectName}
|
objectNameSingular={formData.objectName}
|
||||||
defaultValue={formData.objectRecordId}
|
defaultValue={formData.objectRecordId}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormMultiSelectFieldInput
|
||||||
|
label="Fields to update"
|
||||||
|
defaultValue={formData.fieldsToUpdate}
|
||||||
|
options={inlineFieldDefinitions.map((field) => ({
|
||||||
|
label: field.label,
|
||||||
|
value: field.metadata.fieldName,
|
||||||
|
icon: getIcon(field.iconName),
|
||||||
|
color: 'gray',
|
||||||
|
}))}
|
||||||
|
onPersist={(fieldsToUpdate) =>
|
||||||
|
handleFieldChange('fieldsToUpdate', fieldsToUpdate)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalSeparator noMargin />
|
||||||
|
|
||||||
|
{formData.fieldsToUpdate.map((fieldName) => {
|
||||||
|
const fieldDefinition = inlineFieldDefinitions.find(
|
||||||
|
(definition) => definition.metadata.fieldName === fieldName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(fieldDefinition)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentValue = formData[
|
||||||
|
fieldDefinition.metadata.fieldName
|
||||||
|
] as JsonValue;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormFieldInput
|
||||||
|
key={fieldDefinition.metadata.fieldName}
|
||||||
|
defaultValue={currentValue}
|
||||||
|
field={fieldDefinition}
|
||||||
|
onPersist={(value) => {
|
||||||
|
handleFieldChange(fieldDefinition.metadata.fieldName, value);
|
||||||
|
}}
|
||||||
|
VariablePicker={WorkflowVariablePicker}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</WorkflowStepBody>
|
</WorkflowStepBody>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
|
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
|
||||||
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
@ -20,7 +21,6 @@ import {
|
|||||||
WorkflowActionType,
|
WorkflowActionType,
|
||||||
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
import { isDefined } from 'src/utils/is-defined';
|
import { isDefined } from 'src/utils/is-defined';
|
||||||
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
|
|
||||||
|
|
||||||
const TRIGGER_STEP_ID = 'trigger';
|
const TRIGGER_STEP_ID = 'trigger';
|
||||||
|
|
||||||
@ -152,6 +152,7 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||||
objectRecord: {},
|
objectRecord: {},
|
||||||
objectRecordId: '',
|
objectRecordId: '',
|
||||||
|
fieldsToUpdate: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@ export type WorkflowUpdateRecordActionInput = {
|
|||||||
objectName: string;
|
objectName: string;
|
||||||
objectRecord: ObjectRecord;
|
objectRecord: ObjectRecord;
|
||||||
objectRecordId: string;
|
objectRecordId: string;
|
||||||
|
fieldsToUpdate: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkflowDeleteRecordActionInput = {
|
export type WorkflowDeleteRecordActionInput = {
|
||||||
|
@ -2,7 +2,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
|
||||||
|
|
||||||
|
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
|
||||||
|
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
|
||||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
|
import { formatData } from 'src/engine/twenty-orm/utils/format-data.util';
|
||||||
|
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||||
import {
|
import {
|
||||||
RecordCRUDActionException,
|
RecordCRUDActionException,
|
||||||
RecordCRUDActionExceptionCode,
|
RecordCRUDActionExceptionCode,
|
||||||
@ -12,7 +16,11 @@ import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/wor
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UpdateRecordWorkflowAction implements WorkflowAction {
|
export class UpdateRecordWorkflowAction implements WorkflowAction {
|
||||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
|
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||||
|
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
|
||||||
|
) {}
|
||||||
|
|
||||||
async execute(
|
async execute(
|
||||||
workflowActionInput: WorkflowUpdateRecordActionInput,
|
workflowActionInput: WorkflowUpdateRecordActionInput,
|
||||||
@ -34,14 +42,85 @@ export class UpdateRecordWorkflowAction implements WorkflowAction {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const workspaceId = this.scopedWorkspaceContextFactory.create().workspaceId;
|
||||||
|
|
||||||
|
if (!workspaceId) {
|
||||||
|
throw new RecordCRUDActionException(
|
||||||
|
'Failed to read: Workspace ID is required',
|
||||||
|
RecordCRUDActionExceptionCode.INVALID_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCacheVersion =
|
||||||
|
await this.workspaceCacheStorageService.getMetadataVersion(workspaceId);
|
||||||
|
|
||||||
|
if (currentCacheVersion === undefined) {
|
||||||
|
throw new RecordCRUDActionException(
|
||||||
|
'Failed to read: Metadata cache version not found',
|
||||||
|
RecordCRUDActionExceptionCode.INVALID_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectMetadataMaps =
|
||||||
|
await this.workspaceCacheStorageService.getObjectMetadataMaps(
|
||||||
|
workspaceId,
|
||||||
|
currentCacheVersion,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadataMaps) {
|
||||||
|
throw new RecordCRUDActionException(
|
||||||
|
'Failed to read: Object metadata collection not found',
|
||||||
|
RecordCRUDActionExceptionCode.INVALID_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectMetadataItemWithFieldsMaps =
|
||||||
|
getObjectMetadataMapItemByNameSingular(
|
||||||
|
objectMetadataMaps,
|
||||||
|
workflowActionInput.objectName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadataItemWithFieldsMaps) {
|
||||||
|
throw new RecordCRUDActionException(
|
||||||
|
`Failed to read: Object ${workflowActionInput.objectName} not found`,
|
||||||
|
RecordCRUDActionExceptionCode.INVALID_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workflowActionInput.fieldsToUpdate.length === 0) {
|
||||||
|
return {
|
||||||
|
result: {
|
||||||
|
...objectRecord,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectRecordWithFilteredFields = Object.keys(
|
||||||
|
workflowActionInput.objectRecord,
|
||||||
|
).reduce((acc, key) => {
|
||||||
|
if (workflowActionInput.fieldsToUpdate.includes(key)) {
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[key]: workflowActionInput.objectRecord[key],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const objectRecordFormatted = formatData(
|
||||||
|
objectRecordWithFilteredFields,
|
||||||
|
objectMetadataItemWithFieldsMaps,
|
||||||
|
);
|
||||||
|
|
||||||
await repository.update(workflowActionInput.objectRecordId, {
|
await repository.update(workflowActionInput.objectRecordId, {
|
||||||
...workflowActionInput.objectRecord,
|
...objectRecordFormatted,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
result: {
|
result: {
|
||||||
...objectRecord,
|
...objectRecord,
|
||||||
...workflowActionInput.objectRecord,
|
...objectRecordWithFilteredFields,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Tag } from '@ui/display';
|
import { IconComponent, Tag } from '@ui/display';
|
||||||
import { Checkbox, CheckboxShape, CheckboxSize } from '@ui/input';
|
import { Checkbox, CheckboxShape, CheckboxSize } from '@ui/input';
|
||||||
import { ThemeColor } from '@ui/theme';
|
import { ThemeColor } from '@ui/theme';
|
||||||
import {
|
import {
|
||||||
@ -13,6 +13,7 @@ type MenuItemMultiSelectTagProps = {
|
|||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
color: ThemeColor | 'transparent';
|
color: ThemeColor | 'transparent';
|
||||||
text: string;
|
text: string;
|
||||||
|
Icon?: IconComponent;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MenuItemMultiSelectTag = ({
|
export const MenuItemMultiSelectTag = ({
|
||||||
@ -22,6 +23,7 @@ export const MenuItemMultiSelectTag = ({
|
|||||||
onClick,
|
onClick,
|
||||||
isKeySelected,
|
isKeySelected,
|
||||||
text,
|
text,
|
||||||
|
Icon,
|
||||||
}: MenuItemMultiSelectTagProps) => {
|
}: MenuItemMultiSelectTagProps) => {
|
||||||
return (
|
return (
|
||||||
<StyledMenuItemBase
|
<StyledMenuItemBase
|
||||||
@ -35,7 +37,7 @@ export const MenuItemMultiSelectTag = ({
|
|||||||
checked={selected}
|
checked={selected}
|
||||||
/>
|
/>
|
||||||
<StyledMenuItemLeftContent>
|
<StyledMenuItemLeftContent>
|
||||||
<Tag color={color} text={text} />
|
<Tag color={color} text={text} Icon={Icon} />
|
||||||
</StyledMenuItemLeftContent>
|
</StyledMenuItemLeftContent>
|
||||||
</StyledMenuItemBase>
|
</StyledMenuItemBase>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user