Relations many in table view (#5842)
Closes #5924. Adding the "many" side of relations in the table view, and fixing some issues (glitch in Multi record select, cache update after update). --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -0,0 +1,132 @@
|
||||
import { useEffect } from 'react';
|
||||
import {
|
||||
useRecoilCallback,
|
||||
useRecoilState,
|
||||
useRecoilValue,
|
||||
useSetRecoilState,
|
||||
} from 'recoil';
|
||||
|
||||
import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates';
|
||||
import { objectRecordMultiSelectComponentFamilyState } from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
||||
import { useRelationPickerScopedStates } from '@/object-record/relation-picker/hooks/internal/useRelationPickerScopedStates';
|
||||
import {
|
||||
ObjectRecordForSelect,
|
||||
SelectedObjectRecordId,
|
||||
useMultiObjectSearch,
|
||||
} from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const ActivityTargetInlineCellEditModeMultiRecordsEffect = ({
|
||||
selectedObjectRecordIds,
|
||||
}: {
|
||||
selectedObjectRecordIds: SelectedObjectRecordId[];
|
||||
}) => {
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
RelationPickerScopeInternalContext,
|
||||
);
|
||||
const {
|
||||
objectRecordsIdsMultiSelectState,
|
||||
objectRecordMultiSelectCheckedRecordsIdsState,
|
||||
recordMultiSelectIsLoadingState,
|
||||
} = useObjectRecordMultiSelectScopedStates(scopeId);
|
||||
const [objectRecordsIdsMultiSelect, setObjectRecordsIdsMultiSelect] =
|
||||
useRecoilState(objectRecordsIdsMultiSelectState);
|
||||
|
||||
const setRecordMultiSelectIsLoading = useSetRecoilState(
|
||||
recordMultiSelectIsLoadingState,
|
||||
);
|
||||
|
||||
const relationPickerScopedId = useAvailableScopeIdOrThrow(
|
||||
RelationPickerScopeInternalContext,
|
||||
);
|
||||
|
||||
const { relationPickerSearchFilterState } = useRelationPickerScopedStates({
|
||||
relationPickerScopedId,
|
||||
});
|
||||
const relationPickerSearchFilter = useRecoilValue(
|
||||
relationPickerSearchFilterState,
|
||||
);
|
||||
const { filteredSelectedObjectRecords, loading, objectRecordsToSelect } =
|
||||
useMultiObjectSearch({
|
||||
searchFilterValue: relationPickerSearchFilter,
|
||||
selectedObjectRecordIds,
|
||||
excludedObjectRecordIds: [],
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
const [
|
||||
objectRecordMultiSelectCheckedRecordsIds,
|
||||
setObjectRecordMultiSelectCheckedRecordsIds,
|
||||
] = useRecoilState(objectRecordMultiSelectCheckedRecordsIdsState);
|
||||
|
||||
const updateRecords = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(newRecords: ObjectRecordForSelect[]) => {
|
||||
for (const newRecord of newRecords) {
|
||||
const currentRecord = snapshot
|
||||
.getLoadable(
|
||||
objectRecordMultiSelectComponentFamilyState({
|
||||
scopeId: scopeId,
|
||||
familyKey: newRecord.record.id,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
const newRecordWithSelected = {
|
||||
...newRecord,
|
||||
selected: objectRecordMultiSelectCheckedRecordsIds.some(
|
||||
(checkedRecordId) => checkedRecordId === newRecord.record.id,
|
||||
),
|
||||
};
|
||||
|
||||
if (
|
||||
!isDeeplyEqual(
|
||||
newRecordWithSelected.selected,
|
||||
currentRecord?.selected,
|
||||
)
|
||||
) {
|
||||
set(
|
||||
objectRecordMultiSelectComponentFamilyState({
|
||||
scopeId: scopeId,
|
||||
familyKey: newRecordWithSelected.record.id,
|
||||
}),
|
||||
newRecordWithSelected,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[objectRecordMultiSelectCheckedRecordsIds, scopeId],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const allRecords = [
|
||||
...(filteredSelectedObjectRecords ?? []),
|
||||
...(objectRecordsToSelect ?? []),
|
||||
];
|
||||
updateRecords(allRecords);
|
||||
const allRecordsIds = allRecords.map((record) => record.record.id);
|
||||
if (!isDeeplyEqual(allRecordsIds, objectRecordsIdsMultiSelect)) {
|
||||
setObjectRecordsIdsMultiSelect(allRecordsIds);
|
||||
}
|
||||
}, [
|
||||
filteredSelectedObjectRecords,
|
||||
objectRecordsIdsMultiSelect,
|
||||
objectRecordsToSelect,
|
||||
setObjectRecordsIdsMultiSelect,
|
||||
updateRecords,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
setObjectRecordMultiSelectCheckedRecordsIds(
|
||||
selectedObjectRecordIds.map((rec) => rec.id),
|
||||
);
|
||||
}, [selectedObjectRecordIds, setObjectRecordMultiSelectCheckedRecordsIds]);
|
||||
|
||||
useEffect(() => {
|
||||
setRecordMultiSelectIsLoading(loading);
|
||||
}, [loading, setRecordMultiSelectIsLoading]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
@ -1,12 +1,14 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates';
|
||||
import { MultipleObjectRecordOnClickOutsideEffect } from '@/object-record/relation-picker/components/MultipleObjectRecordOnClickOutsideEffect';
|
||||
import { MultipleObjectRecordSelectItem } from '@/object-record/relation-picker/components/MultipleObjectRecordSelectItem';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { ObjectRecordForSelect } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { useRelationPickerScopedStates } from '@/object-record/relation-picker/hooks/internal/useRelationPickerScopedStates';
|
||||
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
@ -15,7 +17,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
|
||||
export const StyledSelectableItem = styled(SelectableItem)`
|
||||
height: 100%;
|
||||
@ -24,134 +26,80 @@ export const StyledSelectableItem = styled(SelectableItem)`
|
||||
export const MultiRecordSelect = ({
|
||||
onChange,
|
||||
onSubmit,
|
||||
selectedObjectRecords,
|
||||
allRecords,
|
||||
loading,
|
||||
searchFilter,
|
||||
setSearchFilter,
|
||||
}: {
|
||||
onChange?: (
|
||||
changedRecordForSelect: ObjectRecordForSelect,
|
||||
newSelectedValue: boolean,
|
||||
) => void;
|
||||
onSubmit?: (objectRecordsForSelect: ObjectRecordForSelect[]) => void;
|
||||
selectedObjectRecords: ObjectRecordForSelect[];
|
||||
allRecords: ObjectRecordForSelect[];
|
||||
loading: boolean;
|
||||
searchFilter: string;
|
||||
setSearchFilter: (searchFilter: string) => void;
|
||||
onChange?: (changedRecordForSelectId: string) => void;
|
||||
onSubmit?: () => void;
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [internalSelectedRecords, setInternalSelectedRecords] = useState<
|
||||
ObjectRecordForSelect[]
|
||||
>([]);
|
||||
const relationPickerScopedId = useAvailableScopeIdOrThrow(
|
||||
RelationPickerScopeInternalContext,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading) {
|
||||
setInternalSelectedRecords(selectedObjectRecords);
|
||||
}
|
||||
}, [selectedObjectRecords, loading]);
|
||||
const { objectRecordsIdsMultiSelectState, recordMultiSelectIsLoadingState } =
|
||||
useObjectRecordMultiSelectScopedStates(relationPickerScopedId);
|
||||
|
||||
const recordMultiSelectIsLoading = useRecoilValue(
|
||||
recordMultiSelectIsLoadingState,
|
||||
);
|
||||
const objectRecordsIdsMultiSelect = useRecoilValue(
|
||||
objectRecordsIdsMultiSelectState,
|
||||
);
|
||||
|
||||
const { relationPickerSearchFilterState } = useRelationPickerScopedStates({
|
||||
relationPickerScopedId,
|
||||
});
|
||||
|
||||
const setSearchFilter = useSetRecoilState(relationPickerSearchFilterState);
|
||||
const relationPickerSearchFilter = useRecoilValue(
|
||||
relationPickerSearchFilterState,
|
||||
);
|
||||
const debouncedSetSearchFilter = useDebouncedCallback(setSearchFilter, 100, {
|
||||
leading: true,
|
||||
});
|
||||
|
||||
const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
debouncedSetSearchFilter(event.currentTarget.value);
|
||||
};
|
||||
|
||||
const handleSelectChange = (
|
||||
changedRecordForSelect: ObjectRecordForSelect,
|
||||
newSelectedValue: boolean,
|
||||
) => {
|
||||
const newSelectedRecords = newSelectedValue
|
||||
? [...internalSelectedRecords, changedRecordForSelect]
|
||||
: internalSelectedRecords.filter(
|
||||
(selectedRecord) =>
|
||||
selectedRecord.record.id !== changedRecordForSelect.record.id,
|
||||
);
|
||||
|
||||
setInternalSelectedRecords(newSelectedRecords);
|
||||
|
||||
onChange?.(changedRecordForSelect, newSelectedValue);
|
||||
};
|
||||
|
||||
const entitiesInDropdown = useMemo(
|
||||
() =>
|
||||
[...(allRecords ?? [])].filter((entity) =>
|
||||
isNonEmptyString(entity.recordIdentifier.id),
|
||||
),
|
||||
[allRecords],
|
||||
const handleFilterChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
debouncedSetSearchFilter(event.currentTarget.value);
|
||||
},
|
||||
[debouncedSetSearchFilter],
|
||||
);
|
||||
|
||||
const selectableItemIds = entitiesInDropdown.map(
|
||||
(entity) => entity.record.id,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MultipleObjectRecordOnClickOutsideEffect
|
||||
containerRef={containerRef}
|
||||
onClickOutside={() => {
|
||||
onSubmit?.(internalSelectedRecords);
|
||||
onSubmit?.();
|
||||
}}
|
||||
/>
|
||||
<DropdownMenu ref={containerRef} data-select-disable>
|
||||
<DropdownMenuSearchInput
|
||||
value={searchFilter}
|
||||
value={relationPickerSearchFilter}
|
||||
onChange={handleFilterChange}
|
||||
autoFocus
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{loading ? (
|
||||
{recordMultiSelectIsLoading ? (
|
||||
<MenuItem text="Loading..." />
|
||||
) : (
|
||||
<>
|
||||
<SelectableList
|
||||
selectableListId={MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID}
|
||||
selectableItemIdArray={selectableItemIds}
|
||||
selectableItemIdArray={objectRecordsIdsMultiSelect}
|
||||
hotkeyScope={RelationPickerHotkeyScope.RelationPicker}
|
||||
onEnter={(recordId) => {
|
||||
const recordIsSelected = internalSelectedRecords?.some(
|
||||
(selectedRecord) => selectedRecord.record.id === recordId,
|
||||
);
|
||||
|
||||
const correspondingRecordForSelect = entitiesInDropdown?.find(
|
||||
(entity) => entity.record.id === recordId,
|
||||
);
|
||||
|
||||
if (isDefined(correspondingRecordForSelect)) {
|
||||
handleSelectChange(
|
||||
correspondingRecordForSelect,
|
||||
!recordIsSelected,
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{entitiesInDropdown?.map((objectRecordForSelect) => (
|
||||
<MultipleObjectRecordSelectItem
|
||||
key={objectRecordForSelect.record.id}
|
||||
objectRecordForSelect={objectRecordForSelect}
|
||||
onSelectedChange={(newSelectedValue) =>
|
||||
handleSelectChange(
|
||||
objectRecordForSelect,
|
||||
newSelectedValue,
|
||||
)
|
||||
}
|
||||
selected={internalSelectedRecords?.some(
|
||||
(selectedRecord) => {
|
||||
return (
|
||||
selectedRecord.record.id ===
|
||||
objectRecordForSelect.record.id
|
||||
);
|
||||
},
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
{objectRecordsIdsMultiSelect?.map((recordId) => {
|
||||
return (
|
||||
<MultipleObjectRecordSelectItem
|
||||
key={recordId}
|
||||
objectRecordId={recordId}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</SelectableList>
|
||||
{entitiesInDropdown?.length === 0 && (
|
||||
{objectRecordsIdsMultiSelect?.length === 0 && (
|
||||
<MenuItem text="No result" />
|
||||
)}
|
||||
</>
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { MultiRecordSelect } from '@/object-record/relation-picker/components/MultiRecordSelect';
|
||||
import {
|
||||
ObjectRecordForSelect,
|
||||
SelectedObjectRecordId,
|
||||
useMultiObjectSearch,
|
||||
} from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
|
||||
export const StyledSelectableItem = styled(SelectableItem)`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
`;
|
||||
export const MultipleObjectRecordSelect = ({
|
||||
onChange,
|
||||
onSubmit,
|
||||
selectedObjectRecordIds,
|
||||
}: {
|
||||
onChange?: (
|
||||
changedRecordForSelect: ObjectRecordForSelect,
|
||||
newSelectedValue: boolean,
|
||||
) => void;
|
||||
onSubmit?: (objectRecordsForSelect: ObjectRecordForSelect[]) => void;
|
||||
selectedObjectRecordIds: SelectedObjectRecordId[];
|
||||
}) => {
|
||||
const [searchFilter, setSearchFilter] = useState<string>('');
|
||||
|
||||
const {
|
||||
filteredSelectedObjectRecords,
|
||||
loading,
|
||||
objectRecordsToSelect,
|
||||
selectedObjectRecords,
|
||||
} = useMultiObjectSearch({
|
||||
searchFilterValue: searchFilter,
|
||||
selectedObjectRecordIds,
|
||||
excludedObjectRecordIds: [],
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
const selectedObjectRecordsForSelect = useMemo(
|
||||
() =>
|
||||
selectedObjectRecords.filter((selectedObjectRecord) =>
|
||||
selectedObjectRecordIds.some(
|
||||
(selectedObjectRecordId) =>
|
||||
selectedObjectRecordId.id ===
|
||||
selectedObjectRecord.recordIdentifier.id,
|
||||
),
|
||||
),
|
||||
[selectedObjectRecords, selectedObjectRecordIds],
|
||||
);
|
||||
|
||||
return (
|
||||
<MultiRecordSelect
|
||||
onChange={onChange}
|
||||
onSubmit={onSubmit}
|
||||
selectedObjectRecords={selectedObjectRecordsForSelect}
|
||||
allRecords={[
|
||||
...(filteredSelectedObjectRecords ?? []),
|
||||
...(objectRecordsToSelect ?? []),
|
||||
]}
|
||||
loading={loading}
|
||||
searchFilter={searchFilter}
|
||||
setSearchFilter={setSearchFilter}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -3,12 +3,15 @@ import { useRecoilValue } from 'recoil';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { ObjectRecordForSelect } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const StyledSelectableItem = styled(SelectableItem)`
|
||||
height: 100%;
|
||||
@ -16,45 +19,60 @@ export const StyledSelectableItem = styled(SelectableItem)`
|
||||
`;
|
||||
|
||||
export const MultipleObjectRecordSelectItem = ({
|
||||
objectRecordForSelect,
|
||||
onSelectedChange,
|
||||
selected,
|
||||
objectRecordId,
|
||||
onChange,
|
||||
}: {
|
||||
objectRecordForSelect: ObjectRecordForSelect;
|
||||
onSelectedChange?: (selected: boolean) => void;
|
||||
selected: boolean;
|
||||
objectRecordId: string;
|
||||
onChange?: (changedRecordForSelectId: string) => void;
|
||||
}) => {
|
||||
const { isSelectedItemIdSelector } = useSelectableList(
|
||||
MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
);
|
||||
|
||||
const isSelectedByKeyboard = useRecoilValue(
|
||||
isSelectedItemIdSelector(objectRecordForSelect.record.id),
|
||||
isSelectedItemIdSelector(objectRecordId),
|
||||
);
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
RelationPickerScopeInternalContext,
|
||||
);
|
||||
|
||||
const { objectRecordMultiSelectFamilyState } =
|
||||
useObjectRecordMultiSelectScopedStates(scopeId);
|
||||
|
||||
const record = useRecoilValue(
|
||||
objectRecordMultiSelectFamilyState(objectRecordId),
|
||||
);
|
||||
|
||||
if (!record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleSelectChange = () => {
|
||||
onChange?.(objectRecordId);
|
||||
};
|
||||
|
||||
const { selected, recordIdentifier } = record;
|
||||
|
||||
if (!isDefined(recordIdentifier)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledSelectableItem
|
||||
itemId={objectRecordForSelect.record.id}
|
||||
key={objectRecordForSelect.record.id + v4()}
|
||||
>
|
||||
<StyledSelectableItem itemId={objectRecordId} key={objectRecordId + v4()}>
|
||||
<MenuItemMultiSelectAvatar
|
||||
selected={selected}
|
||||
onSelectChange={onSelectedChange}
|
||||
onSelectChange={(_isNewlySelectedValue) => handleSelectChange()}
|
||||
isKeySelected={isSelectedByKeyboard}
|
||||
selected={selected}
|
||||
avatar={
|
||||
<Avatar
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(
|
||||
objectRecordForSelect.recordIdentifier.avatarUrl,
|
||||
)}
|
||||
entityId={objectRecordForSelect.record.id}
|
||||
placeholder={objectRecordForSelect.recordIdentifier.name}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(recordIdentifier.avatarUrl)}
|
||||
entityId={objectRecordId}
|
||||
placeholder={recordIdentifier.name}
|
||||
size="md"
|
||||
type={
|
||||
objectRecordForSelect.recordIdentifier.avatarType ?? 'rounded'
|
||||
}
|
||||
type={recordIdentifier.avatarType ?? 'rounded'}
|
||||
/>
|
||||
}
|
||||
text={objectRecordForSelect.recordIdentifier.name}
|
||||
text={recordIdentifier.name}
|
||||
/>
|
||||
</StyledSelectableItem>
|
||||
);
|
||||
|
||||
@ -44,7 +44,6 @@ export const SingleEntitySelectMenuItemsWithSearch = ({
|
||||
const { entities, relationPickerSearchFilter } =
|
||||
useRelationPickerEntitiesOptions({
|
||||
relationObjectNameSingular,
|
||||
relationPickerScopeId,
|
||||
selectedRelationRecordIds,
|
||||
excludedRelationRecordIds,
|
||||
});
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
export const TABLE_COLUMNS_DENY_LIST = [
|
||||
'attachments',
|
||||
'activities',
|
||||
'timelineActivities',
|
||||
];
|
||||
@ -1,22 +1,26 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useRelationPickerScopedStates } from '@/object-record/relation-picker/hooks/internal/useRelationPickerScopedStates';
|
||||
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
|
||||
export const useRelationPickerEntitiesOptions = ({
|
||||
relationObjectNameSingular,
|
||||
relationPickerScopeId = 'relation-picker',
|
||||
selectedRelationRecordIds = [],
|
||||
excludedRelationRecordIds = [],
|
||||
}: {
|
||||
relationObjectNameSingular: string;
|
||||
relationPickerScopeId?: string;
|
||||
selectedRelationRecordIds?: string[];
|
||||
excludedRelationRecordIds?: string[];
|
||||
}) => {
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
RelationPickerScopeInternalContext,
|
||||
);
|
||||
|
||||
const { searchQueryState, relationPickerSearchFilterState } =
|
||||
useRelationPickerScopedStates({
|
||||
relationPickerScopedId: relationPickerScopeId,
|
||||
relationPickerScopedId: scopeId,
|
||||
});
|
||||
const relationPickerSearchFilter = useRecoilValue(
|
||||
relationPickerSearchFilterState,
|
||||
|
||||
Reference in New Issue
Block a user