RecordPicker refactoring part 3: remove effects (#10505)
This PR is part 3 of RecordPicker refactoring. It aims to remove all effects from: - (low level layer) SingleRecordPicker, MultipleRecordPicker - (higher level layer) RelationPicker, RelationToOneInput, RelationFromManyInput, ActivityTargetInput... In this PR, I'm re-grouping Effects in ActivityTarget section and creating a hook that will be called on inlineCellOpen
This commit is contained in:
@ -3,7 +3,10 @@ import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil';
|
|||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
||||||
|
import { ActivityTargetInlineCellEditModeMultiRecordsEffect } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditModeMultiRecordsEffect';
|
||||||
|
import { ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect';
|
||||||
import { ActivityTargetObjectRecordEffect } from '@/activities/inline-cell/components/ActivityTargetObjectRecordEffect';
|
import { ActivityTargetObjectRecordEffect } from '@/activities/inline-cell/components/ActivityTargetObjectRecordEffect';
|
||||||
|
import { MultipleObjectRecordOnClickOutsideEffect } from '@/activities/inline-cell/components/MultipleObjectRecordOnClickOutsideEffect';
|
||||||
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
||||||
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
|
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
|
||||||
import { Note } from '@/activities/types/Note';
|
import { Note } from '@/activities/types/Note';
|
||||||
@ -24,12 +27,10 @@ import {
|
|||||||
objectRecordMultiSelectComponentFamilyState,
|
objectRecordMultiSelectComponentFamilyState,
|
||||||
} from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
} from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
|
||||||
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
||||||
import { ActivityTargetInlineCellEditModeMultiRecordsEffect } from '@/object-record/record-picker-morph-legacy/components/ActivityTargetInlineCellEditModeMultiRecordsEffect';
|
|
||||||
import { ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect } from '@/object-record/record-picker-morph-legacy/components/ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect';
|
|
||||||
import { MultipleRecordPicker } from '@/object-record/record-picker/components/MultipleRecordPicker';
|
import { MultipleRecordPicker } from '@/object-record/record-picker/components/MultipleRecordPicker';
|
||||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { prefillRecord } from '@/object-record/utils/prefillRecord';
|
import { prefillRecord } from '@/object-record/utils/prefillRecord';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
type ActivityTargetInlineCellEditModeProps = {
|
type ActivityTargetInlineCellEditModeProps = {
|
||||||
activity: Task | Note;
|
activity: Task | Note;
|
||||||
@ -257,20 +258,31 @@ export const ActivityTargetInlineCellEditMode = ({
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RecordPickerComponentInstanceContext.Provider
|
<ActivityTargetObjectRecordEffect
|
||||||
value={{ instanceId: recordPickerInstanceId }}
|
activityTargetWithTargetRecords={activityTargetWithTargetRecords}
|
||||||
>
|
/>
|
||||||
<ActivityTargetObjectRecordEffect
|
<ActivityTargetInlineCellEditModeMultiRecordsEffect
|
||||||
activityTargetWithTargetRecords={activityTargetWithTargetRecords}
|
recordPickerInstanceId={recordPickerInstanceId}
|
||||||
|
selectedObjectRecordIds={selectedTargetObjectIds}
|
||||||
|
/>
|
||||||
|
<ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect
|
||||||
|
recordPickerInstanceId={recordPickerInstanceId}
|
||||||
|
/>
|
||||||
|
<MultipleObjectRecordOnClickOutsideEffect
|
||||||
|
containerRef={containerRef}
|
||||||
|
onClickOutside={closeEditableField}
|
||||||
|
/>
|
||||||
|
<div ref={containerRef}>
|
||||||
|
<MultipleRecordPicker
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
onChange={handleChange}
|
||||||
|
componentInstanceId={recordPickerInstanceId}
|
||||||
/>
|
/>
|
||||||
<ActivityTargetInlineCellEditModeMultiRecordsEffect
|
</div>
|
||||||
selectedObjectRecordIds={selectedTargetObjectIds}
|
|
||||||
/>
|
|
||||||
<ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect />
|
|
||||||
<MultipleRecordPicker onSubmit={handleSubmit} onChange={handleChange} />
|
|
||||||
</RecordPickerComponentInstanceContext.Provider>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,12 +17,15 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|||||||
|
|
||||||
// Todo: this effect should be deprecated to use sync hooks
|
// Todo: this effect should be deprecated to use sync hooks
|
||||||
export const ActivityTargetInlineCellEditModeMultiRecordsEffect = ({
|
export const ActivityTargetInlineCellEditModeMultiRecordsEffect = ({
|
||||||
|
recordPickerInstanceId,
|
||||||
selectedObjectRecordIds,
|
selectedObjectRecordIds,
|
||||||
}: {
|
}: {
|
||||||
|
recordPickerInstanceId: string;
|
||||||
selectedObjectRecordIds: SelectedObjectRecordId[];
|
selectedObjectRecordIds: SelectedObjectRecordId[];
|
||||||
}) => {
|
}) => {
|
||||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
RecordPickerComponentInstanceContext,
|
RecordPickerComponentInstanceContext,
|
||||||
|
recordPickerInstanceId,
|
||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
objectRecordsIdsMultiSelectState,
|
objectRecordsIdsMultiSelectState,
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/activities/inline-cell/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||||
|
import { useMultiObjectSearch } from '@/activities/inline-cell/hooks/useMultiObjectSearch';
|
||||||
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
|
import { objectRecordMultiSelectMatchesFilterRecordsIdsComponentState } from '@/object-record/record-field/states/objectRecordMultiSelectMatchesFilterRecordsIdsComponentState';
|
||||||
|
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 = ({
|
||||||
|
recordPickerInstanceId,
|
||||||
|
}: {
|
||||||
|
recordPickerInstanceId: string;
|
||||||
|
}) => {
|
||||||
|
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
|
RecordPickerComponentInstanceContext,
|
||||||
|
recordPickerInstanceId,
|
||||||
|
);
|
||||||
|
const setRecordMultiSelectMatchesFilterRecords = useSetRecoilState(
|
||||||
|
objectRecordMultiSelectMatchesFilterRecordsIdsComponentState({
|
||||||
|
scopeId: instanceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordPickerSearchFilter = useRecoilComponentValueV2(
|
||||||
|
recordPickerSearchFilterComponentState,
|
||||||
|
instanceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { matchesSearchFilterObjectRecordsQueryResult } = useMultiObjectSearch({
|
||||||
|
excludedObjects: [CoreObjectNameSingular.Task, CoreObjectNameSingular.Note],
|
||||||
|
searchFilterValue: recordPickerSearchFilter,
|
||||||
|
limit: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { objectRecordForSelectArray } =
|
||||||
|
useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray({
|
||||||
|
multiObjectRecordsQueryResult:
|
||||||
|
matchesSearchFilterObjectRecordsQueryResult,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setRecordMultiSelectMatchesFilterRecords(objectRecordForSelectArray);
|
||||||
|
}, [setRecordMultiSelectMatchesFilterRecords, objectRecordForSelectArray]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
@ -5,6 +5,7 @@ import { IconArrowUpRight, IconPencil } from 'twenty-ui';
|
|||||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||||
import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode';
|
import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode';
|
||||||
|
import { useOpenActivityTargetInlineCellEditMode } from '@/activities/inline-cell/hooks/useOpenActivityTargetInlineCellEditMode';
|
||||||
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
||||||
import { Note } from '@/activities/types/Note';
|
import { Note } from '@/activities/types/Note';
|
||||||
import { Task } from '@/activities/types/Task';
|
import { Task } from '@/activities/types/Task';
|
||||||
@ -59,6 +60,9 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
overridenIsFieldEmpty: activityTargetObjectRecords.length === 0,
|
overridenIsFieldEmpty: activityTargetObjectRecords.length === 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { openActivityTargetInlineCellEditMode } =
|
||||||
|
useOpenActivityTargetInlineCellEditMode();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldInputScope recordFieldInputScopeId={activity?.id ?? ''}>
|
<RecordFieldInputScope recordFieldInputScopeId={activity?.id ?? ''}>
|
||||||
<FieldFocusContextProvider>
|
<FieldFocusContextProvider>
|
||||||
@ -90,6 +94,11 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
maxWidth={maxWidth}
|
maxWidth={maxWidth}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
onOpenEditMode: () => {
|
||||||
|
openActivityTargetInlineCellEditMode({
|
||||||
|
recordPickerInstanceId: `record-picker-${activity.id}`,
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordInlineCellContainer />
|
<RecordInlineCellContainer />
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { act, renderHook } from '@testing-library/react';
|
import { act, renderHook } from '@testing-library/react';
|
||||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/activities/inline-cell/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
|
||||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import { act, renderHook } from '@testing-library/react';
|
import { act, renderHook } from '@testing-library/react';
|
||||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/activities/inline-cell/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectSearchQueryResultFormattedAsObjectRecordsMap';
|
|
||||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
|
||||||
@ -3,15 +3,10 @@ import { useRecoilValue } from 'recoil';
|
|||||||
|
|
||||||
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
||||||
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
||||||
import { RecordGqlConnection } from '@/object-record/graphql/types/RecordGqlConnection';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/record-picker-morph-legacy/utils/formatMultiObjectRecordSearchResults';
|
import { formatMultiObjectRecordSearchResults } from '@/object-record/multiple-objects/utils/formatMultiObjectRecordSearchResults';
|
||||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export type MultiObjectRecordQueryResult = {
|
|
||||||
[namePlural: string]: RecordGqlConnection;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray =
|
export const useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray =
|
||||||
({
|
({
|
||||||
multiObjectRecordsQueryResult,
|
multiObjectRecordsQueryResult,
|
||||||
@ -6,7 +6,7 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
|||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
||||||
import { useGenerateCombinedSearchRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedSearchRecordsQuery';
|
import { useGenerateCombinedSearchRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedSearchRecordsQuery';
|
||||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
import { isObjectMetadataItemSearchableInCombinedRequest } from '@/object-record/utils/isObjectMetadataItemSearchableInCombinedRequest';
|
import { isObjectMetadataItemSearchableInCombinedRequest } from '@/object-record/utils/isObjectMetadataItemSearchableInCombinedRequest';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -3,8 +3,8 @@ import { useRecoilValue } from 'recoil';
|
|||||||
|
|
||||||
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
import { objectMetadataItemsByNamePluralMapSelector } from '@/object-metadata/states/objectMetadataItemsByNamePluralMapSelector';
|
||||||
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
|
||||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
import { formatMultiObjectRecordSearchResults } from '@/object-record/record-picker-morph-legacy/utils/formatMultiObjectRecordSearchResults';
|
import { formatMultiObjectRecordSearchResults } from '@/object-record/multiple-objects/utils/formatMultiObjectRecordSearchResults';
|
||||||
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
import { ObjectRecordForSelect } from '@/object-record/types/ObjectRecordForSelect';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -2,14 +2,12 @@ import { gql, useQuery } from '@apollo/client';
|
|||||||
import { isNonEmptyArray } from '@sniptt/guards';
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/activities/inline-cell/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||||
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
||||||
import { useOrderByFieldPerMetadataItem } from '@/object-metadata/hooks/useOrderByFieldPerMetadataItem';
|
import { useOrderByFieldPerMetadataItem } from '@/object-metadata/hooks/useOrderByFieldPerMetadataItem';
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||||
import {
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
MultiObjectRecordQueryResult,
|
|
||||||
useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray,
|
|
||||||
} from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
|
||||||
import { SelectedObjectRecordId } from '@/object-record/types/SelectedObjectRecordId';
|
import { SelectedObjectRecordId } from '@/object-record/types/SelectedObjectRecordId';
|
||||||
import { capitalize, isDefined } from 'twenty-shared';
|
import { capitalize, isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
type OpenActivityTargetInlineCellEditModeProps = {
|
||||||
|
recordPickerInstanceId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useOpenActivityTargetInlineCellEditMode = () => {
|
||||||
|
const openActivityTargetInlineCellEditMode = ({
|
||||||
|
recordPickerInstanceId,
|
||||||
|
}: OpenActivityTargetInlineCellEditModeProps) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('openActivityTargetInlineCellEditMode', recordPickerInstanceId);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { openActivityTargetInlineCellEditMode };
|
||||||
|
};
|
||||||
@ -5,7 +5,7 @@ import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
|||||||
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
||||||
import { useCombinedFindManyRecordsQueryVariables } from '@/object-record/multiple-objects/hooks/useCombinedFindManyRecordsQueryVariables';
|
import { useCombinedFindManyRecordsQueryVariables } from '@/object-record/multiple-objects/hooks/useCombinedFindManyRecordsQueryVariables';
|
||||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
|
|
||||||
export const useCombinedFindManyRecords = ({
|
export const useCombinedFindManyRecords = ({
|
||||||
operationSignatures,
|
operationSignatures,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
|||||||
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery';
|
||||||
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
||||||
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery';
|
||||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
|
|
||||||
export const useCombinedGetTotalCount = ({
|
export const useCombinedGetTotalCount = ({
|
||||||
objectMetadataItems,
|
objectMetadataItems,
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { RecordGqlConnection } from '@/object-record/graphql/types/RecordGqlConnection';
|
||||||
|
|
||||||
|
export type MultiObjectRecordQueryResult = {
|
||||||
|
[namePlural: string]: RecordGqlConnection;
|
||||||
|
};
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { MultiObjectRecordQueryResult } from '@/object-record/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
import { MultiObjectRecordQueryResult } from '@/object-record/multiple-objects/types/MultiObjectRecordQueryResult';
|
||||||
|
|
||||||
export const formatMultiObjectRecordSearchResults = (
|
export const formatMultiObjectRecordSearchResults = (
|
||||||
searchResults: MultiObjectRecordQueryResult | undefined | null,
|
searchResults: MultiObjectRecordQueryResult | undefined | null,
|
||||||
@ -33,6 +33,8 @@ export type GenericFieldContextType = {
|
|||||||
overridenIsFieldEmpty?: boolean;
|
overridenIsFieldEmpty?: boolean;
|
||||||
displayedMaxRows?: number;
|
displayedMaxRows?: number;
|
||||||
isDisplayModeFixHeight?: boolean;
|
isDisplayModeFixHeight?: boolean;
|
||||||
|
onOpenEditMode?: () => void;
|
||||||
|
onCloseEditMode?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FieldContext = createContext<GenericFieldContextType>(
|
export const FieldContext = createContext<GenericFieldContextType>(
|
||||||
|
|||||||
@ -57,6 +57,7 @@ export const RelationFromManyFieldInput = ({
|
|||||||
>
|
>
|
||||||
<RelationFromManyFieldInputMultiRecordsEffect />
|
<RelationFromManyFieldInputMultiRecordsEffect />
|
||||||
<MultipleRecordPicker
|
<MultipleRecordPicker
|
||||||
|
componentInstanceId={recordPickerInstanceId}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onChange={updateRelation}
|
onChange={updateRelation}
|
||||||
onCreate={createNewRecordAndOpenRightDrawer}
|
onCreate={createNewRecordAndOpenRightDrawer}
|
||||||
|
|||||||
@ -3,11 +3,11 @@ import { IconForbid } from 'twenty-ui';
|
|||||||
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
|
import { RelationPickerInitialValueEffect } from '@/object-record/record-field/meta-types/input/components/RelationPickerInitialValueEffect';
|
||||||
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/record-field/meta-types/input/hooks/useAddNewRecordAndOpenRightDrawer';
|
import { useAddNewRecordAndOpenRightDrawer } from '@/object-record/record-field/meta-types/input/hooks/useAddNewRecordAndOpenRightDrawer';
|
||||||
import { RelationPickerHotkeyScope } from '@/object-record/record-field/meta-types/input/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/object-record/record-field/meta-types/input/types/RelationPickerHotkeyScope';
|
||||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||||
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { SearchPickerInitialValueEffect } from '@/object-record/record-picker-morph-legacy/components/SearchPickerInitialValueEffect';
|
|
||||||
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
|
||||||
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
import { SingleRecordPickerRecord } from '@/object-record/record-picker/types/SingleRecordPickerRecord';
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export const RelationPicker = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchPickerInitialValueEffect
|
<RelationPickerInitialValueEffect
|
||||||
initialValueForSearchFilter={initialSearchFilter}
|
initialValueForSearchFilter={initialSearchFilter}
|
||||||
recordPickerInstanceId={recordPickerInstanceId}
|
recordPickerInstanceId={recordPickerInstanceId}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
// Todo: this effect should be deprecated to use sync hooks
|
// Todo: this effect should be deprecated to use sync hooks
|
||||||
export const SearchPickerInitialValueEffect = ({
|
export const RelationPickerInitialValueEffect = ({
|
||||||
initialValueForSearchFilter,
|
initialValueForSearchFilter,
|
||||||
recordPickerInstanceId,
|
recordPickerInstanceId,
|
||||||
}: {
|
}: {
|
||||||
@ -31,8 +31,14 @@ type RecordInlineCellProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
||||||
const { fieldDefinition, recordId, isCentered, isDisplayModeFixHeight } =
|
const {
|
||||||
useContext(FieldContext);
|
fieldDefinition,
|
||||||
|
recordId,
|
||||||
|
isCentered,
|
||||||
|
isDisplayModeFixHeight,
|
||||||
|
onOpenEditMode,
|
||||||
|
onCloseEditMode,
|
||||||
|
} = useContext(FieldContext);
|
||||||
const buttonIcon = useGetButtonIcon();
|
const buttonIcon = useGetButtonIcon();
|
||||||
|
|
||||||
const isFieldInputOnly = useIsFieldInputOnly();
|
const isFieldInputOnly = useIsFieldInputOnly();
|
||||||
@ -129,6 +135,8 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
|||||||
isDisplayModeFixHeight: isDisplayModeFixHeight,
|
isDisplayModeFixHeight: isDisplayModeFixHeight,
|
||||||
editModeContentOnly: isFieldInputOnly,
|
editModeContentOnly: isFieldInputOnly,
|
||||||
loading: loading,
|
loading: loading,
|
||||||
|
onOpenEditMode,
|
||||||
|
onCloseEditMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -17,6 +17,8 @@ export type RecordInlineCellContextProps = {
|
|||||||
disableHoverEffect?: boolean;
|
disableHoverEffect?: boolean;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
isCentered?: boolean;
|
isCentered?: boolean;
|
||||||
|
onOpenEditMode?: () => void;
|
||||||
|
onCloseEditMode?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultRecordInlineCellContextProp: RecordInlineCellContextProps = {
|
const defaultRecordInlineCellContextProp: RecordInlineCellContextProps = {
|
||||||
@ -34,6 +36,8 @@ const defaultRecordInlineCellContextProp: RecordInlineCellContextProps = {
|
|||||||
disableHoverEffect: false,
|
disableHoverEffect: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
isCentered: false,
|
isCentered: false,
|
||||||
|
onOpenEditMode: undefined,
|
||||||
|
onCloseEditMode: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordInlineCellContext =
|
export const RecordInlineCellContext =
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
|||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2';
|
import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2';
|
||||||
|
import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
||||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||||
@ -24,6 +25,8 @@ export const useInlineCell = () => {
|
|||||||
isInlineCellInEditModeScopedState(recoilScopeId),
|
isInlineCellInEditModeScopedState(recoilScopeId),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { onOpenEditMode, onCloseEditMode } = useRecordInlineCellContext();
|
||||||
|
|
||||||
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
||||||
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
||||||
const { goBackToPreviousDropdownFocusId } =
|
const { goBackToPreviousDropdownFocusId } =
|
||||||
@ -37,6 +40,7 @@ export const useInlineCell = () => {
|
|||||||
const initFieldInputDraftValue = useInitDraftValueV2();
|
const initFieldInputDraftValue = useInitDraftValueV2();
|
||||||
|
|
||||||
const closeInlineCell = () => {
|
const closeInlineCell = () => {
|
||||||
|
onCloseEditMode?.();
|
||||||
setIsInlineCellInEditMode(false);
|
setIsInlineCellInEditMode(false);
|
||||||
|
|
||||||
goBackToPreviousHotkeyScope();
|
goBackToPreviousHotkeyScope();
|
||||||
@ -45,6 +49,7 @@ export const useInlineCell = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openInlineCell = (customEditHotkeyScopeForField?: HotkeyScope) => {
|
const openInlineCell = (customEditHotkeyScopeForField?: HotkeyScope) => {
|
||||||
|
onOpenEditMode?.();
|
||||||
setIsInlineCellInEditMode(true);
|
setIsInlineCellInEditMode(true);
|
||||||
initFieldInputDraftValue({ recordId, fieldDefinition });
|
initFieldInputDraftValue({ recordId, fieldDefinition });
|
||||||
|
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
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/record-picker-morph-legacy/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
|
||||||
import { useMultiObjectSearch } from '@/object-record/record-picker-morph-legacy/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(
|
|
||||||
RecordPickerComponentInstanceContext,
|
|
||||||
);
|
|
||||||
const setRecordMultiSelectMatchesFilterRecords = useSetRecoilState(
|
|
||||||
objectRecordMultiSelectMatchesFilterRecordsIdsComponentState({
|
|
||||||
scopeId: instanceId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordPickerSearchFilter = useRecoilComponentValueV2(
|
|
||||||
recordPickerSearchFilterComponentState,
|
|
||||||
instanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { matchesSearchFilterObjectRecordsQueryResult } =
|
|
||||||
useMultiObjectSearch({
|
|
||||||
excludedObjects: [
|
|
||||||
CoreObjectNameSingular.Task,
|
|
||||||
CoreObjectNameSingular.Note,
|
|
||||||
],
|
|
||||||
searchFilterValue: recordPickerSearchFilter,
|
|
||||||
limit: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { objectRecordForSelectArray } =
|
|
||||||
useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray({
|
|
||||||
multiObjectRecordsQueryResult:
|
|
||||||
matchesSearchFilterObjectRecordsQueryResult,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRecordMultiSelectMatchesFilterRecords(objectRecordForSelectArray);
|
|
||||||
}, [setRecordMultiSelectMatchesFilterRecords, objectRecordForSelectArray]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -33,22 +33,27 @@ export const StyledSelectableItem = styled(SelectableItem)`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type MultipleRecordPickerProps = {
|
||||||
|
onChange?: (changedRecordForSelectId: string) => void;
|
||||||
|
onSubmit?: () => void;
|
||||||
|
onCreate?: ((searchInput?: string) => void) | (() => void);
|
||||||
|
dropdownPlacement?: Placement | null;
|
||||||
|
componentInstanceId: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const MultipleRecordPicker = ({
|
export const MultipleRecordPicker = ({
|
||||||
onChange,
|
onChange,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCreate,
|
onCreate,
|
||||||
dropdownPlacement,
|
dropdownPlacement,
|
||||||
}: {
|
componentInstanceId,
|
||||||
onChange?: (changedRecordForSelectId: string) => void;
|
}: MultipleRecordPickerProps) => {
|
||||||
onSubmit?: () => void;
|
|
||||||
onCreate?: ((searchInput?: string) => void) | (() => void);
|
|
||||||
dropdownPlacement?: Placement | null;
|
|
||||||
}) => {
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope();
|
const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
RecordPickerComponentInstanceContext,
|
RecordPickerComponentInstanceContext,
|
||||||
|
componentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { objectRecordsIdsMultiSelectState, recordMultiSelectIsLoadingState } =
|
const { objectRecordsIdsMultiSelectState, recordMultiSelectIsLoadingState } =
|
||||||
@ -143,49 +148,57 @@ export const MultipleRecordPicker = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu ref={containerRef} data-select-disable width={200}>
|
<RecordPickerComponentInstanceContext.Provider
|
||||||
{dropdownPlacement?.includes('end') && (
|
value={{ instanceId: componentInstanceId }}
|
||||||
<>
|
>
|
||||||
{isDefined(onCreate) && !hasObjectReadOnlyPermission && (
|
<DropdownMenu ref={containerRef} data-select-disable width={200}>
|
||||||
<DropdownMenuItemsContainer scrollable={false}>
|
{dropdownPlacement?.includes('end') && (
|
||||||
{createNewButton}
|
<>
|
||||||
</DropdownMenuItemsContainer>
|
{isDefined(onCreate) && !hasObjectReadOnlyPermission && (
|
||||||
)}
|
<DropdownMenuItemsContainer scrollable={false}>
|
||||||
<DropdownMenuSeparator />
|
{createNewButton}
|
||||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
</DropdownMenuItemsContainer>
|
||||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
)}
|
||||||
<>
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuSkeletonItem />
|
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||||
|
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||||
|
<>
|
||||||
|
<DropdownMenuSkeletonItem />
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{objectRecordsIdsMultiSelect?.length > 0 && (
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
</>
|
)}
|
||||||
)}
|
</>
|
||||||
{objectRecordsIdsMultiSelect?.length > 0 && <DropdownMenuSeparator />}
|
)}
|
||||||
</>
|
<DropdownMenuSearchInput
|
||||||
)}
|
value={recordPickerSearchFilter}
|
||||||
<DropdownMenuSearchInput
|
onChange={handleFilterChange}
|
||||||
value={recordPickerSearchFilter}
|
autoFocus
|
||||||
onChange={handleFilterChange}
|
/>
|
||||||
autoFocus
|
{(dropdownPlacement?.includes('start') ||
|
||||||
/>
|
isUndefinedOrNull(dropdownPlacement)) && (
|
||||||
{(dropdownPlacement?.includes('start') ||
|
<>
|
||||||
isUndefinedOrNull(dropdownPlacement)) && (
|
<DropdownMenuSeparator />
|
||||||
<>
|
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
||||||
<DropdownMenuSeparator />
|
<>
|
||||||
{recordMultiSelectIsLoading && !recordPickerSearchFilter && (
|
<DropdownMenuSkeletonItem />
|
||||||
<>
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuSkeletonItem />
|
</>
|
||||||
|
)}
|
||||||
|
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
||||||
|
{objectRecordsIdsMultiSelect?.length > 0 && (
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
</>
|
)}
|
||||||
)}
|
{isDefined(onCreate) && (
|
||||||
{objectRecordsIdsMultiSelect?.length > 0 && results}
|
<DropdownMenuItemsContainer scrollable={false}>
|
||||||
{objectRecordsIdsMultiSelect?.length > 0 && <DropdownMenuSeparator />}
|
{createNewButton}
|
||||||
{isDefined(onCreate) && (
|
</DropdownMenuItemsContainer>
|
||||||
<DropdownMenuItemsContainer scrollable={false}>
|
)}
|
||||||
{createNewButton}
|
</>
|
||||||
</DropdownMenuItemsContainer>
|
)}
|
||||||
)}
|
</DropdownMenu>
|
||||||
</>
|
</RecordPickerComponentInstanceContext.Provider>
|
||||||
)}
|
|
||||||
</DropdownMenu>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { ComponentDecorator, IconUserCircle } from 'twenty-ui';
|
|||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
||||||
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
||||||
import { RecordPickerDecorator } from '~/testing/decorators/RecordPickerDecorator';
|
|
||||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { getPeopleMock } from '~/testing/mock-data/people';
|
import { getPeopleMock } from '~/testing/mock-data/people';
|
||||||
@ -30,7 +29,6 @@ const meta: Meta<typeof SingleRecordPicker> = {
|
|||||||
decorators: [
|
decorators: [
|
||||||
ComponentDecorator,
|
ComponentDecorator,
|
||||||
ComponentWithRecoilScopeDecorator,
|
ComponentWithRecoilScopeDecorator,
|
||||||
RecordPickerDecorator,
|
|
||||||
ObjectMetadataItemsDecorator,
|
ObjectMetadataItemsDecorator,
|
||||||
SnackBarDecorator,
|
SnackBarDecorator,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -219,6 +219,7 @@ export const RecordDetailRelationSection = ({
|
|||||||
<>
|
<>
|
||||||
<RelationFromManyFieldInputMultiRecordsEffect />
|
<RelationFromManyFieldInputMultiRecordsEffect />
|
||||||
<MultipleRecordPicker
|
<MultipleRecordPicker
|
||||||
|
componentInstanceId={dropdownId}
|
||||||
onCreate={() => {
|
onCreate={() => {
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
createNewRecordAndOpenRightDrawer?.();
|
createNewRecordAndOpenRightDrawer?.();
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
import { RecordPickerComponentInstanceContext } from '@/object-record/record-picker/states/contexts/RecordPickerComponentInstanceContext';
|
|
||||||
import { Decorator } from '@storybook/react';
|
|
||||||
|
|
||||||
export const RecordPickerDecorator: Decorator = (Story) => (
|
|
||||||
<RecordPickerComponentInstanceContext.Provider
|
|
||||||
value={{ instanceId: 'record-picker-decorator-instance-id' }}
|
|
||||||
>
|
|
||||||
<Story />
|
|
||||||
</RecordPickerComponentInstanceContext.Provider>
|
|
||||||
);
|
|
||||||
Reference in New Issue
Block a user