Removed use-context-selector completely (#12139)
This PR removes use-context-selector completely, so that any bug associated with state synchronization between recoil and use-context-selector disappears. There might be a slight performance decrease on the table, but since we have already improved the average performance per line by a lot, and that the performance bottleneck right now is the fetch more logic and the windowing solution we use, it is not relevant. Also the DX has become so hindered by this parallel state logic recently (think [cache invalidation](https://martinfowler.com/bliki/TwoHardThings.html)), that the main benefit we gain from this removal is the DX improvement. Fixes https://github.com/twentyhq/twenty/issues/12123 Fixes https://github.com/twentyhq/twenty/issues/12109
This commit is contained in:
@ -191,7 +191,6 @@
|
|||||||
"tsup": "^8.2.4",
|
"tsup": "^8.2.4",
|
||||||
"type-fest": "4.10.1",
|
"type-fest": "4.10.1",
|
||||||
"typescript": "5.3.3",
|
"typescript": "5.3.3",
|
||||||
"use-context-selector": "^2.0.0",
|
|
||||||
"use-debounce": "^10.0.0",
|
"use-debounce": "^10.0.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"vite-tsconfig-paths": "^4.2.1",
|
"vite-tsconfig-paths": "^4.2.1",
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
@ -11,7 +10,6 @@ export const CalendarEventDetailsEffect = ({
|
|||||||
record,
|
record,
|
||||||
}: CalendarEventDetailsEffectProps) => {
|
}: CalendarEventDetailsEffectProps) => {
|
||||||
const { upsertRecords } = useUpsertRecordsInStore();
|
const { upsertRecords } = useUpsertRecordsInStore();
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!record) {
|
if (!record) {
|
||||||
@ -19,8 +17,7 @@ export const CalendarEventDetailsEffect = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
upsertRecords([record]);
|
upsertRecords([record]);
|
||||||
setRecordValueInContextSelector(record.id, record);
|
}, [record, upsertRecords]);
|
||||||
}, [record, upsertRecords, setRecordValueInContextSelector]);
|
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { EventFieldDiffValue } from '@/activities/timeline-activities/rows/main-
|
|||||||
import { EventFieldDiffValueEffect } from '@/activities/timeline-activities/rows/main-object/components/EventFieldDiffValueEffect';
|
import { EventFieldDiffValueEffect } from '@/activities/timeline-activities/rows/main-object/components/EventFieldDiffValueEffect';
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
|
|
||||||
type EventFieldDiffProps = {
|
type EventFieldDiffProps = {
|
||||||
@ -54,7 +53,6 @@ export const EventFieldDiff = ({
|
|||||||
isObjectEmpty(diffRecord));
|
isObjectEmpty(diffRecord));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<StyledEventFieldDiffContainer>
|
<StyledEventFieldDiffContainer>
|
||||||
<EventFieldDiffLabel fieldMetadataItem={fieldMetadataItem} />→
|
<EventFieldDiffLabel fieldMetadataItem={fieldMetadataItem} />→
|
||||||
{isUpdatedToEmpty ? (
|
{isUpdatedToEmpty ? (
|
||||||
@ -77,6 +75,5 @@ export const EventFieldDiff = ({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</StyledEventFieldDiffContainer>
|
</StyledEventFieldDiffContainer>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
@ -21,7 +20,6 @@ export const EventFieldDiffValueEffect = ({
|
|||||||
const setEntity = useSetRecoilState(
|
const setEntity = useSetRecoilState(
|
||||||
recordStoreFamilyState(diffArtificialRecordStoreId),
|
recordStoreFamilyState(diffArtificialRecordStoreId),
|
||||||
);
|
);
|
||||||
const setRecordValue = useSetRecordValue();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isDefined(diffRecord)) return;
|
if (!isDefined(diffRecord)) return;
|
||||||
@ -33,14 +31,12 @@ export const EventFieldDiffValueEffect = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
setEntity(forgedObjectRecord);
|
setEntity(forgedObjectRecord);
|
||||||
setRecordValue(forgedObjectRecord.id, forgedObjectRecord);
|
|
||||||
}, [
|
}, [
|
||||||
diffRecord,
|
diffRecord,
|
||||||
diffArtificialRecordStoreId,
|
diffArtificialRecordStoreId,
|
||||||
fieldMetadataItem.name,
|
fieldMetadataItem.name,
|
||||||
mainObjectMetadataItem.nameSingular,
|
mainObjectMetadataItem.nameSingular,
|
||||||
setEntity,
|
setEntity,
|
||||||
setRecordValue,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|||||||
@ -4,10 +4,6 @@ import { FIND_ONE_CALENDAR_EVENT_OPERATION_SIGNATURE } from '@/activities/calend
|
|||||||
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
||||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import {
|
|
||||||
RecordFieldValueSelectorContextProvider,
|
|
||||||
useSetRecordValue,
|
|
||||||
} from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
@ -16,7 +12,6 @@ export const CommandMenuCalendarEventPage = () => {
|
|||||||
const viewableRecordId = useRecoilComponentValueV2(
|
const viewableRecordId = useRecoilComponentValueV2(
|
||||||
viewableRecordIdComponentState,
|
viewableRecordIdComponentState,
|
||||||
);
|
);
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
|
|
||||||
const { record: calendarEvent } = useFindOneRecord<CalendarEvent>({
|
const { record: calendarEvent } = useFindOneRecord<CalendarEvent>({
|
||||||
objectNameSingular:
|
objectNameSingular:
|
||||||
@ -26,7 +21,6 @@ export const CommandMenuCalendarEventPage = () => {
|
|||||||
// TODO: this is not executed on sub-sequent runs, make sure that it is intended
|
// TODO: this is not executed on sub-sequent runs, make sure that it is intended
|
||||||
onCompleted: (record) => {
|
onCompleted: (record) => {
|
||||||
upsertRecords([record]);
|
upsertRecords([record]);
|
||||||
setRecordValueInContextSelector(record.id, record);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -35,9 +29,9 @@ export const CommandMenuCalendarEventPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
<>
|
||||||
<CalendarEventDetailsEffect record={calendarEvent} />
|
<CalendarEventDetailsEffect record={calendarEvent} />
|
||||||
<CalendarEventDetails calendarEvent={calendarEvent} />
|
<CalendarEventDetails calendarEvent={calendarEvent} />
|
||||||
</RecordFieldValueSelectorContextProvider>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { RecordShowContainer } from '@/object-record/record-show/components/Reco
|
|||||||
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
||||||
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
||||||
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
|
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
@ -72,7 +71,6 @@ export const CommandMenuRecordPage = () => {
|
|||||||
value={{ instanceId: commandMenuPageInstanceId }}
|
value={{ instanceId: commandMenuPageInstanceId }}
|
||||||
>
|
>
|
||||||
<StyledRightDrawerRecord isMobile={isMobile}>
|
<StyledRightDrawerRecord isMobile={isMobile}>
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<TimelineActivityContext.Provider
|
<TimelineActivityContext.Provider
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
@ -89,7 +87,6 @@ export const CommandMenuRecordPage = () => {
|
|||||||
isInRightDrawer={true}
|
isInRightDrawer={true}
|
||||||
/>
|
/>
|
||||||
</TimelineActivityContext.Provider>
|
</TimelineActivityContext.Provider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
</StyledRightDrawerRecord>
|
</StyledRightDrawerRecord>
|
||||||
</ActionMenuComponentInstanceContext.Provider>
|
</ActionMenuComponentInstanceContext.Provider>
|
||||||
</ContextStoreComponentInstanceContext.Provider>
|
</ContextStoreComponentInstanceContext.Provider>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue';
|
import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue';
|
||||||
|
|
||||||
@ -17,8 +16,6 @@ export const useClearField = () => {
|
|||||||
|
|
||||||
const [updateRecord] = useUpdateRecord();
|
const [updateRecord] = useUpdateRecord();
|
||||||
|
|
||||||
const setRecordFieldValue = useSetRecordFieldValue();
|
|
||||||
|
|
||||||
const clearField = useRecoilCallback(
|
const clearField = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
() => {
|
() => {
|
||||||
@ -51,8 +48,6 @@ export const useClearField = () => {
|
|||||||
emptyFieldValue,
|
emptyFieldValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
setRecordFieldValue(recordId, fieldName, emptyFieldValue);
|
|
||||||
|
|
||||||
updateRecord?.({
|
updateRecord?.({
|
||||||
variables: {
|
variables: {
|
||||||
where: { id: recordId },
|
where: { id: recordId },
|
||||||
@ -62,7 +57,7 @@ export const useClearField = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[recordId, fieldDefinition, updateRecord, setRecordFieldValue],
|
[recordId, fieldDefinition, updateRecord],
|
||||||
);
|
);
|
||||||
|
|
||||||
return clearField;
|
return clearField;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
import { isFieldValueEmpty } from '@/object-record/record-field/utils/isFieldValueEmpty';
|
import { isFieldValueEmpty } from '@/object-record/record-field/utils/isFieldValueEmpty';
|
||||||
import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
|
|
||||||
import { FieldContext } from '../contexts/FieldContext';
|
import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
import { FieldContext } from '../contexts/FieldContext';
|
||||||
|
|
||||||
export const useIsFieldEmpty = () => {
|
export const useIsFieldEmpty = () => {
|
||||||
const { recordId, fieldDefinition, overridenIsFieldEmpty } =
|
const { recordId, fieldDefinition, overridenIsFieldEmpty } =
|
||||||
|
|||||||
@ -1,102 +0,0 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
|
||||||
import { RelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RelationFromManyFieldDisplay';
|
|
||||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
|
||||||
import {
|
|
||||||
RecordFieldValueSelectorContextProvider,
|
|
||||||
useSetRecordFieldValue,
|
|
||||||
} from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
|
||||||
import { ChipGeneratorsDecorator } from '~/testing/decorators/ChipGeneratorsDecorator';
|
|
||||||
import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator';
|
|
||||||
import { getProfilingStory } from '~/testing/profiling/utils/getProfilingStory';
|
|
||||||
|
|
||||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
|
||||||
import {
|
|
||||||
fieldValue,
|
|
||||||
otherPersonMock,
|
|
||||||
relationFromManyFieldDisplayMock,
|
|
||||||
} from './relationFromManyFieldDisplayMock';
|
|
||||||
|
|
||||||
const RelationFieldValueSetterEffect = () => {
|
|
||||||
const setEntity = useSetRecoilState(
|
|
||||||
recordStoreFamilyState(relationFromManyFieldDisplayMock.recordId),
|
|
||||||
);
|
|
||||||
|
|
||||||
const setRelationEntity = useSetRecoilState(
|
|
||||||
recordStoreFamilyState(relationFromManyFieldDisplayMock.relationRecordId),
|
|
||||||
);
|
|
||||||
|
|
||||||
const setRecordFieldValue = useSetRecordFieldValue();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setEntity(relationFromManyFieldDisplayMock.entityValue);
|
|
||||||
setRelationEntity(relationFromManyFieldDisplayMock.relationFieldValue);
|
|
||||||
|
|
||||||
setRecordFieldValue(
|
|
||||||
relationFromManyFieldDisplayMock.entityValue.id,
|
|
||||||
'company',
|
|
||||||
[relationFromManyFieldDisplayMock.entityValue],
|
|
||||||
);
|
|
||||||
setRecordFieldValue(otherPersonMock.entityValue.id, 'company', [
|
|
||||||
relationFromManyFieldDisplayMock.entityValue,
|
|
||||||
]);
|
|
||||||
setRecordFieldValue(
|
|
||||||
relationFromManyFieldDisplayMock.relationFieldValue.id,
|
|
||||||
'company',
|
|
||||||
relationFromManyFieldDisplayMock.relationFieldValue,
|
|
||||||
);
|
|
||||||
}, [setEntity, setRelationEntity, setRecordFieldValue]);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const meta: Meta = {
|
|
||||||
title: 'UI/Data/Field/Display/RelationFromManyFieldDisplay',
|
|
||||||
decorators: [
|
|
||||||
MemoryRouterDecorator,
|
|
||||||
ChipGeneratorsDecorator,
|
|
||||||
(Story) => (
|
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<FieldContext.Provider
|
|
||||||
value={{
|
|
||||||
recordId: relationFromManyFieldDisplayMock.recordId,
|
|
||||||
isLabelIdentifier: false,
|
|
||||||
fieldDefinition: {
|
|
||||||
...relationFromManyFieldDisplayMock.fieldDefinition,
|
|
||||||
} as unknown as FieldDefinition<FieldMetadata>,
|
|
||||||
isReadOnly: false,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RelationFieldValueSetterEffect />
|
|
||||||
<Story />
|
|
||||||
</FieldContext.Provider>
|
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
),
|
|
||||||
ComponentDecorator,
|
|
||||||
],
|
|
||||||
component: RelationFromManyFieldDisplay,
|
|
||||||
argTypes: { value: { control: 'date' } },
|
|
||||||
args: { fieldValue: fieldValue },
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
|
|
||||||
type Story = StoryObj<typeof RelationFromManyFieldDisplay>;
|
|
||||||
|
|
||||||
export const Default: Story = {};
|
|
||||||
|
|
||||||
// TODO: optimize this component once we have morph many
|
|
||||||
export const Performance = getProfilingStory({
|
|
||||||
componentName: 'RelationFromManyFieldDisplay',
|
|
||||||
averageThresholdInMs: 1,
|
|
||||||
numberOfRuns: 20,
|
|
||||||
numberOfTestsPerRun: 100,
|
|
||||||
});
|
|
||||||
@ -1,13 +1,13 @@
|
|||||||
import { isNonEmptyString } from '@sniptt/guards';
|
|
||||||
import { useContext } from 'react';
|
|
||||||
|
|
||||||
import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext';
|
import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext';
|
||||||
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
||||||
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
||||||
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
|
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
|
||||||
import { useRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { isFieldActor } from '@/object-record/record-field/types/guards/isFieldActor';
|
import { isFieldActor } from '@/object-record/record-field/types/guards/isFieldActor';
|
||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export const useChipFieldDisplay = () => {
|
|||||||
? fieldDefinition.metadata.objectMetadataNameSingular
|
? fieldDefinition.metadata.objectMetadataNameSingular
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const recordValue = useRecordValue(recordId);
|
const recordValue = useRecoilValue(recordStoreFamilyState(recordId));
|
||||||
|
|
||||||
if (!isNonEmptyString(objectNameSingular)) {
|
if (!isNonEmptyString(objectNameSingular)) {
|
||||||
throw new Error('Object metadata name singular is not a non-empty string');
|
throw new Error('Object metadata name singular is not a non-empty string');
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { recordIndexViewTypeState } from '@/object-record/record-index/states/re
|
|||||||
|
|
||||||
import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
|
import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider';
|
import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider';
|
||||||
|
|
||||||
import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect';
|
import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect';
|
||||||
@ -48,7 +47,6 @@ export const RecordIndexContainer = () => {
|
|||||||
<>
|
<>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<InformationBannerWrapper />
|
<InformationBannerWrapper />
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<SpreadsheetImportProvider>
|
<SpreadsheetImportProvider>
|
||||||
<ViewBar
|
<ViewBar
|
||||||
viewBarId={recordIndexId}
|
viewBarId={recordIndexId}
|
||||||
@ -89,7 +87,6 @@ export const RecordIndexContainer = () => {
|
|||||||
<RecordIndexBoardDataLoaderEffect recordBoardId={recordIndexId} />
|
<RecordIndexBoardDataLoaderEffect recordBoardId={recordIndexId} />
|
||||||
</StyledContainerWithPadding>
|
</StyledContainerWithPadding>
|
||||||
)}
|
)}
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hook
|
|||||||
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
@ -32,7 +32,6 @@ export const useLoadRecordIndexBoardColumn = ({
|
|||||||
recordBoardId,
|
recordBoardId,
|
||||||
columnId,
|
columnId,
|
||||||
}: UseLoadRecordIndexBoardProps) => {
|
}: UseLoadRecordIndexBoardProps) => {
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
@ -102,10 +101,7 @@ export const useLoadRecordIndexBoardColumn = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
upsertRecordsInStore(records);
|
upsertRecordsInStore(records);
|
||||||
for (const record of records) {
|
}, [records, upsertRecordsInStore]);
|
||||||
setRecordValueInContextSelector(record.id, record);
|
|
||||||
}
|
|
||||||
}, [records, upsertRecordsInStore, setRecordValueInContextSelector]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
records,
|
records,
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import { buildFindOneRecordForShowPageOperationSignature } from '@/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory';
|
import { buildFindOneRecordForShowPageOperationSignature } from '@/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
@ -19,7 +18,6 @@ export const RecordShowEffect = ({
|
|||||||
}: RecordShowEffectProps) => {
|
}: RecordShowEffectProps) => {
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
||||||
const { objectMetadataItems } = useObjectMetadataItems();
|
const { objectMetadataItems } = useObjectMetadataItems();
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
|
|
||||||
const FIND_ONE_RECORD_FOR_SHOW_PAGE_OPERATION_SIGNATURE =
|
const FIND_ONE_RECORD_FOR_SHOW_PAGE_OPERATION_SIGNATURE =
|
||||||
buildFindOneRecordForShowPageOperationSignature({
|
buildFindOneRecordForShowPageOperationSignature({
|
||||||
@ -44,10 +42,8 @@ export const RecordShowEffect = ({
|
|||||||
if (JSON.stringify(previousRecordValue) !== JSON.stringify(newRecord)) {
|
if (JSON.stringify(previousRecordValue) !== JSON.stringify(newRecord)) {
|
||||||
set(recordStoreFamilyState(recordId), newRecord);
|
set(recordStoreFamilyState(recordId), newRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
setRecordValueInContextSelector(recordId, newRecord);
|
|
||||||
},
|
},
|
||||||
[recordId, setRecordValueInContextSelector],
|
[recordId],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useContext, useEffect } from 'react';
|
|||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
@ -14,8 +14,6 @@ type RecordDetailRelationRecordsListItemEffectProps = {
|
|||||||
export const RecordDetailRelationRecordsListItemEffect = ({
|
export const RecordDetailRelationRecordsListItemEffect = ({
|
||||||
relationRecordId,
|
relationRecordId,
|
||||||
}: RecordDetailRelationRecordsListItemEffectProps) => {
|
}: RecordDetailRelationRecordsListItemEffectProps) => {
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
|
|
||||||
const { fieldDefinition } = useContext(FieldContext);
|
const { fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
const { relationObjectMetadataNameSingular } =
|
const { relationObjectMetadataNameSingular } =
|
||||||
@ -31,9 +29,8 @@ export const RecordDetailRelationRecordsListItemEffect = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDefined(record)) {
|
if (isDefined(record)) {
|
||||||
upsertRecords([record]);
|
upsertRecords([record]);
|
||||||
setRecordValueInContextSelector(record.id, record);
|
|
||||||
}
|
}
|
||||||
}, [record, upsertRecords, setRecordValueInContextSelector]);
|
}, [record, upsertRecords]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,78 +1,16 @@
|
|||||||
import { Dispatch, SetStateAction, useState } from 'react';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
import { createContext, useContextSelector } from 'use-context-selector';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
|
||||||
|
|
||||||
export type RecordFieldValue = {
|
|
||||||
[recordId: string]: {
|
|
||||||
[fieldName: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RecordFieldValueSelectorContext = createContext<
|
|
||||||
[RecordFieldValue, Dispatch<SetStateAction<RecordFieldValue>>]
|
|
||||||
>([{}, () => {}]);
|
|
||||||
|
|
||||||
export const useSetRecordValue = () => {
|
|
||||||
const setTableValue = useContextSelector(
|
|
||||||
RecordFieldValueSelectorContext,
|
|
||||||
(value) => value[1],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (recordId: string, newRecord: any) => {
|
|
||||||
setTableValue((currentTable) => ({
|
|
||||||
...currentTable,
|
|
||||||
[recordId]: newRecord,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useRecordValue = (recordId: string) => {
|
|
||||||
const tableValue = useContextSelector(
|
|
||||||
RecordFieldValueSelectorContext,
|
|
||||||
(value) => value[0]?.[recordId],
|
|
||||||
);
|
|
||||||
|
|
||||||
return tableValue as ObjectRecord | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useRecordFieldValue = <T,>(
|
export const useRecordFieldValue = <T,>(
|
||||||
recordId: string,
|
recordId: string,
|
||||||
fieldName: string,
|
fieldName: string,
|
||||||
) => {
|
) => {
|
||||||
const recordFieldValue = useContextSelector(
|
const recordFieldValue = useRecoilValue(
|
||||||
RecordFieldValueSelectorContext,
|
recordStoreFamilySelector({
|
||||||
(value) => value[0]?.[recordId]?.[fieldName],
|
recordId,
|
||||||
|
fieldName,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return recordFieldValue as T | undefined;
|
return recordFieldValue as T | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSetRecordFieldValue = () => {
|
|
||||||
const setTableValue = useContextSelector(
|
|
||||||
RecordFieldValueSelectorContext,
|
|
||||||
(value) => value[1],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (recordId: string, fieldName: string, newValue: any) => {
|
|
||||||
setTableValue((currentTable) => ({
|
|
||||||
...currentTable,
|
|
||||||
[recordId]: {
|
|
||||||
...currentTable[recordId],
|
|
||||||
[fieldName]: newValue,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RecordFieldValueSelectorContextProvider = ({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: any;
|
|
||||||
}) => (
|
|
||||||
<RecordFieldValueSelectorContext.Provider
|
|
||||||
value={useState<RecordFieldValue>({})}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</RecordFieldValueSelectorContext.Provider>
|
|
||||||
);
|
|
||||||
|
|||||||
@ -6,10 +6,6 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
|||||||
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
||||||
|
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import {
|
|
||||||
RecordFieldValueSelectorContextProvider,
|
|
||||||
useSetRecordValue,
|
|
||||||
} from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
@ -36,22 +32,14 @@ const RelationFieldValueSetterEffect = () => {
|
|||||||
recordStoreFamilyState(mockPerformance.relationRecordId),
|
recordStoreFamilyState(mockPerformance.relationRecordId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const setRecordValue = useSetRecordValue();
|
|
||||||
|
|
||||||
const [, setObjectMetadataItems] = useRecoilState(objectMetadataItemsState);
|
const [, setObjectMetadataItems] = useRecoilState(objectMetadataItemsState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setEntity(mockPerformance.entityValue);
|
setEntity(mockPerformance.entityValue);
|
||||||
setRelationEntity(mockPerformance.relationFieldValue);
|
setRelationEntity(mockPerformance.relationFieldValue);
|
||||||
|
|
||||||
setRecordValue(mockPerformance.entityValue.id, mockPerformance.entityValue);
|
|
||||||
setRecordValue(
|
|
||||||
mockPerformance.relationFieldValue.id,
|
|
||||||
mockPerformance.relationFieldValue,
|
|
||||||
);
|
|
||||||
|
|
||||||
setObjectMetadataItems(generatedMockObjectMetadataItems);
|
setObjectMetadataItems(generatedMockObjectMetadataItems);
|
||||||
}, [setEntity, setRelationEntity, setRecordValue, setObjectMetadataItems]);
|
}, [setEntity, setRelationEntity, setObjectMetadataItems]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@ -63,7 +51,6 @@ const meta: Meta = {
|
|||||||
ChipGeneratorsDecorator,
|
ChipGeneratorsDecorator,
|
||||||
(Story) => {
|
(Story) => {
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<RecordIndexContextProvider
|
<RecordIndexContextProvider
|
||||||
value={{
|
value={{
|
||||||
indexIdentifierUrl: (_recordId: string) => '',
|
indexIdentifierUrl: (_recordId: string) => '',
|
||||||
@ -151,7 +138,6 @@ const meta: Meta = {
|
|||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
</RecordTableContextProvider>
|
</RecordTableContextProvider>
|
||||||
</RecordIndexContextProvider>
|
</RecordIndexContextProvider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
ComponentDecorator,
|
ComponentDecorator,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
|
|
||||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||||
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { useSetIsRecordTableFocusActive } from '@/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableFocusActive';
|
import { useSetIsRecordTableFocusActive } from '@/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableFocusActive';
|
||||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
||||||
@ -27,8 +27,6 @@ export const useSetRecordTableData = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
onEntityCountChange,
|
onEntityCountChange,
|
||||||
}: useSetRecordTableDataProps) => {
|
}: useSetRecordTableDataProps) => {
|
||||||
const setRecordValueInContextSelector = useSetRecordValue();
|
|
||||||
|
|
||||||
const recordIndexRecordIdsByGroupFamilyState =
|
const recordIndexRecordIdsByGroupFamilyState =
|
||||||
useRecoilComponentCallbackStateV2(
|
useRecoilComponentCallbackStateV2(
|
||||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||||
@ -82,7 +80,6 @@ export const useSetRecordTableData = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
set(recordStoreFamilyState(record.id), newRecord);
|
set(recordStoreFamilyState(record.id), newRecord);
|
||||||
setRecordValueInContextSelector(record.id, newRecord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +127,6 @@ export const useSetRecordTableData = ({
|
|||||||
setRecordTableHoverPosition,
|
setRecordTableHoverPosition,
|
||||||
onEntityCountChange,
|
onEntityCountChange,
|
||||||
isRowSelectedFamilyState,
|
isRowSelectedFamilyState,
|
||||||
setRecordValueInContextSelector,
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { INLINE_CELL_HOTKEY_SCOPE_MEMOIZE_KEY } from '@/object-record/record-inline-cell/constants/InlineCellHotkeyScopeMemoizeKey';
|
import { INLINE_CELL_HOTKEY_SCOPE_MEMOIZE_KEY } from '@/object-record/record-inline-cell/constants/InlineCellHotkeyScopeMemoizeKey';
|
||||||
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
||||||
import { useRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { TitleInputHotkeyScope } from '@/ui/input/types/TitleInputHotkeyScope';
|
import { TitleInputHotkeyScope } from '@/ui/input/types/TitleInputHotkeyScope';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { Theme, withTheme } from '@emotion/react';
|
import { Theme, withTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
|
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||||
|
|
||||||
const StyledDiv = styled.div`
|
const StyledDiv = styled.div`
|
||||||
@ -33,7 +34,9 @@ const StyledEmptyText = withTheme(styled.div<{ theme: Theme }>`
|
|||||||
|
|
||||||
export const RecordTitleCellSingleTextDisplayMode = () => {
|
export const RecordTitleCellSingleTextDisplayMode = () => {
|
||||||
const { recordId, fieldDefinition } = useContext(FieldContext);
|
const { recordId, fieldDefinition } = useContext(FieldContext);
|
||||||
const recordValue = useRecordValue(recordId);
|
|
||||||
|
const recordValue = useRecoilValue(recordStoreFamilyState(recordId));
|
||||||
|
|
||||||
const isEmpty =
|
const isEmpty =
|
||||||
recordValue?.[fieldDefinition.metadata.fieldName]?.trim() === '';
|
recordValue?.[fieldDefinition.metadata.fieldName]?.trim() === '';
|
||||||
|
|
||||||
|
|||||||
@ -112,10 +112,7 @@ export const SettingsDataModelFieldPreview = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isDefined(previewRecord) ? (
|
{isDefined(previewRecord) ? (
|
||||||
<SettingsDataModelSetPreviewRecordEffect
|
<SettingsDataModelSetPreviewRecordEffect record={previewRecord} />
|
||||||
fieldName={fieldName}
|
|
||||||
record={previewRecord}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<SettingsDataModelSetFieldValueEffect
|
<SettingsDataModelSetFieldValueEffect
|
||||||
recordId={recordId}
|
recordId={recordId}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
import { settingsPreviewRecordIdState } from '@/settings/data-model/fields/preview/states/settingsPreviewRecordIdState';
|
import { settingsPreviewRecordIdState } from '@/settings/data-model/fields/preview/states/settingsPreviewRecordIdState';
|
||||||
@ -29,7 +28,6 @@ export const SettingsDataModelSetFieldValueEffect = ({
|
|||||||
fieldName,
|
fieldName,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const setRecordFieldValue = useSetRecordFieldValue();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -37,23 +35,10 @@ export const SettingsDataModelSetFieldValueEffect = ({
|
|||||||
!!upsertedPreviewRecord[fieldName]
|
!!upsertedPreviewRecord[fieldName]
|
||||||
) {
|
) {
|
||||||
setFieldValue(upsertedPreviewRecord[fieldName]);
|
setFieldValue(upsertedPreviewRecord[fieldName]);
|
||||||
setRecordFieldValue(
|
|
||||||
recordId,
|
|
||||||
fieldName,
|
|
||||||
upsertedPreviewRecord[fieldName],
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
setFieldValue(value);
|
setFieldValue(value);
|
||||||
setRecordFieldValue(recordId, fieldName, value);
|
|
||||||
}
|
}
|
||||||
}, [
|
}, [value, setFieldValue, recordId, fieldName, upsertedPreviewRecord]);
|
||||||
value,
|
|
||||||
setFieldValue,
|
|
||||||
setRecordFieldValue,
|
|
||||||
recordId,
|
|
||||||
fieldName,
|
|
||||||
upsertedPreviewRecord,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { settingsPreviewRecordIdState } from '@/settings/data-model/fields/preview/states/settingsPreviewRecordIdState';
|
import { settingsPreviewRecordIdState } from '@/settings/data-model/fields/preview/states/settingsPreviewRecordIdState';
|
||||||
@ -7,15 +6,12 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
|
|
||||||
type SettingsDataModelSetPreviewRecordEffectProps = {
|
type SettingsDataModelSetPreviewRecordEffectProps = {
|
||||||
record: ObjectRecord;
|
record: ObjectRecord;
|
||||||
fieldName: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SettingsDataModelSetPreviewRecordEffect = ({
|
export const SettingsDataModelSetPreviewRecordEffect = ({
|
||||||
record,
|
record,
|
||||||
fieldName,
|
|
||||||
}: SettingsDataModelSetPreviewRecordEffectProps) => {
|
}: SettingsDataModelSetPreviewRecordEffectProps) => {
|
||||||
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||||
const setRecordFieldValue = useSetRecordFieldValue();
|
|
||||||
|
|
||||||
const setSettingsPreviewRecordId = useSetRecoilState(
|
const setSettingsPreviewRecordId = useSetRecoilState(
|
||||||
settingsPreviewRecordIdState,
|
settingsPreviewRecordIdState,
|
||||||
@ -23,15 +19,8 @@ export const SettingsDataModelSetPreviewRecordEffect = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
upsertRecordsInStore([record]);
|
upsertRecordsInStore([record]);
|
||||||
setRecordFieldValue(record.id, fieldName, record[fieldName]);
|
|
||||||
setSettingsPreviewRecordId(record.id);
|
setSettingsPreviewRecordId(record.id);
|
||||||
}, [
|
}, [record, upsertRecordsInStore, setSettingsPreviewRecordId]);
|
||||||
record,
|
|
||||||
upsertRecordsInStore,
|
|
||||||
setRecordFieldValue,
|
|
||||||
fieldName,
|
|
||||||
setSettingsPreviewRecordId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
|
||||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SettingsUpdateDataModelObjectAboutForm } from '@/settings/data-model/object-details/components/SettingsUpdateDataModelObjectAboutForm';
|
import { SettingsUpdateDataModelObjectAboutForm } from '@/settings/data-model/object-details/components/SettingsUpdateDataModelObjectAboutForm';
|
||||||
import { SettingsDataModelObjectSettingsFormCard } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectSettingsFormCard';
|
import { SettingsDataModelObjectSettingsFormCard } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectSettingsFormCard';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
|
||||||
import { Button } from 'twenty-ui/input';
|
|
||||||
import { H2Title, IconArchive } from 'twenty-ui/display';
|
import { H2Title, IconArchive } from 'twenty-ui/display';
|
||||||
|
import { Button } from 'twenty-ui/input';
|
||||||
import { Section } from 'twenty-ui/layout';
|
import { Section } from 'twenty-ui/layout';
|
||||||
|
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||||
|
|
||||||
type ObjectSettingsProps = {
|
type ObjectSettingsProps = {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
@ -39,7 +38,6 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<StyledContentContainer>
|
<StyledContentContainer>
|
||||||
<StyledFormSection>
|
<StyledFormSection>
|
||||||
<H2Title
|
<H2Title
|
||||||
@ -63,10 +61,7 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
|||||||
</StyledFormSection>
|
</StyledFormSection>
|
||||||
<StyledFormSection>
|
<StyledFormSection>
|
||||||
<Section>
|
<Section>
|
||||||
<H2Title
|
<H2Title title={t`Danger zone`} description={t`Deactivate object`} />
|
||||||
title={t`Danger zone`}
|
|
||||||
description={t`Deactivate object`}
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
Icon={IconArchive}
|
Icon={IconArchive}
|
||||||
title={t`Deactivate`}
|
title={t`Deactivate`}
|
||||||
@ -76,6 +71,5 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
|||||||
</Section>
|
</Section>
|
||||||
</StyledFormSection>
|
</StyledFormSection>
|
||||||
</StyledContentContainer>
|
</StyledContentContainer>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SignInBackgroundMockContainer } from '@/sign-in-background-mock/components/SignInBackgroundMockContainer';
|
import { SignInBackgroundMockContainer } from '@/sign-in-background-mock/components/SignInBackgroundMockContainer';
|
||||||
import { PageBody } from '@/ui/layout/page/components/PageBody';
|
import { PageBody } from '@/ui/layout/page/components/PageBody';
|
||||||
import { PageContainer } from '@/ui/layout/page/components/PageContainer';
|
import { PageContainer } from '@/ui/layout/page/components/PageContainer';
|
||||||
@ -18,11 +17,9 @@ export const SignInBackgroundMockPage = () => {
|
|||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageHeader title="Companies" Icon={IconBuildingSkyscraper} />
|
<PageHeader title="Companies" Icon={IconBuildingSkyscraper} />
|
||||||
<PageBody>
|
<PageBody>
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<StyledTableContainer>
|
<StyledTableContainer>
|
||||||
<SignInBackgroundMockContainer />
|
<SignInBackgroundMockContainer />
|
||||||
</StyledTableContainer>
|
</StyledTableContainer>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
</PageBody>
|
</PageBody>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { RecordShowContainer } from '@/object-record/record-show/components/Reco
|
|||||||
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
||||||
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
||||||
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { PageHeaderToggleCommandMenuButton } from '@/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton';
|
import { PageHeaderToggleCommandMenuButton } from '@/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton';
|
||||||
import { PageBody } from '@/ui/layout/page/components/PageBody';
|
import { PageBody } from '@/ui/layout/page/components/PageBody';
|
||||||
import { PageContainer } from '@/ui/layout/page/components/PageContainer';
|
import { PageContainer } from '@/ui/layout/page/components/PageContainer';
|
||||||
@ -30,7 +29,6 @@ export const RecordShowPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<RecordFilterGroupsComponentInstanceContext.Provider
|
<RecordFilterGroupsComponentInstanceContext.Provider
|
||||||
value={{ instanceId: `record-show-${objectRecordId}` }}
|
value={{ instanceId: `record-show-${objectRecordId}` }}
|
||||||
>
|
>
|
||||||
@ -81,6 +79,5 @@ export const RecordShowPage = () => {
|
|||||||
</RecordSortsComponentInstanceContext.Provider>
|
</RecordSortsComponentInstanceContext.Provider>
|
||||||
</RecordFiltersComponentInstanceContext.Provider>
|
</RecordFiltersComponentInstanceContext.Provider>
|
||||||
</RecordFilterGroupsComponentInstanceContext.Provider>
|
</RecordFilterGroupsComponentInstanceContext.Provider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMe
|
|||||||
import { useUpdateOneFieldMetadataItem } from '@/object-metadata/hooks/useUpdateOneFieldMetadataItem';
|
import { useUpdateOneFieldMetadataItem } from '@/object-metadata/hooks/useUpdateOneFieldMetadataItem';
|
||||||
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
|
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
|
||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import { FIELD_NAME_MAXIMUM_LENGTH } from '@/settings/data-model/constants/FieldNameMaximumLength';
|
import { FIELD_NAME_MAXIMUM_LENGTH } from '@/settings/data-model/constants/FieldNameMaximumLength';
|
||||||
@ -161,7 +160,7 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
<>
|
||||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||||
<FormProvider {...formConfig}>
|
<FormProvider {...formConfig}>
|
||||||
<SubMenuTopBarContainer
|
<SubMenuTopBarContainer
|
||||||
@ -265,6 +264,6 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataIt
|
|||||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
|
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
|
||||||
@ -27,6 +26,8 @@ import pick from 'lodash.pick';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
import { H2Title } from 'twenty-ui/display';
|
||||||
|
import { Section } from 'twenty-ui/layout';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
@ -35,8 +36,6 @@ import { DEFAULT_ICONS_BY_FIELD_TYPE } from '~/pages/settings/data-model/constan
|
|||||||
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils';
|
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils';
|
||||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||||
import { H2Title } from 'twenty-ui/display';
|
|
||||||
import { Section } from 'twenty-ui/layout';
|
|
||||||
|
|
||||||
type SettingsDataModelNewFieldFormValues = z.infer<
|
type SettingsDataModelNewFieldFormValues = z.infer<
|
||||||
ReturnType<typeof settingsFieldFormSchema>
|
ReturnType<typeof settingsFieldFormSchema>
|
||||||
@ -200,7 +199,6 @@ export const SettingsObjectNewFieldConfigure = () => {
|
|||||||
if (!activeObjectMetadataItem) return null;
|
if (!activeObjectMetadataItem) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<FormProvider // eslint-disable-next-line react/jsx-props-no-spreading
|
<FormProvider // eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...formConfig}
|
{...formConfig}
|
||||||
>
|
>
|
||||||
@ -281,6 +279,5 @@ export const SettingsObjectNewFieldConfigure = () => {
|
|||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
|
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
|
||||||
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
|
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
|
||||||
@ -10,15 +9,15 @@ import { AppPath } from '@/types/AppPath';
|
|||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from '@lingui/core/macro';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||||
import { t } from '@lingui/core/macro';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
|
|
||||||
export const settingsDataModelFieldTypeFormSchema = z.object({
|
export const settingsDataModelFieldTypeFormSchema = z.object({
|
||||||
type: z.enum(
|
type: z.enum(
|
||||||
@ -64,7 +63,6 @@ export const SettingsObjectNewFieldSelect = () => {
|
|||||||
if (!activeObjectMetadataItem) return null;
|
if (!activeObjectMetadataItem) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<FormProvider // eslint-disable-next-line react/jsx-props-no-spreading
|
<FormProvider // eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...formMethods}
|
{...formMethods}
|
||||||
>
|
>
|
||||||
@ -90,6 +88,5 @@ export const SettingsObjectNewFieldSelect = () => {
|
|||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { RecordFiltersComponentInstanceContext } from '@/object-record/record-fi
|
|||||||
import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
|
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
|
||||||
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { RecordTableBodyContextProvider } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
import { RecordTableBodyContextProvider } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
||||||
import { RecordTableContextProvider } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { RecordTableContextProvider } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||||
@ -126,7 +125,6 @@ export const RecordTableDecorator: Decorator = (Story, context) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<RecordTableComponentInstanceContext.Provider
|
<RecordTableComponentInstanceContext.Provider
|
||||||
value={{ instanceId: recordIndexId, onColumnsChange: () => {} }}
|
value={{ instanceId: recordIndexId, onColumnsChange: () => {} }}
|
||||||
>
|
>
|
||||||
@ -161,6 +159,5 @@ export const RecordTableDecorator: Decorator = (Story, context) => {
|
|||||||
</RecordFilterGroupsComponentInstanceContext.Provider>
|
</RecordFilterGroupsComponentInstanceContext.Provider>
|
||||||
</ViewComponentInstanceContext.Provider>
|
</ViewComponentInstanceContext.Provider>
|
||||||
</RecordTableComponentInstanceContext.Provider>
|
</RecordTableComponentInstanceContext.Provider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,10 +6,6 @@ import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/uti
|
|||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import {
|
|
||||||
RecordFieldValueSelectorContextProvider,
|
|
||||||
useSetRecordValue,
|
|
||||||
} from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
@ -27,15 +23,12 @@ const RecordMockSetterEffect = ({
|
|||||||
people: ObjectRecord[];
|
people: ObjectRecord[];
|
||||||
tasks: ObjectRecord[];
|
tasks: ObjectRecord[];
|
||||||
}) => {
|
}) => {
|
||||||
const setRecordValue = useSetRecordValue();
|
|
||||||
|
|
||||||
const setRecordInStores = useRecoilCallback(
|
const setRecordInStores = useRecoilCallback(
|
||||||
({ set }) =>
|
({ set }) =>
|
||||||
(record: ObjectRecord) => {
|
(record: ObjectRecord) => {
|
||||||
set(recordStoreFamilyState(record.id), record);
|
set(recordStoreFamilyState(record.id), record);
|
||||||
setRecordValue(record.id, record);
|
|
||||||
},
|
},
|
||||||
[setRecordValue],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -130,7 +123,6 @@ export const getFieldDecorator =
|
|||||||
instanceId: 'record-field-component-instance-id',
|
instanceId: 'record-field-component-instance-id',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordFieldValueSelectorContextProvider>
|
|
||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
recordId: record.id,
|
recordId: record.id,
|
||||||
@ -150,7 +142,6 @@ export const getFieldDecorator =
|
|||||||
/>
|
/>
|
||||||
<Story />
|
<Story />
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
</RecordFieldValueSelectorContextProvider>
|
|
||||||
</RecordFieldComponentInstanceContext.Provider>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
11
yarn.lock
11
yarn.lock
@ -55579,7 +55579,6 @@ __metadata:
|
|||||||
tsx: "npm:^4.17.0"
|
tsx: "npm:^4.17.0"
|
||||||
type-fest: "npm:4.10.1"
|
type-fest: "npm:4.10.1"
|
||||||
typescript: "npm:5.3.3"
|
typescript: "npm:5.3.3"
|
||||||
use-context-selector: "npm:^2.0.0"
|
|
||||||
use-debounce: "npm:^10.0.0"
|
use-debounce: "npm:^10.0.0"
|
||||||
uuid: "npm:^9.0.0"
|
uuid: "npm:^9.0.0"
|
||||||
vite: "npm:^5.4.0"
|
vite: "npm:^5.4.0"
|
||||||
@ -56763,16 +56762,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"use-context-selector@npm:^2.0.0":
|
|
||||||
version: 2.0.0
|
|
||||||
resolution: "use-context-selector@npm:2.0.0"
|
|
||||||
peerDependencies:
|
|
||||||
react: ">=18.0.0"
|
|
||||||
scheduler: ">=0.19.0"
|
|
||||||
checksum: 10c0/4eb6054ab8996ae8b3f87f9d102e576066e5a8b9db5db2c891128ae920bd64bcdcb4e93a13bc99658ef16280929a8331fc8ac45177f4acd716c425b1bc31135a
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"use-debounce@npm:^10.0.0":
|
"use-debounce@npm:^10.0.0":
|
||||||
version: 10.0.2
|
version: 10.0.2
|
||||||
resolution: "use-debounce@npm:10.0.2"
|
resolution: "use-debounce@npm:10.0.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user