Add suggested values for variable dropdown (#9437)
<img width="378" alt="Capture d’écran 2025-01-07 à 15 37 20" src="https://github.com/user-attachments/assets/c15abcac-684a-4c3b-ad12-62cf91afe927" /> Here is a first version: - simple fields have a suggested value - composite do not, but sub values of composite do - json, arrays or complex values do not
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-e2e-testing",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-emails",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-front",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ServerlessFunctionExecutionStatus } from '~/generated-metadata/graphql';
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { ServerlessFunctionExecutionStatus } from '~/generated-metadata/graphql';
|
||||
|
||||
export type ServerlessFunctionTestData = {
|
||||
input: { [field: string]: any };
|
||||
@ -13,8 +13,7 @@ export type ServerlessFunctionTestData = {
|
||||
height: number;
|
||||
};
|
||||
|
||||
export const DEFAULT_OUTPUT_VALUE =
|
||||
'Enter an input above then press "run Function"';
|
||||
export const DEFAULT_OUTPUT_VALUE = 'Enter an input above then press "Test"';
|
||||
|
||||
export const serverlessFunctionTestDataFamilyState = createFamilyState<
|
||||
ServerlessFunctionTestData,
|
||||
|
||||
@ -145,15 +145,18 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer>
|
||||
{filteredOptions.map(([key, value]) => (
|
||||
{filteredOptions.map(([key, subStep]) => (
|
||||
<MenuItemSelect
|
||||
key={key}
|
||||
selected={false}
|
||||
hovered={false}
|
||||
onClick={() => handleSelectField(key)}
|
||||
text={value.label || key}
|
||||
hasSubMenu={!value.isLeaf}
|
||||
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
|
||||
text={subStep.label || key}
|
||||
hasSubMenu={!subStep.isLeaf}
|
||||
LeftIcon={subStep.icon ? getIcon(subStep.icon) : undefined}
|
||||
contextualText={
|
||||
subStep.isLeaf ? subStep?.value?.toString() : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-server",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@ -7,13 +7,16 @@ type FakeValueTypes =
|
||||
| Date
|
||||
| FakeValueTypes[]
|
||||
| FieldMetadataType
|
||||
| { [key: string]: FakeValueTypes };
|
||||
| { [key: string]: FakeValueTypes }
|
||||
| null;
|
||||
|
||||
export const generateFakeValue = (valueType: string): FakeValueTypes => {
|
||||
type TypeClassification = 'Primitive' | 'FieldMetadataType';
|
||||
|
||||
const generatePrimitiveValue = (valueType: string): FakeValueTypes => {
|
||||
if (valueType === 'string') {
|
||||
return 'generated-string-value';
|
||||
return 'My text';
|
||||
} else if (valueType === 'number') {
|
||||
return 1;
|
||||
return 20;
|
||||
} else if (valueType === 'boolean') {
|
||||
return true;
|
||||
} else if (valueType === 'Date') {
|
||||
@ -38,9 +41,51 @@ export const generateFakeValue = (valueType: string): FakeValueTypes => {
|
||||
});
|
||||
|
||||
return objData;
|
||||
} else if (valueType === FieldMetadataType.TEXT) {
|
||||
return 'My text';
|
||||
} else {
|
||||
return 'generated-string-value';
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const generateFieldMetadataTypeValue = (
|
||||
valueType: string,
|
||||
): FakeValueTypes | null => {
|
||||
// composite types do not need to be generated
|
||||
switch (valueType) {
|
||||
case FieldMetadataType.TEXT:
|
||||
return 'My text';
|
||||
case FieldMetadataType.NUMBER:
|
||||
return 20;
|
||||
case FieldMetadataType.BOOLEAN:
|
||||
return true;
|
||||
case FieldMetadataType.DATE:
|
||||
return '01/23/2025';
|
||||
case FieldMetadataType.DATE_TIME:
|
||||
return '01/23/2025 15:16';
|
||||
case FieldMetadataType.ADDRESS:
|
||||
return '123 Main St, Anytown, CA 12345';
|
||||
case FieldMetadataType.FULL_NAME:
|
||||
return 'Tim Cook';
|
||||
case FieldMetadataType.RAW_JSON:
|
||||
return null;
|
||||
case FieldMetadataType.RICH_TEXT:
|
||||
return 'My rich text';
|
||||
case FieldMetadataType.UUID:
|
||||
return '123e4567-e89b-12d3-a456-426614174000';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const generateFakeValue = (
|
||||
valueType: string,
|
||||
classification: TypeClassification = 'Primitive',
|
||||
): FakeValueTypes => {
|
||||
switch (classification) {
|
||||
case 'Primitive':
|
||||
return generatePrimitiveValue(valueType);
|
||||
case 'FieldMetadataType':
|
||||
return generateFieldMetadataTypeValue(valueType);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -25,7 +25,7 @@ const generateObjectRecordFields = (
|
||||
type: field.type,
|
||||
icon: field.icon,
|
||||
label: field.label,
|
||||
value: generateFakeValue(field.type),
|
||||
value: generateFakeValue(field.type, 'FieldMetadataType'),
|
||||
};
|
||||
} else {
|
||||
acc[field.name] = {
|
||||
@ -37,7 +37,7 @@ const generateObjectRecordFields = (
|
||||
isLeaf: true,
|
||||
type: property.type,
|
||||
label: camelToTitleCase(property.name),
|
||||
value: generateFakeValue(property.type),
|
||||
value: generateFakeValue(property.type, 'FieldMetadataType'),
|
||||
};
|
||||
|
||||
return acc;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-ui",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@ -47,6 +47,7 @@ type MenuItemSelectProps = {
|
||||
disabled?: boolean;
|
||||
hovered?: boolean;
|
||||
hasSubMenu?: boolean;
|
||||
contextualText?: string;
|
||||
};
|
||||
|
||||
export const MenuItemSelect = ({
|
||||
@ -59,6 +60,7 @@ export const MenuItemSelect = ({
|
||||
disabled,
|
||||
hovered,
|
||||
hasSubMenu = false,
|
||||
contextualText,
|
||||
}: MenuItemSelectProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@ -73,8 +75,13 @@ export const MenuItemSelect = ({
|
||||
aria-selected={selected}
|
||||
aria-disabled={disabled}
|
||||
>
|
||||
<MenuItemLeftContent LeftIcon={LeftIcon} text={text} />
|
||||
<MenuItemLeftContent
|
||||
LeftIcon={LeftIcon}
|
||||
text={text}
|
||||
contextualText={contextualText}
|
||||
/>
|
||||
{selected && needIconCheck && <IconCheck size={theme.icon.size.md} />}
|
||||
|
||||
{hasSubMenu && (
|
||||
<IconChevronRight
|
||||
size={theme.icon.size.sm}
|
||||
|
||||
@ -14,6 +14,10 @@ import {
|
||||
StyledMenuItemLeftContent,
|
||||
} from './StyledMenuItemBase';
|
||||
|
||||
const StyledMainText = styled.div`
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const StyledContextualText = styled.div`
|
||||
color: ${({ theme }) => theme.color.gray35};
|
||||
font-family: inherit;
|
||||
@ -29,6 +33,7 @@ const StyledContextualText = styled.div`
|
||||
white-space: nowrap;
|
||||
|
||||
padding-left: ${({ theme }) => theme.spacing(1)};
|
||||
flex-shrink: 1;
|
||||
`;
|
||||
|
||||
type MenuItemLeftContentProps = {
|
||||
@ -67,7 +72,13 @@ export const MenuItemLeftContent = ({
|
||||
<LeftIcon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
|
||||
)}
|
||||
<StyledMenuItemLabel hasLeftIcon={!!LeftIcon}>
|
||||
{isString(text) ? <OverflowingTextWithTooltip text={text} /> : text}
|
||||
{isString(text) ? (
|
||||
<StyledMainText>
|
||||
<OverflowingTextWithTooltip text={text} />
|
||||
</StyledMainText>
|
||||
) : (
|
||||
text
|
||||
)}
|
||||
{isString(contextualText) ? (
|
||||
<StyledContextualText>{`· ${contextualText}`}</StyledContextualText>
|
||||
) : (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-website",
|
||||
"version": "0.40.0-canary",
|
||||
"version": "0.35.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js",
|
||||
|
||||
Reference in New Issue
Block a user