Introduce main identifier to power RelationFieldDisplay (#2577)
* Introduce main identifier to power RelationFieldDisplay, FilterDrodown, TableFirstColumn * Apply to RelationPicker
This commit is contained in:
@ -36,7 +36,7 @@ export const ActivityTargetChips = ({
|
|||||||
key={company.id}
|
key={company.id}
|
||||||
id={company.id}
|
id={company.id}
|
||||||
name={company.name}
|
name={company.name}
|
||||||
pictureUrl={getLogoUrlFromDomainName(company.domainName)}
|
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ export const ActivityTargetChips = ({
|
|||||||
key={person.id}
|
key={person.id}
|
||||||
id={person.id}
|
id={person.id}
|
||||||
name={person.name.firstName + ' ' + person.name.lastName}
|
name={person.name.firstName + ' ' + person.name.lastName}
|
||||||
pictureUrl={person.avatarUrl ?? undefined}
|
avatarUrl={person.avatarUrl ?? undefined}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,6 @@ import styled from '@emotion/styled';
|
|||||||
import { useHandleCheckableActivityTargetChange } from '@/activities/hooks/useHandleCheckableActivityTargetChange';
|
import { useHandleCheckableActivityTargetChange } from '@/activities/hooks/useHandleCheckableActivityTargetChange';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/activities/utils/flatMapAndSortEntityForSelectArrayByName';
|
|
||||||
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
|
|
||||||
import { useFilteredSearchPeopleQuery } from '@/people/hooks/useFilteredSearchPeopleQuery';
|
|
||||||
import { MultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect';
|
|
||||||
import { useInlineCell } from '@/ui/object/record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '@/ui/object/record-inline-cell/hooks/useInlineCell';
|
||||||
import { assertNotNull } from '~/utils/assert';
|
import { assertNotNull } from '~/utils/assert';
|
||||||
|
|
||||||
@ -60,31 +56,31 @@ export const ActivityRelationEditableFieldEditMode = ({
|
|||||||
Record<string, boolean>
|
Record<string, boolean>
|
||||||
>(initialSelectedEntityIds);
|
>(initialSelectedEntityIds);
|
||||||
|
|
||||||
const personsForMultiSelect = useFilteredSearchPeopleQuery({
|
// const personsForMultiSelect = useFilteredSearchPeopleQuery({
|
||||||
searchFilter,
|
// searchFilter,
|
||||||
selectedIds: initialPeopleIds,
|
// selectedIds: initialPeopleIds,
|
||||||
});
|
// });
|
||||||
|
|
||||||
const companiesForMultiSelect = useFilteredSearchCompanyQuery({
|
// const companiesForMultiSelect = useFilteredSearchCompanyQuery({
|
||||||
searchFilter,
|
// searchFilter,
|
||||||
selectedIds: initialCompanyIds,
|
// selectedIds: initialCompanyIds,
|
||||||
});
|
// });
|
||||||
|
|
||||||
const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([
|
// const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([
|
||||||
personsForMultiSelect.selectedEntities,
|
// personsForMultiSelect.selectedEntities,
|
||||||
companiesForMultiSelect.selectedEntities,
|
// companiesForMultiSelect.selectedEntities,
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
const filteredSelectedEntities =
|
// const filteredSelectedEntities =
|
||||||
flatMapAndSortEntityForSelectArrayOfArrayByName([
|
// flatMapAndSortEntityForSelectArrayOfArrayByName([
|
||||||
personsForMultiSelect.filteredSelectedEntities,
|
// personsForMultiSelect.filteredSelectedEntities,
|
||||||
companiesForMultiSelect.filteredSelectedEntities,
|
// companiesForMultiSelect.filteredSelectedEntities,
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([
|
// const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([
|
||||||
personsForMultiSelect.entitiesToSelect,
|
// personsForMultiSelect.entitiesToSelect,
|
||||||
companiesForMultiSelect.entitiesToSelect,
|
// companiesForMultiSelect.entitiesToSelect,
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
const handleCheckItemsChange = useHandleCheckableActivityTargetChange({
|
const handleCheckItemsChange = useHandleCheckableActivityTargetChange({
|
||||||
activity,
|
activity,
|
||||||
@ -102,7 +98,7 @@ export const ActivityRelationEditableFieldEditMode = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledSelectContainer>
|
<StyledSelectContainer>
|
||||||
<MultipleEntitySelect
|
{/* <MultipleEntitySelect
|
||||||
entities={{
|
entities={{
|
||||||
entitiesToSelect,
|
entitiesToSelect,
|
||||||
filteredSelectedEntities,
|
filteredSelectedEntities,
|
||||||
@ -115,7 +111,7 @@ export const ActivityRelationEditableFieldEditMode = ({
|
|||||||
value={selectedEntityIds}
|
value={selectedEntityIds}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
/>
|
/> */}
|
||||||
</StyledSelectContainer>
|
</StyledSelectContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export const TimelineActivityCardFooter = ({
|
|||||||
' ' +
|
' ' +
|
||||||
activity.assignee.name.lastName ?? ''
|
activity.assignee.name.lastName ?? ''
|
||||||
}
|
}
|
||||||
pictureUrl={activity.assignee.avatarUrl ?? ''}
|
avatarUrl={activity.assignee.avatarUrl ?? ''}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export const SmallName: Story = {
|
|||||||
args: {
|
args: {
|
||||||
id: 'airbnb',
|
id: 'airbnb',
|
||||||
name: '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: {
|
args: {
|
||||||
id: 'google',
|
id: 'google',
|
||||||
name: 'Google with a real big name to overflow the cell',
|
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',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,10 +3,6 @@ import styled from '@emotion/styled';
|
|||||||
import { flip, offset, useFloating } from '@floating-ui/react';
|
import { flip, offset, useFloating } from '@floating-ui/react';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import {
|
|
||||||
PeoplePicker,
|
|
||||||
PersonForSelect,
|
|
||||||
} from '@/people/components/PeoplePicker';
|
|
||||||
import { IconPlus } from '@/ui/display/icon';
|
import { IconPlus } from '@/ui/display/icon';
|
||||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
@ -67,7 +63,7 @@ export const AddPersonToCompany = ({
|
|||||||
} = usePreviousHotkeyScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const handlePersonSelected =
|
const handlePersonSelected =
|
||||||
(companyId: string) => async (newPerson: PersonForSelect | null) => {
|
(companyId: string) => async (newPerson: any | null) => {
|
||||||
if (newPerson) {
|
if (newPerson) {
|
||||||
// await updatePerson({
|
// await updatePerson({
|
||||||
// variables: {
|
// variables: {
|
||||||
@ -146,13 +142,14 @@ export const AddPersonToCompany = ({
|
|||||||
/>
|
/>
|
||||||
</StyledInputContainer>
|
</StyledInputContainer>
|
||||||
) : (
|
) : (
|
||||||
<PeoplePicker
|
<>todo</>
|
||||||
personId={''}
|
// <PeoplePicker
|
||||||
onSubmit={handlePersonSelected(companyId)}
|
// personId={''}
|
||||||
onCancel={handleClosePicker}
|
// onSubmit={handlePersonSelected(companyId)}
|
||||||
onCreate={() => setIsCreationDropdownOpen(true)}
|
// onCancel={handleClosePicker}
|
||||||
excludePersonIds={peopleIds}
|
// onCreate={() => setIsCreationDropdownOpen(true)}
|
||||||
/>
|
// excludePersonIds={peopleIds}
|
||||||
|
// />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -208,7 +208,7 @@ export const CompanyBoardCard = () => {
|
|||||||
<CompanyChip
|
<CompanyChip
|
||||||
id={company.id}
|
id={company.id}
|
||||||
name={company.name}
|
name={company.name}
|
||||||
pictureUrl={getLogoUrlFromDomainName(company.domainName)}
|
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
|
||||||
variant={EntityChipVariant.Transparent}
|
variant={EntityChipVariant.Transparent}
|
||||||
/>
|
/>
|
||||||
{showCompactView && (
|
{showCompactView && (
|
||||||
@ -239,14 +239,13 @@ export const CompanyBoardCard = () => {
|
|||||||
value={{
|
value={{
|
||||||
entityId: boardCardId,
|
entityId: boardCardId,
|
||||||
recoilScopeId: boardCardId + viewField.fieldMetadataId,
|
recoilScopeId: boardCardId + viewField.fieldMetadataId,
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: viewField.fieldMetadataId,
|
fieldMetadataId: viewField.fieldMetadataId,
|
||||||
label: viewField.label,
|
label: viewField.label,
|
||||||
iconName: viewField.iconName,
|
iconName: viewField.iconName,
|
||||||
type: viewField.type,
|
type: viewField.type,
|
||||||
metadata: viewField.metadata,
|
metadata: viewField.metadata,
|
||||||
entityChipDisplayMapper:
|
|
||||||
viewField.entityChipDisplayMapper,
|
|
||||||
},
|
},
|
||||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||||
|
|||||||
@ -6,14 +6,14 @@ import {
|
|||||||
type CompanyChipProps = {
|
type CompanyChipProps = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
pictureUrl?: string;
|
avatarUrl?: string;
|
||||||
variant?: EntityChipVariant;
|
variant?: EntityChipVariant;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CompanyChip = ({
|
export const CompanyChip = ({
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
pictureUrl,
|
avatarUrl,
|
||||||
variant = EntityChipVariant.Regular,
|
variant = EntityChipVariant.Regular,
|
||||||
}: CompanyChipProps) => (
|
}: CompanyChipProps) => (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
@ -21,7 +21,7 @@ export const CompanyChip = ({
|
|||||||
linkToEntity={`/objects/companies/${id}`}
|
linkToEntity={`/objects/companies/${id}`}
|
||||||
name={name}
|
name={name}
|
||||||
avatarType="squared"
|
avatarType="squared"
|
||||||
pictureUrl={pictureUrl}
|
avatarUrl={avatarUrl}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -3,7 +3,6 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
|
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
|
||||||
import { IconChevronDown } from '@/ui/display/icon';
|
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 { useEntitySelectSearch } from '@/ui/input/relation-picker/hooks/useEntitySelectSearch';
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
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 { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
|
|
||||||
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
|
|
||||||
|
|
||||||
export type CompanyProgressPickerProps = {
|
export type CompanyProgressPickerProps = {
|
||||||
companyId: string | null;
|
companyId: string | null;
|
||||||
onSubmit: (
|
onSubmit: (
|
||||||
@ -34,10 +31,10 @@ export const CompanyProgressPicker = ({
|
|||||||
|
|
||||||
const { searchFilter, handleSearchFilterChange } = useEntitySelectSearch();
|
const { searchFilter, handleSearchFilterChange } = useEntitySelectSearch();
|
||||||
|
|
||||||
const companies = useFilteredSearchCompanyQuery({
|
// const companies = useFilteredSearchCompanyQuery({
|
||||||
searchFilter,
|
// searchFilter,
|
||||||
selectedIds: companyId ? [companyId] : [],
|
// selectedIds: companyId ? [companyId] : [],
|
||||||
});
|
// });
|
||||||
|
|
||||||
const [isProgressSelectionUnfolded, setIsProgressSelectionUnfolded] =
|
const [isProgressSelectionUnfolded, setIsProgressSelectionUnfolded] =
|
||||||
useState(false);
|
useState(false);
|
||||||
@ -113,13 +110,13 @@ export const CompanyProgressPicker = ({
|
|||||||
/>
|
/>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<RecoilScope>
|
<RecoilScope>
|
||||||
<SingleEntitySelectBase
|
{/* <SingleEntitySelectBase
|
||||||
entitiesToSelect={companies.entitiesToSelect}
|
entitiesToSelect={companies.entitiesToSelect}
|
||||||
loading={companies.loading}
|
loading={companies.loading}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onEntitySelected={handleEntitySelected}
|
onEntitySelected={handleEntitySelected}
|
||||||
selectedEntity={companies.selectedEntities[0]}
|
selectedEntity={companies.selectedEntities[0]}
|
||||||
/>
|
/> */}
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -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}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -5,7 +5,6 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
|||||||
import { Company } from '@/companies/types/Company';
|
import { Company } from '@/companies/types/Company';
|
||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
||||||
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
|
|
||||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||||
import { PipelineStep } from '@/pipeline/types/PipelineStep';
|
import { PipelineStep } from '@/pipeline/types/PipelineStep';
|
||||||
import { useBoardActionBarEntries } from '@/ui/layout/board/hooks/useBoardActionBarEntries';
|
import { useBoardActionBarEntries } from '@/ui/layout/board/hooks/useBoardActionBarEntries';
|
||||||
@ -117,7 +116,7 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAvailableFilterDefinitions(opportunitiesBoardOptions.filterDefinitions);
|
setAvailableFilterDefinitions(opportunitiesBoardOptions.filterDefinitions);
|
||||||
setAvailableSortDefinitions?.(opportunitiesBoardOptions.sortDefinitions);
|
setAvailableSortDefinitions?.(opportunitiesBoardOptions.sortDefinitions);
|
||||||
setAvailableFieldDefinitions?.(pipelineAvailableFieldDefinitions);
|
setAvailableFieldDefinitions?.([]);
|
||||||
}, [
|
}, [
|
||||||
setAvailableFieldDefinitions,
|
setAvailableFieldDefinitions,
|
||||||
setAvailableFilterDefinitions,
|
setAvailableFilterDefinitions,
|
||||||
@ -140,7 +139,7 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
if (!loading && opportunities && companies) {
|
if (!loading && opportunities && companies) {
|
||||||
setActionBarEntries();
|
setActionBarEntries();
|
||||||
setContextMenuEntries();
|
setContextMenuEntries();
|
||||||
setAvailableBoardCardFields(pipelineAvailableFieldDefinitions);
|
setAvailableBoardCardFields([]);
|
||||||
updateCompanyBoard(pipelineSteps, opportunities, companies);
|
updateCompanyBoard(pipelineSteps, opportunities, companies);
|
||||||
setEntityCountInCurrentView(companies.length);
|
setEntityCountInCurrentView(companies.length);
|
||||||
}
|
}
|
||||||
@ -160,10 +159,7 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentViewFields) {
|
if (currentViewFields) {
|
||||||
setBoardCardFields(
|
setBoardCardFields(
|
||||||
mapViewFieldsToBoardFieldDefinitions(
|
mapViewFieldsToBoardFieldDefinitions(currentViewFields, []),
|
||||||
currentViewFields,
|
|
||||||
pipelineAvailableFieldDefinitions,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [currentViewFields, setBoardCardFields]);
|
}, [currentViewFields, setBoardCardFields]);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useCallback, useContext, useState } from 'react';
|
import { useCallback, useContext, useState } from 'react';
|
||||||
|
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
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 { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { NewButton } from '@/ui/layout/board/components/NewButton';
|
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 { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
|
|
||||||
|
|
||||||
export const NewCompanyProgressButton = () => {
|
export const NewCompanyProgressButton = () => {
|
||||||
const [isCreatingCard, setIsCreatingCard] = useState(false);
|
const [isCreatingCard, setIsCreatingCard] = useState(false);
|
||||||
const column = useContext(BoardColumnContext);
|
const column = useContext(BoardColumnContext);
|
||||||
@ -55,22 +52,23 @@ export const NewCompanyProgressButton = () => {
|
|||||||
relationPickerSearchFilterScopedState,
|
relationPickerSearchFilterScopedState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const companies = useFilteredSearchCompanyQuery({
|
// const companies = useFilteredSearchCompanyQuery({
|
||||||
searchFilter: relationPickerSearchFilter,
|
// searchFilter: relationPickerSearchFilter,
|
||||||
});
|
// });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isCreatingCard ? (
|
{isCreatingCard ? (
|
||||||
<SingleEntitySelect
|
<>TODO</>
|
||||||
disableBackgroundBlur
|
|
||||||
entitiesToSelect={companies.entitiesToSelect}
|
|
||||||
loading={companies.loading}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
onEntitySelected={handleEntitySelect}
|
|
||||||
selectedEntity={companies.selectedEntities[0]}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
|
// <SingleEntitySelect
|
||||||
|
// disableBackgroundBlur
|
||||||
|
// entitiesToSelect={companies.entitiesToSelect}
|
||||||
|
// loading={companies.loading}
|
||||||
|
// onCancel={handleCancel}
|
||||||
|
// onEntitySelected={handleEntitySelect}
|
||||||
|
// selectedEntity={companies.selectedEntities[0]}
|
||||||
|
// />
|
||||||
<NewButton onClick={handleNewClick} />
|
<NewButton onClick={handleNewClick} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -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,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -26,7 +26,6 @@ export const useComputeDefinitionsFromFieldMetadata = (
|
|||||||
formatFieldMetadataItemAsColumnDefinition({
|
formatFieldMetadataItemAsColumnDefinition({
|
||||||
position: index,
|
position: index,
|
||||||
field,
|
field,
|
||||||
objectMetadataItem: objectMetadataItem,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export const useMapFieldMetadataToGraphQLQuery = () => {
|
|||||||
|
|
||||||
const mapFieldMetadataToGraphQLQuery = (
|
const mapFieldMetadataToGraphQLQuery = (
|
||||||
field: FieldMetadataItem,
|
field: FieldMetadataItem,
|
||||||
maxDepthForRelations: number = 1,
|
maxDepthForRelations: number = 2,
|
||||||
): any => {
|
): any => {
|
||||||
if (maxDepthForRelations <= 0) {
|
if (maxDepthForRelations <= 0) {
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
|
||||||
|
|
||||||
|
export const useObjectMainIdentifier = (
|
||||||
|
objectMetadataItem?: ObjectMetadataItem,
|
||||||
|
) => {
|
||||||
|
if (!objectMetadataItem) {
|
||||||
|
return {
|
||||||
|
mainIdentifierMapper: undefined,
|
||||||
|
mainIdentifierFieldMetadataId: undefined,
|
||||||
|
basePathToShowPage: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainIdentifierMapper: MainIdentifierMapper = (record: any) => {
|
||||||
|
if (objectMetadataItem.nameSingular === 'company') {
|
||||||
|
return {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
avatarUrl: record.avatarUrl,
|
||||||
|
avatarType: 'squared',
|
||||||
|
record: record,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectMetadataItem.nameSingular === 'workspaceMember') {
|
||||||
|
return {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name.firstName + ' ' + record.name.lastName,
|
||||||
|
avatarUrl: record.avatarUrl,
|
||||||
|
avatarType: 'rounded',
|
||||||
|
record: record,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
avatarUrl: record.avatarUrl,
|
||||||
|
avatarType: 'rounded',
|
||||||
|
record: record,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mainIdentifierFieldMetadataId = objectMetadataItem.fields.find(
|
||||||
|
({ name }) => name === 'name',
|
||||||
|
)?.id;
|
||||||
|
|
||||||
|
const basePathToShowPage = `/object/${objectMetadataItem.nameSingular}/`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
mainIdentifierMapper,
|
||||||
|
mainIdentifierFieldMetadataId,
|
||||||
|
basePathToShowPage,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -6,12 +6,18 @@ export type FieldMetadataItem = Omit<
|
|||||||
> & {
|
> & {
|
||||||
fromRelationMetadata?:
|
fromRelationMetadata?:
|
||||||
| (Pick<Relation, 'id' | 'toFieldMetadataId' | 'relationType'> & {
|
| (Pick<Relation, 'id' | 'toFieldMetadataId' | 'relationType'> & {
|
||||||
toObjectMetadata: Pick<Relation['toObjectMetadata'], 'id'>;
|
toObjectMetadata: Pick<
|
||||||
|
Relation['toObjectMetadata'],
|
||||||
|
'id' | 'nameSingular' | 'namePlural'
|
||||||
|
>;
|
||||||
})
|
})
|
||||||
| null;
|
| null;
|
||||||
toRelationMetadata?:
|
toRelationMetadata?:
|
||||||
| (Pick<Relation, 'id' | 'fromFieldMetadataId' | 'relationType'> & {
|
| (Pick<Relation, 'id' | 'fromFieldMetadataId' | 'relationType'> & {
|
||||||
fromObjectMetadata: Pick<Relation['fromObjectMetadata'], 'id'>;
|
fromObjectMetadata: Pick<
|
||||||
|
Relation['fromObjectMetadata'],
|
||||||
|
'id' | 'nameSingular' | 'namePlural'
|
||||||
|
>;
|
||||||
})
|
})
|
||||||
| null;
|
| null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,32 +1,68 @@
|
|||||||
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
|
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
|
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
||||||
|
import { getLogoUrlFromDomainName } from '~/utils';
|
||||||
|
|
||||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||||
import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|
||||||
|
|
||||||
import { parseFieldType } from './parseFieldType';
|
import { parseFieldType } from './parseFieldType';
|
||||||
|
|
||||||
export const formatFieldMetadataItemAsColumnDefinition = ({
|
export const formatFieldMetadataItemAsColumnDefinition = ({
|
||||||
position,
|
position,
|
||||||
field,
|
field,
|
||||||
objectMetadataItem,
|
|
||||||
}: {
|
}: {
|
||||||
position: number;
|
position: number;
|
||||||
field: FieldMetadataItem;
|
field: FieldMetadataItem;
|
||||||
objectMetadataItem: Omit<ObjectMetadataItem, 'fields'>;
|
}): ColumnDefinition<FieldMetadata> => {
|
||||||
}): ColumnDefinition<FieldMetadata> => ({
|
const relationObjectMetadataItem =
|
||||||
position,
|
field.toRelationMetadata?.fromObjectMetadata;
|
||||||
fieldMetadataId: field.id,
|
|
||||||
label: field.label,
|
const mainIdentifierMapper: MainIdentifierMapper = (record: any) => {
|
||||||
size: 100,
|
if (relationObjectMetadataItem?.nameSingular === 'company') {
|
||||||
type: parseFieldType(field.type),
|
return {
|
||||||
metadata: {
|
id: record.id,
|
||||||
fieldName: field.name,
|
name: record.name,
|
||||||
placeHolder: field.label,
|
avatarUrl: getLogoUrlFromDomainName(record.domainName),
|
||||||
},
|
avatarType: 'squared',
|
||||||
iconName: field.icon ?? 'Icon123',
|
record: record,
|
||||||
isVisible: true,
|
};
|
||||||
basePathToShowPage: `/object/${objectMetadataItem.nameSingular}/`,
|
}
|
||||||
relationType: parseFieldRelationType(field),
|
if (relationObjectMetadataItem?.nameSingular === 'workspaceMember') {
|
||||||
});
|
return {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name.firstName + ' ' + record.name.lastName,
|
||||||
|
avatarUrl: record.avatarUrl,
|
||||||
|
avatarType: 'rounded',
|
||||||
|
record: record,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
avatarUrl: record.avatarUrl,
|
||||||
|
avatarType: 'rounded',
|
||||||
|
record: record,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
position,
|
||||||
|
fieldMetadataId: field.id,
|
||||||
|
label: field.label,
|
||||||
|
size: 100,
|
||||||
|
type: parseFieldType(field.type),
|
||||||
|
metadata: {
|
||||||
|
fieldName: field.name,
|
||||||
|
placeHolder: field.label,
|
||||||
|
mainIdentifierMapper: mainIdentifierMapper,
|
||||||
|
relationType: parseFieldRelationType(field),
|
||||||
|
searchFields: ['name'],
|
||||||
|
objectMetadataNamePlural: relationObjectMetadataItem?.namePlural,
|
||||||
|
objectMetadataNameSingular: relationObjectMetadataItem?.nameSingular,
|
||||||
|
},
|
||||||
|
iconName: field.icon ?? 'Icon123',
|
||||||
|
isVisible: true,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@ -165,11 +165,11 @@ export const RecordShowPage = () => {
|
|||||||
value={{
|
value={{
|
||||||
entityId: object.id,
|
entityId: object.id,
|
||||||
recoilScopeId: object.id + metadataField.id,
|
recoilScopeId: object.id + metadataField.id,
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition:
|
fieldDefinition:
|
||||||
formatFieldMetadataItemAsColumnDefinition({
|
formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: metadataField,
|
field: metadataField,
|
||||||
position: index,
|
position: index,
|
||||||
objectMetadataItem: foundObjectMetadataItem,
|
|
||||||
}),
|
}),
|
||||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useEffect } from 'react';
|
|||||||
|
|
||||||
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
|
import { useObjectMainIdentifier } from '@/object-metadata/hooks/useObjectMainIdentifier';
|
||||||
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
||||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
@ -13,12 +14,19 @@ export const RecordTableEffect = () => {
|
|||||||
scopeId: objectNamePlural,
|
scopeId: objectNamePlural,
|
||||||
setAvailableTableColumns,
|
setAvailableTableColumns,
|
||||||
setOnEntityCountChange,
|
setOnEntityCountChange,
|
||||||
|
setObjectMetadataConfig,
|
||||||
} = useRecordTable();
|
} = useRecordTable();
|
||||||
|
|
||||||
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
||||||
objectNamePlural,
|
objectNamePlural,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
mainIdentifierMapper,
|
||||||
|
basePathToShowPage,
|
||||||
|
mainIdentifierFieldMetadataId,
|
||||||
|
} = useObjectMainIdentifier(foundObjectMetadataItem);
|
||||||
|
|
||||||
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||||
useComputeDefinitionsFromFieldMetadata(foundObjectMetadataItem);
|
useComputeDefinitionsFromFieldMetadata(foundObjectMetadataItem);
|
||||||
|
|
||||||
@ -31,6 +39,26 @@ export const RecordTableEffect = () => {
|
|||||||
setEntityCountInCurrentView,
|
setEntityCountInCurrentView,
|
||||||
} = useView();
|
} = useView();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
mainIdentifierMapper &&
|
||||||
|
basePathToShowPage &&
|
||||||
|
mainIdentifierFieldMetadataId
|
||||||
|
) {
|
||||||
|
setObjectMetadataConfig?.({
|
||||||
|
mainIdentifierMapper,
|
||||||
|
basePathToShowPage,
|
||||||
|
mainIdentifierFieldMetadataId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
basePathToShowPage,
|
||||||
|
foundObjectMetadataItem,
|
||||||
|
mainIdentifierFieldMetadataId,
|
||||||
|
mainIdentifierMapper,
|
||||||
|
setObjectMetadataConfig,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!foundObjectMetadataItem) {
|
if (!foundObjectMetadataItem) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
|
import { isFieldRelation } from '@/ui/object/field/types/guards/isFieldRelation';
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
||||||
|
|
||||||
export const filterAvailableTableColumns = (
|
export const filterAvailableTableColumns = (
|
||||||
columnDefinition: ColumnDefinition<FieldMetadata>,
|
columnDefinition: ColumnDefinition<FieldMetadata>,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (
|
if (
|
||||||
columnDefinition.type === 'RELATION' &&
|
isFieldRelation(columnDefinition) &&
|
||||||
columnDefinition.relationType !== 'TO_ONE_OBJECT'
|
columnDefinition.metadata?.relationType !== 'TO_ONE_OBJECT'
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ export const mapPaginatedObjectsToObjects = <
|
|||||||
pagedObjects: ObjectTypeQuery | undefined;
|
pagedObjects: ObjectTypeQuery | undefined;
|
||||||
objectNamePlural: string;
|
objectNamePlural: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
console.log(objectNamePlural);
|
||||||
const formattedObjects: ObjectType[] =
|
const formattedObjects: ObjectType[] =
|
||||||
pagedObjects?.[objectNamePlural].edges.map((objectEdge: ObjectEdge) => ({
|
pagedObjects?.[objectNamePlural].edges.map((objectEdge: ObjectEdge) => ({
|
||||||
...objectEdge.node,
|
...objectEdge.node,
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
import { useFilteredSearchPeopleQuery } from '@/people/hooks/useFilteredSearchPeopleQuery';
|
|
||||||
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
|
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
|
||||||
|
|
||||||
export const FilterDropdownPeopleSearchSelect = () => {
|
|
||||||
const {
|
|
||||||
objectFilterDropdownSearchInput,
|
|
||||||
objectFilterDropdownSelectedEntityId,
|
|
||||||
} = useFilter();
|
|
||||||
|
|
||||||
const peopleForSelect = useFilteredSearchPeopleQuery({
|
|
||||||
searchFilter: objectFilterDropdownSearchInput,
|
|
||||||
selectedIds: objectFilterDropdownSelectedEntityId
|
|
||||||
? [objectFilterDropdownSelectedEntityId]
|
|
||||||
: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ObjectFilterDropdownEntitySearchSelect
|
|
||||||
entitiesForSelect={peopleForSelect}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,96 +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';
|
|
||||||
|
|
||||||
export type PeoplePickerProps = {
|
|
||||||
personId: string | null;
|
|
||||||
companyId?: string;
|
|
||||||
onSubmit: (newPersonId: PersonForSelect | null) => void;
|
|
||||||
onCancel?: () => void;
|
|
||||||
onCreate?: () => void;
|
|
||||||
excludePersonIds?: string[];
|
|
||||||
initialSearchFilter?: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PersonForSelect = EntityForSelect & {
|
|
||||||
entityType: Entity.Person;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PeoplePicker = ({
|
|
||||||
personId,
|
|
||||||
companyId,
|
|
||||||
onSubmit,
|
|
||||||
onCancel,
|
|
||||||
onCreate,
|
|
||||||
excludePersonIds,
|
|
||||||
initialSearchFilter,
|
|
||||||
}: PeoplePickerProps) => {
|
|
||||||
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
|
||||||
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRelationPickerSearchFilter(initialSearchFilter ?? '');
|
|
||||||
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
|
||||||
|
|
||||||
const queryFilters = [
|
|
||||||
{
|
|
||||||
fieldNames: ['name.firstName', 'name.lastName'],
|
|
||||||
filter: relationPickerSearchFilter,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (companyId) {
|
|
||||||
queryFilters.push({
|
|
||||||
fieldNames: ['companyId'],
|
|
||||||
filter: companyId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { findManyQuery } = useFindOneObjectMetadataItem({
|
|
||||||
objectNameSingular: 'person',
|
|
||||||
});
|
|
||||||
|
|
||||||
const useFindManyPeople = (options: any) => useQuery(findManyQuery, options);
|
|
||||||
|
|
||||||
const people = useFilteredSearchEntityQueryV2({
|
|
||||||
queryHook: useFindManyPeople,
|
|
||||||
filters: queryFilters,
|
|
||||||
orderByField: 'createdAt',
|
|
||||||
mappingFunction: (workspaceMember) => ({
|
|
||||||
entityType: Entity.WorkspaceMember,
|
|
||||||
id: workspaceMember.id,
|
|
||||||
name:
|
|
||||||
workspaceMember.name.firstName + ' ' + workspaceMember.name.lastName,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
avatarUrl: '',
|
|
||||||
originalEntity: workspaceMember,
|
|
||||||
}),
|
|
||||||
selectedIds: [personId ?? ''],
|
|
||||||
excludeEntityIds: excludePersonIds,
|
|
||||||
objectNamePlural: 'people',
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleEntitySelected = async (
|
|
||||||
selectedPerson: any | null | undefined,
|
|
||||||
) => {
|
|
||||||
onSubmit(selectedPerson ?? null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SingleEntitySelect
|
|
||||||
entitiesToSelect={people.entitiesToSelect}
|
|
||||||
loading={people.loading}
|
|
||||||
onCancel={onCancel}
|
|
||||||
onCreate={onCreate}
|
|
||||||
onEntitySelected={handleEntitySelected}
|
|
||||||
selectedEntity={people.selectedEntities[0]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -6,14 +6,14 @@ import {
|
|||||||
export type PersonChipProps = {
|
export type PersonChipProps = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
pictureUrl?: string;
|
avatarUrl?: string;
|
||||||
variant?: EntityChipVariant;
|
variant?: EntityChipVariant;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PersonChip = ({
|
export const PersonChip = ({
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
pictureUrl,
|
avatarUrl,
|
||||||
variant,
|
variant,
|
||||||
}: PersonChipProps) => (
|
}: PersonChipProps) => (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
@ -21,7 +21,7 @@ export const PersonChip = ({
|
|||||||
linkToEntity={`/person/${id}`}
|
linkToEntity={`/person/${id}`}
|
||||||
name={name}
|
name={name}
|
||||||
avatarType="rounded"
|
avatarType="rounded"
|
||||||
pictureUrl={pictureUrl}
|
avatarUrl={avatarUrl}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,43 +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 useFilteredSearchPeopleQuery = ({
|
|
||||||
searchFilter,
|
|
||||||
selectedIds = [],
|
|
||||||
limit,
|
|
||||||
}: {
|
|
||||||
searchFilter: string;
|
|
||||||
selectedIds?: string[];
|
|
||||||
limit?: number;
|
|
||||||
}) => {
|
|
||||||
const { findManyQuery } = useFindOneObjectMetadataItem({
|
|
||||||
objectNameSingular: 'person',
|
|
||||||
});
|
|
||||||
|
|
||||||
const useFindManyPeople = (options: any) => useQuery(findManyQuery, options);
|
|
||||||
|
|
||||||
return useFilteredSearchEntityQueryV2({
|
|
||||||
queryHook: useFindManyPeople,
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
fieldNames: ['name.firstName', 'name.lastName'],
|
|
||||||
filter: searchFilter,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
orderByField: 'createdAt',
|
|
||||||
mappingFunction: (person) => ({
|
|
||||||
entityType: Entity.Person,
|
|
||||||
id: person.id,
|
|
||||||
name: person.name.firstName + ' ' + person.name.lastName,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
avatarUrl: '',
|
|
||||||
originalEntity: person,
|
|
||||||
}),
|
|
||||||
selectedIds: selectedIds,
|
|
||||||
objectNamePlural: 'workspaceMembers',
|
|
||||||
limit,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
import { Person } from '@/people/types/Person';
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import {
|
|
||||||
FieldDateMetadata,
|
|
||||||
FieldMetadata,
|
|
||||||
FieldNumberMetadata,
|
|
||||||
FieldProbabilityMetadata,
|
|
||||||
FieldRelationMetadata,
|
|
||||||
} from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
|
||||||
|
|
||||||
export const pipelineAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[] =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'closeDate',
|
|
||||||
label: 'Close Date',
|
|
||||||
iconName: 'IconCalendarEvent',
|
|
||||||
position: 0,
|
|
||||||
type: 'DATE',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'closeDate',
|
|
||||||
},
|
|
||||||
size: 0,
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent:
|
|
||||||
'Specified date by which an opportunity must be completed.',
|
|
||||||
} satisfies ColumnDefinition<FieldDateMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'amount',
|
|
||||||
label: 'Amount',
|
|
||||||
iconName: 'IconCurrencyDollar',
|
|
||||||
position: 1,
|
|
||||||
type: 'NUMBER',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'amount',
|
|
||||||
placeHolder: '0',
|
|
||||||
},
|
|
||||||
size: 0,
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'Potential monetary value of a business opportunity.',
|
|
||||||
} satisfies ColumnDefinition<FieldNumberMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'probability',
|
|
||||||
label: 'Probability',
|
|
||||||
iconName: 'IconProgressCheck',
|
|
||||||
position: 2,
|
|
||||||
type: 'PROBABILITY',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'probability',
|
|
||||||
},
|
|
||||||
size: 0,
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent:
|
|
||||||
"Level of certainty in the lead's potential to convert into a success.",
|
|
||||||
} satisfies ColumnDefinition<FieldProbabilityMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'pointOfContact',
|
|
||||||
label: 'Point of Contact',
|
|
||||||
iconName: 'IconUser',
|
|
||||||
position: 3,
|
|
||||||
type: 'RELATION',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'pointOfContact',
|
|
||||||
relationType: Entity.Person,
|
|
||||||
useEditButton: true,
|
|
||||||
},
|
|
||||||
size: 0,
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'Primary contact within the company.',
|
|
||||||
entityChipDisplayMapper: (dataObject: Person) => {
|
|
||||||
return {
|
|
||||||
name: dataObject?.name.firstName + ' ' + dataObject?.name.lastName,
|
|
||||||
pictureUrl: dataObject?.avatarUrl ?? undefined,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
} satisfies ColumnDefinition<FieldRelationMetadata>,
|
|
||||||
];
|
|
||||||
@ -18,7 +18,7 @@ const DEFAULT_SEARCH_REQUEST_LIMIT = 30;
|
|||||||
|
|
||||||
// TODO: use this for all search queries, because we need selectedEntities and entitiesToSelect each time we want to search
|
// TODO: use this for all search queries, because we need selectedEntities and entitiesToSelect each time we want to search
|
||||||
// Filtered entities to select are
|
// Filtered entities to select are
|
||||||
export const useFilteredSearchEntityQueryV2 = ({
|
export const useFilteredSearchEntityQuery = ({
|
||||||
queryHook,
|
queryHook,
|
||||||
orderByField,
|
orderByField,
|
||||||
filters,
|
filters,
|
||||||
@ -90,12 +90,11 @@ export const SettingsObjectFieldPreview = ({
|
|||||||
objectMetadataId,
|
objectMetadataId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { defaultValue: relationDefaultValue, entityChipDisplayMapper } =
|
const { defaultValue: relationDefaultValue } = useRelationFieldPreview({
|
||||||
useRelationFieldPreview({
|
relationObjectMetadataId,
|
||||||
relationObjectMetadataId,
|
skipDefaultValue:
|
||||||
skipDefaultValue:
|
fieldMetadata.type !== FieldMetadataType.Relation || hasValue,
|
||||||
fieldMetadata.type !== FieldMetadataType.Relation || hasValue,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const defaultValue =
|
const defaultValue =
|
||||||
fieldMetadata.type === FieldMetadataType.Relation
|
fieldMetadata.type === FieldMetadataType.Relation
|
||||||
@ -138,16 +137,13 @@ export const SettingsObjectFieldPreview = ({
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId,
|
entityId,
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
type: parseFieldType(fieldMetadata.type),
|
type: parseFieldType(fieldMetadata.type),
|
||||||
iconName: 'FieldIcon',
|
iconName: 'FieldIcon',
|
||||||
fieldMetadataId: fieldMetadata.id || '',
|
fieldMetadataId: fieldMetadata.id || '',
|
||||||
label: fieldMetadata.label,
|
label: fieldMetadata.label,
|
||||||
metadata: { fieldName },
|
metadata: { fieldName },
|
||||||
entityChipDisplayMapper:
|
|
||||||
fieldMetadata.type === FieldMetadataType.Relation
|
|
||||||
? entityChipDisplayMapper
|
|
||||||
: undefined,
|
|
||||||
},
|
},
|
||||||
hotkeyScope: 'field-preview',
|
hotkeyScope: 'field-preview',
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export type EntityChipProps = {
|
|||||||
linkToEntity?: string;
|
linkToEntity?: string;
|
||||||
entityId: string;
|
entityId: string;
|
||||||
name: string;
|
name: string;
|
||||||
pictureUrl?: string;
|
avatarUrl?: string;
|
||||||
avatarType?: AvatarType;
|
avatarType?: AvatarType;
|
||||||
variant?: EntityChipVariant;
|
variant?: EntityChipVariant;
|
||||||
LeftIcon?: IconComponent;
|
LeftIcon?: IconComponent;
|
||||||
@ -27,7 +27,7 @@ export const EntityChip = ({
|
|||||||
linkToEntity,
|
linkToEntity,
|
||||||
entityId,
|
entityId,
|
||||||
name,
|
name,
|
||||||
pictureUrl,
|
avatarUrl,
|
||||||
avatarType = 'rounded',
|
avatarType = 'rounded',
|
||||||
variant = EntityChipVariant.Regular,
|
variant = EntityChipVariant.Regular,
|
||||||
LeftIcon,
|
LeftIcon,
|
||||||
@ -59,7 +59,7 @@ export const EntityChip = ({
|
|||||||
<LeftIcon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
|
<LeftIcon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
|
||||||
) : (
|
) : (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={pictureUrl}
|
avatarUrl={avatarUrl}
|
||||||
colorId={entityId}
|
colorId={entityId}
|
||||||
placeholder={name}
|
placeholder={name}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -11,14 +11,12 @@ import { sleep } from '~/testing/sleep';
|
|||||||
|
|
||||||
import { relationPickerSearchFilterScopedState } from '../../states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '../../states/relationPickerSearchFilterScopedState';
|
||||||
import { EntityForSelect } from '../../types/EntityForSelect';
|
import { EntityForSelect } from '../../types/EntityForSelect';
|
||||||
import { Entity } from '../../types/EntityTypeForSelect';
|
|
||||||
import { SingleEntitySelect } from '../SingleEntitySelect';
|
import { SingleEntitySelect } from '../SingleEntitySelect';
|
||||||
|
|
||||||
const entities = mockedPeopleData.map<EntityForSelect>((person) => ({
|
const entities = mockedPeopleData.map<EntityForSelect>((person) => ({
|
||||||
id: person.id,
|
id: person.id,
|
||||||
entityType: Entity.Person,
|
|
||||||
name: person.name.firstName + ' ' + person.name.lastName,
|
name: person.name.firstName + ' ' + person.name.lastName,
|
||||||
originalEntity: person,
|
record: person,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const meta: Meta<typeof SingleEntitySelect> = {
|
const meta: Meta<typeof SingleEntitySelect> = {
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
import { AvatarType } from '@/users/components/Avatar';
|
import { AvatarType } from '@/users/components/Avatar';
|
||||||
|
|
||||||
import { EntityTypeForSelect } from './EntityTypeForSelect';
|
|
||||||
|
|
||||||
export type EntityForSelect = {
|
export type EntityForSelect = {
|
||||||
id: string;
|
id: string;
|
||||||
entityType: EntityTypeForSelect;
|
|
||||||
name: string;
|
name: string;
|
||||||
avatarUrl?: string;
|
avatarUrl?: string;
|
||||||
avatarType?: AvatarType;
|
avatarType?: AvatarType;
|
||||||
originalEntity: any;
|
record: any;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
|
||||||
|
|
||||||
export enum Entity {
|
|
||||||
Company = 'Company',
|
|
||||||
Person = 'Person',
|
|
||||||
User = 'User',
|
|
||||||
WorkspaceMember = 'WorkspaceMember',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EntityTypeForSelect = ActivityTargetableEntityType | Entity;
|
|
||||||
@ -2,7 +2,6 @@ import { useCallback, useContext, useRef, useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
|
|
||||||
import {
|
import {
|
||||||
IconArrowLeft,
|
IconArrowLeft,
|
||||||
IconArrowRight,
|
IconArrowRight,
|
||||||
@ -10,7 +9,6 @@ import {
|
|||||||
IconPlus,
|
IconPlus,
|
||||||
} from '@/ui/display/icon';
|
} from '@/ui/display/icon';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
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 { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
@ -98,9 +96,9 @@ export const BoardColumnMenu = ({
|
|||||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||||
relationPickerSearchFilterScopedState,
|
relationPickerSearchFilterScopedState,
|
||||||
);
|
);
|
||||||
const companies = useFilteredSearchCompanyQuery({
|
// const companies = useFilteredSearchCompanyQuery({
|
||||||
searchFilter: relationPickerSearchFilter,
|
// searchFilter: relationPickerSearchFilter,
|
||||||
});
|
// });
|
||||||
|
|
||||||
useListenClickOutside({
|
useListenClickOutside({
|
||||||
refs: [boardColumnMenuRef],
|
refs: [boardColumnMenuRef],
|
||||||
@ -172,14 +170,15 @@ export const BoardColumnMenu = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{currentMenu === 'add' && (
|
{currentMenu === 'add' && (
|
||||||
<SingleEntitySelect
|
<div>add</div>
|
||||||
disableBackgroundBlur
|
// <SingleEntitySelect
|
||||||
entitiesToSelect={companies.entitiesToSelect}
|
// disableBackgroundBlur
|
||||||
loading={companies.loading}
|
// entitiesToSelect={companies.entitiesToSelect}
|
||||||
onCancel={closeMenu}
|
// loading={companies.loading}
|
||||||
onEntitySelected={handleCompanySelected}
|
// onCancel={closeMenu}
|
||||||
selectedEntity={companies.selectedEntities[0]}
|
// onEntitySelected={handleCompanySelected}
|
||||||
/>
|
// selectedEntity={companies.selectedEntities[0]}
|
||||||
|
// />
|
||||||
)}
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</StyledMenuContainer>
|
</StyledMenuContainer>
|
||||||
|
|||||||
@ -10,6 +10,13 @@ export type GenericFieldContextType = {
|
|||||||
entityId: string;
|
entityId: string;
|
||||||
recoilScopeId?: string;
|
recoilScopeId?: string;
|
||||||
hotkeyScope: string;
|
hotkeyScope: string;
|
||||||
|
isMainIdentifier: boolean;
|
||||||
|
mainIdentifierMapper?: (record: any) => {
|
||||||
|
name: string;
|
||||||
|
avatarUrl?: string;
|
||||||
|
avatarType: string;
|
||||||
|
};
|
||||||
|
basePathToShowPage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FieldContext = createContext<GenericFieldContextType>(
|
export const FieldContext = createContext<GenericFieldContextType>(
|
||||||
|
|||||||
@ -10,10 +10,8 @@ export const useIsFieldEmpty = () => {
|
|||||||
const isFieldEmpty = useRecoilValue(
|
const isFieldEmpty = useRecoilValue(
|
||||||
isEntityFieldEmptyFamilySelector({
|
isEntityFieldEmptyFamilySelector({
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: fieldDefinition.fieldMetadataId,
|
|
||||||
label: fieldDefinition.label,
|
|
||||||
type: fieldDefinition.type,
|
type: fieldDefinition.type,
|
||||||
metadata: fieldDefinition.metadata,
|
metadata: { ...fieldDefinition.metadata, mainIdentifierMapper: null },
|
||||||
},
|
},
|
||||||
entityId,
|
entityId,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -18,6 +18,7 @@ export const FieldContextProvider = ({
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: entityId ?? '1',
|
entityId: entityId ?? '1',
|
||||||
|
isMainIdentifier: false,
|
||||||
recoilScopeId: '1',
|
recoilScopeId: '1',
|
||||||
hotkeyScope: 'hotkey-scope',
|
hotkeyScope: 'hotkey-scope',
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
|
|||||||
@ -2,14 +2,12 @@ import { useChipField } from '../../hooks/useChipField';
|
|||||||
import { ChipDisplay } from '../content-display/components/ChipDisplay';
|
import { ChipDisplay } from '../content-display/components/ChipDisplay';
|
||||||
|
|
||||||
export const ChipFieldDisplay = () => {
|
export const ChipFieldDisplay = () => {
|
||||||
const { avatarFieldValue, contentFieldValue, entityType, entityId } =
|
const { avatarFieldValue, contentFieldValue, entityId } = useChipField();
|
||||||
useChipField();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChipDisplay
|
<ChipDisplay
|
||||||
displayName={contentFieldValue}
|
displayName={contentFieldValue}
|
||||||
avatarUrlValue={avatarFieldValue}
|
avatarUrlValue={avatarFieldValue}
|
||||||
entityType={entityType}
|
|
||||||
entityId={entityId}
|
entityId={entityId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useDoubleTextChipField } from '../../hooks/useDoubleTextChipField';
|
|||||||
import { ChipDisplay } from '../content-display/components/ChipDisplay';
|
import { ChipDisplay } from '../content-display/components/ChipDisplay';
|
||||||
|
|
||||||
export const DoubleTextChipFieldDisplay = () => {
|
export const DoubleTextChipFieldDisplay = () => {
|
||||||
const { avatarUrl, firstValue, secondValue, entityType, entityId } =
|
const { avatarUrl, firstValue, secondValue, entityId } =
|
||||||
useDoubleTextChipField();
|
useDoubleTextChipField();
|
||||||
|
|
||||||
const content = [firstValue, secondValue].filter(Boolean).join(' ');
|
const content = [firstValue, secondValue].filter(Boolean).join(' ');
|
||||||
@ -11,7 +11,6 @@ export const DoubleTextChipFieldDisplay = () => {
|
|||||||
<ChipDisplay
|
<ChipDisplay
|
||||||
displayName={content}
|
displayName={content}
|
||||||
avatarUrlValue={avatarUrl}
|
avatarUrlValue={avatarUrl}
|
||||||
entityType={entityType}
|
|
||||||
entityId={entityId}
|
entityId={entityId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,22 +1,23 @@
|
|||||||
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
|
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
|
||||||
import { getEntityChipFromFieldMetadata } from '@/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata';
|
|
||||||
|
|
||||||
import { useRelationField } from '../../hooks/useRelationField';
|
import { useRelationField } from '../../hooks/useRelationField';
|
||||||
|
|
||||||
export const RelationFieldDisplay = () => {
|
export const RelationFieldDisplay = () => {
|
||||||
const { fieldValue, fieldDefinition } = useRelationField();
|
const { fieldValue, fieldDefinition } = useRelationField();
|
||||||
|
|
||||||
const entityChipProps = getEntityChipFromFieldMetadata(
|
if (!fieldValue || !fieldDefinition) {
|
||||||
fieldDefinition,
|
return <></>;
|
||||||
fieldValue,
|
}
|
||||||
);
|
|
||||||
|
const mainIdentifierMapped =
|
||||||
|
fieldDefinition.metadata.mainIdentifierMapper(fieldValue);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
entityId={entityChipProps.entityId}
|
entityId={fieldValue.id}
|
||||||
name={entityChipProps.name}
|
name={mainIdentifierMapped.name}
|
||||||
pictureUrl={entityChipProps.pictureUrl}
|
avatarUrl={mainIdentifierMapped.avatarUrl}
|
||||||
avatarType={entityChipProps.avatarType}
|
avatarType={mainIdentifierMapped.avatarType}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,6 +26,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'date',
|
fieldMetadataId: 'date',
|
||||||
label: 'Date',
|
label: 'Date',
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'email',
|
fieldMetadataId: 'email',
|
||||||
label: 'Email',
|
label: 'Email',
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'enum',
|
fieldMetadataId: 'enum',
|
||||||
label: 'Enum',
|
label: 'Enum',
|
||||||
|
|||||||
@ -24,6 +24,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'money',
|
fieldMetadataId: 'money',
|
||||||
label: 'Money',
|
label: 'Money',
|
||||||
|
|||||||
@ -24,6 +24,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'number',
|
fieldMetadataId: 'number',
|
||||||
label: 'Number',
|
label: 'Number',
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'phone',
|
fieldMetadataId: 'phone',
|
||||||
label: 'Phone',
|
label: 'Phone',
|
||||||
|
|||||||
@ -24,6 +24,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'text',
|
fieldMetadataId: 'text',
|
||||||
label: 'Text',
|
label: 'Text',
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const meta: Meta = {
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
entityId: '',
|
entityId: '',
|
||||||
|
isMainIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: 'URL',
|
fieldMetadataId: 'URL',
|
||||||
label: 'URL',
|
label: 'URL',
|
||||||
|
|||||||
@ -1,45 +1,34 @@
|
|||||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
|
||||||
import { PersonChip } from '@/people/components/PersonChip';
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
|
||||||
import { logError } from '~/utils/logError';
|
|
||||||
|
|
||||||
type ChipDisplayProps = {
|
type ChipDisplayProps = {
|
||||||
entityType: Entity;
|
|
||||||
displayName: string;
|
displayName: string;
|
||||||
entityId: string | null;
|
entityId: string | null;
|
||||||
avatarUrlValue?: string;
|
avatarUrlValue?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChipDisplay = ({
|
export const ChipDisplay = ({
|
||||||
entityType,
|
|
||||||
displayName,
|
displayName,
|
||||||
entityId,
|
entityId,
|
||||||
avatarUrlValue,
|
avatarUrlValue,
|
||||||
}: ChipDisplayProps) => {
|
}: ChipDisplayProps) => {
|
||||||
switch (entityType) {
|
switch (true) {
|
||||||
case Entity.Company: {
|
// case Entity.Company: {
|
||||||
return (
|
// return (
|
||||||
<CompanyChip
|
// <CompanyChip
|
||||||
id={entityId ?? ''}
|
// id={entityId ?? ''}
|
||||||
name={displayName}
|
// name={displayName}
|
||||||
pictureUrl={getLogoUrlFromDomainName(avatarUrlValue)}
|
// avatarUrl={getLogoUrlFromDomainName(avatarUrlValue)}
|
||||||
/>
|
// />
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
case Entity.Person: {
|
// case Entity.Person: {
|
||||||
return (
|
// return (
|
||||||
<PersonChip
|
// <PersonChip
|
||||||
id={entityId ?? ''}
|
// id={entityId ?? ''}
|
||||||
name={displayName}
|
// name={displayName}
|
||||||
pictureUrl={avatarUrlValue}
|
// avatarUrl={avatarUrlValue}
|
||||||
/>
|
// />
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
default:
|
default:
|
||||||
logError(
|
|
||||||
`Unknown relation type: "${entityType}" in DoubleTextChipDisplay`,
|
|
||||||
);
|
|
||||||
return <> </>;
|
return <> </>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
import { EntityChipProps } from '@/ui/display/chip/components/EntityChip';
|
|
||||||
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
|
|
||||||
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
|
||||||
|
|
||||||
export const getEntityChipFromFieldMetadata = (
|
|
||||||
fieldDefinition: FieldDefinition<FieldRelationMetadata>,
|
|
||||||
fieldValue: any,
|
|
||||||
) => {
|
|
||||||
const { entityChipDisplayMapper } = fieldDefinition;
|
|
||||||
const { fieldName } = fieldDefinition.metadata;
|
|
||||||
|
|
||||||
const defaultChipValue: Pick<
|
|
||||||
EntityChipProps,
|
|
||||||
'name' | 'pictureUrl' | 'avatarType' | 'entityId'
|
|
||||||
> = {
|
|
||||||
name: '',
|
|
||||||
pictureUrl: '',
|
|
||||||
avatarType: 'rounded',
|
|
||||||
entityId: fieldValue?.id,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (['accountOwner', 'person'].includes(fieldName) && fieldValue) {
|
|
||||||
return {
|
|
||||||
...defaultChipValue,
|
|
||||||
name: `${fieldValue.firstName} ${fieldValue.lastName}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldName === 'company' && fieldValue) {
|
|
||||||
return {
|
|
||||||
...defaultChipValue,
|
|
||||||
name: fieldValue.name,
|
|
||||||
pictureUrl: getLogoUrlFromDomainName(fieldValue.domainName),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...defaultChipValue,
|
|
||||||
...entityChipDisplayMapper?.(fieldValue),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -29,8 +29,6 @@ export const useChipField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const entityType = fieldDefinition.metadata.relationType;
|
|
||||||
|
|
||||||
const fieldInitialValue = useFieldInitialValue();
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
const initialContentValue = fieldInitialValue?.isEmpty
|
const initialContentValue = fieldInitialValue?.isEmpty
|
||||||
@ -51,7 +49,6 @@ export const useChipField = () => {
|
|||||||
avatarFieldValue,
|
avatarFieldValue,
|
||||||
initialAvatarValue,
|
initialAvatarValue,
|
||||||
setAvatarFieldValue,
|
setAvatarFieldValue,
|
||||||
entityType,
|
|
||||||
entityId,
|
entityId,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -39,8 +39,6 @@ export const useDoubleTextChipField = () => {
|
|||||||
|
|
||||||
const fullValue = [firstValue, secondValue].filter(Boolean).join(' ');
|
const fullValue = [firstValue, secondValue].filter(Boolean).join(' ');
|
||||||
|
|
||||||
const entityType = fieldDefinition.metadata.entityType;
|
|
||||||
|
|
||||||
const fieldInitialValue = useFieldInitialValue();
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
const initialFirstValue = fieldInitialValue?.isEmpty
|
const initialFirstValue = fieldInitialValue?.isEmpty
|
||||||
@ -68,7 +66,6 @@ export const useDoubleTextChipField = () => {
|
|||||||
firstValue,
|
firstValue,
|
||||||
setFirstValue,
|
setFirstValue,
|
||||||
fullValue,
|
fullValue,
|
||||||
entityType,
|
|
||||||
entityId,
|
entityId,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
initialAvatarUrl,
|
initialAvatarUrl,
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CompanyPicker } from '@/companies/components/CompanyPicker';
|
|
||||||
import { PeoplePicker } from '@/people/components/PeoplePicker';
|
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { WorkspaceMemberPicker } from '@/workspace-member/components/WorkspaceMemberPicker';
|
import { RelationPicker } from '@/ui/object/field/meta-types/input/components/internal/RelationPicker';
|
||||||
|
|
||||||
import { usePersistField } from '../../../hooks/usePersistField';
|
import { usePersistField } from '../../../hooks/usePersistField';
|
||||||
import { useRelationField } from '../../hooks/useRelationField';
|
import { useRelationField } from '../../hooks/useRelationField';
|
||||||
@ -32,14 +30,21 @@ export const RelationFieldInput = ({
|
|||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
const handleSubmit = (newEntity: EntityForSelect | null) => {
|
const handleSubmit = (newEntity: EntityForSelect | null) => {
|
||||||
onSubmit?.(() => persistField(newEntity?.originalEntity ?? null));
|
onSubmit?.(() => persistField(newEntity?.record ?? null));
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {}, [initialSearchValue]);
|
useEffect(() => {}, [initialSearchValue]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledRelationPickerContainer>
|
<StyledRelationPickerContainer>
|
||||||
{fieldDefinition.metadata.fieldName === 'person' ? (
|
<RelationPicker
|
||||||
|
fieldDefinition={fieldDefinition}
|
||||||
|
recordId={initialValue?.id ?? ''}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
onCancel={onCancel}
|
||||||
|
initialSearchFilter={initialSearchValue}
|
||||||
|
/>
|
||||||
|
{/* {fieldDefinition.metadata.fieldName === 'person' ? (
|
||||||
<PeoplePicker
|
<PeoplePicker
|
||||||
personId={initialValue?.id ?? ''}
|
personId={initialValue?.id ?? ''}
|
||||||
companyId={initialValue?.companyId ?? ''}
|
companyId={initialValue?.companyId ?? ''}
|
||||||
@ -47,13 +52,6 @@ export const RelationFieldInput = ({
|
|||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
initialSearchFilter={initialSearchValue}
|
initialSearchFilter={initialSearchValue}
|
||||||
/>
|
/>
|
||||||
) : fieldDefinition.metadata.fieldName === 'accountOwner' ? (
|
|
||||||
<WorkspaceMemberPicker
|
|
||||||
userId={initialValue?.id ?? ''}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
onCancel={onCancel}
|
|
||||||
initialSearchFilter={initialSearchValue}
|
|
||||||
/>
|
|
||||||
) : fieldDefinition.metadata.fieldName === 'company' ? (
|
) : fieldDefinition.metadata.fieldName === 'company' ? (
|
||||||
<CompanyPicker
|
<CompanyPicker
|
||||||
companyId={initialValue?.id ?? ''}
|
companyId={initialValue?.id ?? ''}
|
||||||
@ -61,7 +59,7 @@ export const RelationFieldInput = ({
|
|||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
initialSearchFilter={initialSearchValue}
|
initialSearchFilter={initialSearchValue}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null} */}
|
||||||
</StyledRelationPickerContainer>
|
</StyledRelationPickerContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
|
|||||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
|
|
||||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||||
@ -52,7 +51,6 @@ const ChipFieldInputWithContext = ({
|
|||||||
contentFieldName: 'name',
|
contentFieldName: 'name',
|
||||||
urlFieldName: 'xURL',
|
urlFieldName: 'xURL',
|
||||||
placeHolder: 'X URL',
|
placeHolder: 'X URL',
|
||||||
relationType: Entity.Person,
|
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
entityId={entityId}
|
entityId={entityId}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
|
|||||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
|
|
||||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||||
@ -67,7 +66,7 @@ const DoubleTextChipFieldInputWithContext = ({
|
|||||||
secondValueFieldName: 'Second-text',
|
secondValueFieldName: 'Second-text',
|
||||||
secondValuePlaceholder: 'Second-text',
|
secondValuePlaceholder: 'Second-text',
|
||||||
avatarUrlFieldName: 'avatarUrl',
|
avatarUrlFieldName: 'avatarUrl',
|
||||||
entityType: Entity.Person,
|
fieldName: '',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
entityId={entityId}
|
entityId={entityId}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
|
|||||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
@ -52,7 +51,6 @@ const RelationFieldInputWithContext = ({
|
|||||||
iconName: 'IconLink',
|
iconName: 'IconLink',
|
||||||
metadata: {
|
metadata: {
|
||||||
fieldName: 'Relation',
|
fieldName: 'Relation',
|
||||||
relationType: Entity.Person,
|
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
entityId={entityId}
|
entityId={entityId}
|
||||||
|
|||||||
@ -2,29 +2,32 @@ import { useEffect } from 'react';
|
|||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
|
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { useFilteredSearchEntityQueryV2 } from '@/search/hooks/useFilteredSearchEntityQueryV2';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { IconUserCircle } from '@/ui/display/icon';
|
import { IconUserCircle } from '@/ui/display/icon';
|
||||||
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
||||||
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
|
||||||
|
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
export type WorkspaceMemberPickerProps = {
|
export type RelationPickerProps = {
|
||||||
userId: string;
|
recordId: string;
|
||||||
onSubmit: (newUser: EntityForSelect | null) => void;
|
onSubmit: (newUser: EntityForSelect | null) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
width?: number;
|
width?: number;
|
||||||
initialSearchFilter?: string | null;
|
initialSearchFilter?: string | null;
|
||||||
|
fieldDefinition: FieldDefinition<FieldRelationMetadata>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WorkspaceMemberPicker = ({
|
export const RelationPicker = ({
|
||||||
userId,
|
recordId,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
width,
|
width,
|
||||||
initialSearchFilter,
|
initialSearchFilter,
|
||||||
}: WorkspaceMemberPickerProps) => {
|
fieldDefinition,
|
||||||
|
}: RelationPickerProps) => {
|
||||||
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||||
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||||
|
|
||||||
@ -33,32 +36,23 @@ export const WorkspaceMemberPicker = ({
|
|||||||
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
||||||
|
|
||||||
const { findManyQuery } = useFindOneObjectMetadataItem({
|
const { findManyQuery } = useFindOneObjectMetadataItem({
|
||||||
objectNameSingular: 'workspaceMember',
|
objectNameSingular: fieldDefinition.metadata.objectMetadataNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const useFindManyWorkspaceMembers = (options: any) =>
|
const useFindManyQuery = (options: any) => useQuery(findManyQuery, options);
|
||||||
useQuery(findManyQuery, options);
|
|
||||||
|
|
||||||
const workspaceMembers = useFilteredSearchEntityQueryV2({
|
const workspaceMembers = useFilteredSearchEntityQuery({
|
||||||
queryHook: useFindManyWorkspaceMembers,
|
queryHook: useFindManyQuery,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
fieldNames: ['name.firstName', 'name.lastName'],
|
fieldNames: fieldDefinition.metadata.searchFields,
|
||||||
filter: relationPickerSearchFilter,
|
filter: relationPickerSearchFilter,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
orderByField: 'createdAt',
|
orderByField: 'createdAt',
|
||||||
mappingFunction: (workspaceMember) => ({
|
mappingFunction: fieldDefinition.metadata.mainIdentifierMapper,
|
||||||
entityType: Entity.WorkspaceMember,
|
selectedIds: recordId ? [recordId] : [],
|
||||||
id: workspaceMember.id,
|
objectNamePlural: fieldDefinition.metadata.objectMetadataNamePlural,
|
||||||
name:
|
|
||||||
workspaceMember.name.firstName + ' ' + workspaceMember.name.lastName,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
avatarUrl: '',
|
|
||||||
originalEntity: workspaceMember,
|
|
||||||
}),
|
|
||||||
selectedIds: userId ? [userId] : [],
|
|
||||||
objectNamePlural: 'workspaceMembers',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleEntitySelected = async (selectedUser: any | null | undefined) => {
|
const handleEntitySelected = async (selectedUser: any | null | undefined) => {
|
||||||
@ -34,10 +34,9 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
|
|||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
entityId,
|
entityId,
|
||||||
}: {
|
}: {
|
||||||
fieldDefinition: Pick<
|
fieldDefinition: Pick<FieldDefinition<FieldMetadata>, 'type'> & {
|
||||||
FieldDefinition<FieldMetadata>,
|
metadata: Omit<FieldMetadata, 'mainIdentifierMapper'>;
|
||||||
'type' | 'metadata' | 'fieldMetadataId' | 'label'
|
};
|
||||||
>;
|
|
||||||
entityId: string;
|
entityId: string;
|
||||||
}) => {
|
}) => {
|
||||||
return ({ get }) => {
|
return ({ get }) => {
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { AvatarType } from '@/users/components/Avatar';
|
|
||||||
|
|
||||||
import { FieldMetadata } from './FieldMetadata';
|
import { FieldMetadata } from './FieldMetadata';
|
||||||
import { FieldType } from './FieldType';
|
import { FieldType } from './FieldType';
|
||||||
|
|
||||||
@ -15,12 +13,5 @@ export type FieldDefinition<T extends FieldMetadata> = {
|
|||||||
iconName: string;
|
iconName: string;
|
||||||
type: FieldType;
|
type: FieldType;
|
||||||
metadata: T;
|
metadata: T;
|
||||||
basePathToShowPage?: string;
|
|
||||||
infoTooltipContent?: string;
|
infoTooltipContent?: string;
|
||||||
entityChipDisplayMapper?: (dataObject: any) => {
|
|
||||||
name: string;
|
|
||||||
pictureUrl?: string;
|
|
||||||
avatarType: AvatarType;
|
|
||||||
};
|
|
||||||
relationType?: FieldDefinitionRelationType;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
|
||||||
import { ThemeColor } from '@/ui/theme/constants/colors';
|
import { ThemeColor } from '@/ui/theme/constants/colors';
|
||||||
|
|
||||||
export type FieldUuidMetadata = {
|
export type FieldUuidMetadata = {
|
||||||
@ -58,14 +58,23 @@ export type FieldEmailMetadata = {
|
|||||||
placeHolder: string;
|
placeHolder: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FieldDefinitionRelationType =
|
||||||
|
| 'FROM_MANY_OBJECTS'
|
||||||
|
| 'FROM_ONE_OBJECT'
|
||||||
|
| 'TO_MANY_OBJECTS'
|
||||||
|
| 'TO_ONE_OBJECT';
|
||||||
|
|
||||||
export type FieldRelationMetadata = {
|
export type FieldRelationMetadata = {
|
||||||
relationType: Entity;
|
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
useEditButton?: boolean;
|
useEditButton?: boolean;
|
||||||
|
relationType?: FieldDefinitionRelationType;
|
||||||
|
mainIdentifierMapper: MainIdentifierMapper;
|
||||||
|
searchFields: string[];
|
||||||
|
objectMetadataNameSingular: string;
|
||||||
|
objectMetadataNamePlural: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FieldChipMetadata = {
|
export type FieldChipMetadata = {
|
||||||
relationType: Entity;
|
|
||||||
contentFieldName: string;
|
contentFieldName: string;
|
||||||
urlFieldName: string;
|
urlFieldName: string;
|
||||||
placeHolder: string;
|
placeHolder: string;
|
||||||
@ -84,7 +93,6 @@ export type FieldDoubleTextChipMetadata = {
|
|||||||
secondValueFieldName: string;
|
secondValueFieldName: string;
|
||||||
secondValuePlaceholder: string;
|
secondValuePlaceholder: string;
|
||||||
avatarUrlFieldName: string;
|
avatarUrlFieldName: string;
|
||||||
entityType: Entity;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FieldProbabilityMetadata = {
|
export type FieldProbabilityMetadata = {
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { AvatarType } from '@/users/components/Avatar';
|
||||||
|
|
||||||
|
export type MainIdentifierMapper = (record: any) => {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
avatarUrl?: string;
|
||||||
|
avatarType: AvatarType;
|
||||||
|
record: any;
|
||||||
|
};
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
|
||||||
|
|
||||||
|
export type FieldDefinitionRelationType =
|
||||||
|
| 'FROM_MANY_OBJECTS'
|
||||||
|
| 'FROM_ONE_OBJECT'
|
||||||
|
| 'TO_MANY_OBJECTS'
|
||||||
|
| 'TO_ONE_OBJECT';
|
||||||
|
|
||||||
|
export type RelationFieldConfig = {
|
||||||
|
relationType?: FieldDefinitionRelationType;
|
||||||
|
mainIdentifierMapper: MainIdentifierMapper;
|
||||||
|
searchFields: string[];
|
||||||
|
objectMetadataNameSingular: string;
|
||||||
|
};
|
||||||
@ -16,7 +16,7 @@ export const GenericEntityFilterChip = ({
|
|||||||
entityId={filter.value}
|
entityId={filter.value}
|
||||||
name={filter.displayValue}
|
name={filter.displayValue}
|
||||||
avatarType="rounded"
|
avatarType="rounded"
|
||||||
pictureUrl={filter.displayAvatarUrl}
|
avatarUrl={filter.displayAvatarUrl}
|
||||||
LeftIcon={Icon}
|
LeftIcon={Icon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
||||||
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
|
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
|
||||||
|
import { useRecordTableScopedStates } from '@/ui/object/record-table/hooks/internal/useRecordTableScopedStates';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
|
|
||||||
import { FieldContext } from '../../field/contexts/FieldContext';
|
import { FieldContext } from '../../field/contexts/FieldContext';
|
||||||
@ -20,6 +21,9 @@ export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {
|
|||||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||||
const currentRowId = useContext(RowIdContext);
|
const currentRowId = useContext(RowIdContext);
|
||||||
|
const { objectMetadataConfigState } = useRecordTableScopedStates();
|
||||||
|
|
||||||
|
const objectMetadataConfig = useRecoilValue(objectMetadataConfigState);
|
||||||
|
|
||||||
const { setCurrentRowSelected } = useCurrentRowSelected();
|
const { setCurrentRowSelected } = useCurrentRowSelected();
|
||||||
|
|
||||||
@ -56,6 +60,10 @@ export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {
|
|||||||
fieldDefinition: columnDefinition,
|
fieldDefinition: columnDefinition,
|
||||||
useUpdateEntityMutation: () => [updateEntityMutation, {}],
|
useUpdateEntityMutation: () => [updateEntityMutation, {}],
|
||||||
hotkeyScope: customHotkeyScope,
|
hotkeyScope: customHotkeyScope,
|
||||||
|
isMainIdentifier:
|
||||||
|
columnDefinition.fieldMetadataId ===
|
||||||
|
objectMetadataConfig?.mainIdentifierFieldMetadataId,
|
||||||
|
mainIdentifierMapper: objectMetadataConfig?.mainIdentifierMapper,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TableCell customHotkeyScope={{ scope: customHotkeyScope }} />
|
<TableCell customHotkeyScope={{ scope: customHotkeyScope }} />
|
||||||
|
|||||||
@ -18,6 +18,7 @@ export const useRecordTableScopedStates = (args?: {
|
|||||||
tableFiltersState,
|
tableFiltersState,
|
||||||
tableSortsState,
|
tableSortsState,
|
||||||
tableColumnsState,
|
tableColumnsState,
|
||||||
|
objectMetadataConfigState,
|
||||||
tableColumnsByKeySelector,
|
tableColumnsByKeySelector,
|
||||||
hiddenTableColumnsSelector,
|
hiddenTableColumnsSelector,
|
||||||
visibleTableColumnsSelector,
|
visibleTableColumnsSelector,
|
||||||
@ -33,6 +34,7 @@ export const useRecordTableScopedStates = (args?: {
|
|||||||
tableFiltersState,
|
tableFiltersState,
|
||||||
tableSortsState,
|
tableSortsState,
|
||||||
tableColumnsState,
|
tableColumnsState,
|
||||||
|
objectMetadataConfigState,
|
||||||
tableColumnsByKeySelector,
|
tableColumnsByKeySelector,
|
||||||
hiddenTableColumnsSelector,
|
hiddenTableColumnsSelector,
|
||||||
visibleTableColumnsSelector,
|
visibleTableColumnsSelector,
|
||||||
|
|||||||
@ -43,6 +43,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
|||||||
tableFiltersState,
|
tableFiltersState,
|
||||||
tableSortsState,
|
tableSortsState,
|
||||||
tableColumnsState,
|
tableColumnsState,
|
||||||
|
objectMetadataConfigState,
|
||||||
onEntityCountChangeState,
|
onEntityCountChangeState,
|
||||||
} = useRecordTableScopedStates({
|
} = useRecordTableScopedStates({
|
||||||
customRecordTableScopeId: scopeId,
|
customRecordTableScopeId: scopeId,
|
||||||
@ -54,6 +55,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
|||||||
|
|
||||||
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
|
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
|
||||||
const setTableFilters = useSetRecoilState(tableFiltersState);
|
const setTableFilters = useSetRecoilState(tableFiltersState);
|
||||||
|
const setObjectMetadataConfig = useSetRecoilState(objectMetadataConfigState);
|
||||||
|
|
||||||
const setTableSorts = useSetRecoilState(tableSortsState);
|
const setTableSorts = useSetRecoilState(tableSortsState);
|
||||||
|
|
||||||
@ -301,6 +303,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
|||||||
setAvailableTableColumns,
|
setAvailableTableColumns,
|
||||||
setTableFilters,
|
setTableFilters,
|
||||||
setTableSorts,
|
setTableSorts,
|
||||||
|
setObjectMetadataConfig,
|
||||||
setOnEntityCountChange,
|
setOnEntityCountChange,
|
||||||
setRecordTableData,
|
setRecordTableData,
|
||||||
setTableColumns,
|
setTableColumns,
|
||||||
|
|||||||
@ -37,7 +37,8 @@ export const useTableCell = () => {
|
|||||||
|
|
||||||
const isEmpty = useIsFieldEmpty();
|
const isEmpty = useIsFieldEmpty();
|
||||||
|
|
||||||
const { entityId, fieldDefinition } = useContext(FieldContext);
|
const { entityId, fieldDefinition, basePathToShowPage } =
|
||||||
|
useContext(FieldContext);
|
||||||
|
|
||||||
const [, setFieldInitialValue] = useRecoilState(
|
const [, setFieldInitialValue] = useRecoilState(
|
||||||
entityFieldInitialValueFamilyState({
|
entityFieldInitialValueFamilyState({
|
||||||
@ -47,8 +48,8 @@ export const useTableCell = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const openTableCell = (options?: { initialValue?: FieldInitialValue }) => {
|
const openTableCell = (options?: { initialValue?: FieldInitialValue }) => {
|
||||||
if (isFirstColumnCell && !isEmpty && fieldDefinition.basePathToShowPage) {
|
if (isFirstColumnCell && !isEmpty && basePathToShowPage) {
|
||||||
navigate(`${fieldDefinition.basePathToShowPage}${entityId}`);
|
navigate(`${basePathToShowPage}${entityId}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { ObjectMetadataConfig } from '@/ui/object/record-table/types/ObjectMetadataConfig';
|
||||||
|
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
|
||||||
|
|
||||||
|
export const objectMetadataConfigScopedState =
|
||||||
|
createScopedState<ObjectMetadataConfig | null>({
|
||||||
|
key: 'objectMetadataConfigScopedState',
|
||||||
|
defaultValue: null,
|
||||||
|
});
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { AvatarType } from '@/users/components/Avatar';
|
||||||
|
|
||||||
|
export type ObjectMetadataConfig = {
|
||||||
|
mainIdentifierFieldMetadataId: string;
|
||||||
|
mainIdentifierMapper: (record: any) => {
|
||||||
|
name: string;
|
||||||
|
avatarUrl?: string;
|
||||||
|
avatarType: AvatarType;
|
||||||
|
};
|
||||||
|
basePathToShowPage: string;
|
||||||
|
};
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { objectMetadataConfigScopedState } from '@/ui/object/record-table/states/objectMetadataConfigScopedState';
|
||||||
import { getScopedState } from '@/ui/utilities/recoil-scope/utils/getScopedState';
|
import { getScopedState } from '@/ui/utilities/recoil-scope/utils/getScopedState';
|
||||||
|
|
||||||
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
|
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
|
||||||
@ -36,6 +37,11 @@ export const getRecordTableScopedStates = ({
|
|||||||
recordTableScopeId,
|
recordTableScopeId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const objectMetadataConfigState = getScopedState(
|
||||||
|
objectMetadataConfigScopedState,
|
||||||
|
recordTableScopeId,
|
||||||
|
);
|
||||||
|
|
||||||
const tableColumnsByKeySelector =
|
const tableColumnsByKeySelector =
|
||||||
tableColumnsByKeyScopedSelector(recordTableScopeId);
|
tableColumnsByKeyScopedSelector(recordTableScopeId);
|
||||||
|
|
||||||
@ -60,6 +66,7 @@ export const getRecordTableScopedStates = ({
|
|||||||
tableFiltersState,
|
tableFiltersState,
|
||||||
tableSortsState,
|
tableSortsState,
|
||||||
tableColumnsState,
|
tableColumnsState,
|
||||||
|
objectMetadataConfigState,
|
||||||
tableColumnsByKeySelector,
|
tableColumnsByKeySelector,
|
||||||
hiddenTableColumnsSelector,
|
hiddenTableColumnsSelector,
|
||||||
visibleTableColumnsSelector,
|
visibleTableColumnsSelector,
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
|
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { useFilteredSearchEntityQueryV2 } from '@/search/hooks/useFilteredSearchEntityQueryV2';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
|
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ export const FilterDropdownUserSearchSelect = () => {
|
|||||||
const useFindManyWorkspaceMembers = (options: any) =>
|
const useFindManyWorkspaceMembers = (options: any) =>
|
||||||
useQuery(findManyQuery, options);
|
useQuery(findManyQuery, options);
|
||||||
|
|
||||||
const workspaceMembers = useFilteredSearchEntityQueryV2({
|
const workspaceMembers = useFilteredSearchEntityQuery({
|
||||||
queryHook: useFindManyWorkspaceMembers,
|
queryHook: useFindManyWorkspaceMembers,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
@ -29,13 +28,13 @@ export const FilterDropdownUserSearchSelect = () => {
|
|||||||
],
|
],
|
||||||
orderByField: 'createdAt',
|
orderByField: 'createdAt',
|
||||||
mappingFunction: (workspaceMember) => ({
|
mappingFunction: (workspaceMember) => ({
|
||||||
entityType: Entity.WorkspaceMember,
|
entityType: 'WorkspaceMember',
|
||||||
id: workspaceMember.id,
|
id: workspaceMember.id,
|
||||||
name:
|
name:
|
||||||
workspaceMember.name.firstName + ' ' + workspaceMember.name.lastName,
|
workspaceMember.name.firstName + ' ' + workspaceMember.name.lastName,
|
||||||
avatarType: 'rounded',
|
avatarType: 'rounded',
|
||||||
avatarUrl: '',
|
avatarUrl: '',
|
||||||
originalEntity: workspaceMember,
|
record: workspaceMember,
|
||||||
}),
|
}),
|
||||||
selectedIds: objectFilterDropdownSelectedEntityId
|
selectedIds: objectFilterDropdownSelectedEntityId
|
||||||
? [objectFilterDropdownSelectedEntityId]
|
? [objectFilterDropdownSelectedEntityId]
|
||||||
|
|||||||
@ -3,14 +3,14 @@ import { EntityChip } from '@/ui/display/chip/components/EntityChip';
|
|||||||
export type UserChipProps = {
|
export type UserChipProps = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
pictureUrl?: string;
|
avatarUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserChip = ({ id, name, pictureUrl }: UserChipProps) => (
|
export const UserChip = ({ id, name, avatarUrl }: UserChipProps) => (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
entityId={id}
|
entityId={id}
|
||||||
name={name}
|
name={name}
|
||||||
avatarType="rounded"
|
avatarType="rounded"
|
||||||
pictureUrl={pictureUrl}
|
avatarUrl={avatarUrl}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,10 +19,7 @@ export const mapViewFieldsToBoardFieldDefinitions = (
|
|||||||
fieldMetadataId: viewField.fieldMetadataId,
|
fieldMetadataId: viewField.fieldMetadataId,
|
||||||
label: correspondingFieldMetadata.label,
|
label: correspondingFieldMetadata.label,
|
||||||
metadata: correspondingFieldMetadata.metadata,
|
metadata: correspondingFieldMetadata.metadata,
|
||||||
entityChipDisplayMapper:
|
|
||||||
correspondingFieldMetadata.entityChipDisplayMapper,
|
|
||||||
infoTooltipContent: correspondingFieldMetadata.infoTooltipContent,
|
infoTooltipContent: correspondingFieldMetadata.infoTooltipContent,
|
||||||
basePathToShowPage: correspondingFieldMetadata.basePathToShowPage,
|
|
||||||
iconName: correspondingFieldMetadata.iconName,
|
iconName: correspondingFieldMetadata.iconName,
|
||||||
type: correspondingFieldMetadata.type,
|
type: correspondingFieldMetadata.type,
|
||||||
position: viewField.position,
|
position: viewField.position,
|
||||||
|
|||||||
@ -19,10 +19,7 @@ export const mapViewFieldsToColumnDefinitions = (
|
|||||||
fieldMetadataId: viewField.fieldMetadataId,
|
fieldMetadataId: viewField.fieldMetadataId,
|
||||||
label: correspondingFieldMetadata.label,
|
label: correspondingFieldMetadata.label,
|
||||||
metadata: correspondingFieldMetadata.metadata,
|
metadata: correspondingFieldMetadata.metadata,
|
||||||
entityChipDisplayMapper:
|
|
||||||
correspondingFieldMetadata.entityChipDisplayMapper,
|
|
||||||
infoTooltipContent: correspondingFieldMetadata.infoTooltipContent,
|
infoTooltipContent: correspondingFieldMetadata.infoTooltipContent,
|
||||||
basePathToShowPage: correspondingFieldMetadata.basePathToShowPage,
|
|
||||||
iconName: correspondingFieldMetadata.iconName,
|
iconName: correspondingFieldMetadata.iconName,
|
||||||
type: correspondingFieldMetadata.type,
|
type: correspondingFieldMetadata.type,
|
||||||
position: viewField.position,
|
position: viewField.position,
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import { FilterDropdownCompanySearchSelect } from '@/companies/components/FilterDropdownCompanySearchSelect';
|
|
||||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||||
import { FilterDefinitionByEntity } from '@/ui/object/object-filter-dropdown/types/FilterDefinitionByEntity';
|
import { FilterDefinitionByEntity } from '@/ui/object/object-filter-dropdown/types/FilterDefinitionByEntity';
|
||||||
|
|
||||||
import { FilterDropdownPeopleSearchSelect } from '../../../modules/people/components/FilterDropdownPeopleSearchSelect';
|
|
||||||
|
|
||||||
export const opportunityBoardFilterDefinitions: FilterDefinitionByEntity<Opportunity>[] =
|
export const opportunityBoardFilterDefinitions: FilterDefinitionByEntity<Opportunity>[] =
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -23,13 +20,13 @@ export const opportunityBoardFilterDefinitions: FilterDefinitionByEntity<Opportu
|
|||||||
label: 'Company',
|
label: 'Company',
|
||||||
iconName: 'IconBuildingSkyscraper',
|
iconName: 'IconBuildingSkyscraper',
|
||||||
type: 'ENTITY',
|
type: 'ENTITY',
|
||||||
entitySelectComponent: <FilterDropdownCompanySearchSelect />,
|
// entitySelectComponent: <FilterDropdownCompanySearchSelect />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldMetadataId: 'pointOfContactId',
|
fieldMetadataId: 'pointOfContactId',
|
||||||
label: 'Point of contact',
|
label: 'Point of contact',
|
||||||
iconName: 'IconUser',
|
iconName: 'IconUser',
|
||||||
type: 'ENTITY',
|
type: 'ENTITY',
|
||||||
entitySelectComponent: <FilterDropdownPeopleSearchSelect />,
|
//entitySelectComponent: <FilterDropdownPeopleSearchSelect />,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user