feat(twenty-server): allow shouldHideEmptyGroups in app view manifest (#21370)
## Context The view **Hide empty groups** setting (`shouldHideEmptyGroups`) can be toggled in the UI, is persisted on the `View` entity, exposed in the `CreateView`/`UpdateView` GraphQL inputs, and tracked by the flat-view sync machinery — but it could **not** be set from an app's view manifest. Root cause: the field postdates the manifest plumbing (added in #16385, Dec 2025). Two spots were never updated to thread it through: - `ViewManifest` didn't declare the field. - `fromViewManifestToUniversalFlatView` hardcoded `shouldHideEmptyGroups: false`. Ref: twentyhq/core-team-issues#414 ## Changes - Add optional `shouldHideEmptyGroups?: boolean` to `ViewManifest`. - Read it in the converter (`?? false`), mirroring the existing `isCompact` handling. - Cover it in the converter unit test (default + explicit value). No migration or schema change — the column already exists, and downstream sync (`FLAT_VIEW_EDITABLE_PROPERTIES` + the universal-flat compare type) already handles it. ## Test - `npx jest from-view-manifest-to-universal-flat-view` → 5 passed - `tsgo -p tsconfig.json` (twenty-server) → no new errors - oxlint + oxfmt clean
This commit is contained in:
+3
@@ -35,6 +35,7 @@ describe('fromViewManifestToUniversalFlatView', () => {
|
||||
expect(result.icon).toBe('IconList');
|
||||
expect(result.position).toBe(0);
|
||||
expect(result.isCompact).toBe(false);
|
||||
expect(result.shouldHideEmptyGroups).toBe(false);
|
||||
expect(result.isCustom).toBe(true);
|
||||
expect(result.visibility).toBe(ViewVisibility.WORKSPACE);
|
||||
expect(result.openRecordIn).toBe(ViewOpenRecordIn.SIDE_PANEL);
|
||||
@@ -53,6 +54,7 @@ describe('fromViewManifestToUniversalFlatView', () => {
|
||||
icon: 'IconLayoutKanban',
|
||||
position: 3,
|
||||
isCompact: true,
|
||||
shouldHideEmptyGroups: true,
|
||||
visibility: ViewVisibility.UNLISTED,
|
||||
openRecordIn: ViewOpenRecordIn.RECORD_PAGE,
|
||||
},
|
||||
@@ -64,6 +66,7 @@ describe('fromViewManifestToUniversalFlatView', () => {
|
||||
expect(result.icon).toBe('IconLayoutKanban');
|
||||
expect(result.position).toBe(3);
|
||||
expect(result.isCompact).toBe(true);
|
||||
expect(result.shouldHideEmptyGroups).toBe(true);
|
||||
expect(result.visibility).toBe(ViewVisibility.UNLISTED);
|
||||
expect(result.openRecordIn).toBe(ViewOpenRecordIn.RECORD_PAGE);
|
||||
});
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ export const fromViewManifestToUniversalFlatView = ({
|
||||
viewManifest.calendarFieldMetadataUniversalIdentifier ?? null,
|
||||
mainGroupByFieldMetadataUniversalIdentifier:
|
||||
viewManifest.mainGroupByFieldMetadataUniversalIdentifier ?? null,
|
||||
shouldHideEmptyGroups: false,
|
||||
shouldHideEmptyGroups: viewManifest.shouldHideEmptyGroups ?? false,
|
||||
anyFieldFilterValue: null,
|
||||
createdByUserWorkspaceId: null,
|
||||
viewFieldUniversalIdentifiers: [],
|
||||
|
||||
@@ -74,6 +74,7 @@ export type ViewManifest = SyncableEntityOptions & {
|
||||
visibility?: ViewVisibility;
|
||||
openRecordIn?: ViewOpenRecordIn;
|
||||
mainGroupByFieldMetadataUniversalIdentifier?: string;
|
||||
shouldHideEmptyGroups?: boolean;
|
||||
kanbanAggregateOperation?: AggregateOperations;
|
||||
kanbanAggregateOperationFieldMetadataUniversalIdentifier?: string;
|
||||
calendarLayout?: ViewCalendarLayout;
|
||||
|
||||
Reference in New Issue
Block a user