mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-10 18:56:53 +00:00
fix(scheduler): show every Timeline lane dot and rename the Maintenance lane to Upkeep (#1618)
The Timeline lane marker lacked shrink-0, so inside the fixed 80px label column the widest labels flex-shrank their color dot to zero width. The Maintenance and Lifecycle dots collapsed and rendered as no dot at all, while the shorter labels kept theirs. Add shrink-0 so every lane dot renders at a consistent size. Maintenance was the only label wide enough to fill the 80px column on its own, which is what left its dot no room. Rename it to Upkeep so all five labels fit and align. A registry test now pins each lane's key, order, and label, and asserts every lane carries a color, so a future rewrite of the action registry cannot silently rename a lane or drop a dot color.
This commit is contained in:
@@ -621,7 +621,7 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
<div key={lane.key} className="grid grid-cols-[80px_1fr] items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className="w-1.5 h-1.5 rounded-full"
|
||||
className="w-1.5 h-1.5 rounded-full shrink-0"
|
||||
style={{ backgroundColor: lane.color }}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
@@ -373,7 +373,7 @@ describe('ScheduledOperationsView', () => {
|
||||
it('renders the five registry category lanes in the timeline view', async () => {
|
||||
render(<ScheduledOperationsView />);
|
||||
// Timeline is the default view; the lane track always renders.
|
||||
for (const lane of ['Lifecycle', 'Updates', 'Security', 'Maintenance', 'Backups']) {
|
||||
for (const lane of ['Lifecycle', 'Updates', 'Security', 'Upkeep', 'Backups']) {
|
||||
expect(await screen.findByText(lane)).toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -49,6 +49,25 @@ describe('scheduledActions registry', () => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('timeline lanes', () => {
|
||||
it('pins each lane key, order, and label so a registry rewrite cannot silently rename or reorder one', () => {
|
||||
expect(SCHEDULED_ACTION_CATEGORIES.map(lane => [lane.key, lane.label])).toEqual([
|
||||
['lifecycle', 'Lifecycle'],
|
||||
['updates', 'Updates'],
|
||||
['security', 'Security'],
|
||||
['maintenance', 'Upkeep'],
|
||||
['backups', 'Backups'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('gives every lane a non-empty color and background so its Timeline dot always renders', () => {
|
||||
for (const lane of SCHEDULED_ACTION_CATEGORIES) {
|
||||
expect(lane.color.trim()).not.toBe('');
|
||||
expect(lane.bg.trim()).not.toBe('');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('marks scan and prune as local-node actions', () => {
|
||||
expect(getActionById('scan')).toMatchObject({ requiresNode: true, nodeScope: 'local' });
|
||||
expect(getActionById('prune')).toMatchObject({ requiresNode: true, nodeScope: 'local' });
|
||||
|
||||
@@ -183,6 +183,6 @@ export const SCHEDULED_ACTION_CATEGORIES: ScheduledActionCategoryLane[] = [
|
||||
{ key: 'lifecycle', label: 'Lifecycle', color: 'var(--label-blue)', bg: 'var(--label-blue-bg)' },
|
||||
{ key: 'updates', label: 'Updates', color: 'var(--success)', bg: 'oklch(from var(--success) l c h / 0.18)' },
|
||||
{ key: 'security', label: 'Security', color: 'var(--label-purple)', bg: 'var(--label-purple-bg)' },
|
||||
{ key: 'maintenance', label: 'Maintenance', color: 'var(--warning)', bg: 'oklch(from var(--warning) l c h / 0.18)' },
|
||||
{ key: 'maintenance', label: 'Upkeep', color: 'var(--warning)', bg: 'oklch(from var(--warning) l c h / 0.18)' },
|
||||
{ key: 'backups', label: 'Backups', color: 'var(--brand)', bg: 'oklch(from var(--brand) l c h / 0.18)' },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user