Register grouped table mode control governance

This commit is contained in:
rcourtman
2026-06-12 14:06:19 +01:00
parent 77134632e2
commit c5afa2e52f
3 changed files with 75 additions and 0 deletions
@@ -2416,6 +2416,11 @@ small leading status-dot glyph used by filter options. Page and feature
surfaces must not copy the chip-dot `<span>` factory or import the legacy
`PageControls` deck for resource-list filtering; those drift checks live in
`shared-template-registry.json` and run through `shared-template-audit.mjs`.
Grouped/list table-mode controls are registry-backed as well.
`GroupedTableModeSegmentedControl` owns the shared `Group by` label,
`Grouped` / `List` labels, tooltip titles, and icons for table mode switching.
Resource surfaces must compose that primitive instead of copying grouped/list
segmented-control labels locally.
Inline detail table rows are also registry-backed. `InlineDetailTableRow`
owns the row/cell/content shell and row-click containment for platform,
workload, and infrastructure inline drawers; callers may pass row-specific
@@ -239,6 +239,20 @@
"src/components/shared/FilterBar/FilterBar.test.tsx",
"scripts/shared-template-audit.mjs"
]
},
{
"id": "grouped-table-mode-segmented-control",
"category": "table-mode-control",
"summary": "Grouped/list table-mode controls must compose GroupedTableModeSegmentedControl instead of recreating grouped/list labels, titles, or icons locally.",
"canonical": {
"path": "src/components/shared/GroupedTableModeSegmentedControl.tsx",
"export": "GroupedTableModeSegmentedControl"
},
"requiredConsumers": [{ "path": "src/components/Workloads/WorkloadsFilter.tsx" }],
"proof": [
"src/components/shared/SharedPrimitives.guardrails.test.ts",
"scripts/shared-template-audit.mjs"
]
}
],
"patternGuards": [
@@ -339,6 +353,24 @@
"scripts/shared-template-audit.mjs"
]
},
{
"id": "grouped-table-mode-local-segmented-control",
"category": "table-mode-control",
"summary": "Resource surfaces must not copy the grouped/list table-mode segmented-control labels owned by GroupedTableModeSegmentedControl.",
"canonical": {
"path": "src/components/shared/GroupedTableModeSegmentedControl.tsx",
"export": "GroupedTableModeSegmentedControl"
},
"scopes": ["src/components", "src/features"],
"extensions": [".tsx"],
"allPatterns": ["Grouped table view", "Flat list view"],
"legacyReason": "Retired migration debt. Grouped/list table-mode controls must use GroupedTableModeSegmentedControl; no local label/title copies are currently allowed.",
"allowedPaths": [],
"proof": [
"src/components/shared/SharedPrimitives.guardrails.test.ts",
"scripts/shared-template-audit.mjs"
]
},
{
"id": "filter-bar-consumer-legacy-page-controls",
"category": "filter-bar",
@@ -598,6 +598,44 @@ describe('shared primitive guardrails', () => {
});
it('keeps grouped/list table-mode controls on one shared presentation contract', () => {
const registry = JSON.parse(sharedTemplateRegistrySource) as {
rules?: Array<{
id: string;
canonical?: { path?: string; export?: string };
requiredConsumers?: Array<{ path?: string }>;
}>;
patternGuards?: Array<{
id: string;
canonical?: { path?: string; export?: string };
allPatterns?: string[];
scopes?: string[];
allowedPaths?: string[];
}>;
};
const registeredRule = registry.rules?.find(
(rule) => rule.id === 'grouped-table-mode-segmented-control',
);
const registeredGuard = registry.patternGuards?.find(
(guard) => guard.id === 'grouped-table-mode-local-segmented-control',
);
expect(registeredRule?.canonical?.path).toBe(
'src/components/shared/GroupedTableModeSegmentedControl.tsx',
);
expect(registeredRule?.canonical?.export).toBe('GroupedTableModeSegmentedControl');
expect(registeredRule?.requiredConsumers?.map((consumer) => consumer.path)).toEqual([
'src/components/Workloads/WorkloadsFilter.tsx',
]);
expect(registeredGuard?.canonical?.path).toBe(
'src/components/shared/GroupedTableModeSegmentedControl.tsx',
);
expect(registeredGuard?.canonical?.export).toBe('GroupedTableModeSegmentedControl');
expect(registeredGuard?.allPatterns).toEqual(['Grouped table view', 'Flat list view']);
expect(registeredGuard?.allowedPaths ?? []).toHaveLength(0);
expect(registeredGuard?.scopes).toEqual(
expect.arrayContaining(['src/components', 'src/features']),
);
expect(groupedTableModeSegmentedControlSource).toContain('GroupedTableModeSegmentedControl');
expect(groupedTableModeSegmentedControlSource).toContain('GROUPED_TABLE_MODE_ARIA_LABEL');
expect(groupedTableModeSegmentedControlSource).toContain(