Introduce main identifier to power RelationFieldDisplay (#2577)

* Introduce main identifier to power RelationFieldDisplay, FilterDrodown, TableFirstColumn

* Apply to RelationPicker
This commit is contained in:
Charles Bochet
2023-11-20 10:33:36 +01:00
committed by GitHub
parent 18ee95179e
commit 25950ab82a
75 changed files with 412 additions and 717 deletions

View File

@ -17,7 +17,7 @@ export const SmallName: Story = {
args: {
id: 'airbnb',
name: 'Airbnb',
pictureUrl: 'https://api.faviconkit.com/airbnb.com/144',
avatarUrl: 'https://api.faviconkit.com/airbnb.com/144',
},
};
@ -25,6 +25,6 @@ export const BigName: Story = {
args: {
id: 'google',
name: 'Google with a real big name to overflow the cell',
pictureUrl: 'https://api.faviconkit.com/google.com/144',
avatarUrl: 'https://api.faviconkit.com/google.com/144',
},
};

View File

@ -3,10 +3,6 @@ import styled from '@emotion/styled';
import { flip, offset, useFloating } from '@floating-ui/react';
import { v4 } from 'uuid';
import {
PeoplePicker,
PersonForSelect,
} from '@/people/components/PeoplePicker';
import { IconPlus } from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
@ -67,7 +63,7 @@ export const AddPersonToCompany = ({
} = usePreviousHotkeyScope();
const handlePersonSelected =
(companyId: string) => async (newPerson: PersonForSelect | null) => {
(companyId: string) => async (newPerson: any | null) => {
if (newPerson) {
// await updatePerson({
// variables: {
@ -146,13 +142,14 @@ export const AddPersonToCompany = ({
/>
</StyledInputContainer>
) : (
<PeoplePicker
personId={''}
onSubmit={handlePersonSelected(companyId)}
onCancel={handleClosePicker}
onCreate={() => setIsCreationDropdownOpen(true)}
excludePersonIds={peopleIds}
/>
<>todo</>
// <PeoplePicker
// personId={''}
// onSubmit={handlePersonSelected(companyId)}
// onCancel={handleClosePicker}
// onCreate={() => setIsCreationDropdownOpen(true)}
// excludePersonIds={peopleIds}
// />
)}
</div>
)}

View File

@ -208,7 +208,7 @@ export const CompanyBoardCard = () => {
<CompanyChip
id={company.id}
name={company.name}
pictureUrl={getLogoUrlFromDomainName(company.domainName)}
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
variant={EntityChipVariant.Transparent}
/>
{showCompactView && (
@ -239,14 +239,13 @@ export const CompanyBoardCard = () => {
value={{
entityId: boardCardId,
recoilScopeId: boardCardId + viewField.fieldMetadataId,
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: viewField.fieldMetadataId,
label: viewField.label,
iconName: viewField.iconName,
type: viewField.type,
metadata: viewField.metadata,
entityChipDisplayMapper:
viewField.entityChipDisplayMapper,
},
useUpdateEntityMutation: useUpdateOneObjectMutation,
hotkeyScope: InlineCellHotkeyScope.InlineCell,

View File

@ -6,14 +6,14 @@ import {
type CompanyChipProps = {
id: string;
name: string;
pictureUrl?: string;
avatarUrl?: string;
variant?: EntityChipVariant;
};
export const CompanyChip = ({
id,
name,
pictureUrl,
avatarUrl,
variant = EntityChipVariant.Regular,
}: CompanyChipProps) => (
<EntityChip
@ -21,7 +21,7 @@ export const CompanyChip = ({
linkToEntity={`/objects/companies/${id}`}
name={name}
avatarType="squared"
pictureUrl={pictureUrl}
avatarUrl={avatarUrl}
variant={variant}
/>
);

View File

@ -1,78 +0,0 @@
import { useEffect } from 'react';
import { useQuery } from '@apollo/client';
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
import { useFilteredSearchEntityQueryV2 } from '@/search/hooks/useFilteredSearchEntityQueryV2';
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';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { getLogoUrlFromDomainName } from '~/utils';
export type CompanyPickerProps = {
companyId: string | null;
onSubmit: (newCompanyId: EntityForSelect | null) => void;
onCancel?: () => void;
initialSearchFilter?: string | null;
};
export const CompanyPicker = ({
companyId,
onSubmit,
onCancel,
initialSearchFilter,
}: CompanyPickerProps) => {
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
useRecoilScopedState(relationPickerSearchFilterScopedState);
useEffect(() => {
if (initialSearchFilter) {
setRelationPickerSearchFilter(initialSearchFilter);
}
}, [initialSearchFilter, setRelationPickerSearchFilter]);
const { findManyQuery } = useFindOneObjectMetadataItem({
objectNamePlural: 'companies',
});
const useFindManyCompanies = (options: any) =>
useQuery(findManyQuery, options);
const companies = useFilteredSearchEntityQueryV2({
queryHook: useFindManyCompanies,
filters: [
{
fieldNames: ['name'],
filter: relationPickerSearchFilter,
},
],
orderByField: 'name',
mappingFunction: (company) => ({
entityType: Entity.Company,
id: company.id,
name: company.name,
avatarType: 'squared',
avatarUrl: getLogoUrlFromDomainName(company.domainName),
originalEntity: company,
}),
selectedIds: companyId ? [companyId] : [],
objectNamePlural: 'companies',
});
const handleEntitySelected = async (
selectedCompany: EntityForSelect | null | undefined,
) => {
onSubmit(selectedCompany ?? null);
};
return (
<SingleEntitySelect
entitiesToSelect={companies.entitiesToSelect}
loading={companies.loading}
onCancel={onCancel}
onEntitySelected={handleEntitySelected}
selectedEntity={companies.selectedEntities[0]}
/>
);
};

View File

@ -3,7 +3,6 @@ import { useRecoilState } from 'recoil';
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
import { IconChevronDown } from '@/ui/display/icon';
import { SingleEntitySelectBase } from '@/ui/input/relation-picker/components/SingleEntitySelectBase';
import { useEntitySelectSearch } from '@/ui/input/relation-picker/hooks/useEntitySelectSearch';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
@ -14,8 +13,6 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
export type CompanyProgressPickerProps = {
companyId: string | null;
onSubmit: (
@ -34,10 +31,10 @@ export const CompanyProgressPicker = ({
const { searchFilter, handleSearchFilterChange } = useEntitySelectSearch();
const companies = useFilteredSearchCompanyQuery({
searchFilter,
selectedIds: companyId ? [companyId] : [],
});
// const companies = useFilteredSearchCompanyQuery({
// searchFilter,
// selectedIds: companyId ? [companyId] : [],
// });
const [isProgressSelectionUnfolded, setIsProgressSelectionUnfolded] =
useState(false);
@ -113,13 +110,13 @@ export const CompanyProgressPicker = ({
/>
<DropdownMenuSeparator />
<RecoilScope>
<SingleEntitySelectBase
{/* <SingleEntitySelectBase
entitiesToSelect={companies.entitiesToSelect}
loading={companies.loading}
onCancel={onCancel}
onEntitySelected={handleEntitySelected}
selectedEntity={companies.selectedEntities[0]}
/>
/> */}
</RecoilScope>
</>
)}

View File

@ -1,24 +0,0 @@
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
export const FilterDropdownCompanySearchSelect = () => {
const {
objectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
} = useFilter();
const usersForSelect = useFilteredSearchCompanyQuery({
searchFilter: objectFilterDropdownSearchInput,
selectedIds: objectFilterDropdownSelectedEntityId
? [objectFilterDropdownSelectedEntityId]
: [],
});
return (
<ObjectFilterDropdownEntitySearchSelect
entitiesForSelect={usersForSelect}
/>
);
};

View File

@ -5,7 +5,6 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { Company } from '@/companies/types/Company';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
import { Opportunity } from '@/pipeline/types/Opportunity';
import { PipelineStep } from '@/pipeline/types/PipelineStep';
import { useBoardActionBarEntries } from '@/ui/layout/board/hooks/useBoardActionBarEntries';
@ -117,7 +116,7 @@ export const HooksCompanyBoardEffect = () => {
useEffect(() => {
setAvailableFilterDefinitions(opportunitiesBoardOptions.filterDefinitions);
setAvailableSortDefinitions?.(opportunitiesBoardOptions.sortDefinitions);
setAvailableFieldDefinitions?.(pipelineAvailableFieldDefinitions);
setAvailableFieldDefinitions?.([]);
}, [
setAvailableFieldDefinitions,
setAvailableFilterDefinitions,
@ -140,7 +139,7 @@ export const HooksCompanyBoardEffect = () => {
if (!loading && opportunities && companies) {
setActionBarEntries();
setContextMenuEntries();
setAvailableBoardCardFields(pipelineAvailableFieldDefinitions);
setAvailableBoardCardFields([]);
updateCompanyBoard(pipelineSteps, opportunities, companies);
setEntityCountInCurrentView(companies.length);
}
@ -160,10 +159,7 @@ export const HooksCompanyBoardEffect = () => {
useEffect(() => {
if (currentViewFields) {
setBoardCardFields(
mapViewFieldsToBoardFieldDefinitions(
currentViewFields,
pipelineAvailableFieldDefinitions,
),
mapViewFieldsToBoardFieldDefinitions(currentViewFields, []),
);
}
}, [currentViewFields, setBoardCardFields]);

View File

@ -1,7 +1,6 @@
import { useCallback, useContext, useState } from 'react';
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { NewButton } from '@/ui/layout/board/components/NewButton';
@ -9,8 +8,6 @@ import { BoardColumnContext } from '@/ui/layout/board/contexts/BoardColumnContex
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
export const NewCompanyProgressButton = () => {
const [isCreatingCard, setIsCreatingCard] = useState(false);
const column = useContext(BoardColumnContext);
@ -55,22 +52,23 @@ export const NewCompanyProgressButton = () => {
relationPickerSearchFilterScopedState,
);
const companies = useFilteredSearchCompanyQuery({
searchFilter: relationPickerSearchFilter,
});
// const companies = useFilteredSearchCompanyQuery({
// searchFilter: relationPickerSearchFilter,
// });
return (
<>
{isCreatingCard ? (
<SingleEntitySelect
disableBackgroundBlur
entitiesToSelect={companies.entitiesToSelect}
loading={companies.loading}
onCancel={handleCancel}
onEntitySelected={handleEntitySelect}
selectedEntity={companies.selectedEntities[0]}
/>
<>TODO</>
) : (
// <SingleEntitySelect
// disableBackgroundBlur
// entitiesToSelect={companies.entitiesToSelect}
// loading={companies.loading}
// onCancel={handleCancel}
// onEntitySelected={handleEntitySelect}
// selectedEntity={companies.selectedEntities[0]}
// />
<NewButton onClick={handleNewClick} />
)}
</>

View File

@ -1,44 +0,0 @@
import { useQuery } from '@apollo/client';
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
import { useFilteredSearchEntityQueryV2 } from '@/search/hooks/useFilteredSearchEntityQueryV2';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
export const useFilteredSearchCompanyQuery = ({
searchFilter,
selectedIds = [],
limit,
}: {
searchFilter: string;
selectedIds?: string[];
limit?: number;
}) => {
const { findManyQuery } = useFindOneObjectMetadataItem({
objectNameSingular: 'company',
});
const useFindManyCompanies = (options: any) =>
useQuery(findManyQuery, options);
return useFilteredSearchEntityQueryV2({
queryHook: useFindManyCompanies,
filters: [
{
fieldNames: ['name.firstName', 'name.lastName'],
filter: searchFilter,
},
],
orderByField: 'createdAt',
mappingFunction: (company) => ({
entityType: Entity.Company,
id: company.id,
name: company.name,
avatarType: 'squared',
avatarUrl: '',
originalEntity: company,
}),
selectedIds: selectedIds,
objectNamePlural: 'workspaceMembers',
limit,
});
};