Register chart visibility toggle governance

This commit is contained in:
rcourtman
2026-06-12 14:11:59 +01:00
parent c5afa2e52f
commit 40af69bdb8
3 changed files with 90 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`.
Chart visibility display actions are registry-backed too.
`ChartVisibilityToggleButton` owns the `Show charts` / `Hide charts` label,
pressed-state, title, icon, and toolbar action styling for summary-bearing
filter surfaces. Pages must compose that primitive instead of recreating local
chart visibility buttons or one-option segmented controls.
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.
@@ -240,6 +240,21 @@
"scripts/shared-template-audit.mjs"
]
},
{
"id": "chart-visibility-toggle-button",
"category": "display-toggle",
"summary": "Summary-bearing filter surfaces must compose ChartVisibilityToggleButton for chart show/hide display actions instead of recreating one-off chart toggle buttons.",
"canonical": {
"path": "src/components/shared/FilterToolbar.tsx",
"export": "ChartVisibilityToggleButton"
},
"requiredConsumers": [{ "path": "src/components/Workloads/WorkloadsFilter.tsx" }],
"proof": [
"src/components/shared/SharedPrimitives.guardrails.test.ts",
"src/components/shared/FilterToolbar.test.tsx",
"scripts/shared-template-audit.mjs"
]
},
{
"id": "grouped-table-mode-segmented-control",
"category": "table-mode-control",
@@ -353,6 +368,25 @@
"scripts/shared-template-audit.mjs"
]
},
{
"id": "chart-visibility-local-toggle-labels",
"category": "display-toggle",
"summary": "Summary-bearing surfaces must not copy the Show charts / Hide charts display-toggle labels owned by ChartVisibilityToggleButton.",
"canonical": {
"path": "src/components/shared/FilterToolbar.tsx",
"export": "ChartVisibilityToggleButton"
},
"scopes": ["src/components/Workloads", "src/features", "src/pages"],
"extensions": [".tsx"],
"allPatterns": ["Show charts", "Hide charts"],
"legacyReason": "Retired migration debt. Chart visibility display actions must use ChartVisibilityToggleButton; local show/hide chart toggle copies are not allowed.",
"allowedPaths": [],
"ignoredPaths": ["src/components/Workloads/__tests__/WorkloadsFilter.test.tsx"],
"proof": [
"src/components/shared/SharedPrimitives.guardrails.test.ts",
"scripts/shared-template-audit.mjs"
]
},
{
"id": "grouped-table-mode-local-segmented-control",
"category": "table-mode-control",
@@ -15,6 +15,7 @@ import dialogSource from '@/components/shared/Dialog.tsx?raw';
import dialogModelSource from '@/components/shared/dialogModel.ts?raw';
import filterButtonGroupSource from '@/components/shared/FilterButtonGroup.tsx?raw';
import filterButtonGroupModelSource from '@/components/shared/filterButtonGroupModel.ts?raw';
import filterToolbarSource from '@/components/shared/FilterToolbar.tsx?raw';
import filterOptionPresentationSource from '@/components/shared/filterOptionPresentation.ts?raw';
import formSelectSource from '@/components/shared/FormSelect.tsx?raw';
import helpIconSource from '@/components/shared/HelpIcon.tsx?raw';
@@ -597,6 +598,56 @@ describe('shared primitive guardrails', () => {
}
});
it('keeps chart visibility display actions on the shared toolbar toggle', () => {
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[];
ignoredPaths?: string[];
}>;
};
const registeredRule = registry.rules?.find(
(rule) => rule.id === 'chart-visibility-toggle-button',
);
const registeredGuard = registry.patternGuards?.find(
(guard) => guard.id === 'chart-visibility-local-toggle-labels',
);
expect(registeredRule?.canonical?.path).toBe('src/components/shared/FilterToolbar.tsx');
expect(registeredRule?.canonical?.export).toBe('ChartVisibilityToggleButton');
expect(registeredRule?.requiredConsumers?.map((consumer) => consumer.path)).toEqual([
'src/components/Workloads/WorkloadsFilter.tsx',
]);
expect(registeredGuard?.canonical?.path).toBe('src/components/shared/FilterToolbar.tsx');
expect(registeredGuard?.canonical?.export).toBe('ChartVisibilityToggleButton');
expect(registeredGuard?.allPatterns).toEqual(['Show charts', 'Hide charts']);
expect(registeredGuard?.allowedPaths ?? []).toHaveLength(0);
expect(registeredGuard?.ignoredPaths).toEqual([
'src/components/Workloads/__tests__/WorkloadsFilter.test.tsx',
]);
expect(registeredGuard?.scopes).toEqual(
expect.arrayContaining(['src/components/Workloads', 'src/features', 'src/pages']),
);
expect(filterToolbarSource).toContain('export const ChartVisibilityToggleButton');
expect(filterToolbarSource).toContain("local.collapsed ? 'Show charts' : 'Hide charts'");
expect(filterToolbarSource).toContain('active={!local.collapsed}');
expect(filterToolbarSource).toContain('aria-pressed={!local.collapsed}');
expect(filterToolbarSource).toContain('title={label()}');
expect(workloadsFilterSource).toContain('ChartVisibilityToggleButton');
expect(workloadsFilterSource).not.toContain('Show charts');
expect(workloadsFilterSource).not.toContain('Hide charts');
});
it('keeps grouped/list table-mode controls on one shared presentation contract', () => {
const registry = JSON.parse(sharedTemplateRegistrySource) as {
rules?: Array<{