Add system view fallback (#18536)

## Context
The goal is to add a "See records" button in all objects that would
redirect to that view (this will be done in a later PR). See screenshot
below.
<img width="665" height="312" alt="Screenshot 2026-03-10 at 15 54 36"
src="https://github.com/user-attachments/assets/6e23a75b-cff0-4d93-bce8-b5481b05c6f6"
/>

## Implementation
- If a view does not exist on an object, there is a **temporary**
fallback where the frontend creates the missing view as a custom view
when going over the object index page
- System objects are now surfaced but we don't want their records to be
editable, they will be readonly (mostly, all fields will be non-editable
except for their custom fields).
- We can't create a new record of a system object, some actions are also
hidden.
- The backend now rejects if you are trying to delete the last view of
an object
This commit is contained in:
Weiko
2026-03-11 13:48:02 +01:00
committed by GitHub
parent 99f885306e
commit 00c3cd1051
31 changed files with 343 additions and 37 deletions
@@ -149,6 +149,7 @@ export class FlatViewValidatorService {
flatEntityToValidate,
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
flatViewMaps: optimisticFlatViewMaps,
flatObjectMetadataMaps: optimisticFlatObjectMetadataMaps,
},
}: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.view
@@ -172,6 +173,34 @@ export class FlatViewValidatorService {
message: t`View not found`,
userFriendlyMessage: msg`View not found`,
});
return validationResult;
}
const parentObjectStillExists = isDefined(
findFlatEntityByUniversalIdentifier({
universalIdentifier: existingFlatView.objectMetadataUniversalIdentifier,
flatEntityMaps: optimisticFlatObjectMetadataMaps,
}),
);
if (parentObjectStillExists) {
const viewsForSameObject = Object.values(
optimisticFlatViewMaps.byUniversalIdentifier,
).filter(
(view) =>
isDefined(view) &&
view.objectMetadataUniversalIdentifier ===
existingFlatView.objectMetadataUniversalIdentifier,
);
if (viewsForSameObject.length <= 1) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`Cannot delete the only view for this object`,
userFriendlyMessage: msg`Cannot delete the only view for this object`,
});
}
}
return validationResult;