Relations many in table view (#5842)

Closes #5924.

Adding the "many" side of relations in the table view, and fixing some
issues (glitch in Multi record select, cache update after update).

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Marie
2024-06-27 11:28:03 +02:00
committed by GitHub
parent dcb709feee
commit 7eb69a78ef
82 changed files with 1531 additions and 751 deletions

View File

@ -5,17 +5,17 @@ import { FIND_ONE_CALENDAR_EVENT_OPERATION_SIGNATURE } from '@/activities/calend
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
export const RightDrawerCalendarEvent = () => {
const { setRecords } = useSetRecordInStore();
const { upsertRecords } = useUpsertRecordsInStore();
const viewableRecordId = useRecoilValue(viewableRecordIdState);
const { record: calendarEvent } = useFindOneRecord<CalendarEvent>({
objectNameSingular:
FIND_ONE_CALENDAR_EVENT_OPERATION_SIGNATURE.objectNameSingular,
objectRecordId: viewableRecordId ?? '',
recordGqlFields: FIND_ONE_CALENDAR_EVENT_OPERATION_SIGNATURE.fields,
onCompleted: (record) => setRecords([record]),
onCompleted: (record) => upsertRecords([record]),
});
if (!calendarEvent) {

View File

@ -86,14 +86,6 @@ export const ActivityEditorFields = ({
customUseUpdateOneObjectHook: useUpsertOneActivityMutation,
});
const { FieldContextProvider: ActivityTargetsContextProvider } =
useFieldContext({
objectNameSingular: CoreObjectNameSingular.Activity,
objectRecordId: activityId,
fieldMetadataName: 'activityTargets',
fieldPosition: 3,
});
return (
<StyledPropertyBox>
{activity.type === 'Task' &&
@ -112,16 +104,12 @@ export const ActivityEditorFields = ({
</AssigneeFieldContextProvider>
</>
)}
{ActivityTargetsContextProvider &&
isDefined(activityFromCache) &&
isRightDrawerAnimationCompleted && (
<ActivityTargetsContextProvider>
<ActivityTargetsInlineCell
activity={activityFromCache}
maxWidth={340}
/>
</ActivityTargetsContextProvider>
)}
{isDefined(activityFromCache) && isRightDrawerAnimationCompleted && (
<ActivityTargetsInlineCell
activity={activityFromCache}
maxWidth={340}
/>
)}
</StyledPropertyBox>
);
};

View File

@ -8,11 +8,11 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
export const useRightDrawerEmailThread = () => {
const viewableRecordId = useRecoilValue(viewableRecordIdState);
const { setRecords } = useSetRecordInStore();
const { upsertRecords } = useUpsertRecordsInStore();
const { record: thread } = useFindOneRecord<EmailThread>({
objectNameSingular: CoreObjectNameSingular.MessageThread,
@ -20,7 +20,7 @@ export const useRightDrawerEmailThread = () => {
recordGqlFields: {
id: true,
},
onCompleted: (record) => setRecords([record]),
onCompleted: (record) => upsertRecords([record]),
});
const FETCH_ALL_MESSAGES_OPERATION_SIGNATURE =

View File

@ -0,0 +1,35 @@
import { objectRecordsIdsMultiSelecComponentState } from '@/activities/states/objectRecordsIdsMultiSelectComponentState';
import { objectRecordMultiSelectCheckedRecordsIdsComponentState } from '@/object-record/record-field/states/objectRecordMultiSelectCheckedRecordsIdsComponentState';
import { objectRecordMultiSelectComponentFamilyState } from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
import { recordMultiSelectIsLoadingComponentState } from '@/object-record/record-field/states/recordMultiSelectIsLoadingComponentState';
import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
export const useObjectRecordMultiSelectScopedStates = (scopeId: string) => {
const objectRecordsIdsMultiSelectState = extractComponentState(
objectRecordsIdsMultiSelecComponentState,
scopeId,
);
const objectRecordMultiSelectCheckedRecordsIdsState = extractComponentState(
objectRecordMultiSelectCheckedRecordsIdsComponentState,
scopeId,
);
const objectRecordMultiSelectFamilyState = extractComponentFamilyState(
objectRecordMultiSelectComponentFamilyState,
scopeId,
);
const recordMultiSelectIsLoadingState = extractComponentState(
recordMultiSelectIsLoadingComponentState,
scopeId,
);
return {
objectRecordsIdsMultiSelectState,
objectRecordMultiSelectCheckedRecordsIdsState,
objectRecordMultiSelectFamilyState,
recordMultiSelectIsLoadingState,
};
};

View File

@ -1,9 +1,10 @@
import styled from '@emotion/styled';
import { isNonEmptyArray, isNull } from '@sniptt/guards';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { isNull } from '@sniptt/guards';
import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil';
import { v4 } from 'uuid';
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
import { ActivityTargetObjectRecordEffect } from '@/activities/inline-cell/components/ActivityTargetObjectRecordEffect';
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
import { Activity } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
@ -15,10 +16,17 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { useCreateManyRecordsInCache } from '@/object-record/cache/hooks/useCreateManyRecordsInCache';
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { activityTargetObjectRecordFamilyState } from '@/object-record/record-field/states/activityTargetObjectRecordFamilyState';
import { objectRecordMultiSelectCheckedRecordsIdsComponentState } from '@/object-record/record-field/states/objectRecordMultiSelectCheckedRecordsIdsComponentState';
import {
ObjectRecordAndSelected,
objectRecordMultiSelectComponentFamilyState,
} from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState';
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { MultipleObjectRecordSelect } from '@/object-record/relation-picker/components/MultipleObjectRecordSelect';
import { ObjectRecordForSelect } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
import { ActivityTargetInlineCellEditModeMultiRecordsEffect } from '@/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect';
import { MultiRecordSelect } from '@/object-record/relation-picker/components/MultiRecordSelect';
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
import { prefillRecord } from '@/object-record/utils/prefillRecord';
const StyledSelectContainer = styled.div`
@ -37,6 +45,7 @@ export const ActivityTargetInlineCellEditMode = ({
activityTargetWithTargetRecords,
}: ActivityTargetInlineCellEditModeProps) => {
const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState);
const relationPickerScopeId = `relation-picker-${activity.id}`;
const selectedTargetObjectIds = activityTargetWithTargetRecords.map(
(activityTarget) => ({
@ -74,109 +83,181 @@ export const ActivityTargetInlineCellEditMode = ({
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
});
const handleSubmit = async (selectedRecords: ObjectRecordForSelect[]) => {
closeEditableField();
const handleSubmit = useRecoilCallback(
({ snapshot }) =>
async () => {
const activityTargetsAfterUpdate =
activityTargetWithTargetRecords.filter((activityTarget) => {
const record = snapshot
.getLoadable(
objectRecordMultiSelectComponentFamilyState({
scopeId: relationPickerScopeId,
familyKey: activityTarget.targetObject.id,
}),
)
.getValue() as ObjectRecordAndSelected;
const activityTargetsToDelete = activityTargetWithTargetRecords.filter(
(activityTargetObjectRecord) =>
!selectedRecords.some(
(selectedRecord) =>
selectedRecord.recordIdentifier.id ===
activityTargetObjectRecord.targetObject.id,
),
);
return record.selected;
});
setActivityFromStore((currentActivity) => {
if (isNull(currentActivity)) {
return null;
}
const selectedTargetObjectsToCreate = selectedRecords.filter(
(selectedRecord) =>
!activityTargetWithTargetRecords.some(
(activityTargetWithTargetRecord) =>
activityTargetWithTargetRecord.targetObject.id ===
selectedRecord.recordIdentifier.id,
),
);
const existingActivityTargets = activityTargetWithTargetRecords.map(
(activityTargetObjectRecord) => activityTargetObjectRecord.activityTarget,
);
let activityTargetsAfterUpdate = Array.from(existingActivityTargets);
const activityTargetsToCreate = selectedTargetObjectsToCreate.map(
(selectedRecord) => {
const emptyActivityTarget = prefillRecord<ActivityTarget>({
objectMetadataItem: objectMetadataItemActivityTarget,
input: {
id: v4(),
activityId: activity.id,
activity,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
[getActivityTargetObjectFieldName({
nameSingular: selectedRecord.objectMetadataItem.nameSingular,
})]: selectedRecord.record,
[getActivityTargetObjectFieldIdName({
nameSingular: selectedRecord.objectMetadataItem.nameSingular,
})]: selectedRecord.recordIdentifier.id,
},
return {
...currentActivity,
activityTargets: activityTargetsAfterUpdate,
};
});
return emptyActivityTarget;
closeEditableField();
},
);
[
activityTargetWithTargetRecords,
closeEditableField,
relationPickerScopeId,
setActivityFromStore,
],
);
activityTargetsAfterUpdate.push(...activityTargetsToCreate);
if (isNonEmptyArray(activityTargetsToDelete)) {
activityTargetsAfterUpdate = activityTargetsAfterUpdate.filter(
(activityTarget) =>
!activityTargetsToDelete.some(
(activityTargetToDelete) =>
activityTargetToDelete.activityTarget.id === activityTarget.id,
),
);
}
if (isActivityInCreateMode) {
createManyActivityTargetsInCache(activityTargetsToCreate);
upsertActivity({
activity,
input: {
activityTargets: activityTargetsAfterUpdate,
},
});
} else {
if (activityTargetsToCreate.length > 0) {
await createManyActivityTargets(activityTargetsToCreate);
}
if (activityTargetsToDelete.length > 0) {
await deleteManyActivityTargets(
activityTargetsToDelete.map(
(activityTargetObjectRecord) =>
activityTargetObjectRecord.activityTarget.id,
),
const handleChange = useRecoilCallback(
({ snapshot, set }) =>
async (recordId: string) => {
const existingActivityTargets = activityTargetWithTargetRecords.map(
(activityTargetObjectRecord) =>
activityTargetObjectRecord.activityTarget,
);
}
}
setActivityFromStore((currentActivity) => {
if (isNull(currentActivity)) {
return null;
}
let activityTargetsAfterUpdate = Array.from(existingActivityTargets);
return {
...currentActivity,
activityTargets: activityTargetsAfterUpdate,
};
});
};
const previouslyCheckedRecordsIds = snapshot
.getLoadable(
objectRecordMultiSelectCheckedRecordsIdsComponentState({
scopeId: relationPickerScopeId,
}),
)
.getValue();
const isNewlySelected = !previouslyCheckedRecordsIds.includes(recordId);
if (isNewlySelected) {
const record = snapshot
.getLoadable(
objectRecordMultiSelectComponentFamilyState({
scopeId: relationPickerScopeId,
familyKey: recordId,
}),
)
.getValue();
if (!record) {
throw new Error(
`Could not find selected record with id ${recordId}`,
);
}
set(
objectRecordMultiSelectCheckedRecordsIdsComponentState({
scopeId: relationPickerScopeId,
}),
(prev) => [...prev, recordId],
);
const newActivityTargetId = v4();
const fieldName = getActivityTargetObjectFieldName({
nameSingular: record.objectMetadataItem.nameSingular,
});
const fieldNameWithIdSuffix = getActivityTargetObjectFieldIdName({
nameSingular: record.objectMetadataItem.nameSingular,
});
const newActivityTarget = prefillRecord<ActivityTarget>({
objectMetadataItem: objectMetadataItemActivityTarget,
input: {
id: newActivityTargetId,
activityId: activity.id,
activity,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
[fieldName]: record.record,
[fieldNameWithIdSuffix]: recordId,
},
});
activityTargetsAfterUpdate.push(newActivityTarget);
if (isActivityInCreateMode) {
createManyActivityTargetsInCache([newActivityTarget]);
upsertActivity({
activity,
input: {
activityTargets: activityTargetsAfterUpdate,
},
});
} else {
await createManyActivityTargets([newActivityTarget]);
}
set(activityTargetObjectRecordFamilyState(recordId), {
activityTargetId: newActivityTargetId,
});
} else {
const activityTargetToDeleteId = snapshot
.getLoadable(activityTargetObjectRecordFamilyState(recordId))
.getValue().activityTargetId;
if (!activityTargetToDeleteId) {
throw new Error('Could not delete this activity target.');
}
set(
objectRecordMultiSelectCheckedRecordsIdsComponentState({
scopeId: relationPickerScopeId,
}),
previouslyCheckedRecordsIds.filter((id) => id !== recordId),
);
activityTargetsAfterUpdate = activityTargetsAfterUpdate.filter(
(activityTarget) => activityTarget.id !== activityTargetToDeleteId,
);
if (isActivityInCreateMode) {
upsertActivity({
activity,
input: {
activityTargets: activityTargetsAfterUpdate,
},
});
} else {
await deleteManyActivityTargets([activityTargetToDeleteId]);
}
set(activityTargetObjectRecordFamilyState(recordId), {
activityTargetId: null,
});
}
},
[
activity,
activityTargetWithTargetRecords,
createManyActivityTargets,
createManyActivityTargetsInCache,
deleteManyActivityTargets,
isActivityInCreateMode,
objectMetadataItemActivityTarget,
relationPickerScopeId,
upsertActivity,
],
);
return (
<StyledSelectContainer>
<MultipleObjectRecordSelect
selectedObjectRecordIds={selectedTargetObjectIds}
onSubmit={handleSubmit}
/>
<RelationPickerScope relationPickerScopeId={relationPickerScopeId}>
<ActivityTargetObjectRecordEffect
activityTargetWithTargetRecords={activityTargetWithTargetRecords}
/>
<ActivityTargetInlineCellEditModeMultiRecordsEffect
selectedObjectRecordIds={selectedTargetObjectIds}
/>
<MultiRecordSelect onSubmit={handleSubmit} onChange={handleChange} />
</RelationPickerScope>
</StyledSelectContainer>
);
};

View File

@ -0,0 +1,42 @@
import { useEffect } from 'react';
import { useRecoilCallback } from 'recoil';
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
import { activityTargetObjectRecordFamilyState } from '@/object-record/record-field/states/activityTargetObjectRecordFamilyState';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const ActivityTargetObjectRecordEffect = ({
activityTargetWithTargetRecords,
}: {
activityTargetWithTargetRecords: ActivityTargetWithTargetRecord[];
}) => {
const updateActivityTargets = useRecoilCallback(
({ snapshot, set }) =>
(newActivityTargets: ActivityTargetWithTargetRecord[]) => {
for (const newActivityTarget of newActivityTargets) {
const objectRecordId = newActivityTarget.targetObject.id;
const record = snapshot
.getLoadable(activityTargetObjectRecordFamilyState(objectRecordId))
.getValue();
if (
!isDeeplyEqual(
record.activityTargetId,
newActivityTarget.activityTarget.id,
)
) {
set(activityTargetObjectRecordFamilyState(objectRecordId), {
activityTargetId: newActivityTarget.activityTarget.id,
});
}
}
},
[],
);
useEffect(() => {
updateActivityTargets(activityTargetWithTargetRecords);
}, [activityTargetWithTargetRecords, updateActivityTargets]);
return <></>;
};

View File

@ -7,6 +7,8 @@ import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTa
import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode';
import { Activity } from '@/activities/types/Activity';
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { FieldFocusContextProvider } from '@/object-record/record-field/contexts/FieldFocusContextProvider';
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
@ -41,33 +43,45 @@ export const ActivityTargetsInlineCell = ({
ActivityEditorHotkeyScope.ActivityTargets,
);
const { FieldContextProvider: ActivityTargetsContextProvider } =
useFieldContext({
objectNameSingular: CoreObjectNameSingular.Activity,
objectRecordId: activity.id,
fieldMetadataName: 'activityTargets',
fieldPosition: 3,
overridenIsFieldEmpty: activityTargetObjectRecords.length === 0,
});
return (
<RecordFieldInputScope recordFieldInputScopeId={activity?.id ?? ''}>
<FieldFocusContextProvider>
<RecordInlineCellContainer
buttonIcon={IconPencil}
customEditHotkeyScope={{
scope: ActivityEditorHotkeyScope.ActivityTargets,
}}
IconLabel={showLabel ? IconArrowUpRight : undefined}
showLabel={showLabel}
readonly={readonly}
labelWidth={fieldDefinition?.labelWidth}
editModeContent={
<ActivityTargetInlineCellEditMode
activity={activity}
activityTargetWithTargetRecords={activityTargetObjectRecords}
{ActivityTargetsContextProvider && (
<ActivityTargetsContextProvider>
<RecordInlineCellContainer
buttonIcon={IconPencil}
customEditHotkeyScope={{
scope: ActivityEditorHotkeyScope.ActivityTargets,
}}
IconLabel={showLabel ? IconArrowUpRight : undefined}
showLabel={showLabel}
readonly={readonly}
labelWidth={fieldDefinition?.labelWidth}
editModeContent={
<ActivityTargetInlineCellEditMode
activity={activity}
activityTargetWithTargetRecords={activityTargetObjectRecords}
/>
}
label="Relations"
displayModeContent={
<ActivityTargetChips
activityTargetObjectRecords={activityTargetObjectRecords}
maxWidth={maxWidth}
/>
}
/>
}
label="Relations"
displayModeContent={
<ActivityTargetChips
activityTargetObjectRecords={activityTargetObjectRecords}
maxWidth={maxWidth}
/>
}
isDisplayModeContentEmpty={activityTargetObjectRecords.length === 0}
/>
</ActivityTargetsContextProvider>
)}
</FieldFocusContextProvider>
</RecordFieldInputScope>
);

View File

@ -0,0 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectRecordsIdsMultiSelecComponentState = createComponentState<
string[]
>({
key: 'objectRecordsIdsMultiSelectComponentState',
defaultValue: [],
});

View File

@ -4,7 +4,7 @@ import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil';
import { useActivities } from '@/activities/hooks/useActivities';
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FindManyTimelineActivitiesOrderBy';
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState';
import { timelineActivitiesFammilyState } from '@/activities/timeline/states/timelineActivitiesFamilyState';
import { timelineActivitiesFamilyState } from '@/activities/timeline/states/timelineActivitiesFamilyState';
import { timelineActivitiesForGroupState } from '@/activities/timeline/states/timelineActivitiesForGroupState';
import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState';
import { Activity } from '@/activities/types/Activity';
@ -68,11 +68,11 @@ export const TimelineQueryEffect = ({
(newActivities: Activity[]) => {
for (const newActivity of newActivities) {
const currentActivity = snapshot
.getLoadable(timelineActivitiesFammilyState(newActivity.id))
.getLoadable(timelineActivitiesFamilyState(newActivity.id))
.getValue();
if (!isDeeplyEqual(newActivity, currentActivity)) {
set(timelineActivitiesFammilyState(newActivity.id), newActivity);
set(timelineActivitiesFamilyState(newActivity.id), newActivity);
}
const currentActivityWithoutTarget = snapshot

View File

@ -1,10 +1,10 @@
import { Activity } from '@/activities/types/Activity';
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const timelineActivitiesFammilyState = createFamilyState<
export const timelineActivitiesFamilyState = createFamilyState<
Activity | null,
string
>({
key: 'timelineActivitiesFammilyState',
key: 'timelineActivitiesFamilyState',
defaultValue: null,
});

View File

@ -5,7 +5,7 @@ import { useOpenCalendarEventRightDrawer } from '@/activities/calendar/right-dra
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import {
formatToHumanReadableDay,
formatToHumanReadableMonth,
@ -85,7 +85,7 @@ export const EventCardCalendarEvent = ({
}: {
calendarEventId: string;
}) => {
const { setRecords } = useSetRecordInStore();
const { upsertRecords } = useUpsertRecordsInStore();
const {
record: calendarEvent,
@ -101,7 +101,7 @@ export const EventCardCalendarEvent = ({
endsAt: true,
},
onCompleted: (data) => {
setRecords([data]);
upsertRecords([data]);
},
});

View File

@ -7,7 +7,7 @@ import { EmailThreadMessage } from '@/activities/emails/types/EmailThreadMessage
import { EventCardMessageNotShared } from '@/activities/timelineActivities/rows/message/components/EventCardMessageNotShared';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { isDefined } from '~/utils/isDefined';
const StyledEventCardMessageContainer = styled.div`
@ -56,7 +56,7 @@ export const EventCardMessage = ({
messageId: string;
authorFullName: string;
}) => {
const { setRecords } = useSetRecordInStore();
const { upsertRecords } = useUpsertRecordsInStore();
const {
record: message,
@ -75,7 +75,7 @@ export const EventCardMessage = ({
},
},
onCompleted: (data) => {
setRecords([data]);
upsertRecords([data]);
},
});