Activity as standard object (#6219)
In this PR I layout the first steps to migrate Activity to a traditional Standard objects Since this is a big transition, I'd rather split it into several deployments / PRs <img width="1512" alt="image" src="https://github.com/user-attachments/assets/012e2bbf-9d1b-4723-aaf6-269ef588b050"> --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Co-authored-by: Weiko <corentin@twenty.com> Co-authored-by: Faisal-imtiyaz123 <142205282+Faisal-imtiyaz123@users.noreply.github.com> Co-authored-by: Prateek Jain <prateekj1171998@gmail.com>
This commit is contained in:
@ -6,10 +6,13 @@ 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';
|
||||
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
|
||||
import { Note } from '@/activities/types/Note';
|
||||
import { NoteTarget } from '@/activities/types/NoteTarget';
|
||||
import { Task } from '@/activities/types/Task';
|
||||
import { TaskTarget } from '@/activities/types/TaskTarget';
|
||||
import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName';
|
||||
import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useCreateManyRecordsInCache } from '@/object-record/cache/hooks/useCreateManyRecordsInCache';
|
||||
@ -35,13 +38,17 @@ const StyledSelectContainer = styled.div`
|
||||
`;
|
||||
|
||||
type ActivityTargetInlineCellEditModeProps = {
|
||||
activity: Activity;
|
||||
activity: Task | Note;
|
||||
activityTargetWithTargetRecords: ActivityTargetWithTargetRecord[];
|
||||
activityObjectNameSingular:
|
||||
| CoreObjectNameSingular.Note
|
||||
| CoreObjectNameSingular.Task;
|
||||
};
|
||||
|
||||
export const ActivityTargetInlineCellEditMode = ({
|
||||
activity,
|
||||
activityTargetWithTargetRecords,
|
||||
activityObjectNameSingular,
|
||||
}: ActivityTargetInlineCellEditModeProps) => {
|
||||
const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState);
|
||||
const relationPickerScopeId = `relation-picker-${activity.id}`;
|
||||
@ -53,24 +60,27 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
}),
|
||||
);
|
||||
|
||||
const { createManyRecords: createManyActivityTargets } =
|
||||
useCreateManyRecords<ActivityTarget>({
|
||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||
});
|
||||
const { createManyRecords: createManyActivityTargets } = useCreateManyRecords<
|
||||
NoteTarget | TaskTarget
|
||||
>({
|
||||
objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular),
|
||||
});
|
||||
|
||||
const { deleteManyRecords: deleteManyActivityTargets } = useDeleteManyRecords(
|
||||
{
|
||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||
objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular),
|
||||
},
|
||||
);
|
||||
|
||||
const { closeInlineCell: closeEditableField } = useInlineCell();
|
||||
|
||||
const { upsertActivity } = useUpsertActivity();
|
||||
const { upsertActivity } = useUpsertActivity({
|
||||
activityObjectNameSingular,
|
||||
});
|
||||
|
||||
const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||
objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular),
|
||||
});
|
||||
|
||||
const setActivityFromStore = useSetRecoilState(
|
||||
@ -78,8 +88,8 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
);
|
||||
|
||||
const { createManyRecordsInCache: createManyActivityTargetsInCache } =
|
||||
useCreateManyRecordsInCache<ActivityTarget>({
|
||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||
useCreateManyRecordsInCache<NoteTarget | TaskTarget>({
|
||||
objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular),
|
||||
});
|
||||
|
||||
const handleSubmit = useRecoilCallback(
|
||||
@ -166,12 +176,19 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
const fieldNameWithIdSuffix = getActivityTargetObjectFieldIdName({
|
||||
nameSingular: record.objectMetadataItem.nameSingular,
|
||||
});
|
||||
const newActivityTarget = prefillRecord<ActivityTarget>({
|
||||
|
||||
const newActivityTarget = prefillRecord<NoteTarget | TaskTarget>({
|
||||
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||
input: {
|
||||
id: newActivityTargetId,
|
||||
activityId: activity.id,
|
||||
activity,
|
||||
taskId:
|
||||
activityObjectNameSingular === CoreObjectNameSingular.Task
|
||||
? activity.id
|
||||
: null,
|
||||
noteId:
|
||||
activityObjectNameSingular === CoreObjectNameSingular.Note
|
||||
? activity.id
|
||||
: null,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
[fieldName]: record.record,
|
||||
@ -186,7 +203,11 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
upsertActivity({
|
||||
activity,
|
||||
input: {
|
||||
activityTargets: activityTargetsAfterUpdate,
|
||||
[activityObjectNameSingular === CoreObjectNameSingular.Task
|
||||
? 'taskTargets'
|
||||
: activityObjectNameSingular === CoreObjectNameSingular.Note
|
||||
? 'noteTargets'
|
||||
: '']: activityTargetsAfterUpdate,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
@ -219,7 +240,11 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
upsertActivity({
|
||||
activity,
|
||||
input: {
|
||||
activityTargets: activityTargetsAfterUpdate,
|
||||
[activityObjectNameSingular === CoreObjectNameSingular.Task
|
||||
? 'taskTargets'
|
||||
: activityObjectNameSingular === CoreObjectNameSingular.Note
|
||||
? 'noteTargets'
|
||||
: '']: activityTargetsAfterUpdate,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
@ -241,6 +266,7 @@ export const ActivityTargetInlineCellEditMode = ({
|
||||
objectMetadataItemActivityTarget,
|
||||
relationPickerScopeId,
|
||||
upsertActivity,
|
||||
activityObjectNameSingular,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@ -5,8 +5,9 @@ import { IconArrowUpRight, IconPencil } from 'twenty-ui';
|
||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||
import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode';
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
||||
import { Note } from '@/activities/types/Note';
|
||||
import { Task } from '@/activities/types/Task';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
|
||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||
@ -17,10 +18,13 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
|
||||
type ActivityTargetsInlineCellProps = {
|
||||
activity: Activity;
|
||||
activity: Task | Note;
|
||||
showLabel?: boolean;
|
||||
maxWidth?: number;
|
||||
readonly?: boolean;
|
||||
activityObjectNameSingular:
|
||||
| CoreObjectNameSingular.Note
|
||||
| CoreObjectNameSingular.Task;
|
||||
};
|
||||
|
||||
export const ActivityTargetsInlineCell = ({
|
||||
@ -28,9 +32,13 @@ export const ActivityTargetsInlineCell = ({
|
||||
showLabel = true,
|
||||
maxWidth,
|
||||
readonly,
|
||||
activityObjectNameSingular,
|
||||
}: ActivityTargetsInlineCellProps) => {
|
||||
const { activityTargetObjectRecords } =
|
||||
useActivityTargetObjectRecords(activity);
|
||||
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
||||
activity,
|
||||
activityObjectNameSingular,
|
||||
);
|
||||
|
||||
const { closeInlineCell } = useInlineCell();
|
||||
|
||||
const { fieldDefinition } = useContext(FieldContext);
|
||||
@ -45,9 +53,9 @@ export const ActivityTargetsInlineCell = ({
|
||||
|
||||
const { FieldContextProvider: ActivityTargetsContextProvider } =
|
||||
useFieldContext({
|
||||
objectNameSingular: CoreObjectNameSingular.Activity,
|
||||
objectNameSingular: activityObjectNameSingular,
|
||||
objectRecordId: activity.id,
|
||||
fieldMetadataName: 'activityTargets',
|
||||
fieldMetadataName: fieldDefinition.metadata.fieldName,
|
||||
fieldPosition: 3,
|
||||
overridenIsFieldEmpty: activityTargetObjectRecords.length === 0,
|
||||
});
|
||||
@ -70,6 +78,7 @@ export const ActivityTargetsInlineCell = ({
|
||||
<ActivityTargetInlineCellEditMode
|
||||
activity={activity}
|
||||
activityTargetWithTargetRecords={activityTargetObjectRecords}
|
||||
activityObjectNameSingular={activityObjectNameSingular}
|
||||
/>
|
||||
}
|
||||
label="Relations"
|
||||
|
||||
Reference in New Issue
Block a user