Relation picker module (#335)

- Created a relation picker module
- Added a CustomeEntityForSelect type
This commit is contained in:
Lucas Bordeau
2023-06-20 11:06:53 +02:00
committed by GitHub
parent c120903a45
commit e2eb40c1ea
9 changed files with 64 additions and 50 deletions

View File

@ -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,
});

View File

@ -1,92 +0,0 @@
import { debounce } from 'lodash';
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';
export type EntitiesForMultipleEntitySelect = {
selectedEntities: EntityForSelect[];
filteredSelectedEntities: EntityForSelect[];
entitiesToSelect: EntityForSelect[];
};
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({
entities,
onItemCheckChange,
onSearchFilterChange,
searchFilter,
}: {
entities: EntitiesForMultipleEntitySelect;
searchFilter: string;
onSearchFilterChange: (newSearchFilter: string) => void;
onItemCheckChange: (
newCheckedValue: boolean,
entity: EntityForSelect,
) => void;
}) {
const debouncedSetSearchFilter = debounce(onSearchFilterChange, 100, {
leading: true,
});
function handleFilterChange(event: React.ChangeEvent<HTMLInputElement>) {
debouncedSetSearchFilter(event.currentTarget.value);
onSearchFilterChange(event.currentTarget.value);
}
const entitiesInDropdown = [
...(entities.filteredSelectedEntities ?? []),
...(entities.entitiesToSelect ?? []),
];
return (
<DropdownMenu>
<DropdownMenuSearch
value={searchFilter}
onChange={handleFilterChange}
autoFocus
/>
<DropdownMenuSeparator />
<DropdownMenuItemContainer>
{entitiesInDropdown?.map((entity) => (
<DropdownMenuCheckableItem
key={entity.id}
checked={
entities.selectedEntities
?.map((selectedEntity) => selectedEntity.id)
?.includes(entity.id) ?? false
}
onChange={(newCheckedValue) =>
onItemCheckChange(newCheckedValue, entity)
}
>
<Avatar
avatarUrl={entity.avatarUrl}
placeholder={entity.name}
size={16}
type={entity.avatarType ?? 'rounded'}
/>
{entity.name}
</DropdownMenuCheckableItem>
))}
{entitiesInDropdown?.length === 0 && (
<DropdownMenuItem>No result</DropdownMenuItem>
)}
</DropdownMenuItemContainer>
</DropdownMenu>
);
}

View File

@ -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({

View File

@ -1,6 +1,6 @@
import { CommentableType } from '~/generated/graphql';
export type CommentableEntity = {
type: CommentableType;
id: string;
type: CommentableType;
};

View File

@ -0,0 +1,6 @@
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
import { CommentableType } from '~/generated/graphql';
export type CommentableEntityForSelect = EntityForSelect & {
entityType: CommentableType;
};