Index v2 side effects (#14567)
# Introduction Honestly this implem is a mess, discussing a potential side effect handler with @weiko before the build and run that would handle each side effect per entity and operation Handling: - [ ] unique index is generated when a field is updated with the `isUnique` - [x] an index is generated when a relation is created - [x] search vector index creation on custom object creation - [x] renaming a field metadata or an object should re-create all related indexes which are composed by their namings - [x] delete object should remove any related indexes - [x] delete field should update related indexes ( if index ends up empty it should be removed ) - [ ] on object renaming that contains morph fields -> triggers update field -> trigger index recompute - [x] on update name renaming should recompute all related indexes ## TODO - [x] Integration testing - [ ] Refactor the index maps cache to be storing a `idsByObjectMetadataId` - [x] Refactor deterministic name to use order sorting - [x] Remove flat index from flat object ## What's next Will handle morph indexes in a new dedicated PR for the moment will stick to this Same for the cache improvement and uniqueness
This commit is contained in:
-1
@@ -24,6 +24,5 @@ export const ATTACHMENT_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-bd3d-4c60-8dca-571c71d4447a',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(ATTACHMENT_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const COMPANY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-b374-4779-a561-80086cb2e17f',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(COMPANY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const FAVORITE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-ab56-4e05-92a3-e2414a499860',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(FAVORITE_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const FAVORITE_FOLDER_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-7cf8-401f-8211-a9587d27fd2d',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(FAVORITE_FOLDER_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ export const getFlatObjectMetadataMock = (
|
||||
|
||||
return {
|
||||
flatFieldMetadatas: [],
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
description: 'default flat object metadata description',
|
||||
icon: 'icon',
|
||||
id: faker.string.uuid(),
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const NOTE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-0b00-45cd-b6f6-6cd806fc6804',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(NOTE_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const NOTE_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-fff0-4b44-be82-bda313884400',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(NOTETARGET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const OPPORTUNITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-9549-49dd-b2b2-883999db8938',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(OPPORTUNITY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const PERSON_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-e674-48e5-a542-72570eee7213',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(PERSON_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const PET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: 'd34e0f07-1b8c-4de0-938e-599cf05e1f7f',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(PET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const ROCKET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: 'd78ec657-74a4-4652-a350-1f44ff62970a',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(ROCKET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const TASK_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-1ba1-48ba-bc83-ef7e5990ed10',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(TASK_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const TASK_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-5a9a-44e8-95df-771cd06d0fb1',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(TASKTARGET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const TIMELINE_ACTIVITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-6736-4337-b5c4-8b39fae325a5',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(TIMELINEACTIVITY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-2
@@ -1,5 +1,4 @@
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type';
|
||||
import { type MetadataEntitiesRelationTarget } from 'src/engine/workspace-manager/workspace-migration-v2/types/metadata-entities-relation-targets.type';
|
||||
@@ -23,7 +22,6 @@ export type FlatObjectMetadata = Omit<
|
||||
ObjectMetadataRelationProperties | 'dataSourceId'
|
||||
> & {
|
||||
universalIdentifier: string;
|
||||
flatIndexMetadatas: FlatIndexMetadata[];
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
};
|
||||
|
||||
|
||||
+22
-7
@@ -5,10 +5,12 @@ import {
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
||||
import { buildDefaultFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util';
|
||||
import { buildDefaultIndexesForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-index-for-custom-object.util';
|
||||
import { buildDefaultRelationFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util';
|
||||
|
||||
type FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs =
|
||||
@@ -24,7 +26,8 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
existingFlatObjectMetadataMaps,
|
||||
}: FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs): {
|
||||
flatObjectMetadataToCreate: FlatObjectMetadata;
|
||||
relationTargetFlatFieldMetadatas: FlatFieldMetadata[];
|
||||
relationTargetFlatFieldMetadataToCreate: FlatFieldMetadata[];
|
||||
flatIndexMetadataToCreate: FlatIndexMetadata[];
|
||||
} => {
|
||||
const createObjectInput =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -41,9 +44,11 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
);
|
||||
|
||||
const objectMetadataId = v4();
|
||||
const baseCustomFlatFieldMetadatas =
|
||||
const defaultFlatFieldForCustomObjectMaps =
|
||||
buildDefaultFlatFieldMetadatasForCustomObject({
|
||||
objectMetadataId,
|
||||
flatObjectMetadata: {
|
||||
id: objectMetadataId,
|
||||
},
|
||||
workspaceId,
|
||||
});
|
||||
const createdAt = new Date();
|
||||
@@ -53,7 +58,6 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
updatedAt: createdAt,
|
||||
duplicateCriteria: null,
|
||||
description: createObjectInput.description ?? null,
|
||||
flatIndexMetadatas: [],
|
||||
icon: createObjectInput.icon ?? null,
|
||||
id: objectMetadataId,
|
||||
imageIdentifierFieldMetadataId: null,
|
||||
@@ -65,7 +69,8 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
isSearchable: true,
|
||||
isUIReadOnly: false,
|
||||
isSystem: false,
|
||||
labelIdentifierFieldMetadataId: baseCustomFlatFieldMetadatas.nameField.id,
|
||||
labelIdentifierFieldMetadataId:
|
||||
defaultFlatFieldForCustomObjectMaps.fields.nameField.id,
|
||||
labelPlural: capitalize(createObjectInput.labelPlural),
|
||||
labelSingular: capitalize(createObjectInput.labelSingular),
|
||||
namePlural: createObjectInput.namePlural,
|
||||
@@ -77,6 +82,7 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
targetTableName: 'DEPRECATED',
|
||||
workspaceId,
|
||||
};
|
||||
|
||||
const {
|
||||
standardSourceFlatFieldMetadatas,
|
||||
standardTargetFlatFieldMetadatas,
|
||||
@@ -87,12 +93,21 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
});
|
||||
|
||||
flatObjectMetadataToCreate.flatFieldMetadatas = [
|
||||
...Object.values(baseCustomFlatFieldMetadatas),
|
||||
...Object.values(defaultFlatFieldForCustomObjectMaps.fields),
|
||||
...standardSourceFlatFieldMetadatas,
|
||||
];
|
||||
|
||||
const defaultIndexesForCustomObject = buildDefaultIndexesForCustomObject({
|
||||
defaultFlatFieldForCustomObjectMaps,
|
||||
flatObjectMetadata: flatObjectMetadataToCreate,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return {
|
||||
flatObjectMetadataToCreate,
|
||||
relationTargetFlatFieldMetadatas: standardTargetFlatFieldMetadatas,
|
||||
relationTargetFlatFieldMetadataToCreate: standardTargetFlatFieldMetadatas,
|
||||
flatIndexMetadataToCreate: Object.values(
|
||||
defaultIndexesForCustomObject.indexes,
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
+21
-4
@@ -3,9 +3,11 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps.util';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -15,15 +17,20 @@ import {
|
||||
ObjectMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
|
||||
type FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs = {
|
||||
deleteObjectInput: DeleteOneObjectInput;
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatIndexMaps: FlatEntityMaps<FlatIndexMetadata>;
|
||||
};
|
||||
export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
|
||||
deleteObjectInput: rawDeleteObjectInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
}: {
|
||||
deleteObjectInput: DeleteOneObjectInput;
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
}): {
|
||||
existingFlatIndexMaps,
|
||||
// This should return an AllFlatEntityMaps
|
||||
}: FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs): {
|
||||
flatFieldMetadatasToDelete: FlatFieldMetadata[];
|
||||
flatObjectMetadataToDelete: FlatObjectMetadata;
|
||||
flatIndexToDelete: FlatIndexMetadata[];
|
||||
} => {
|
||||
const { id: objectMetadataToDeleteId } =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -61,8 +68,18 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
|
||||
},
|
||||
);
|
||||
|
||||
// We should maintain a idsByObjectMetadataId maps in the index
|
||||
const flatIndexMetadataToDelete = Object.values(
|
||||
existingFlatIndexMaps.byId,
|
||||
).filter(
|
||||
(flatIndex): flatIndex is FlatIndexMetadata =>
|
||||
isDefined(flatIndex) &&
|
||||
flatIndex.objectMetadataId === flatObjectMetadataToDelete.id,
|
||||
);
|
||||
|
||||
return {
|
||||
flatFieldMetadatasToDelete,
|
||||
flatObjectMetadataToDelete,
|
||||
flatIndexToDelete: flatIndexMetadataToDelete,
|
||||
};
|
||||
};
|
||||
|
||||
-1
@@ -17,7 +17,6 @@ export const fromObjectMetadataEntityToFlatObjectMetadata = (
|
||||
|
||||
return {
|
||||
...objectMetadataEntityWithoutRelations,
|
||||
flatIndexMetadatas: [], // TODO prastoin handle indexes
|
||||
universalIdentifier:
|
||||
objectMetadataEntityWithoutRelations.standardId ??
|
||||
objectMetadataEntityWithoutRelations.id,
|
||||
|
||||
-1
@@ -35,6 +35,5 @@ export const fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata = ({
|
||||
...rest,
|
||||
flatFieldMetadatas,
|
||||
universalIdentifier: rest.standardId ?? rest.id,
|
||||
flatIndexMetadatas: [], // prastoin TODO convert from indexMetadatas to flatIndexMetadatas
|
||||
};
|
||||
};
|
||||
|
||||
+36
-7
@@ -4,12 +4,15 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps.util';
|
||||
import { FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-object-metadata/constants/flat-object-metadata-properties-to-compare.constant';
|
||||
import { type FlatObjectMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-properties-to-compare.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { recomputeIndexAfterFlatObjectMetadataSingularNameUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/recompute-index-after-flat-object-metadata-singular-name-update.util';
|
||||
import { renameRelatedMorphFieldOnObjectNamesUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/rename-related-morph-field-on-object-names-update.util';
|
||||
import { OBJECT_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/object-metadata/constants/object-metadata-standard-overrides-properties.constant';
|
||||
import { type UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
|
||||
@@ -23,7 +26,7 @@ import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standar
|
||||
type FromUpdateObjectInputToFlatObjectMetadataArgs = {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
updateObjectInput: UpdateOneObjectInput;
|
||||
};
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
|
||||
const objectMetadataEditableProperties =
|
||||
FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE.filter(
|
||||
@@ -37,12 +40,14 @@ const objectMetadataEditableProperties =
|
||||
|
||||
type UpdatedFlatObjectAndOtherObjectFieldMetadatas = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
otherObjectFlatFieldMetadatas: FlatFieldMetadata[];
|
||||
otherObjectFlatFieldMetadataToUpdate: FlatFieldMetadata[];
|
||||
flatIndexMetadataToUpdate: FlatIndexMetadata[];
|
||||
};
|
||||
|
||||
export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
existingFlatObjectMetadataMaps,
|
||||
updateObjectInput: rawUpdateObjectInput,
|
||||
flatIndexMaps,
|
||||
}: FromUpdateObjectInputToFlatObjectMetadataArgs): UpdatedFlatObjectAndOtherObjectFieldMetadatas => {
|
||||
const { id: objectMetadataIdToUpdate } =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -102,17 +107,26 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
|
||||
return {
|
||||
flatObjectMetadata: updatedStandardFlatObjectdMetadata,
|
||||
otherObjectFlatFieldMetadatas: [],
|
||||
otherObjectFlatFieldMetadataToUpdate: [],
|
||||
flatIndexMetadataToUpdate: [],
|
||||
};
|
||||
}
|
||||
|
||||
const initialAccumulator: UpdatedFlatObjectAndOtherObjectFieldMetadatas = {
|
||||
flatObjectMetadata: flatObjectMetadataToUpdate,
|
||||
otherObjectFlatFieldMetadatas: [],
|
||||
otherObjectFlatFieldMetadataToUpdate: [],
|
||||
flatIndexMetadataToUpdate: [],
|
||||
};
|
||||
|
||||
return objectMetadataEditableProperties.reduce<UpdatedFlatObjectAndOtherObjectFieldMetadatas>(
|
||||
({ flatObjectMetadata, otherObjectFlatFieldMetadatas }, property) => {
|
||||
(
|
||||
{
|
||||
flatObjectMetadata,
|
||||
otherObjectFlatFieldMetadataToUpdate: otherObjectFlatFieldMetadatas,
|
||||
flatIndexMetadataToUpdate,
|
||||
},
|
||||
property,
|
||||
) => {
|
||||
const updatedPropertyValue = updatedEditableObjectProperties[property];
|
||||
const isPropertyUpdated =
|
||||
updatedPropertyValue !== undefined &&
|
||||
@@ -121,7 +135,8 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
if (!isPropertyUpdated) {
|
||||
return {
|
||||
flatObjectMetadata,
|
||||
otherObjectFlatFieldMetadatas,
|
||||
otherObjectFlatFieldMetadataToUpdate: otherObjectFlatFieldMetadatas,
|
||||
flatIndexMetadataToUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -129,6 +144,7 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
...flatObjectMetadata,
|
||||
[property]: updatedPropertyValue,
|
||||
};
|
||||
|
||||
const newUpdatedOtherObjectFlatFieldMetadatas =
|
||||
property === 'nameSingular' || property === 'namePlural'
|
||||
? renameRelatedMorphFieldOnObjectNamesUpdate({
|
||||
@@ -138,12 +154,25 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
})
|
||||
: [];
|
||||
|
||||
const newUpdatedFlatIndexMetadatas =
|
||||
property === 'nameSingular'
|
||||
? recomputeIndexAfterFlatObjectMetadataSingularNameUpdate({
|
||||
existingFlatObjectMetadata: flatObjectMetadataToUpdate,
|
||||
flatIndexMaps,
|
||||
updatedSingularName: updatedFlatObjectMetadata.nameSingular,
|
||||
})
|
||||
: [];
|
||||
|
||||
return {
|
||||
flatObjectMetadata: updatedFlatObjectMetadata,
|
||||
otherObjectFlatFieldMetadatas: [
|
||||
otherObjectFlatFieldMetadataToUpdate: [
|
||||
...otherObjectFlatFieldMetadatas,
|
||||
...newUpdatedOtherObjectFlatFieldMetadatas,
|
||||
],
|
||||
flatIndexMetadataToUpdate: [
|
||||
...flatIndexMetadataToUpdate,
|
||||
...newUpdatedFlatIndexMetadatas,
|
||||
],
|
||||
};
|
||||
},
|
||||
initialAccumulator,
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
|
||||
type RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs = {
|
||||
existingFlatObjectMetadata: FlatObjectMetadata;
|
||||
updatedSingularName: string;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
export const recomputeIndexAfterFlatObjectMetadataSingularNameUpdate = ({
|
||||
existingFlatObjectMetadata,
|
||||
flatIndexMaps,
|
||||
updatedSingularName,
|
||||
}: RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs): FlatIndexMetadata[] => {
|
||||
const allRelatedFlatIndexMetadata = Object.values(flatIndexMaps.byId).filter(
|
||||
(flatIndexMetadata): flatIndexMetadata is FlatIndexMetadata =>
|
||||
isDefined(flatIndexMetadata) &&
|
||||
flatIndexMetadata.objectMetadataId === existingFlatObjectMetadata.id,
|
||||
);
|
||||
|
||||
if (allRelatedFlatIndexMetadata.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const optimisticFlatObjectMetadata: FlatObjectMetadata = {
|
||||
...existingFlatObjectMetadata,
|
||||
nameSingular: updatedSingularName,
|
||||
};
|
||||
|
||||
return allRelatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatIndex,
|
||||
flatObjectMetadata: optimisticFlatObjectMetadata,
|
||||
});
|
||||
|
||||
return newIndex;
|
||||
});
|
||||
};
|
||||
+1
@@ -37,6 +37,7 @@ type RenameRelatedMorphFieldOnObjectNamesUpdateArgs = FromTo<
|
||||
> & {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
};
|
||||
// We should recompute each index here too ? YES TODO prastoin
|
||||
export const renameRelatedMorphFieldOnObjectNamesUpdate = ({
|
||||
fromFlatObjectMetadata,
|
||||
existingFlatObjectMetadataMaps,
|
||||
|
||||
Reference in New Issue
Block a user