mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-21 03:05:44 +00:00
Register grouped table mode control governance
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user