Relation picker module (#335)
- Created a relation picker module - Added a CustomeEntityForSelect type
This commit is contained in:
@ -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,
|
||||
});
|
||||
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
@ -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({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { CommentableType } from '~/generated/graphql';
|
||||
|
||||
export type CommentableEntity = {
|
||||
type: CommentableType;
|
||||
id: string;
|
||||
type: CommentableType;
|
||||
};
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
|
||||
import { CommentableType } from '~/generated/graphql';
|
||||
|
||||
export type CommentableEntityForSelect = EntityForSelect & {
|
||||
entityType: CommentableType;
|
||||
};
|
||||
Reference in New Issue
Block a user