Add is active to overridable entities and deactivation logic for page layouts (#19200)

- Replace soft-deletion (deletedAt) with isActive boolean for
overridable entities (tabs, widgets, viewFieldGroups, viewFields).
Standard entities are deactivated (isActive: false) when removed from
update payloads, while custom entities are hard-deleted.
- When a viewFieldGroup is deactivated/deleted, its viewFields are
reassigned to the next section by position (or null if none remain).
- Add isActive: true filters to viewFieldGroup and viewField API queries
so deactivated entities are excluded from responses.

Next: 
- fields-widget-upsert.service.ts should be refactored a bit
- Add restore logic
This commit is contained in:
Weiko
2026-04-02 16:50:50 +02:00
committed by GitHub
parent 67d34be7c8
commit c1e4756f9c
35 changed files with 392 additions and 286 deletions
@@ -174,6 +174,7 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
"position",
"deletedAt",
"icon",
"isActive",
"overrides",
],
"propertiesToStringify": [
@@ -190,6 +191,7 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
"universalConfiguration",
"deletedAt",
"conditionalDisplay",
"isActive",
"overrides",
],
"propertiesToStringify": [
@@ -299,6 +301,7 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
"aggregateOperation",
"viewFieldGroupUniversalIdentifier",
"deletedAt",
"isActive",
"universalOverrides",
],
"propertiesToStringify": [
@@ -310,6 +313,7 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
"name",
"position",
"isVisible",
"isActive",
"deletedAt",
"overrides",
],
@@ -373,6 +373,12 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
toCompare: true,
isOverridable: true,
},
isActive: {
toCompare: true,
toStringify: false,
universalProperty: undefined,
isOverridable: false,
},
deletedAt: {
toStringify: false,
universalProperty: undefined,
@@ -455,6 +461,12 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
toStringify: false,
universalProperty: 'viewUniversalIdentifier',
},
isActive: {
toCompare: true,
toStringify: false,
universalProperty: undefined,
isOverridable: false,
},
overrides: {
toCompare: true,
toStringify: true,
@@ -916,6 +928,12 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
universalProperty: undefined,
isOverridable: true,
},
isActive: {
toCompare: true,
toStringify: false,
universalProperty: undefined,
isOverridable: false,
},
overrides: {
toCompare: true,
toStringify: true,
@@ -966,6 +984,12 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
toStringify: false,
universalProperty: undefined,
},
isActive: {
toCompare: true,
toStringify: false,
universalProperty: undefined,
isOverridable: false,
},
overrides: {
toCompare: true,
toStringify: true,
@@ -0,0 +1,38 @@
type EntityWithApplicationIdentifier = {
applicationUniversalIdentifier: string;
};
export const splitEntitiesByRemovalStrategy = <
T extends EntityWithApplicationIdentifier,
>({
entitiesToRemove,
workspaceCustomApplicationUniversalIdentifier,
now,
}: {
entitiesToRemove: T[];
workspaceCustomApplicationUniversalIdentifier: string;
now: string;
}): {
toHardDelete: T[];
toDeactivate: (T & { isActive: false; updatedAt: string })[];
} => {
const toHardDelete: T[] = [];
const toDeactivate: (T & { isActive: false; updatedAt: string })[] = [];
for (const entity of entitiesToRemove) {
if (
entity.applicationUniversalIdentifier ===
workspaceCustomApplicationUniversalIdentifier
) {
toHardDelete.push(entity);
} else {
toDeactivate.push({
...entity,
isActive: false as const,
updatedAt: now,
});
}
}
return { toHardDelete, toDeactivate };
};