diff --git a/front/src/modules/activities/components/ActivityAssigneePicker.tsx b/front/src/modules/activities/components/ActivityAssigneePicker.tsx index 58c0ee2a7..f6b6f429c 100644 --- a/front/src/modules/activities/components/ActivityAssigneePicker.tsx +++ b/front/src/modules/activities/components/ActivityAssigneePicker.tsx @@ -97,13 +97,11 @@ export function ActivityAssigneePicker({ return ( ); } diff --git a/front/src/modules/companies/components/CompanyPicker.tsx b/front/src/modules/companies/components/CompanyPicker.tsx index 4666e6c80..a75fb57b3 100644 --- a/front/src/modules/companies/components/CompanyPicker.tsx +++ b/front/src/modules/companies/components/CompanyPicker.tsx @@ -34,13 +34,11 @@ export function CompanyPicker({ companyId, onSubmit, onCancel }: OwnProps) { return ( ); } diff --git a/front/src/modules/companies/components/CompanyPickerCell.tsx b/front/src/modules/companies/components/CompanyPickerCell.tsx index adb9f0691..9adf76532 100644 --- a/front/src/modules/companies/components/CompanyPickerCell.tsx +++ b/front/src/modules/companies/components/CompanyPickerCell.tsx @@ -1,4 +1,5 @@ import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery'; +import { IconBuildingSkyscraper } from '@/ui/icon'; import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect'; import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState'; import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect'; @@ -77,34 +78,25 @@ export function CompanyPickerCell({ }); setIsCreateMode(false); } - const noCompany: CompanyPickerSelectedCompany = { - entityType: Entity.Company, - id: '', - name: 'No Company', - avatarType: 'rounded', - domainName: '', - avatarUrl: '', - }; return isCreateMode ? ( ) : ( ); } diff --git a/front/src/modules/companies/components/CompanyProgressPicker.tsx b/front/src/modules/companies/components/CompanyProgressPicker.tsx index 4ff2c92fc..19b4706b7 100644 --- a/front/src/modules/companies/components/CompanyProgressPicker.tsx +++ b/front/src/modules/companies/components/CompanyProgressPicker.tsx @@ -114,13 +114,11 @@ export function CompanyProgressPicker({ diff --git a/front/src/modules/companies/components/NewCompanyProgressButton.tsx b/front/src/modules/companies/components/NewCompanyProgressButton.tsx index 95acacf45..ce8caed3e 100644 --- a/front/src/modules/companies/components/NewCompanyProgressButton.tsx +++ b/front/src/modules/companies/components/NewCompanyProgressButton.tsx @@ -64,14 +64,12 @@ export function NewCompanyProgressButton() { {isCreatingCard ? ( handleEntitySelect(value)} + disableBackgroundBlur + entitiesToSelect={companies.entitiesToSelect} + loading={companies.loading} onCancel={handleCancel} - entities={{ - entitiesToSelect: companies.entitiesToSelect, - selectedEntity: companies.selectedEntities[0], - loading: companies.loading, - }} - disableBackgroundBlur={true} + onEntitySelected={handleEntitySelect} + selectedEntity={companies.selectedEntities[0]} /> ) : ( diff --git a/front/src/modules/people/components/PeoplePicker.tsx b/front/src/modules/people/components/PeoplePicker.tsx index 227ea4685..c6871f854 100644 --- a/front/src/modules/people/components/PeoplePicker.tsx +++ b/front/src/modules/people/components/PeoplePicker.tsx @@ -68,14 +68,12 @@ export function PeoplePicker({ return ( ); } diff --git a/front/src/modules/ui/board/components/BoardColumnMenu.tsx b/front/src/modules/ui/board/components/BoardColumnMenu.tsx index 4ffcac132..c92c8562d 100644 --- a/front/src/modules/ui/board/components/BoardColumnMenu.tsx +++ b/front/src/modules/ui/board/components/BoardColumnMenu.tsx @@ -157,14 +157,12 @@ export function BoardColumnMenu({ )} {currentMenu === 'add' && ( handleCompanySelected(value)} + disableBackgroundBlur + entitiesToSelect={companies.entitiesToSelect} + loading={companies.loading} onCancel={closeMenu} - entities={{ - entitiesToSelect: companies.entitiesToSelect, - selectedEntity: companies.selectedEntities[0], - loading: companies.loading, - }} - disableBackgroundBlur={true} + onEntitySelected={handleCompanySelected} + selectedEntity={companies.selectedEntities[0]} /> )} diff --git a/front/src/modules/ui/editable-field/hooks/useUpdateGenericEntityField.ts b/front/src/modules/ui/editable-field/hooks/useUpdateGenericEntityField.ts index de809610f..1e8c6a078 100644 --- a/front/src/modules/ui/editable-field/hooks/useUpdateGenericEntityField.ts +++ b/front/src/modules/ui/editable-field/hooks/useUpdateGenericEntityField.ts @@ -2,7 +2,7 @@ import { useContext } from 'react'; import { EditableFieldMutationContext } from '../contexts/EditableFieldMutationContext'; import { FieldDefinition } from '../types/FieldDefinition'; -import { +import type { FieldBooleanMetadata, FieldBooleanValue, FieldChipMetadata, @@ -82,163 +82,85 @@ export function useUpdateGenericEntityField() { >( currentEntityId: string, field: FieldDefinition, - newFieldValue: ValueType, + newFieldValue: ValueType | null, ) { - const newFieldValueUnknown = newFieldValue as unknown; // TODO: improve type guards organization, maybe with a common typeguard for all fields // taking an object of options as parameter ? // // The goal would be to check that the field value not only is valid, // but also that it is validated against the corresponding field type - // Relation - if (isFieldRelation(field) && isFieldRelationValue(newFieldValueUnknown)) { - const newSelectedEntity = newFieldValueUnknown; - - const fieldName = field.metadata.fieldName; - - if (!newSelectedEntity) { - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [fieldName]: { - disconnect: true, - }, - }, - }, - }); - } else { - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [fieldName]: { - connect: { id: newSelectedEntity.id }, - }, - }, - }, - }); - } - // Chip - } else if (isFieldChip(field) && isFieldChipValue(newFieldValueUnknown)) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.contentFieldName]: newContent }, - }, - }); - // Text - } else if (isFieldText(field) && isFieldTextValue(newFieldValueUnknown)) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); - // Double text - } else if ( - isFieldDoubleText(field) && - isFieldDoubleTextValue(newFieldValueUnknown) + if ( + // Relation + isFieldRelation(field) && + isFieldRelationValue(newFieldValue) ) { - const newContent = newFieldValueUnknown; - updateEntity({ variables: { where: { id: currentEntityId }, data: { - [field.metadata.firstValueFieldName]: newContent.firstValue, - [field.metadata.secondValueFieldName]: newContent.secondValue, + [field.metadata.fieldName]: newFieldValue + ? { connect: { id: newFieldValue.id } } + : { disconnect: true }, }, }, }); - // Double Text Chip - } else if ( - isFieldDoubleTextChip(field) && - isFieldDoubleTextChipValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [field.metadata.firstValueFieldName]: newContent.firstValue, - [field.metadata.secondValueFieldName]: newContent.secondValue, - }, - }, - }); - // Phone - } else if (isFieldPhone(field) && isFieldPhoneValue(newFieldValueUnknown)) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); - // URL - } else if (isFieldURL(field) && isFieldURLValue(newFieldValueUnknown)) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); - // Number - } else if ( - isFieldNumber(field) && - isFieldNumberValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); - // Date - } else if (isFieldDate(field) && isFieldDateValue(newFieldValueUnknown)) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); - } else if ( - isFieldProbability(field) && - isFieldProbabilityValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, - }, - }); + return; } - // Boolean - else if ( - isFieldBoolean(field) && - isFieldBooleanValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; + if ( + // Chip + isFieldChip(field) && + isFieldChipValue(newFieldValue) + ) { updateEntity({ variables: { where: { id: currentEntityId }, - data: { [field.metadata.fieldName]: newContent }, + data: { [field.metadata.contentFieldName]: newFieldValue }, + }, + }); + return; + } + + if ( + // Text + (isFieldText(field) && isFieldTextValue(newFieldValue)) || + // Phone + (isFieldPhone(field) && isFieldPhoneValue(newFieldValue)) || + // URL + (isFieldURL(field) && isFieldURLValue(newFieldValue)) || + // Number + (isFieldNumber(field) && isFieldNumberValue(newFieldValue)) || + // Date + (isFieldDate(field) && isFieldDateValue(newFieldValue)) || + // Probability + (isFieldProbability(field) && isFieldProbabilityValue(newFieldValue)) || + // Boolean + (isFieldBoolean(field) && isFieldBooleanValue(newFieldValue)) + ) { + updateEntity({ + variables: { + where: { id: currentEntityId }, + data: { [field.metadata.fieldName]: newFieldValue }, + }, + }); + return; + } + + if ( + // Double text + (isFieldDoubleText(field) && isFieldDoubleTextValue(newFieldValue)) || + // Double Text Chip + (isFieldDoubleTextChip(field) && + isFieldDoubleTextChipValue(newFieldValue)) + ) { + updateEntity({ + variables: { + where: { id: currentEntityId }, + data: { + [field.metadata.firstValueFieldName]: newFieldValue.firstValue, + [field.metadata.secondValueFieldName]: newFieldValue.secondValue, + }, }, }); } diff --git a/front/src/modules/ui/editable-field/types/guards/isFieldRelationValue.ts b/front/src/modules/ui/editable-field/types/guards/isFieldRelationValue.ts index 5624e0c25..c96be88e0 100644 --- a/front/src/modules/ui/editable-field/types/guards/isFieldRelationValue.ts +++ b/front/src/modules/ui/editable-field/types/guards/isFieldRelationValue.ts @@ -4,9 +4,5 @@ import { FieldRelationValue } from '../FieldMetadata'; export function isFieldRelationValue( fieldValue: unknown, ): fieldValue is FieldRelationValue { - return ( - fieldValue !== null && - fieldValue !== undefined && - typeof fieldValue === 'object' - ); + return fieldValue !== undefined && typeof fieldValue === 'object'; } diff --git a/front/src/modules/ui/editable-field/types/guards/isViewFieldRelationValue.ts b/front/src/modules/ui/editable-field/types/guards/isViewFieldRelationValue.ts index 62f80f816..122bbe7e9 100644 --- a/front/src/modules/ui/editable-field/types/guards/isViewFieldRelationValue.ts +++ b/front/src/modules/ui/editable-field/types/guards/isViewFieldRelationValue.ts @@ -4,9 +4,5 @@ import { ViewFieldRelationValue } from '../ViewField'; export function isViewFieldRelationValue( fieldValue: unknown, ): fieldValue is ViewFieldRelationValue { - return ( - fieldValue !== null && - fieldValue !== undefined && - typeof fieldValue === 'object' - ); + return fieldValue !== undefined && typeof fieldValue === 'object'; } diff --git a/front/src/modules/ui/input/relation-picker/components/SingleEntitySelect.tsx b/front/src/modules/ui/input/relation-picker/components/SingleEntitySelect.tsx index ece4d9a56..ebb44fe46 100644 --- a/front/src/modules/ui/input/relation-picker/components/SingleEntitySelect.tsx +++ b/front/src/modules/ui/input/relation-picker/components/SingleEntitySelect.tsx @@ -13,29 +13,36 @@ import { useEntitySelectSearch } from '../hooks/useEntitySelectSearch'; import { EntityForSelect } from '../types/EntityForSelect'; import { - EntitiesForSingleEntitySelect, SingleEntitySelectBase, + type SingleEntitySelectBaseProps, } from './SingleEntitySelectBase'; +export type SingleEntitySelectProps< + CustomEntityForSelect extends EntityForSelect, +> = { + disableBackgroundBlur?: boolean; + onCreate?: () => void; + width?: number; +} & Pick< + SingleEntitySelectBaseProps, + | 'EmptyIcon' + | 'emptyLabel' + | 'entitiesToSelect' + | 'loading' + | 'onCancel' + | 'onEntitySelected' + | 'selectedEntity' +>; + export function SingleEntitySelect< CustomEntityForSelect extends EntityForSelect, >({ - entities, - onEntitySelected, - onCreate, - onCancel, - width, disableBackgroundBlur = false, - noUser, -}: { - onCancel?: () => void; - onCreate?: () => void; - entities: EntitiesForSingleEntitySelect; - onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void; - disableBackgroundBlur?: boolean; - width?: number; - noUser?: CustomEntityForSelect; -}) { + onCancel, + onCreate, + width, + ...props +}: SingleEntitySelectProps) { const containerRef = useRef(null); const { searchFilter, handleSearchFilterChange } = useEntitySelectSearch(); @@ -64,12 +71,7 @@ export function SingleEntitySelect< autoFocus /> - + {showCreateButton && ( <> diff --git a/front/src/modules/ui/input/relation-picker/components/SingleEntitySelectBase.tsx b/front/src/modules/ui/input/relation-picker/components/SingleEntitySelectBase.tsx index a91e10b06..d7098c697 100644 --- a/front/src/modules/ui/input/relation-picker/components/SingleEntitySelectBase.tsx +++ b/front/src/modules/ui/input/relation-picker/components/SingleEntitySelectBase.tsx @@ -2,49 +2,47 @@ import { useRef } from 'react'; import { Key } from 'ts-key-enum'; import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer'; -import { IconBuildingSkyscraper, IconUserCircle } from '@/ui/icon'; +import type { IconComponent } from '@/ui/icon/types/IconComponent'; import { MenuItem } from '@/ui/menu-item/components/MenuItem'; import { MenuItemSelectAvatar } from '@/ui/menu-item/components/MenuItemSelectAvatar'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { Avatar } from '@/users/components/Avatar'; -import { isDefined } from '~/utils/isDefined'; +import { assertNotNull } from '~/utils/assert'; import { isNonEmptyString } from '~/utils/isNonEmptyString'; import { useEntitySelectScroll } from '../hooks/useEntitySelectScroll'; import { EntityForSelect } from '../types/EntityForSelect'; -import { Entity } from '../types/EntityTypeForSelect'; import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope'; import { DropdownMenuSkeletonItem } from './skeletons/DropdownMenuSkeletonItem'; -export type EntitiesForSingleEntitySelect< +export type SingleEntitySelectBaseProps< CustomEntityForSelect extends EntityForSelect, > = { - selectedEntity: CustomEntityForSelect; + EmptyIcon?: IconComponent; + emptyLabel?: string; entitiesToSelect: CustomEntityForSelect[]; - loading: boolean; + loading?: boolean; + onCancel?: () => void; + onEntitySelected: (entity?: CustomEntityForSelect) => void; + selectedEntity?: CustomEntityForSelect; }; export function SingleEntitySelectBase< CustomEntityForSelect extends EntityForSelect, >({ - entities, - onEntitySelected, + EmptyIcon, + emptyLabel, + entitiesToSelect, + loading, onCancel, - noUser, -}: { - entities: EntitiesForSingleEntitySelect; - onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void; - onCancel?: () => void; - noUser?: CustomEntityForSelect; -}) { + onEntitySelected, + selectedEntity, +}: SingleEntitySelectBaseProps) { const containerRef = useRef(null); - let entitiesInDropdown = isDefined(entities.selectedEntity) - ? [entities.selectedEntity, ...(entities.entitiesToSelect ?? [])] - : entities.entitiesToSelect ?? []; - - entitiesInDropdown = entitiesInDropdown.filter((entity) => - isNonEmptyString(entity.name), + const entitiesInDropdown = [selectedEntity, ...entitiesToSelect].filter( + (entity): entity is CustomEntityForSelect => + assertNotNull(entity) && isNonEmptyString(entity.name.trim()), ); const { hoveredIndex, resetScroll } = useEntitySelectScroll({ @@ -71,25 +69,16 @@ export function SingleEntitySelectBase< [onCancel], ); - entitiesInDropdown = entitiesInDropdown.filter((entity) => - isNonEmptyString(entity.name.trim()), - ); - - const NoUserIcon = - noUser?.entityType === Entity.User - ? IconUserCircle - : IconBuildingSkyscraper; - return ( - {noUser && ( + {emptyLabel && ( onEntitySelected(noUser)} - LeftIcon={NoUserIcon} - text={noUser.name} + onClick={() => onEntitySelected()} + LeftIcon={EmptyIcon} + text={emptyLabel} /> )} - {entities.loading ? ( + {loading ? ( ) : entitiesInDropdown.length === 0 ? ( @@ -98,7 +87,7 @@ export function SingleEntitySelectBase< onEntitySelected(entity)} text={entity.name} hovered={hoveredIndex === entitiesInDropdown.indexOf(entity)} diff --git a/front/src/modules/ui/input/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx b/front/src/modules/ui/input/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx new file mode 100644 index 000000000..b4aea64de --- /dev/null +++ b/front/src/modules/ui/input/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx @@ -0,0 +1,81 @@ +import { expect } from '@storybook/jest'; +import type { Meta, StoryObj } from '@storybook/react'; +import { userEvent, within } from '@storybook/testing-library'; + +import { IconUserCircle } from '@/ui/icon'; +import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; +import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; +import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator'; +import { mockedPeopleData } from '~/testing/mock-data/people'; +import { sleep } from '~/testing/sleep'; + +import { relationPickerSearchFilterScopedState } from '../../states/relationPickerSearchFilterScopedState'; +import type { EntityForSelect } from '../../types/EntityForSelect'; +import { Entity } from '../../types/EntityTypeForSelect'; +import { SingleEntitySelect } from '../SingleEntitySelect'; + +const entities = mockedPeopleData.map((person) => ({ + id: person.id, + entityType: Entity.Person, + name: person.displayName, +})); + +const meta: Meta = { + title: 'UI/Input/RelationPicker/SingleEntitySelect', + component: SingleEntitySelect, + decorators: [ComponentDecorator, ComponentWithRecoilScopeDecorator], + argTypes: { + selectedEntity: { + options: entities.map(({ name }) => name), + mapping: entities.reduce( + (result, entity) => ({ ...result, [entity.name]: entity }), + {}, + ), + }, + }, + render: function Render(args) { + const searchFilter = useRecoilScopedValue( + relationPickerSearchFilterScopedState, + ); + + return ( + + entity.id !== args.selectedEntity?.id && + entity.name.includes(searchFilter), + )} + /> + ); + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const WithSelectedEntity: Story = { + args: { selectedEntity: entities[2] }, +}; + +export const WithEmptyOption: Story = { + args: { + EmptyIcon: IconUserCircle, + emptyLabel: 'Nobody', + }, +}; + +export const WithSearchFilter: Story = { + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + const searchInput = canvas.getByRole('textbox'); + + await step('Enter search text', async () => { + await sleep(50); + await userEvent.type(searchInput, 'a'); + await expect(searchInput).toHaveValue('a'); + }); + }, +}; diff --git a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCellEditMode.tsx b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCellEditMode.tsx index 03f876650..01d23726d 100644 --- a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCellEditMode.tsx +++ b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCellEditMode.tsx @@ -35,9 +35,6 @@ export function GenericEditableRelationCellEditMode({ const updateEntityField = useUpdateEntityField(); function updateCachedPersonField(newFieldEntity: EntityForSelect | null) { - if (newFieldEntity === null) { - return; - } setFieldValueEntity({ avatarUrl: newFieldEntity?.avatarUrl ?? '', entityType: Entity.Company, @@ -49,10 +46,6 @@ export function GenericEditableRelationCellEditMode({ function updateCachedCompanyField( newFieldEntity: CompanyPickerSelectedCompany | null, ) { - if (newFieldEntity === null) { - return; - } - setFieldValueEntity({ id: newFieldEntity?.id ?? '', name: newFieldEntity?.name ?? '', @@ -64,7 +57,6 @@ export function GenericEditableRelationCellEditMode({ newFieldEntity: CompanyPickerSelectedCompany | null, ) { if ( - newFieldEntity && newFieldEntity?.id !== fieldValueEntity?.id && currentRowEntityId && updateEntityField diff --git a/front/src/modules/ui/table/hooks/useUpdateEntityField.ts b/front/src/modules/ui/table/hooks/useUpdateEntityField.ts index 08b1fa5f2..b2c4afd3d 100644 --- a/front/src/modules/ui/table/hooks/useUpdateEntityField.ts +++ b/front/src/modules/ui/table/hooks/useUpdateEntityField.ts @@ -76,52 +76,39 @@ export function useUpdateEntityField() { >( currentEntityId: string, columnDefinition: ColumnDefinition, - newFieldValue: ValueType, + newFieldValue: ValueType | null, ) { - const newFieldValueUnknown = newFieldValue as unknown; // TODO: improve type guards organization, maybe with a common typeguard for all view fields // taking an object of options as parameter ? // // The goal would be to check that the view field value not only is valid, // but also that it is validated against the corresponding view field type - // Relation if ( + // Relation isViewFieldRelation(columnDefinition) && - isViewFieldRelationValue(newFieldValueUnknown) + isViewFieldRelationValue(newFieldValue) ) { - const newSelectedEntity = newFieldValueUnknown; + updateEntity({ + variables: { + where: { id: currentEntityId }, + data: { + [columnDefinition.metadata.fieldName]: + !newFieldValue || newFieldValue.id === '' + ? { disconnect: true } + : { connect: { id: newFieldValue.id } }, + }, + }, + }); + return; + } - const fieldName = columnDefinition.metadata.fieldName; - if (!newSelectedEntity || newSelectedEntity.id === '') { - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [fieldName]: { - disconnect: true, - }, - }, - }, - }); - } else { - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [fieldName]: { - connect: { id: newSelectedEntity.id }, - }, - }, - }, - }); - } + if ( // Chip - } else if ( isViewFieldChip(columnDefinition) && - isViewFieldChipValue(newFieldValueUnknown) + isViewFieldChipValue(newFieldValue) ) { - const newContent = newFieldValueUnknown; + const newContent = newFieldValue; updateEntity({ variables: { @@ -129,144 +116,60 @@ export function useUpdateEntityField() { data: { [columnDefinition.metadata.contentFieldName]: newContent }, }, }); + return; + } + + if ( // Text - } else if ( - isViewFieldText(columnDefinition) && - isViewFieldTextValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); - // Double text - } else if ( - isViewFieldDoubleText(columnDefinition) && - isViewFieldDoubleTextValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [columnDefinition.metadata.firstValueFieldName]: - newContent.firstValue, - [columnDefinition.metadata.secondValueFieldName]: - newContent.secondValue, - }, - }, - }); - // Double Text Chip - } else if ( - isViewFieldDoubleTextChip(columnDefinition) && - isViewFieldDoubleTextChipValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { - [columnDefinition.metadata.firstValueFieldName]: - newContent.firstValue, - [columnDefinition.metadata.secondValueFieldName]: - newContent.secondValue, - }, - }, - }); + (isViewFieldText(columnDefinition) && + isViewFieldTextValue(newFieldValue)) || // Phone - } else if ( - isViewFieldPhone(columnDefinition) && - isViewFieldPhoneValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); + (isViewFieldPhone(columnDefinition) && + isViewFieldPhoneValue(newFieldValue)) || // Email - } else if ( - isViewFieldEmail(columnDefinition) && - isViewFieldEmailValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); + (isViewFieldEmail(columnDefinition) && + isViewFieldEmailValue(newFieldValue)) || // URL - } else if ( - isViewFieldURL(columnDefinition) && - isViewFieldURLValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); + (isViewFieldURL(columnDefinition) && + isViewFieldURLValue(newFieldValue)) || // Number - } else if ( - isViewFieldNumber(columnDefinition) && - isViewFieldNumberValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); + (isViewFieldNumber(columnDefinition) && + isViewFieldNumberValue(newFieldValue)) || // Boolean - } else if ( - isViewFieldBoolean(columnDefinition) && - isViewFieldBooleanValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; - - updateEntity({ - variables: { - where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, - }, - }); + (isViewFieldBoolean(columnDefinition) && + isViewFieldBooleanValue(newFieldValue)) || // Money - } else if ( - isViewFieldMoney(columnDefinition) && - isViewFieldMoneyValue(newFieldValueUnknown) + (isViewFieldMoney(columnDefinition) && + isViewFieldMoneyValue(newFieldValue)) || + // Date + (isViewFieldDate(columnDefinition) && isViewFieldDateValue(newFieldValue)) ) { - const newContent = newFieldValueUnknown; - updateEntity({ variables: { where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, + data: { [columnDefinition.metadata.fieldName]: newFieldValue }, }, }); - // Date - } else if ( - isViewFieldDate(columnDefinition) && - isViewFieldDateValue(newFieldValueUnknown) - ) { - const newContent = newFieldValueUnknown; + return; + } + if ( + // Double text + (isViewFieldDoubleText(columnDefinition) && + isViewFieldDoubleTextValue(newFieldValue)) || + // Double Text Chip + (isViewFieldDoubleTextChip(columnDefinition) && + isViewFieldDoubleTextChipValue(newFieldValue)) + ) { updateEntity({ variables: { where: { id: currentEntityId }, - data: { [columnDefinition.metadata.fieldName]: newContent }, + data: { + [columnDefinition.metadata.firstValueFieldName]: + newFieldValue.firstValue, + [columnDefinition.metadata.secondValueFieldName]: + newFieldValue.secondValue, + }, }, }); } diff --git a/front/src/modules/ui/view-bar/components/FilterDropdownEntitySearchSelect.tsx b/front/src/modules/ui/view-bar/components/FilterDropdownEntitySearchSelect.tsx index 1f8120f81..06504198d 100644 --- a/front/src/modules/ui/view-bar/components/FilterDropdownEntitySearchSelect.tsx +++ b/front/src/modules/ui/view-bar/components/FilterDropdownEntitySearchSelect.tsx @@ -76,11 +76,9 @@ export function FilterDropdownEntitySearchSelect({ return ( <> diff --git a/front/src/modules/users/components/UserPicker.tsx b/front/src/modules/users/components/UserPicker.tsx index 61928ac3e..07c26830d 100644 --- a/front/src/modules/users/components/UserPicker.tsx +++ b/front/src/modules/users/components/UserPicker.tsx @@ -1,4 +1,5 @@ import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery'; +import { IconUserCircle } from '@/ui/icon'; import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect'; import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState'; import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect'; @@ -51,24 +52,17 @@ export function UserPicker({ ) { onSubmit(selectedUser ?? null); } - const noUser: UserForSelect = { - entityType: Entity.User, - id: '', - name: 'No Owner', - avatarType: 'rounded', - avatarUrl: '', - }; + return ( ); }