mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-31 20:58:04 +00:00
fix(sidebar): require admin role for Schedule task and debounce search input (#1243)
The right-click Schedule task menu item and its keyboard shortcut were gated
only on isPaid, but the backend write routes under /api/scheduled-tasks
enforce requireAdmin + requirePaid on every action. Non-admin Skipper or
Admiral users would see the menu item and hit a 403 on click. The frontend
now mirrors the backend by gating Schedule task on isPaid && isAdmin so the
affordance only renders for users whose action will actually succeed.
Also adds a 120ms keystroke debounce to the sidebar search input. The
useStackListState filter rebuild was previously running on every keystroke
because <Command shouldFilter={false}> disables cmdk's own filter and the
existing 250ms timer only debounces state-invalidate events. Visible input
stays immediate via local state; the debounced emit drives the filter pass.
Adds a regression guard that /api/stacks/statuses is short-circuited by the
remote-node proxy (covers the sidebar status poll path) and updates the
sidebar feature docs to reflect the admin role requirement on Schedule task.
This commit is contained in:
@@ -11,6 +11,7 @@ function makeCtx(overrides: Partial<StackMenuCtx> = {}): StackMenuCtx {
|
||||
isBusy: false,
|
||||
isPaid: true,
|
||||
isAdmiral: false,
|
||||
isAdmin: true,
|
||||
canDelete: true,
|
||||
canEditLabels: true,
|
||||
canCreateLabels: true,
|
||||
@@ -94,6 +95,12 @@ describe('useStackMenuItems', () => {
|
||||
expect(lifecycle.items.some(i => i.id === 'schedule')).toBe(true);
|
||||
});
|
||||
|
||||
it('hides Schedule task when paid but not admin', () => {
|
||||
const { result } = renderHook(() => useStackMenuItems('web.yml', makeCtx({ isPaid: true, isAdmin: false })));
|
||||
const lifecycle = result.current.find(g => g.id === 'lifecycle');
|
||||
expect(lifecycle?.items.some(i => i.id === 'schedule')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('keeps label assignment available when !isPaid', () => {
|
||||
const { result } = renderHook(() => useStackMenuItems('web.yml', makeCtx({
|
||||
isPaid: false,
|
||||
|
||||
Reference in New Issue
Block a user