Refactor RecordSingleSelect and RecordMultiSelect to be synchronous (#10469)
## Context We are experiencing a lot of re-rendering / flash on MultiRecordSelect / SingleRecordSelect / RelationPicker. This PR is a first step to refactor this components ## Scope Only move files to uniformize and prepare for the upcoming refactoring ## Vision - SingleRecordPicker - MultipleRecordPicker - sharing RecordPicker tooling (RecordPickerComponentInstanceContext, searchState) Used in other areas: - RelationPicker (which is actually only a subcomponent of RelationToOneFieldInput) - RelationFromManyFieldInput - WorkflowRelationFieldInput - etc. + remove all effects + migrate to the latest APIs + make a pass on re-renders to remove them completely (we likely need to use a bit more familyStates here)
This commit is contained in:
@ -24,11 +24,11 @@ import {
|
||||
objectRecordMultiSelectComponentFamilyState,
|
||||
} from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
||||
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
||||
import { MultipleRecordPicker } from '@/object-record/record-picker/components/MultipleRecordPicker';
|
||||
import { ActivityTargetInlineCellEditModeMultiRecordsEffect } from '@/object-record/record-picker/legacy/components/ActivityTargetInlineCellEditModeMultiRecordsEffect';
|
||||
import { ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect } from '@/object-record/record-picker/legacy/components/ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { ActivityTargetInlineCellEditModeMultiRecordsEffect } from '@/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect';
|
||||
import { ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect } from '@/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect';
|
||||
import { MultiRecordSelect } from '@/object-record/relation-picker/components/MultiRecordSelect';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { prefillRecord } from '@/object-record/utils/prefillRecord';
|
||||
|
||||
type ActivityTargetInlineCellEditModeProps = {
|
||||
@ -269,7 +269,7 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
selectedObjectRecordIds={selectedTargetObjectIds}
|
||||
/>
|
||||
<ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect />
|
||||
<MultiRecordSelect onSubmit={handleSubmit} onChange={handleChange} />
|
||||
<MultipleRecordPicker onSubmit={handleSubmit} onChange={handleChange} />
|
||||
</RecordPickerComponentInstanceContext.Provider>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -7,8 +7,8 @@ import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlur
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { getCompanyDomainName } from '@/object-metadata/utils/getCompanyDomainName';
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { useMultiObjectSearch } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/object-record/relation-picker/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
||||
import { useMultiObjectSearch } from '@/object-record/record-picker/hooks/useMultiObjectSearch';
|
||||
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/object-record/record-picker/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
||||
import { makeOrFilterVariables } from '@/object-record/utils/makeOrFilterVariables';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
@ -4,8 +4,8 @@ import { useRecoilValue } from 'recoil';
|
||||
import { ObjectMetadataItemsLoadEffect } from '@/object-metadata/components/ObjectMetadataItemsLoadEffect';
|
||||
import { PreComputedChipGeneratorsProvider } from '@/object-metadata/components/PreComputedChipGeneratorsProvider';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { UserOrMetadataLoader } from '~/loading/components/UserOrMetadataLoader';
|
||||
|
||||
export const ObjectMetadataItemsProvider = ({
|
||||
|
||||
@ -5,7 +5,7 @@ import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
||||
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
||||
import { useCombinedFindManyRecordsQueryVariables } from '@/object-record/multiple-objects/hooks/useCombinedFindManyRecordsQueryVariables';
|
||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
|
||||
export const useCombinedFindManyRecords = ({
|
||||
operationSignatures,
|
||||
|
||||
@ -4,7 +4,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
||||
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
|
||||
export const useCombinedGetTotalCount = ({
|
||||
objectMetadataItems,
|
||||
|
||||
@ -8,7 +8,7 @@ import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-recor
|
||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
|
||||
@ -12,7 +12,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { isCompositeField } from '@/object-record/object-filter-dropdown/utils/isCompositeField';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
|
||||
@ -5,8 +5,6 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { useOptionsForSelect } from '@/object-record/object-filter-dropdown/hooks/useOptionsForSelect';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
@ -14,13 +12,16 @@ import { useSelectableListStates } from '@/ui/layout/selectable-list/hooks/inter
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
|
||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { MenuItem, MenuItemMultiSelect } from 'twenty-ui';
|
||||
@ -53,17 +54,19 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const componentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
ObjectFilterDropdownComponentInstanceContext,
|
||||
);
|
||||
|
||||
const { applyRecordFilter } = useApplyRecordFilter();
|
||||
|
||||
const { closeDropdown } = useDropdown();
|
||||
|
||||
const { selectedItemIdState } = useSelectableListStates({
|
||||
selectableListScopeId: MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
selectableListScopeId: componentInstanceId,
|
||||
});
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
);
|
||||
const { resetSelectedItem } = useSelectableList(componentInstanceId);
|
||||
|
||||
const selectedItemId = useRecoilValue(selectedItemIdState);
|
||||
|
||||
@ -159,7 +162,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
||||
|
||||
return (
|
||||
<SelectableList
|
||||
selectableListId={MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID}
|
||||
selectableListId={componentInstanceId}
|
||||
selectableItemIdArray={objectRecordsIds}
|
||||
hotkeyScope={RelationPickerHotkeyScope.RelationPicker}
|
||||
onEnter={(itemId) => {
|
||||
|
||||
@ -12,7 +12,7 @@ import { selectedFilterComponentState } from '@/object-record/object-filter-drop
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||
|
||||
@ -12,7 +12,7 @@ import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-
|
||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
@ -8,8 +8,8 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object-
|
||||
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
@ -2,11 +2,11 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
|
||||
import { recordBoardNewRecordByColumnIdSelector } from '@/object-record/record-board/states/selectors/recordBoardNewRecordByColumnIdSelector';
|
||||
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState';
|
||||
import { SingleRecordSelect } from '@/object-record/relation-picker/components/SingleRecordSelect';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||
@ -70,7 +70,7 @@ export const RecordBoardColumnNewOpportunity = ({
|
||||
<RecordPickerComponentInstanceContext.Provider
|
||||
value={{ instanceId: RelationPickerHotkeyScope.RelationPicker }}
|
||||
>
|
||||
<SingleRecordSelect
|
||||
<SingleRecordPicker
|
||||
onCancel={() => handleCreateSuccess(position, columnId, false)}
|
||||
onRecordSelected={(company) =>
|
||||
company ? handleEntitySelect(position, company) : null
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||
import { recordBoardNewRecordByColumnIdSelector } from '@/object-record/record-board/states/selectors/recordBoardNewRecordByColumnIdSelector';
|
||||
import { useRecordSelectSearch } from '@/object-record/relation-picker/hooks/useRecordSelectSearch';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { useRecordSelectSearch } from '@/object-record/record-picker/hooks/useRecordSelectSearch';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { RecoilState, useRecoilCallback } from 'recoil';
|
||||
@ -71,7 +71,7 @@ export const useAddNewCard = () => {
|
||||
labelValue: string,
|
||||
position: 'first' | 'last',
|
||||
isOpportunity: boolean,
|
||||
company?: RecordForSelect,
|
||||
company?: SingleRecordPickerRecord,
|
||||
) => {
|
||||
if (
|
||||
(isOpportunity && company !== null) ||
|
||||
@ -220,7 +220,7 @@ export const useAddNewCard = () => {
|
||||
const handleEntitySelect = useCallback(
|
||||
(
|
||||
position: 'first' | 'last',
|
||||
company: RecordForSelect,
|
||||
company: SingleRecordPickerRecord,
|
||||
columnId?: string,
|
||||
) => {
|
||||
const columnDefinitionId = getColumnDefinitionId(columnId);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
||||
|
||||
export type NewCard = {
|
||||
@ -7,7 +7,7 @@ export type NewCard = {
|
||||
isCreating: boolean;
|
||||
position: 'first' | 'last';
|
||||
isOpportunity: boolean;
|
||||
company: RecordForSelect | null;
|
||||
company: SingleRecordPickerRecord | null;
|
||||
};
|
||||
|
||||
export const recordBoardNewRecordByColumnIdComponentFamilyState =
|
||||
|
||||
@ -4,9 +4,10 @@ import { FormFieldInputContainer } from '@/object-record/record-field/form-types
|
||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||
import { FormMultiSelectFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormMultiSelectFieldInputHotKeyScope';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { FieldMultiSelectValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { SelectOption } from '@/spreadsheet-import/types';
|
||||
import { MultiSelectDisplay } from '@/ui/field/display/components/MultiSelectDisplay';
|
||||
import { MultiSelectInput } from '@/ui/field/input/components/MultiSelectInput';
|
||||
@ -74,7 +75,8 @@ export const FormMultiSelectFieldInput = ({
|
||||
const inputId = useId();
|
||||
const theme = useTheme();
|
||||
|
||||
const hotkeyScope = MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID;
|
||||
const hotkeyScope =
|
||||
FormMultiSelectFieldInputHotKeyScope.FormMultiSelectFieldInput;
|
||||
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
@ -234,6 +236,9 @@ export const FormMultiSelectFieldInput = ({
|
||||
draftValue.editingMode === 'edit' && (
|
||||
<OverlayContainer>
|
||||
<MultiSelectInput
|
||||
selectableListComponentInstanceId={
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID
|
||||
}
|
||||
hotkeyScope={hotkeyScope}
|
||||
options={options}
|
||||
onCancel={onCancel}
|
||||
|
||||
@ -3,8 +3,8 @@ import { FormFieldInputInputContainer } from '@/object-record/record-field/form-
|
||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
||||
import { SINGLE_RECORD_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleRecordSelectBaseList';
|
||||
import { SelectOption } from '@/spreadsheet-import/types';
|
||||
import { SelectDisplay } from '@/ui/field/display/components/SelectDisplay';
|
||||
import { SelectInput } from '@/ui/field/input/components/SelectInput';
|
||||
@ -141,7 +141,7 @@ export const FormSelectFieldInput = ({
|
||||
const [filteredOptions, setFilteredOptions] = useState<SelectOption[]>([]);
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
SINGLE_RECORD_SELECT_BASE_LIST,
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const clearField = () => {
|
||||
@ -295,7 +295,9 @@ export const FormSelectFieldInput = ({
|
||||
draftValue.editingMode === 'edit' && (
|
||||
<OverlayContainer>
|
||||
<SelectInput
|
||||
selectableListId={SINGLE_RECORD_SELECT_BASE_LIST}
|
||||
selectableListComponentInstanceId={
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID
|
||||
}
|
||||
selectableItemIdArray={optionIds}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={handleSelectEnter}
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
export enum FormMultiSelectFieldInputHotKeyScope {
|
||||
FormMultiSelectFieldInput = 'form-multi-select-field-input',
|
||||
}
|
||||
@ -24,7 +24,6 @@ import { isFieldRelationToOneValue } from '@/object-record/record-field/types/gu
|
||||
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
||||
import { isFieldSelectValue } from '@/object-record/record-field/types/guards/isFieldSelectValue';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
|
||||
import { isFieldArray } from '@/object-record/record-field/types/guards/isFieldArray';
|
||||
import { isFieldArrayValue } from '@/object-record/record-field/types/guards/isFieldArrayValue';
|
||||
@ -32,6 +31,7 @@ import { isFieldRichText } from '@/object-record/record-field/types/guards/isFie
|
||||
import { isFieldRichTextV2 } from '@/object-record/record-field/types/guards/isFieldRichTextV2';
|
||||
import { isFieldRichTextValue } from '@/object-record/record-field/types/guards/isFieldRichTextValue';
|
||||
import { isFieldRichTextV2Value } from '@/object-record/record-field/types/guards/isFieldRichTextValueV2';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { getForeignKeyNameFromRelationFieldName } from '@/object-record/utils/getForeignKeyNameFromRelationFieldName';
|
||||
import { FieldContext } from '../contexts/FieldContext';
|
||||
import { isFieldBoolean } from '../types/guards/isFieldBoolean';
|
||||
@ -156,7 +156,7 @@ export const usePersistField = () => {
|
||||
);
|
||||
|
||||
if (fieldIsRelationToOneObject) {
|
||||
const value = valueToPersist as RecordForSelect;
|
||||
const value = valueToPersist as SingleRecordPickerRecord;
|
||||
updateRecord?.({
|
||||
variables: {
|
||||
where: { id: recordId },
|
||||
|
||||
@ -5,15 +5,15 @@ import { useGetButtonIcon } from '@/object-record/record-field/hooks/useGetButto
|
||||
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
|
||||
import { FieldRelationValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { FieldContext } from '../../contexts/FieldContext';
|
||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||
import { isFieldRelation } from '../../types/guards/isFieldRelation';
|
||||
|
||||
export const useRelationField = <
|
||||
T extends RecordForSelect | RecordForSelect[],
|
||||
T extends SingleRecordPickerRecord | SingleRecordPickerRecord[],
|
||||
>() => {
|
||||
const { recordId, fieldDefinition, maxWidth } = useContext(FieldContext);
|
||||
const button = useGetButtonIcon();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useMultiSelectField } from '@/object-record/record-field/meta-types/hooks/useMultiSelectField';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { MultiSelectInput } from '@/ui/field/input/components/MultiSelectInput';
|
||||
|
||||
type MultiSelectFieldInputProps = {
|
||||
@ -13,6 +14,9 @@ export const MultiSelectFieldInput = ({
|
||||
|
||||
return (
|
||||
<MultiSelectInput
|
||||
selectableListComponentInstanceId={
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID
|
||||
}
|
||||
hotkeyScope={hotkeyScope}
|
||||
options={fieldDefinition.metadata.options}
|
||||
onCancel={onCancel}
|
||||
|
||||
@ -7,10 +7,9 @@ import { useUpdateRelationFromManyFieldInput } from '@/object-record/record-fiel
|
||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
||||
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { MultiRecordSelect } from '@/object-record/relation-picker/components/MultiRecordSelect';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/relation-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { MultipleRecordPicker } from '@/object-record/record-picker/components/MultipleRecordPicker';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/record-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
|
||||
type RelationFromManyFieldInputProps = {
|
||||
onSubmit?: FieldInputEvent;
|
||||
@ -51,19 +50,16 @@ export const RelationFromManyFieldInput = ({
|
||||
recordId,
|
||||
});
|
||||
|
||||
const { dropdownPlacement } = useDropdown(recordPickerInstanceId);
|
||||
|
||||
return (
|
||||
<>
|
||||
<RecordPickerComponentInstanceContext.Provider
|
||||
value={{ instanceId: recordPickerInstanceId }}
|
||||
>
|
||||
<RelationFromManyFieldInputMultiRecordsEffect />
|
||||
<MultiRecordSelect
|
||||
<MultipleRecordPicker
|
||||
onSubmit={handleSubmit}
|
||||
onChange={updateRelation}
|
||||
onCreate={createNewRecordAndOpenRightDrawer}
|
||||
dropdownPlacement={dropdownPlacement}
|
||||
/>
|
||||
</RecordPickerComponentInstanceContext.Provider>
|
||||
</>
|
||||
|
||||
@ -5,15 +5,16 @@ import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useOb
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useRelationField } from '@/object-record/record-field/meta-types/hooks/useRelationField';
|
||||
import { objectRecordMultiSelectComponentFamilyState } from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
||||
import { useRecordPickerRecordsOptions } from '@/object-record/relation-picker/hooks/useRecordPickerRecordsOptions';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { useRecordPickerRecordsOptions } from '@/object-record/record-picker/hooks/useRecordPickerRecordsOptions';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const RelationFromManyFieldInputMultiRecordsEffect = () => {
|
||||
const { fieldValue, fieldDefinition } = useRelationField<RecordForSelect[]>();
|
||||
const { fieldValue, fieldDefinition } =
|
||||
useRelationField<SingleRecordPickerRecord[]>();
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
RecordPickerComponentInstanceContext,
|
||||
);
|
||||
@ -113,7 +114,9 @@ export const RelationFromManyFieldInputMultiRecordsEffect = () => {
|
||||
useEffect(() => {
|
||||
setObjectRecordMultiSelectCheckedRecordsIds(
|
||||
fieldValue
|
||||
? fieldValue.map((fieldValueItem: RecordForSelect) => fieldValueItem.id)
|
||||
? fieldValue.map(
|
||||
(fieldValueItem: SingleRecordPickerRecord) => fieldValueItem.id,
|
||||
)
|
||||
: [],
|
||||
);
|
||||
}, [fieldValue, setObjectRecordMultiSelectCheckedRecordsIds]);
|
||||
|
||||
@ -5,15 +5,15 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { SearchPickerInitialValueEffect } from '@/object-record/relation-picker/components/SearchPickerInitialValueEffect';
|
||||
import { SingleRecordSelect } from '@/object-record/relation-picker/components/SingleRecordSelect';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/relation-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/record-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { SearchPickerInitialValueEffect } from '@/object-record/record-picker/legacy/components/SearchPickerInitialValueEffect';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
|
||||
export type RelationPickerProps = {
|
||||
selectedRecordId?: string;
|
||||
onSubmit: (selectedRecord: RecordForSelect | null) => void;
|
||||
onSubmit: (selectedRecord: SingleRecordPickerRecord | null) => void;
|
||||
onCancel?: () => void;
|
||||
width?: number;
|
||||
excludedRecordIds?: string[];
|
||||
@ -33,7 +33,7 @@ export const RelationPicker = ({
|
||||
const recordPickerInstanceId = RelationPickerHotkeyScope.RelationPicker;
|
||||
|
||||
const handleRecordSelected = (
|
||||
selectedRecord: RecordForSelect | null | undefined,
|
||||
selectedRecord: SingleRecordPickerRecord | null | undefined,
|
||||
) => onSubmit(selectedRecord ?? null);
|
||||
|
||||
const { objectMetadataItem: relationObjectMetadataItem } =
|
||||
@ -63,7 +63,7 @@ export const RelationPicker = ({
|
||||
initialValueForSearchFilter={initialSearchFilter}
|
||||
recordPickerInstanceId={recordPickerInstanceId}
|
||||
/>
|
||||
<SingleRecordSelect
|
||||
<SingleRecordPicker
|
||||
EmptyIcon={IconForbid}
|
||||
emptyLabel={'No ' + fieldDefinition.label}
|
||||
onCancel={onCancel}
|
||||
@ -1,9 +1,8 @@
|
||||
import { RelationPicker } from '@/object-record/relation-picker/components/RelationPicker';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
|
||||
import { RelationPicker } from '@/object-record/record-field/meta-types/input/components/RelationPicker';
|
||||
import { usePersistField } from '../../../hooks/usePersistField';
|
||||
import { useRelationField } from '../../hooks/useRelationField';
|
||||
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { FieldInputEvent } from './DateTimeFieldInput';
|
||||
|
||||
export type RelationToOneFieldInputProps = {
|
||||
@ -16,11 +15,11 @@ export const RelationToOneFieldInput = ({
|
||||
onCancel,
|
||||
}: RelationToOneFieldInputProps) => {
|
||||
const { fieldDefinition, initialSearchValue, fieldValue } =
|
||||
useRelationField<RecordForSelect>();
|
||||
useRelationField<SingleRecordPickerRecord>();
|
||||
|
||||
const persistField = usePersistField();
|
||||
|
||||
const handleSubmit = (newEntity: RecordForSelect | null) => {
|
||||
const handleSubmit = (newEntity: SingleRecordPickerRecord | null) => {
|
||||
onSubmit?.(() => persistField(newEntity?.record ?? null));
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useClearField } from '@/object-record/record-field/hooks/useClearField';
|
||||
import { useSelectField } from '@/object-record/record-field/meta-types/hooks/useSelectField';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
||||
import { SINGLE_RECORD_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleRecordSelectBaseList';
|
||||
import { SelectOption } from '@/spreadsheet-import/types';
|
||||
import { SelectInput } from '@/ui/field/input/components/SelectInput';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
@ -25,7 +25,7 @@ export const SelectFieldInput = ({
|
||||
const [filteredOptions, setFilteredOptions] = useState<SelectOption[]>([]);
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
SINGLE_RECORD_SELECT_BASE_LIST,
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
const clearField = useClearField();
|
||||
|
||||
@ -61,7 +61,9 @@ export const SelectFieldInput = ({
|
||||
|
||||
return (
|
||||
<SelectInput
|
||||
selectableListId={SINGLE_RECORD_SELECT_BASE_LIST}
|
||||
selectableListComponentInstanceId={
|
||||
SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID
|
||||
}
|
||||
selectableItemIdArray={optionIds}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={(itemId) => {
|
||||
|
||||
@ -18,7 +18,7 @@ import {
|
||||
} from '~/testing/mock-data/users';
|
||||
|
||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { getCanvasElementForDropdownTesting } from 'twenty-ui';
|
||||
import {
|
||||
RelationToOneFieldInput,
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
export const SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID =
|
||||
'select-field-input-selectable-list-component-instance-id';
|
||||
@ -2,7 +2,7 @@ import { ThemeColor } from 'twenty-ui';
|
||||
|
||||
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
|
||||
import { ZodHelperLiteral } from '@/object-record/record-field/types/ZodHelperLiteral';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared';
|
||||
import * as z from 'zod';
|
||||
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
||||
@ -260,9 +260,9 @@ export type FieldRatingValue = (typeof RATING_VALUES)[number] | null;
|
||||
export type FieldSelectValue = string | null;
|
||||
export type FieldMultiSelectValue = string[] | null;
|
||||
|
||||
export type FieldRelationToOneValue = RecordForSelect | null;
|
||||
export type FieldRelationToOneValue = SingleRecordPickerRecord | null;
|
||||
|
||||
export type FieldRelationFromManyValue = RecordForSelect[] | [];
|
||||
export type FieldRelationFromManyValue = SingleRecordPickerRecord[] | [];
|
||||
|
||||
export type FieldRelationValue<
|
||||
T extends FieldRelationToOneValue | FieldRelationFromManyValue,
|
||||
|
||||
@ -9,12 +9,12 @@ import { useGetButtonIcon } from '@/object-record/record-field/hooks/useGetButto
|
||||
import { useIsFieldInputOnly } from '@/object-record/record-field/hooks/useIsFieldInputOnly';
|
||||
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
|
||||
import { useInlineCell } from '../hooks/useInlineCell';
|
||||
|
||||
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
||||
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
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 { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { MultipleRecordPickerMenuItem } from '@/object-record/record-picker/components/MultipleRecordPickerMenuItem';
|
||||
import { RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-picker/constants/RecordPickerSelectableListComponentInstanceId';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { CreateNewButton } from '@/ui/input/relation-picker/components/CreateNewButton';
|
||||
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
|
||||
@ -16,13 +15,13 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { Placement } from '@floating-ui/react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
@ -34,7 +33,7 @@ export const StyledSelectableItem = styled(SelectableItem)`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const MultiRecordSelect = ({
|
||||
export const MultipleRecordPicker = ({
|
||||
onChange,
|
||||
onSubmit,
|
||||
onCreate,
|
||||
@ -46,7 +45,6 @@ export const MultiRecordSelect = ({
|
||||
dropdownPlacement?: Placement | null;
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope();
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
@ -57,7 +55,7 @@ export const MultiRecordSelect = ({
|
||||
useObjectRecordMultiSelectScopedStates(instanceId);
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
const recordMultiSelectIsLoading = useRecoilValue(
|
||||
recordMultiSelectIsLoadingState,
|
||||
@ -71,6 +69,7 @@ export const MultiRecordSelect = ({
|
||||
recordPickerSearchFilterComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const recordPickerSearchFilter = useRecoilComponentValueV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
instanceId,
|
||||
@ -78,21 +77,28 @@ export const MultiRecordSelect = ({
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
useEffect(() => {
|
||||
setHotkeyScope(instanceId);
|
||||
}, [setHotkeyScope, instanceId]);
|
||||
const handleSubmit = () => {
|
||||
onSubmit?.();
|
||||
goBackToPreviousHotkeyScope();
|
||||
resetSelectedItem();
|
||||
};
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Escape,
|
||||
() => {
|
||||
onSubmit?.();
|
||||
goBackToPreviousHotkeyScope();
|
||||
resetSelectedItem();
|
||||
handleSubmit();
|
||||
},
|
||||
instanceId,
|
||||
[onSubmit, goBackToPreviousHotkeyScope, resetSelectedItem],
|
||||
[handleSubmit],
|
||||
);
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [containerRef],
|
||||
callback: handleSubmit,
|
||||
listenerId: 'MULTI_RECORD_SELECT_LISTENER_ID',
|
||||
hotkeyScope: instanceId,
|
||||
});
|
||||
|
||||
const handleFilterChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchFilter(event.currentTarget.value);
|
||||
@ -104,7 +110,7 @@ export const MultiRecordSelect = ({
|
||||
const results = (
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
<SelectableList
|
||||
selectableListId={MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID}
|
||||
selectableListId={RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID}
|
||||
selectableItemIdArray={objectRecordsIdsMultiSelect}
|
||||
hotkeyScope={instanceId}
|
||||
onEnter={(selectedId) => {
|
||||
@ -114,7 +120,7 @@ export const MultiRecordSelect = ({
|
||||
>
|
||||
{objectRecordsIdsMultiSelect?.map((recordId) => {
|
||||
return (
|
||||
<MultipleObjectRecordSelectItem
|
||||
<MultipleRecordPickerMenuItem
|
||||
key={recordId}
|
||||
objectRecordId={recordId}
|
||||
onChange={(recordId) => {
|
||||
@ -137,61 +143,49 @@ export const MultiRecordSelect = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MultipleObjectRecordOnClickOutsideEffect
|
||||
containerRef={containerRef}
|
||||
onClickOutside={() => {
|
||||
onSubmit?.();
|
||||
}}
|
||||
<DropdownMenu ref={containerRef} data-select-disable width={200}>
|
||||
{dropdownPlacement?.includes('end') && (
|
||||
<>
|
||||
{isDefined(onCreate) && !hasObjectReadOnlyPermission && (
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{createNewButton}
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||
<>
|
||||
<DropdownMenuSkeletonItem />
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && <DropdownMenuSeparator />}
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuSearchInput
|
||||
value={recordPickerSearchFilter}
|
||||
onChange={handleFilterChange}
|
||||
autoFocus
|
||||
/>
|
||||
<DropdownMenu ref={containerRef} data-select-disable width={200}>
|
||||
{dropdownPlacement?.includes('end') && (
|
||||
<>
|
||||
{isDefined(onCreate) && !hasObjectReadOnlyPermission && (
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{createNewButton}
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||
<>
|
||||
<DropdownMenuSkeletonItem />
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && (
|
||||
{(dropdownPlacement?.includes('start') ||
|
||||
isUndefinedOrNull(dropdownPlacement)) && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||
<>
|
||||
<DropdownMenuSkeletonItem />
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuSearchInput
|
||||
value={recordPickerSearchFilter}
|
||||
onChange={handleFilterChange}
|
||||
autoFocus
|
||||
/>
|
||||
{(dropdownPlacement?.includes('start') ||
|
||||
isUndefinedOrNull(dropdownPlacement)) && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||
<>
|
||||
<DropdownMenuSkeletonItem />
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && (
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
{isDefined(onCreate) && (
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{createNewButton}
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</DropdownMenu>
|
||||
</>
|
||||
</>
|
||||
)}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||
{objectRecordsIdsMultiSelect?.length > 0 && <DropdownMenuSeparator />}
|
||||
{isDefined(onCreate) && (
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{createNewButton}
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
@ -3,8 +3,8 @@ import { useRecoilValue } from 'recoil';
|
||||
import { Avatar, MenuItemMultiSelectAvatar } from 'twenty-ui';
|
||||
|
||||
import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-picker/constants/RecordPickerSelectableListComponentInstanceId';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
@ -15,7 +15,7 @@ export const StyledSelectableItem = styled(SelectableItem)`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const MultipleObjectRecordSelectItem = ({
|
||||
export const MultipleRecordPickerMenuItem = ({
|
||||
objectRecordId,
|
||||
onChange,
|
||||
}: {
|
||||
@ -23,7 +23,7 @@ export const MultipleObjectRecordSelectItem = ({
|
||||
onChange?: (changedRecordForSelectId: string) => void;
|
||||
}) => {
|
||||
const { isSelectedItemIdSelector } = useSelectableList(
|
||||
MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const isSelectedByKeyboard = useRecoilValue(
|
||||
@ -1,18 +1,18 @@
|
||||
import { useRef } from 'react';
|
||||
|
||||
import {
|
||||
SingleRecordSelectMenuItemsWithSearch,
|
||||
SingleRecordSelectMenuItemsWithSearchProps,
|
||||
} from '@/object-record/relation-picker/components/SingleRecordSelectMenuItemsWithSearch';
|
||||
SingleRecordPickerMenuItemsWithSearch,
|
||||
SingleRecordPickerMenuItemsWithSearchProps,
|
||||
} from '@/object-record/record-picker/components/SingleRecordPickerMenuItemsWithSearch';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
export type SingleRecordSelectProps = {
|
||||
export type SingleRecordPickerProps = {
|
||||
width?: number;
|
||||
} & SingleRecordSelectMenuItemsWithSearchProps;
|
||||
} & SingleRecordPickerMenuItemsWithSearchProps;
|
||||
|
||||
export const SingleRecordSelect = ({
|
||||
export const SingleRecordPicker = ({
|
||||
EmptyIcon,
|
||||
emptyLabel,
|
||||
excludedRecordIds,
|
||||
@ -22,7 +22,7 @@ export const SingleRecordSelect = ({
|
||||
objectNameSingular,
|
||||
selectedRecordIds,
|
||||
width = 200,
|
||||
}: SingleRecordSelectProps) => {
|
||||
}: SingleRecordPickerProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useListenClickOutside({
|
||||
@ -43,7 +43,7 @@ export const SingleRecordSelect = ({
|
||||
|
||||
return (
|
||||
<DropdownMenu ref={containerRef} width={width} data-select-disable>
|
||||
<SingleRecordSelectMenuItemsWithSearch
|
||||
<SingleRecordPickerMenuItemsWithSearch
|
||||
{...{
|
||||
EmptyIcon,
|
||||
emptyLabel,
|
||||
@ -2,28 +2,28 @@ import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Avatar, MenuItemSelectAvatar } from 'twenty-ui';
|
||||
|
||||
import { SINGLE_RECORD_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleRecordSelectBaseList';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-picker/constants/RecordPickerSelectableListComponentInstanceId';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
|
||||
type SelectableMenuItemSelectProps = {
|
||||
record: RecordForSelect;
|
||||
onRecordSelected: (recordSelected?: RecordForSelect) => void;
|
||||
selectedRecord?: RecordForSelect;
|
||||
type SingleRecordPickerMenuItemProps = {
|
||||
record: SingleRecordPickerRecord;
|
||||
onRecordSelected: (recordSelected?: SingleRecordPickerRecord) => void;
|
||||
selectedRecord?: SingleRecordPickerRecord;
|
||||
};
|
||||
|
||||
const StyledSelectableItem = styled(SelectableItem)`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const SelectableMenuItemSelect = ({
|
||||
export const SingleRecordPickerMenuItem = ({
|
||||
record,
|
||||
onRecordSelected,
|
||||
selectedRecord,
|
||||
}: SelectableMenuItemSelectProps) => {
|
||||
}: SingleRecordPickerMenuItemProps) => {
|
||||
const { isSelectedItemIdSelector } = useSelectableList(
|
||||
SINGLE_RECORD_SELECT_BASE_LIST,
|
||||
RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const isSelectedItemId = useRecoilValue(isSelectedItemIdSelector(record.id));
|
||||
@ -4,8 +4,6 @@ import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { IconComponent, MenuItemSelect } from 'twenty-ui';
|
||||
|
||||
import { SelectableMenuItemSelect } from '@/object-record/relation-picker/components/SelectableMenuItemSelect';
|
||||
import { SINGLE_RECORD_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleRecordSelectBaseList';
|
||||
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
@ -13,23 +11,25 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
import { RecordForSelect } from '../types/RecordForSelect';
|
||||
import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope';
|
||||
import { SingleRecordPickerMenuItem } from '@/object-record/record-picker/components/SingleRecordPickerMenuItem';
|
||||
import { RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-picker/constants/RecordPickerSelectableListComponentInstanceId';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { RelationPickerHotkeyScope } from '../legacy/types/RelationPickerHotkeyScope';
|
||||
|
||||
export type SingleRecordSelectMenuItemsProps = {
|
||||
export type SingleRecordPickerMenuItemsProps = {
|
||||
EmptyIcon?: IconComponent;
|
||||
emptyLabel?: string;
|
||||
recordsToSelect: RecordForSelect[];
|
||||
recordsToSelect: SingleRecordPickerRecord[];
|
||||
loading?: boolean;
|
||||
onCancel?: () => void;
|
||||
onRecordSelected: (entity?: RecordForSelect) => void;
|
||||
selectedRecord?: RecordForSelect;
|
||||
onRecordSelected: (entity?: SingleRecordPickerRecord) => void;
|
||||
selectedRecord?: SingleRecordPickerRecord;
|
||||
hotkeyScope?: string;
|
||||
isFiltered: boolean;
|
||||
shouldSelectEmptyOption?: boolean;
|
||||
};
|
||||
|
||||
export const SingleRecordSelectMenuItems = ({
|
||||
export const SingleRecordPickerMenuItems = ({
|
||||
EmptyIcon,
|
||||
emptyLabel,
|
||||
recordsToSelect,
|
||||
@ -40,7 +40,7 @@ export const SingleRecordSelectMenuItems = ({
|
||||
hotkeyScope = RelationPickerHotkeyScope.RelationPicker,
|
||||
isFiltered,
|
||||
shouldSelectEmptyOption,
|
||||
}: SingleRecordSelectMenuItemsProps) => {
|
||||
}: SingleRecordPickerMenuItemsProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const selectNone = emptyLabel
|
||||
@ -56,12 +56,12 @@ export const SingleRecordSelectMenuItems = ({
|
||||
selectedRecord,
|
||||
...recordsToSelect,
|
||||
].filter(
|
||||
(entity): entity is RecordForSelect =>
|
||||
(entity): entity is SingleRecordPickerRecord =>
|
||||
isDefined(entity) && isNonEmptyString(entity.name),
|
||||
);
|
||||
|
||||
const { isSelectedItemIdSelector, resetSelectedItem } = useSelectableList(
|
||||
SINGLE_RECORD_SELECT_BASE_LIST,
|
||||
RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const isSelectedSelectNoneButton = useRecoilValue(
|
||||
@ -83,7 +83,7 @@ export const SingleRecordSelectMenuItems = ({
|
||||
return (
|
||||
<div ref={containerRef}>
|
||||
<SelectableList
|
||||
selectableListId={SINGLE_RECORD_SELECT_BASE_LIST}
|
||||
selectableListId={RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID}
|
||||
selectableItemIdArray={selectableItemIds}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={(itemId) => {
|
||||
@ -118,7 +118,7 @@ export const SingleRecordSelectMenuItems = ({
|
||||
}
|
||||
default: {
|
||||
return (
|
||||
<SelectableMenuItemSelect
|
||||
<SingleRecordPickerMenuItem
|
||||
key={record.id}
|
||||
record={record}
|
||||
onRecordSelected={onRecordSelected}
|
||||
@ -1,22 +1,24 @@
|
||||
import {
|
||||
SingleRecordSelectMenuItems,
|
||||
SingleRecordSelectMenuItemsProps,
|
||||
} from '@/object-record/relation-picker/components/SingleRecordSelectMenuItems';
|
||||
import { useRecordPickerRecordsOptions } from '@/object-record/relation-picker/hooks/useRecordPickerRecordsOptions';
|
||||
import { useRecordSelectSearch } from '@/object-record/relation-picker/hooks/useRecordSelectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
SingleRecordPickerMenuItems,
|
||||
SingleRecordPickerMenuItemsProps,
|
||||
} from '@/object-record/record-picker/components/SingleRecordPickerMenuItems';
|
||||
import { useRecordPickerRecordsOptions } from '@/object-record/record-picker/hooks/useRecordPickerRecordsOptions';
|
||||
import { useRecordSelectSearch } from '@/object-record/record-picker/hooks/useRecordSelectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { CreateNewButton } from '@/ui/input/relation-picker/components/CreateNewButton';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { Placement } from '@floating-ui/react';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { IconPlus } from 'twenty-ui';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
export type SingleRecordSelectMenuItemsWithSearchProps = {
|
||||
export type SingleRecordPickerMenuItemsWithSearchProps = {
|
||||
excludedRecordIds?: string[];
|
||||
onCreate?: ((searchInput?: string) => void) | (() => void);
|
||||
objectNameSingular: string;
|
||||
@ -24,7 +26,7 @@ export type SingleRecordSelectMenuItemsWithSearchProps = {
|
||||
selectedRecordIds: string[];
|
||||
dropdownPlacement?: Placement | null;
|
||||
} & Pick<
|
||||
SingleRecordSelectMenuItemsProps,
|
||||
SingleRecordPickerMenuItemsProps,
|
||||
| 'EmptyIcon'
|
||||
| 'emptyLabel'
|
||||
| 'onCancel'
|
||||
@ -32,7 +34,7 @@ export type SingleRecordSelectMenuItemsWithSearchProps = {
|
||||
| 'selectedRecord'
|
||||
>;
|
||||
|
||||
export const SingleRecordSelectMenuItemsWithSearch = ({
|
||||
export const SingleRecordPickerMenuItemsWithSearch = ({
|
||||
EmptyIcon,
|
||||
emptyLabel,
|
||||
excludedRecordIds,
|
||||
@ -42,7 +44,7 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
|
||||
objectNameSingular,
|
||||
selectedRecordIds,
|
||||
dropdownPlacement,
|
||||
}: SingleRecordSelectMenuItemsWithSearchProps) => {
|
||||
}: SingleRecordPickerMenuItemsWithSearchProps) => {
|
||||
const { handleSearchFilterChange } = useRecordSelectSearch();
|
||||
|
||||
const recordPickerInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
@ -51,7 +53,12 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { records, recordPickerSearchFilter } = useRecordPickerRecordsOptions({
|
||||
const recordPickerSearchFilter = useRecoilComponentValueV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
recordPickerInstanceId,
|
||||
);
|
||||
|
||||
const { records } = useRecordPickerRecordsOptions({
|
||||
objectNameSingular,
|
||||
selectedRecordIds,
|
||||
excludedRecordIds,
|
||||
@ -79,7 +86,7 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
|
||||
)}
|
||||
{records.recordsToSelect.length > 0 && <DropdownMenuSeparator />}
|
||||
{shouldDisplayDropdownMenuItems && (
|
||||
<SingleRecordSelectMenuItems
|
||||
<SingleRecordPickerMenuItems
|
||||
recordsToSelect={records.recordsToSelect}
|
||||
loading={records.loading}
|
||||
selectedRecord={records.selectedRecords?.[0]}
|
||||
@ -107,7 +114,7 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
{shouldDisplayDropdownMenuItems && (
|
||||
<SingleRecordSelectMenuItems
|
||||
<SingleRecordPickerMenuItems
|
||||
recordsToSelect={records.recordsToSelect}
|
||||
loading={records.loading}
|
||||
selectedRecord={records.selectedRecords?.[0]}
|
||||
@ -11,12 +11,12 @@ import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getPeopleMock } from '~/testing/mock-data/people';
|
||||
import { sleep } from '~/utils/sleep';
|
||||
|
||||
import { RecordForSelect } from '../../types/RecordForSelect';
|
||||
import { SingleRecordSelect } from '../SingleRecordSelect';
|
||||
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
||||
import { SingleRecordPickerRecord } from '../../types/SingleRecordPickerRecord';
|
||||
|
||||
const peopleMock = getPeopleMock();
|
||||
|
||||
const records = peopleMock.map<RecordForSelect>((person) => ({
|
||||
const records = peopleMock.map<SingleRecordPickerRecord>((person) => ({
|
||||
id: person.id,
|
||||
name: person.name.firstName + ' ' + person.name.lastName,
|
||||
avatarUrl: 'https://picsum.photos/200',
|
||||
@ -24,9 +24,9 @@ const records = peopleMock.map<RecordForSelect>((person) => ({
|
||||
record: { ...person, __typename: 'Person' },
|
||||
}));
|
||||
|
||||
const meta: Meta<typeof SingleRecordSelect> = {
|
||||
title: 'UI/Input/RelationPicker/SingleRecordSelect',
|
||||
component: SingleRecordSelect,
|
||||
const meta: Meta<typeof SingleRecordPicker> = {
|
||||
title: 'UI/RecordPicker/SingleRecordPicker',
|
||||
component: SingleRecordPicker,
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
ComponentWithRecoilScopeDecorator,
|
||||
@ -53,7 +53,7 @@ const meta: Meta<typeof SingleRecordSelect> = {
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof SingleRecordSelect>;
|
||||
type Story = StoryObj<typeof SingleRecordPicker>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
export const RECORD_PICKER_CLICK_OUTSIDE_LISTENER_ID =
|
||||
'record-picker-click-outside-listener';
|
||||
@ -0,0 +1,2 @@
|
||||
export const RECORD_PICKER_SELECTABLE_LIST_COMPONENT_INSTANCE_ID =
|
||||
'record-picker-selectable-list-component-instance-id';
|
||||
@ -1,9 +1,9 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useLimitPerMetadataItem } from '@/object-record/relation-picker/hooks/useLimitPerMetadataItem';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
|
||||
const instanceId = 'instanceId';
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
@ -2,8 +2,8 @@ import { act, renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
|
||||
const instanceId = 'instanceId';
|
||||
@ -2,8 +2,8 @@ import { act, renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/object-record/relation-picker/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/object-record/record-picker/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
|
||||
const instanceId = 'instanceId';
|
||||
@ -2,9 +2,9 @@ import { act, renderHook } from '@testing-library/react';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecordSelectSearch } from '@/object-record/relation-picker/hooks/useRecordSelectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useRecordSelectSearch } from '@/object-record/record-picker/hooks/useRecordSelectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
const instanceId = 'instanceId';
|
||||
@ -4,7 +4,7 @@ import { useRecoilValue } from 'recoil';
|
||||
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
||||
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
||||
import { RecordGqlConnection } from '@/object-record/graphql/types/RecordGqlConnection';
|
||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/relation-picker/utils/formatMultiObjectRecordSearchResults';
|
||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/record-picker/utils/formatMultiObjectRecordSearchResults';
|
||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
||||
import { useGenerateCombinedSearchRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedSearchRecordsQuery';
|
||||
import { useLimitPerMetadataItem } from '@/object-record/relation-picker/hooks/useLimitPerMetadataItem';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { isObjectMetadataItemSearchableInCombinedRequest } from '@/object-record/utils/isObjectMetadataItemSearchableInCombinedRequest';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
@ -3,8 +3,8 @@ import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
||||
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/relation-picker/utils/formatMultiObjectRecordSearchResults';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/record-picker/utils/formatMultiObjectRecordSearchResults';
|
||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
@ -2,14 +2,14 @@ import { gql, useQuery } from '@apollo/client';
|
||||
import { isNonEmptyArray } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||
import { useLimitPerMetadataItem } from '@/object-record/relation-picker/hooks/useLimitPerMetadataItem';
|
||||
import {
|
||||
MultiObjectRecordQueryResult,
|
||||
useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray,
|
||||
} from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { useOrderByFieldPerMetadataItem } from '@/object-record/relation-picker/hooks/useOrderByFieldPerMetadataItem';
|
||||
} from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { useOrderByFieldPerMetadataItem } from '@/object-record/record-picker/hooks/useOrderByFieldPerMetadataItem';
|
||||
import { SelectedObjectRecordId } from '@/object-record/types/SelectedObjectRecordId';
|
||||
import { capitalize, isDefined } from 'twenty-shared';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useFilteredSearchRecordQuery } from '@/search/hooks/useFilteredSearchRecordQuery';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
@ -22,5 +22,5 @@ export const useRecordPickerRecordsOptions = ({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
return { records, recordPickerSearchFilter };
|
||||
return { records };
|
||||
};
|
||||
@ -1,15 +1,22 @@
|
||||
import { recordPickerPreselectedIdComponentState } from '@/object-record/record-picker/states/recordPickerPreselectedIdComponentState';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { useRecordPicker } from '@/object-record/relation-picker/hooks/useRecordPicker';
|
||||
|
||||
export const useRecordSelectSearch = ({
|
||||
recordPickerInstanceId,
|
||||
}: {
|
||||
recordPickerInstanceId?: string;
|
||||
} = {}) => {
|
||||
const { setRecordPickerSearchFilter, setRecordPickerPreselectedId } =
|
||||
useRecordPicker({ recordPickerInstanceId });
|
||||
const setRecordPickerSearchFilter = useSetRecoilComponentStateV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
recordPickerInstanceId,
|
||||
);
|
||||
|
||||
const setRecordPickerPreselectedId = useSetRecoilComponentStateV2(
|
||||
recordPickerPreselectedIdComponentState,
|
||||
recordPickerInstanceId,
|
||||
);
|
||||
const debouncedSetSearchFilter = useDebouncedCallback(
|
||||
setRecordPickerSearchFilter,
|
||||
100,
|
||||
@ -9,12 +9,13 @@ import {
|
||||
import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates';
|
||||
import { objectRecordMultiSelectComponentFamilyState } from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
||||
import { objectRecordMultiSelectMatchesFilterRecordsIdsComponentState } from '@/object-record/record-field/states/objectRecordMultiSelectMatchesFilterRecordsIdsComponentState';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||
import { SelectedObjectRecordId } from '@/object-record/types/SelectedObjectRecordId';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
// Todo: this effect should be deprecated to use sync hooks
|
||||
export const ActivityTargetInlineCellEditModeMultiRecordsEffect = ({
|
||||
selectedObjectRecordIds,
|
||||
}: {
|
||||
@ -3,13 +3,14 @@ import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { objectRecordMultiSelectMatchesFilterRecordsIdsComponentState } from '@/object-record/record-field/states/objectRecordMultiSelectMatchesFilterRecordsIdsComponentState';
|
||||
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { useMultiObjectSearch } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { useMultiObjectSearch } from '@/object-record/record-picker/hooks/useMultiObjectSearch';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
// Todo: this effect should be deprecated to use sync hooks
|
||||
export const ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect =
|
||||
() => {
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
@ -1,10 +1,11 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { MULTI_OBJECT_RECORD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordClickOutsideListenerId';
|
||||
import { RECORD_PICKER_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-picker/constants/RecordPickerClickOutsideListenerId';
|
||||
import { RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID } from '@/ui/layout/right-drawer/constants/RightDrawerClickOutsideListener';
|
||||
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
|
||||
// Todo: this effect should be deprecated to use sync hooks
|
||||
export const MultipleObjectRecordOnClickOutsideEffect = ({
|
||||
containerRef,
|
||||
onClickOutside,
|
||||
@ -32,7 +33,7 @@ export const MultipleObjectRecordOnClickOutsideEffect = ({
|
||||
|
||||
onClickOutside();
|
||||
},
|
||||
listenerId: MULTI_OBJECT_RECORD_CLICK_OUTSIDE_LISTENER_ID,
|
||||
listenerId: RECORD_PICKER_CLICK_OUTSIDE_LISTENER_ID,
|
||||
});
|
||||
|
||||
return <></>;
|
||||
@ -1,7 +1,8 @@
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
// Todo: this effect should be deprecated to use sync hooks
|
||||
export const SearchPickerInitialValueEffect = ({
|
||||
initialValueForSearchFilter,
|
||||
recordPickerInstanceId,
|
||||
@ -1,4 +1,4 @@
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const recordPickerPreselectedIdComponentState = createComponentStateV2<
|
||||
@ -1,4 +1,4 @@
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const recordPickerSearchFilterComponentState =
|
||||
@ -0,0 +1,10 @@
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordPickerSearchQuery } from '@/object-record/record-picker/types/RecordPickerSearchQuery';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const recordPickerSearchQueryComponentState =
|
||||
createComponentStateV2<RecordPickerSearchQuery | null>({
|
||||
key: 'recordPickerSearchQueryComponentState',
|
||||
defaultValue: null,
|
||||
componentInstanceContext: RecordPickerComponentInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
|
||||
export type MultipleRecordPickerRecords<
|
||||
CustomRecordForRecordPicker extends SingleRecordPickerRecord,
|
||||
> = {
|
||||
selectedRecords: CustomRecordForRecordPicker[];
|
||||
filteredSelectedRecords: CustomRecordForRecordPicker[];
|
||||
recordsToSelect: CustomRecordForRecordPicker[];
|
||||
loading: boolean;
|
||||
};
|
||||
@ -1,3 +1,3 @@
|
||||
export type SearchQuery = {
|
||||
export type RecordPickerSearchQuery = {
|
||||
computeFilterFields: (relationPickerType: string) => string[];
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier';
|
||||
|
||||
export type RecordForSelect = ObjectRecordIdentifier & {
|
||||
export type SingleRecordPickerRecord = ObjectRecordIdentifier & {
|
||||
record: ObjectRecord;
|
||||
};
|
||||
@ -1,4 +1,4 @@
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||
|
||||
export const formatMultiObjectRecordSearchResults = (
|
||||
searchResults: MultiObjectRecordQueryResult | undefined | null,
|
||||
@ -11,17 +11,17 @@ import { usePersistField } from '@/object-record/record-field/hooks/usePersistFi
|
||||
import { RelationFromManyFieldInputMultiRecordsEffect } from '@/object-record/record-field/meta-types/input/components/RelationFromManyFieldInputMultiRecordsEffect';
|
||||
import { useUpdateRelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/hooks/useUpdateRelationFromManyFieldInput';
|
||||
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { MultipleRecordPicker } from '@/object-record/record-picker/components/MultipleRecordPicker';
|
||||
import { SingleRecordPickerMenuItemsWithSearch } from '@/object-record/record-picker/components/SingleRecordPickerMenuItemsWithSearch';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/record-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { RecordDetailRelationRecordsList } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList';
|
||||
import { RecordDetailSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailSection';
|
||||
import { RecordDetailSectionHeader } from '@/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { MultiRecordSelect } from '@/object-record/relation-picker/components/MultiRecordSelect';
|
||||
import { SingleRecordSelectMenuItemsWithSearch } from '@/object-record/relation-picker/components/SingleRecordSelectMenuItemsWithSearch';
|
||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/relation-picker/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||
import { useRecordPicker } from '@/object-record/relation-picker/hooks/useRecordPicker';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { prefetchIndexViewIdFromObjectMetadataItemFamilySelector } from '@/prefetch/states/selector/prefetchIndexViewIdFromObjectMetadataItemFamilySelector';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
@ -29,6 +29,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
||||
@ -84,9 +85,10 @@ export const RecordDetailRelationSection = ({
|
||||
const { closeDropdown, isDropdownOpen, dropdownPlacement } =
|
||||
useDropdown(dropdownId);
|
||||
|
||||
const { setRecordPickerSearchFilter } = useRecordPicker({
|
||||
recordPickerInstanceId: dropdownId,
|
||||
});
|
||||
const setRecordPickerSearchFilter = useSetRecoilComponentStateV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const handleCloseRelationPickerDropdown = useCallback(() => {
|
||||
setRecordPickerSearchFilter('');
|
||||
@ -98,7 +100,7 @@ export const RecordDetailRelationSection = ({
|
||||
});
|
||||
|
||||
const handleRelationPickerEntitySelected = (
|
||||
selectedRelationEntity?: RecordForSelect,
|
||||
selectedRelationEntity?: SingleRecordPickerRecord,
|
||||
) => {
|
||||
closeDropdown();
|
||||
|
||||
@ -204,7 +206,7 @@ export const RecordDetailRelationSection = ({
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{isToOneObject ? (
|
||||
<SingleRecordSelectMenuItemsWithSearch
|
||||
<SingleRecordPickerMenuItemsWithSearch
|
||||
EmptyIcon={IconForbid}
|
||||
onRecordSelected={handleRelationPickerEntitySelected}
|
||||
selectedRecordIds={relationRecordIds}
|
||||
@ -216,7 +218,7 @@ export const RecordDetailRelationSection = ({
|
||||
) : (
|
||||
<>
|
||||
<RelationFromManyFieldInputMultiRecordsEffect />
|
||||
<MultiRecordSelect
|
||||
<MultipleRecordPicker
|
||||
onCreate={() => {
|
||||
closeDropdown();
|
||||
createNewRecordAndOpenRightDrawer?.();
|
||||
|
||||
@ -5,12 +5,12 @@ import { FieldContext } from '@/object-record/record-field/contexts/FieldContext
|
||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/record-picker/legacy/types/RelationPickerHotkeyScope';
|
||||
import { RecordUpdateContext } from '@/object-record/record-table/contexts/EntityUpdateMutationHookContext';
|
||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
export const MULTI_OBJECT_RECORD_CLICK_OUTSIDE_LISTENER_ID =
|
||||
'multi-object-record-click-outside-listener';
|
||||
@ -1,2 +0,0 @@
|
||||
export const MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID =
|
||||
'multi-object-record-select-selectable-list';
|
||||
@ -1 +0,0 @@
|
||||
export const SINGLE_RECORD_SELECT_BASE_LIST = 'single-record-select-base-list';
|
||||
@ -1,24 +0,0 @@
|
||||
import { recordPickerPreselectedIdComponentState } from '@/object-record/relation-picker/states/recordPickerPreselectedIdComponentState';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/relation-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
export const useRecordPicker = ({
|
||||
recordPickerInstanceId,
|
||||
}: {
|
||||
recordPickerInstanceId?: string;
|
||||
}) => {
|
||||
const setRecordPickerSearchFilter = useSetRecoilComponentStateV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
recordPickerInstanceId,
|
||||
);
|
||||
|
||||
const setRecordPickerPreselectedId = useSetRecoilComponentStateV2(
|
||||
recordPickerPreselectedIdComponentState,
|
||||
recordPickerInstanceId,
|
||||
);
|
||||
|
||||
return {
|
||||
setRecordPickerSearchFilter,
|
||||
setRecordPickerPreselectedId,
|
||||
};
|
||||
};
|
||||
@ -1,10 +0,0 @@
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { SearchQuery } from '@/object-record/relation-picker/types/SearchQuery';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const searchQueryComponentState =
|
||||
createComponentStateV2<SearchQuery | null>({
|
||||
key: 'searchQueryComponentState',
|
||||
defaultValue: null,
|
||||
componentInstanceContext: RecordPickerComponentInstanceContext,
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
|
||||
export type RecordsForMultipleRecordSelect<
|
||||
CustomRecordForSelect extends RecordForSelect,
|
||||
> = {
|
||||
selectedRecords: CustomRecordForSelect[];
|
||||
filteredSelectedRecords: CustomRecordForSelect[];
|
||||
recordsToSelect: CustomRecordForSelect[];
|
||||
loading: boolean;
|
||||
};
|
||||
@ -1,7 +1,7 @@
|
||||
import { TABLE_COLUMNS_DENY_LIST } from '@/object-record/constants/TableColumnsDenyList';
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { TABLE_COLUMNS_DENY_LIST } from '@/object-record/relation-picker/constants/TableColumnsDenyList';
|
||||
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const filterAvailableTableColumns = (
|
||||
|
||||
@ -5,9 +5,9 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { RecordsForMultipleRecordSelect } from '@/object-record/relation-picker/types/RecordsForMultipleRecordSelect';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
|
||||
import { MultipleRecordPickerRecords } from '@/object-record/record-picker/types/MultipleRecordPickerRecords';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
import {
|
||||
query,
|
||||
@ -90,7 +90,7 @@ describe('useFilteredSearchRecordQuery', () => {
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
const expectedResult: RecordsForMultipleRecordSelect<any> = {
|
||||
const expectedResult: MultipleRecordPickerRecords<any> = {
|
||||
selectedRecords: [],
|
||||
filteredSelectedRecords: [],
|
||||
recordsToSelect: [],
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier';
|
||||
import { DEFAULT_SEARCH_REQUEST_LIMIT } from '@/object-record/constants/DefaultSearchRequestLimit';
|
||||
import { useSearchRecords } from '@/object-record/hooks/useSearchRecords';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { RecordsForMultipleRecordSelect } from '@/object-record/relation-picker/types/RecordsForMultipleRecordSelect';
|
||||
import { MultipleRecordPickerRecords } from '@/object-record/record-picker/types/MultipleRecordPickerRecords';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
@ -21,7 +21,7 @@ export const useFilteredSearchRecordQuery = ({
|
||||
excludedRecordIds?: string[];
|
||||
objectNameSingular: string;
|
||||
searchFilter?: string;
|
||||
}): RecordsForMultipleRecordSelect<RecordForSelect> => {
|
||||
}): MultipleRecordPickerRecords<SingleRecordPickerRecord> => {
|
||||
const { mapToObjectRecordIdentifier } = useMapToObjectRecordIdentifier({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
@ -3,7 +3,6 @@ import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { FieldMultiSelectValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
|
||||
import { SelectOption } from '@/spreadsheet-import/types';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
@ -19,6 +18,7 @@ import { MenuItemMultiSelectTag } from 'twenty-ui';
|
||||
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
|
||||
|
||||
type MultiSelectInputProps = {
|
||||
selectableListComponentInstanceId: string;
|
||||
values: FieldMultiSelectValue;
|
||||
hotkeyScope: string;
|
||||
onCancel?: () => void;
|
||||
@ -27,6 +27,7 @@ type MultiSelectInputProps = {
|
||||
};
|
||||
|
||||
export const MultiSelectInput = ({
|
||||
selectableListComponentInstanceId,
|
||||
values,
|
||||
options,
|
||||
hotkeyScope,
|
||||
@ -34,10 +35,10 @@ export const MultiSelectInput = ({
|
||||
onOptionSelected,
|
||||
}: MultiSelectInputProps) => {
|
||||
const { selectedItemIdState } = useSelectableListStates({
|
||||
selectableListScopeId: MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
selectableListScopeId: selectableListComponentInstanceId,
|
||||
});
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID,
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
|
||||
const selectedItemId = useRecoilValue(selectedItemIdState);
|
||||
@ -96,7 +97,7 @@ export const MultiSelectInput = ({
|
||||
|
||||
return (
|
||||
<SelectableList
|
||||
selectableListId={MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID}
|
||||
selectableListId={selectableListComponentInstanceId}
|
||||
selectableItemIdArray={optionIds}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={(itemId) => {
|
||||
|
||||
@ -3,7 +3,7 @@ import { SelectInput as SelectBaseInput } from '@/ui/input/components/SelectInpu
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
|
||||
type SelectInputProps = {
|
||||
selectableListId: string;
|
||||
selectableListComponentInstanceId: string;
|
||||
selectableItemIdArray: string[];
|
||||
hotkeyScope: string;
|
||||
onEnter: (itemId: string) => void;
|
||||
@ -17,7 +17,7 @@ type SelectInputProps = {
|
||||
};
|
||||
|
||||
export const SelectInput = ({
|
||||
selectableListId,
|
||||
selectableListComponentInstanceId,
|
||||
selectableItemIdArray,
|
||||
hotkeyScope,
|
||||
onEnter,
|
||||
@ -31,7 +31,7 @@ export const SelectInput = ({
|
||||
}: SelectInputProps) => {
|
||||
return (
|
||||
<SelectableList
|
||||
selectableListId={selectableListId}
|
||||
selectableListId={selectableListComponentInstanceId}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={onEnter}
|
||||
|
||||
@ -2,14 +2,15 @@ import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||
import { SingleRecordSelect } from '@/object-record/relation-picker/components/SingleRecordSelect';
|
||||
import { useRecordPicker } from '@/object-record/relation-picker/hooks/useRecordPicker';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
|
||||
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { recordPickerSearchFilterComponentState } from '@/object-record/record-picker/states/recordPickerSearchFilterComponentState';
|
||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
|
||||
import { WorkflowSingleRecordFieldChip } from '@/workflow/workflow-steps/workflow-actions/components/WorkflowSingleRecordFieldChip';
|
||||
import { WorkflowVariablesDropdown } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdown';
|
||||
@ -98,16 +99,17 @@ export const WorkflowSingleRecordPicker = ({
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const { setRecordPickerSearchFilter } = useRecordPicker({
|
||||
recordPickerInstanceId: dropdownId,
|
||||
});
|
||||
const setRecordPickerSearchFilter = useSetRecoilComponentStateV2(
|
||||
recordPickerSearchFilterComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const handleCloseRelationPickerDropdown = useCallback(() => {
|
||||
setRecordPickerSearchFilter('');
|
||||
}, [setRecordPickerSearchFilter]);
|
||||
|
||||
const handleRecordSelected = (
|
||||
selectedEntity: RecordForSelect | null | undefined,
|
||||
selectedEntity: SingleRecordPickerRecord | null | undefined,
|
||||
) => {
|
||||
onChange?.(selectedEntity?.record?.id ?? '');
|
||||
closeDropdown();
|
||||
@ -153,7 +155,7 @@ export const WorkflowSingleRecordPicker = ({
|
||||
<RecordPickerComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
<SingleRecordSelect
|
||||
<SingleRecordPicker
|
||||
EmptyIcon={IconForbid}
|
||||
emptyLabel={'No ' + objectNameSingular}
|
||||
onCancel={() => closeDropdown()}
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { Decorator } from '@storybook/react';
|
||||
|
||||
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
|
||||
export const RecordPickerDecorator: Decorator = (Story) => (
|
||||
<RecordPickerComponentInstanceContext.Provider
|
||||
value={{ instanceId: RelationPickerHotkeyScope.RelationPicker }}
|
||||
value={{ instanceId: 'record-picker-decorator-instance-id' }}
|
||||
>
|
||||
<Story />
|
||||
</RecordPickerComponentInstanceContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user