From e2eb40c1ea568d4f2ece3474591db9c930dfc2a1 Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Tue, 20 Jun 2023 11:06:53 +0200 Subject: [PATCH] Relation picker module (#335) - Created a relation picker module - Added a CustomeEntityForSelect type --- .../CommentThreadRelationPicker.tsx | 34 ++++++++++--------- ...andleCheckableCommentThreadTargetChange.ts | 4 +-- .../comments/types/CommentableEntity.ts | 2 +- .../types/CommentableEntityForSelect.ts | 6 ++++ .../components/MultipleEntitySelect.tsx | 32 +++++++---------- .../hooks}/useFilteredSearchEntityQuery.ts | 11 +++--- .../relation-picker/types/EntityForSelect.ts | 11 ++++++ .../types/EntityTypeForSelect.ts | 3 ++ ...latMapAndSortEntityForSelectArrayByName.ts | 11 +++--- 9 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 front/src/modules/comments/types/CommentableEntityForSelect.ts rename front/src/modules/{comments => relation-picker}/components/MultipleEntitySelect.tsx (77%) rename front/src/modules/{ui/hooks/menu => relation-picker/hooks}/useFilteredSearchEntityQuery.ts (89%) create mode 100644 front/src/modules/relation-picker/types/EntityForSelect.ts create mode 100644 front/src/modules/relation-picker/types/EntityTypeForSelect.ts diff --git a/front/src/modules/comments/components/CommentThreadRelationPicker.tsx b/front/src/modules/comments/components/CommentThreadRelationPicker.tsx index 093912c34..71bafc81f 100644 --- a/front/src/modules/comments/components/CommentThreadRelationPicker.tsx +++ b/front/src/modules/comments/components/CommentThreadRelationPicker.tsx @@ -14,7 +14,7 @@ import { IconArrowUpRight } from '@tabler/icons-react'; import { CommentThreadForDrawer } from '@/comments/types/CommentThreadForDrawer'; import CompanyChip from '@/companies/components/CompanyChip'; import { PersonChip } from '@/people/components/PersonChip'; -import { useFilteredSearchEntityQuery } from '@/ui/hooks/menu/useFilteredSearchEntityQuery'; +import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery'; import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef'; import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flatMapAndSortEntityForSelectArrayByName'; import { getLogoUrlFromDomainName } from '@/utils/utils'; @@ -24,9 +24,9 @@ import { useSearchPeopleQuery, } from '~/generated/graphql'; +import { MultipleEntitySelect } from '../../relation-picker/components/MultipleEntitySelect'; import { useHandleCheckableCommentThreadTargetChange } from '../hooks/useHandleCheckableCommentThreadTargetChange'; - -import { MultipleEntitySelect } from './MultipleEntitySelect'; +import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; type OwnProps = { commentThread: CommentThreadForDrawer; @@ -112,12 +112,13 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) { searchOnFields: ['firstname', 'lastname'], orderByField: 'lastname', selectedIds: peopleIds, - mappingFunction: (entity) => ({ - id: entity.id, - entityType: CommentableType.Person, - name: `${entity.firstname} ${entity.lastname}`, - avatarType: 'rounded', - }), + mappingFunction: (entity) => + ({ + id: entity.id, + entityType: CommentableType.Person, + name: `${entity.firstname} ${entity.lastname}`, + avatarType: 'rounded', + } as CommentableEntityForSelect), searchFilter, }); @@ -126,13 +127,14 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) { searchOnFields: ['name'], orderByField: 'name', selectedIds: companyIds, - mappingFunction: (company) => ({ - id: company.id, - entityType: CommentableType.Company, - name: company.name, - avatarUrl: getLogoUrlFromDomainName(company.domainName), - avatarType: 'squared', - }), + mappingFunction: (company) => + ({ + id: company.id, + entityType: CommentableType.Company, + name: company.name, + avatarUrl: getLogoUrlFromDomainName(company.domainName), + avatarType: 'squared', + } as CommentableEntityForSelect), searchFilter, }); diff --git a/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts b/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts index 0e224d00c..1c0bcf52e 100644 --- a/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts +++ b/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts @@ -8,8 +8,8 @@ import { useRemoveCommentThreadTargetOnCommentThreadMutation, } from '~/generated/graphql'; -import { EntityForSelect } from '../components/MultipleEntitySelect'; import { GET_COMMENT_THREADS_BY_TARGETS } from '../services'; +import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; import { CommentThreadForDrawer } from '../types/CommentThreadForDrawer'; export function useHandleCheckableCommentThreadTargetChange({ @@ -37,7 +37,7 @@ export function useHandleCheckableCommentThreadTargetChange({ return function handleCheckItemChange( newCheckedValue: boolean, - entity: EntityForSelect, + entity: CommentableEntityForSelect, ) { if (newCheckedValue) { addCommentThreadTargetOnCommentThread({ diff --git a/front/src/modules/comments/types/CommentableEntity.ts b/front/src/modules/comments/types/CommentableEntity.ts index 1b50711f7..481e513c8 100644 --- a/front/src/modules/comments/types/CommentableEntity.ts +++ b/front/src/modules/comments/types/CommentableEntity.ts @@ -1,6 +1,6 @@ import { CommentableType } from '~/generated/graphql'; export type CommentableEntity = { - type: CommentableType; id: string; + type: CommentableType; }; diff --git a/front/src/modules/comments/types/CommentableEntityForSelect.ts b/front/src/modules/comments/types/CommentableEntityForSelect.ts new file mode 100644 index 000000000..d97e42d29 --- /dev/null +++ b/front/src/modules/comments/types/CommentableEntityForSelect.ts @@ -0,0 +1,6 @@ +import { EntityForSelect } from '@/relation-picker/types/EntityForSelect'; +import { CommentableType } from '~/generated/graphql'; + +export type CommentableEntityForSelect = EntityForSelect & { + entityType: CommentableType; +}; diff --git a/front/src/modules/comments/components/MultipleEntitySelect.tsx b/front/src/modules/relation-picker/components/MultipleEntitySelect.tsx similarity index 77% rename from front/src/modules/comments/components/MultipleEntitySelect.tsx rename to front/src/modules/relation-picker/components/MultipleEntitySelect.tsx index 5a4a4e5a8..b9141ed09 100644 --- a/front/src/modules/comments/components/MultipleEntitySelect.tsx +++ b/front/src/modules/relation-picker/components/MultipleEntitySelect.tsx @@ -1,42 +1,36 @@ import { debounce } from 'lodash'; +import { EntityForSelect } from '@/relation-picker/types/EntityForSelect'; import { DropdownMenu } from '@/ui/components/menu/DropdownMenu'; import { DropdownMenuCheckableItem } from '@/ui/components/menu/DropdownMenuCheckableItem'; import { DropdownMenuItem } from '@/ui/components/menu/DropdownMenuItem'; import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer'; import { DropdownMenuSearch } from '@/ui/components/menu/DropdownMenuSearch'; import { DropdownMenuSeparator } from '@/ui/components/menu/DropdownMenuSeparator'; -import { Avatar, AvatarType } from '@/users/components/Avatar'; -import { CommentableType } from '~/generated/graphql'; +import { Avatar } from '@/users/components/Avatar'; -export type EntitiesForMultipleEntitySelect = { - selectedEntities: EntityForSelect[]; - filteredSelectedEntities: EntityForSelect[]; - entitiesToSelect: EntityForSelect[]; +export type EntitiesForMultipleEntitySelect< + CustomEntityForSelect extends EntityForSelect, +> = { + selectedEntities: CustomEntityForSelect[]; + filteredSelectedEntities: CustomEntityForSelect[]; + entitiesToSelect: CustomEntityForSelect[]; }; -export type EntityTypeForSelect = CommentableType; // TODO: derivate from all usable entity types - -export type EntityForSelect = { - id: string; - entityType: EntityTypeForSelect; - name: string; - avatarUrl?: string; - avatarType?: AvatarType; -}; - -export function MultipleEntitySelect({ +export function MultipleEntitySelect< + CustomEntityForSelect extends EntityForSelect, +>({ entities, onItemCheckChange, onSearchFilterChange, searchFilter, }: { - entities: EntitiesForMultipleEntitySelect; + entities: EntitiesForMultipleEntitySelect; searchFilter: string; onSearchFilterChange: (newSearchFilter: string) => void; onItemCheckChange: ( newCheckedValue: boolean, - entity: EntityForSelect, + entity: CustomEntityForSelect, ) => void; }) { const debouncedSetSearchFilter = debounce(onSearchFilterChange, 100, { diff --git a/front/src/modules/ui/hooks/menu/useFilteredSearchEntityQuery.ts b/front/src/modules/relation-picker/hooks/useFilteredSearchEntityQuery.ts similarity index 89% rename from front/src/modules/ui/hooks/menu/useFilteredSearchEntityQuery.ts rename to front/src/modules/relation-picker/hooks/useFilteredSearchEntityQuery.ts index 2cfe91dcd..7b2a5c3e9 100644 --- a/front/src/modules/ui/hooks/menu/useFilteredSearchEntityQuery.ts +++ b/front/src/modules/relation-picker/hooks/useFilteredSearchEntityQuery.ts @@ -1,9 +1,7 @@ import * as Apollo from '@apollo/client'; -import { - EntitiesForMultipleEntitySelect, - EntityForSelect, -} from '@/comments/components/MultipleEntitySelect'; +import { EntitiesForMultipleEntitySelect } from '@/relation-picker/components/MultipleEntitySelect'; +import { EntityForSelect } from '@/relation-picker/types/EntityForSelect'; import { Exact, InputMaybe, @@ -46,6 +44,7 @@ export function useFilteredSearchEntityQuery< Array | EntityOrderByWithRelationInput >; }>, + CustomEntityForSelect extends EntityForSelect, >({ queryHook, searchOnFields, @@ -66,10 +65,10 @@ export function useFilteredSearchEntityQuery< orderByField: OrderByField; sortOrder?: SortOrder; selectedIds: string[]; - mappingFunction: (entity: EntityType) => EntityForSelect; + mappingFunction: (entity: EntityType) => CustomEntityForSelect; limit?: number; searchFilter: string; -}): EntitiesForMultipleEntitySelect { +}): EntitiesForMultipleEntitySelect { const { data: selectedEntitiesData } = queryHook({ variables: { where: { diff --git a/front/src/modules/relation-picker/types/EntityForSelect.ts b/front/src/modules/relation-picker/types/EntityForSelect.ts new file mode 100644 index 000000000..c1cf6fd4e --- /dev/null +++ b/front/src/modules/relation-picker/types/EntityForSelect.ts @@ -0,0 +1,11 @@ +import { AvatarType } from '@/users/components/Avatar'; + +import { EntityTypeForSelect } from './EntityTypeForSelect'; + +export type EntityForSelect = { + id: string; + entityType: EntityTypeForSelect; + name: string; + avatarUrl?: string; + avatarType?: AvatarType; +}; diff --git a/front/src/modules/relation-picker/types/EntityTypeForSelect.ts b/front/src/modules/relation-picker/types/EntityTypeForSelect.ts new file mode 100644 index 000000000..756c20e58 --- /dev/null +++ b/front/src/modules/relation-picker/types/EntityTypeForSelect.ts @@ -0,0 +1,3 @@ +import { CommentableType, PipelineProgressableType } from '~/generated/graphql'; + +export type EntityTypeForSelect = CommentableType | PipelineProgressableType; diff --git a/front/src/modules/ui/utils/flatMapAndSortEntityForSelectArrayByName.ts b/front/src/modules/ui/utils/flatMapAndSortEntityForSelectArrayByName.ts index 896b1c7de..79d10eb37 100644 --- a/front/src/modules/ui/utils/flatMapAndSortEntityForSelectArrayByName.ts +++ b/front/src/modules/ui/utils/flatMapAndSortEntityForSelectArrayByName.ts @@ -1,10 +1,9 @@ -import { EntityForSelect } from '@/comments/components/MultipleEntitySelect'; +import { EntityForSelect } from '@/relation-picker/types/EntityForSelect'; -export function flatMapAndSortEntityForSelectArrayOfArrayByName( - entityForSelectArray: EntityForSelect[][], -) { - const sortByName = (a: EntityForSelect, b: EntityForSelect) => - a.name.localeCompare(b.name); +export function flatMapAndSortEntityForSelectArrayOfArrayByName< + T extends EntityForSelect, +>(entityForSelectArray: T[][]) { + const sortByName = (a: T, b: T) => a.name.localeCompare(b.name); return entityForSelectArray.flatMap((entity) => entity).sort(sortByName); }