Only fetch steps and trigger for the current workflow version (#15003)

Avoid fetching full steps and trigger for versions that are not the
current version. Because those won't be used anyway. Better for
performances.

Only difficulty was for the `createDraft` mutation. I needed to return
the full created version so I can store it in cache and use it as new
`currentVersion`. Otherwise the current version is considered as
incomplete for a short time, since workflow is fetched separately from
the current version.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Thomas Trompette
2025-10-12 18:06:12 +02:00
committed by GitHub
parent 0fb2d66808
commit 7b84db4708
54 changed files with 485 additions and 259 deletions
@@ -18,6 +18,7 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { type FieldActorForInputValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
import { getCreateManyRecordsMutationResponseField } from '@/object-record/utils/getCreateManyRecordsMutationResponseField';
@@ -51,6 +52,7 @@ export const useCreateManyRecords = <
shouldRefetchAggregateQueries = true,
}: useCreateManyRecordsProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apolloCoreClient = useApolloCoreClient();
@@ -171,6 +173,7 @@ export const useCreateManyRecords = <
objectMetadataItems,
shouldMatchRootQueryFilter,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -208,6 +211,7 @@ export const useCreateManyRecords = <
shouldMatchRootQueryFilter,
checkForRecordInCache: true,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
},
})
@@ -218,6 +222,8 @@ export const useCreateManyRecords = <
objectMetadataItem,
cache: apolloCoreClient.cache,
recordToDestroy,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
});
@@ -226,6 +232,8 @@ export const useCreateManyRecords = <
objectMetadataItem,
recordsToDestroy: recordsCreatedInCache,
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
throw error;
@@ -17,6 +17,7 @@ import { useCreateOneRecordMutation } from '@/object-record/hooks/useCreateOneRe
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { computeOptimisticCreateRecordBaseRecordInput } from '@/object-record/utils/computeOptimisticCreateRecordBaseRecordInput';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
@@ -39,6 +40,7 @@ export const useCreateOneRecord = <
skipPostOptimisticEffect = false,
shouldMatchRootQueryFilter,
}: useCreateOneRecordProps) => {
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const { registerObjectOperation } = useRegisterObjectOperation();
const apolloCoreClient = useApolloCoreClient();
const [loading, setLoading] = useState(false);
@@ -123,6 +125,7 @@ export const useCreateOneRecord = <
objectMetadataItems,
shouldMatchRootQueryFilter,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
}
@@ -147,6 +150,7 @@ export const useCreateOneRecord = <
shouldMatchRootQueryFilter,
checkForRecordInCache: true,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -163,6 +167,8 @@ export const useCreateOneRecord = <
objectMetadataItem,
cache: apolloCoreClient.cache,
recordToDestroy: recordCreatedInCache,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
triggerDestroyRecordsOptimisticEffect({
@@ -170,6 +176,8 @@ export const useCreateOneRecord = <
objectMetadataItem,
recordsToDestroy: [recordCreatedInCache],
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
throw error;
@@ -13,6 +13,7 @@ import { useDeleteManyRecordsMutation } from '@/object-record/hooks/useDeleteMan
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { getDeleteManyRecordsMutationResponseField } from '@/object-record/utils/getDeleteManyRecordsMutationResponseField';
import { useRecoilValue } from 'recoil';
@@ -34,6 +35,7 @@ export const useDeleteManyRecords = ({
objectNameSingular,
}: useDeleteManyRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apiConfig = useRecoilValue(apiConfigState);
const mutationPageSize =
@@ -133,6 +135,8 @@ export const useDeleteManyRecords = ({
currentRecords: cachedRecordsNode,
updatedRecords: computedOptimisticRecordsNode,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -203,6 +207,8 @@ export const useDeleteManyRecords = ({
currentRecords: computedOptimisticRecordsNode,
updatedRecords: cachedRecordsNode,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
throw error;
@@ -13,6 +13,7 @@ import { useDeleteOneRecordMutation } from '@/object-record/hooks/useDeleteOneRe
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { getDeleteOneRecordMutationResponseField } from '@/object-record/utils/getDeleteOneRecordMutationResponseField';
import { isNull } from '@sniptt/guards';
@@ -26,6 +27,7 @@ export const useDeleteOneRecord = ({
objectNameSingular,
}: useDeleteOneRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apolloCoreClient = useApolloCoreClient();
const { objectMetadataItem } = useObjectMetadataItem({
@@ -100,6 +102,8 @@ export const useDeleteOneRecord = ({
currentRecord: cachedRecordNode,
updatedRecord: optimisticRecordNode,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -121,6 +125,8 @@ export const useDeleteOneRecord = ({
currentRecord: optimisticRecordNode,
updatedRecord: record,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
},
})
@@ -150,6 +156,8 @@ export const useDeleteOneRecord = ({
currentRecord: optimisticRecordNode,
updatedRecord: cachedRecordNode,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
throw error;
@@ -164,16 +172,17 @@ export const useDeleteOneRecord = ({
return deletedRecord.data?.[mutationResponseField] ?? null;
},
[
apolloCoreClient,
deleteOneRecordMutation,
getRecordFromCache,
mutationResponseField,
apolloCoreClient,
objectMetadataItem,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
deleteOneRecordMutation,
refetchAggregateQueries,
objectNameSingular,
registerObjectOperation,
objectNameSingular,
mutationResponseField,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
],
);
@@ -10,6 +10,7 @@ import { useDestroyManyRecordsMutation } from '@/object-record/hooks/useDestroyM
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { getDestroyManyRecordsMutationResponseField } from '@/object-record/utils/getDestroyManyRecordsMutationResponseField';
import { useRecoilValue } from 'recoil';
@@ -31,6 +32,7 @@ export const useDestroyManyRecords = ({
objectNameSingular,
}: useDestroyManyRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apiConfig = useRecoilValue(apiConfigState);
const mutationPageSize =
@@ -112,6 +114,8 @@ export const useDestroyManyRecords = ({
objectMetadataItem,
recordsToDestroy: cachedRecords,
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
},
})
@@ -123,6 +127,7 @@ export const useDestroyManyRecords = ({
recordsToCreate: cachedRecords,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
throw error;
@@ -9,6 +9,7 @@ import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordF
import { useDestroyOneRecordMutation } from '@/object-record/hooks/useDestroyOneRecordMutation';
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { getDestroyOneRecordMutationResponseField } from '@/object-record/utils/getDestroyOneRecordMutationResponseField';
import { capitalize, isDefined } from 'twenty-shared/utils';
@@ -21,6 +22,7 @@ export const useDestroyOneRecord = ({
objectNameSingular,
}: useDestroyOneRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apolloCoreClient = useApolloCoreClient();
@@ -67,6 +69,8 @@ export const useDestroyOneRecord = ({
objectMetadataItem,
recordsToDestroy: [cachedRecord],
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
},
})
@@ -78,6 +82,7 @@ export const useDestroyOneRecord = ({
recordsToCreate: [originalRecord],
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -91,15 +96,16 @@ export const useDestroyOneRecord = ({
return deletedRecord.data?.[mutationResponseField] ?? null;
},
[
getRecordFromCache,
apolloCoreClient,
destroyOneRecordMutation,
getRecordFromCache,
mutationResponseField,
objectMetadataItem,
objectNameSingular,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
registerObjectOperation,
objectMetadataItem,
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
],
);
@@ -17,7 +17,7 @@ export const useLoadSelectedRecordsInContextStore = ({
objectRecordIds,
objectMetadataItemId,
}: UseLoadSelectedRecordsInContextStoreProps) => {
const { upsertRecords } = useUpsertRecordsInStore();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const { findManyRecordsLazy } = useLazyFindManyRecords({
objectNameSingular,
@@ -57,10 +57,15 @@ export const useLoadSelectedRecordsInContextStore = ({
const { records } = await findManyRecordsLazy();
upsertRecords(records ?? []);
upsertRecordsInStore(records ?? []);
};
},
[objectRecordIds, objectMetadataItemId, findManyRecordsLazy, upsertRecords],
[
objectRecordIds,
objectMetadataItemId,
findManyRecordsLazy,
upsertRecordsInStore,
],
);
return {
@@ -116,14 +116,14 @@ export const useMergeManyRecords = <
}
},
[
apolloCoreClient,
findDuplicateRecordsQuery,
findOneRecordQuery,
mergeManyRecordsMutation,
objectMetadataItem.namePlural,
refetchAggregateQueries,
apolloCoreClient,
mergeManyRecordsMutation,
findOneRecordQuery,
findDuplicateRecordsQuery,
registerObjectOperation,
objectNameSingular,
refetchAggregateQueries,
],
);
@@ -11,6 +11,7 @@ import { DEFAULT_MUTATION_BATCH_SIZE } from '@/object-record/constants/DefaultMu
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useRestoreManyRecordsMutation } from '@/object-record/hooks/useRestoreManyRecordsMutation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { getRestoreManyRecordsMutationResponseField } from '@/object-record/utils/getRestoreManyRecordsMutationResponseField';
import { useRecoilValue } from 'recoil';
@@ -32,6 +33,7 @@ export const useRestoreManyRecords = ({
objectNameSingular,
}: useRestoreManyRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apiConfig = useRecoilValue(apiConfigState);
@@ -122,6 +124,8 @@ export const useRestoreManyRecords = ({
currentRecord: cachedRecordWithConnection,
updatedRecord: optimisticRecordWithConnection,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
});
@@ -182,6 +186,8 @@ export const useRestoreManyRecords = ({
currentRecord: optimisticRecordWithConnection,
updatedRecord: cachedRecordWithConnection,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
});
@@ -13,6 +13,7 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
import { getUpdateOneRecordMutationResponseField } from '@/object-record/utils/getUpdateOneRecordMutationResponseField';
@@ -38,6 +39,7 @@ export const useUpdateOneRecord = <
recordGqlFields,
}: useUpdateOneRecordProps) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const apolloCoreClient = useApolloCoreClient();
const { objectMetadataItem } = useObjectMetadataItem({
@@ -138,6 +140,8 @@ export const useUpdateOneRecord = <
currentRecord: cachedRecordWithConnection,
updatedRecord: optimisticRecordWithConnection,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -167,6 +171,8 @@ export const useUpdateOneRecord = <
currentRecord: computedOptimisticRecord,
updatedRecord: record,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
},
})
@@ -213,6 +219,8 @@ export const useUpdateOneRecord = <
currentRecord: optimisticRecordWithConnection,
updatedRecord: cachedRecordWithConnection,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
throw error;
@@ -11,6 +11,8 @@ import { type RecordGqlFields } from '@/object-record/graphql/record-gql-fields/
import { generateDepthRecordGqlFieldsFromObject } from '@/object-record/graphql/record-gql-fields/utils/generateDepthRecordGqlFieldsFromObject';
import { generateDepthRecordGqlFieldsFromRecord } from '@/object-record/graphql/record-gql-fields/utils/generateDepthRecordGqlFieldsFromRecord';
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
import { getUpdateOneRecordMutationResponseField } from '@/object-record/utils/getUpdateOneRecordMutationResponseField';
@@ -29,6 +31,8 @@ type UpdateOneRecordArgs<UpdatedObjectRecord> = {
};
export const useUpdateOneRecordV2 = () => {
const apolloCoreClient = useApolloCoreClient();
const { upsertRecordsInStore } = useUpsertRecordsInStore();
const { registerObjectOperation } = useRegisterObjectOperation();
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
@@ -133,6 +137,8 @@ export const useUpdateOneRecordV2 = () => {
currentRecord: cachedRecordWithConnection,
updatedRecord: optimisticRecordWithConnection,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
}
@@ -171,6 +177,8 @@ export const useUpdateOneRecordV2 = () => {
currentRecord: computedOptimisticRecord,
updatedRecord: record,
objectMetadataItems,
objectPermissionsByObjectMetadataId,
upsertRecordsInStore,
});
},
})
@@ -217,11 +225,17 @@ export const useUpdateOneRecordV2 = () => {
currentRecord: optimisticRecordWithConnection,
updatedRecord: cachedRecordWithConnection,
objectMetadataItems,
upsertRecordsInStore,
objectPermissionsByObjectMetadataId,
});
throw error;
});
registerObjectOperation(objectMetadataItem.nameSingular, {
type: 'update-one',
result: { updatedRecord, updateInput: updateOneRecordInput },
});
return updatedRecord?.data?.[mutationResponseField] ?? null;
};