mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-12 11:47:11 +00:00
feat(fleet): open Fleet Actions tab to Community (admin-only) (#1153)
* feat(fleet): open Fleet Actions tab to Community (admin-only) Removes the requirePaid guard from the five Fleet Actions endpoints (fleet-stop, fleet-prune, match-preview, prune/estimate, bulk-assign) and drops the matching isPaid parent gate on FleetActionsTab so Community admins can run fleet-wide bulk operations. requireAdmin stays on every endpoint; operator and viewer roles still 403 on apply. Tests flipped from "403 PAID_REQUIRED on community" to positive "reachable on community + admin" assertions. Docs (fleet-actions, fleet-view, licensing, overview, stack-labels) rewritten to state the admin-role requirement once and drop the prior Skipper framing. * fix(fleet): apply audit findings from PR #1153 review - stack-labels.mdx: fix the page intro that still framed fleet label actions as "Operators on a Skipper or Admiral license". The cards are now Community + admin, so the intro reads "Admins also get a pair of fleet-wide actions". - Collapse redundant role-rule statements on the two affected pages. fleet-actions.mdx now states the admin gate once in the lead-in Note and again only in the troubleshooting accordion (the Prerequisites row was duplicative). stack-labels.mdx trims the "Limits and rules" bullet to the value-add half (label authoring is open to every role) and drops the Fleet Actions repetition. - Strip now-no-op mockTier('paid') calls from non-tier tests across the three fleet test files, plus the test-wide default in the fleet-action-card-endpoints beforeEach. Those mocks were misleading after the routes stopped consulting tier; if a future change re-adds requirePaid the tests will fail loudly instead of silently passing.
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import { Tags } from 'lucide-react';
|
||||
import { useLicense } from '@/context/LicenseContext';
|
||||
import type { FleetNode } from '@/components/FleetView/types';
|
||||
import { LabelFleetStopCard } from './cards/LabelFleetStopCard';
|
||||
import { BulkLabelAssignCard } from './cards/BulkLabelAssignCard';
|
||||
@@ -10,18 +8,12 @@ interface Props {
|
||||
}
|
||||
|
||||
export function FleetActionsTab({ nodes }: Props) {
|
||||
const { isPaid } = useLicense();
|
||||
|
||||
if (nodes.length === 0) {
|
||||
return (
|
||||
<div className="text-sm text-stat-subtitle">Add a node to the fleet to use bulk actions.</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isPaid) {
|
||||
return <EmptyState />;
|
||||
}
|
||||
|
||||
// Grid: 1 col under lg, 2 cols at lg and above. auto-rows-fr distributes
|
||||
// available height evenly across the auto-created rows, and each card uses
|
||||
// `flex flex-col h-full` (in <FleetActionCard>) with a `flex-1` body so it
|
||||
@@ -36,20 +28,3 @@ export function FleetActionsTab({ nodes }: Props) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Note: the §18.8 Community-tier "single full-width card with cyan rail + locked
|
||||
// footer (shell only, no upsell)" redesign is deferred to a follow-up PR.
|
||||
// Tracked in docs/internal/refactor/fleet-action-card-migration.md.
|
||||
function EmptyState() {
|
||||
return (
|
||||
<div className="rounded-lg border border-card-border/60 bg-card p-8 text-center">
|
||||
<div className="mx-auto mb-3 inline-flex h-10 w-10 items-center justify-center rounded-md bg-glass-highlight">
|
||||
<Tags className="h-5 w-5 text-stat-subtitle" strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 className="text-sm font-medium text-stat-value mb-1">Fleet-wide bulk actions</h3>
|
||||
<p className="text-xs text-stat-subtitle max-w-md mx-auto">
|
||||
Stop stacks across every node by label name, assign labels to many stacks at once, and reclaim Docker disk space fleet-wide. Available on Skipper and Admiral.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user