style(frontend): Prettier config + one-time repo-wide format pass
Prettier 3 (pinned), printWidth 100, double quotes — chosen to match the existing hand-formatting and minimise reflow. This commit is ONLY the mechanical format pass (`prettier --write`) plus the config/ignore/scripts, isolated so it never pollutes a feature diff. Verified behaviour-neutral: typecheck, eslint (0 errors), and vitest all green before and after. See .git-blame-ignore-revs — `git blame` skips this sha.
This commit is contained in:
@@ -58,7 +58,13 @@ function statusKey(job: SchedulerJob): keyof typeof DOT_CLASS {
|
||||
return "idle";
|
||||
}
|
||||
|
||||
function StatusDot({ k, withTooltip = true }: { k: keyof typeof DOT_CLASS; withTooltip?: boolean }) {
|
||||
function StatusDot({
|
||||
k,
|
||||
withTooltip = true,
|
||||
}: {
|
||||
k: keyof typeof DOT_CLASS;
|
||||
withTooltip?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const dot = <span className={`inline-block w-2.5 h-2.5 rounded-full shrink-0 ${DOT_CLASS[k]}`} />;
|
||||
return withTooltip ? <Tooltip hint={t(`scheduler.dot.${k}`)}>{dot}</Tooltip> : dot;
|
||||
@@ -101,7 +107,10 @@ function JobProgress({ p }: { p: SchedulerJob["progress"] }) {
|
||||
</div>
|
||||
<div className="h-1.5 rounded-full bg-border overflow-hidden">
|
||||
{pct != null ? (
|
||||
<div className="h-full rounded-full bg-accent transition-[width]" style={{ width: `${pct}%` }} />
|
||||
<div
|
||||
className="h-full rounded-full bg-accent transition-[width]"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
) : (
|
||||
// Indeterminate: total unknown, so a slim moving sliver instead of a fill.
|
||||
<div className="h-full w-1/3 rounded-full bg-accent animate-pulse" />
|
||||
@@ -164,10 +173,19 @@ function JobRow({
|
||||
className="w-16 bg-card border border-border rounded px-1.5 py-0.5 text-xs outline-none focus:border-accent"
|
||||
/>
|
||||
<span className="text-muted text-xs">{t("scheduler.minutes")}</span>
|
||||
<button onClick={save} disabled={saving} className="text-emerald-400 hover:opacity-80 disabled:opacity-50" aria-label={t("common.save")}>
|
||||
<button
|
||||
onClick={save}
|
||||
disabled={saving}
|
||||
className="text-emerald-400 hover:opacity-80 disabled:opacity-50"
|
||||
aria-label={t("common.save")}
|
||||
>
|
||||
<Check className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<button onClick={() => setEditing(false)} className="text-muted hover:text-fg" aria-label={t("common.cancel")}>
|
||||
<button
|
||||
onClick={() => setEditing(false)}
|
||||
className="text-muted hover:text-fg"
|
||||
aria-label={t("common.cancel")}
|
||||
>
|
||||
<X className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
</span>
|
||||
@@ -272,7 +290,9 @@ function MaintenanceSettings({
|
||||
</button>
|
||||
</div>
|
||||
<div className="text-[11px] text-muted mt-1.5">
|
||||
{t("scheduler.maintenance.batchNote", { default: m.revalidate_batch_default.toLocaleString() })}
|
||||
{t("scheduler.maintenance.batchNote", {
|
||||
default: m.revalidate_batch_default.toLocaleString(),
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -296,7 +316,13 @@ function Stat({
|
||||
<div className="flex items-center gap-2 text-muted text-xs">
|
||||
<Icon className="w-4 h-4 shrink-0" />
|
||||
<Tooltip hint={hint ?? ""}>
|
||||
<span className={hint ? "underline decoration-dotted decoration-muted/40 underline-offset-4 cursor-help" : ""}>
|
||||
<span
|
||||
className={
|
||||
hint
|
||||
? "underline decoration-dotted decoration-muted/40 underline-offset-4 cursor-help"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</Tooltip>
|
||||
@@ -365,14 +391,20 @@ export default function Scheduler() {
|
||||
const runMut = useMutation({
|
||||
mutationFn: (jobId: string) => api.runSchedulerJob(jobId),
|
||||
onSuccess: (_d, jobId) => {
|
||||
notify({ level: "success", message: t("scheduler.triggered", { job: t(`scheduler.jobs.${jobId}`, jobId) }) });
|
||||
notify({
|
||||
level: "success",
|
||||
message: t("scheduler.triggered", { job: t(`scheduler.jobs.${jobId}`, jobId) }),
|
||||
});
|
||||
qc.invalidateQueries({ queryKey: ["scheduler"] });
|
||||
},
|
||||
});
|
||||
const runAllMut = useMutation({
|
||||
mutationFn: () => api.runAllSchedulerJobs(),
|
||||
onSuccess: (res) => {
|
||||
notify({ level: "success", message: t("scheduler.triggeredAll", { count: res.started.length }) });
|
||||
notify({
|
||||
level: "success",
|
||||
message: t("scheduler.triggeredAll", { count: res.started.length }),
|
||||
});
|
||||
qc.invalidateQueries({ queryKey: ["scheduler"] });
|
||||
},
|
||||
});
|
||||
@@ -390,10 +422,8 @@ export default function Scheduler() {
|
||||
},
|
||||
});
|
||||
|
||||
if (q.isLoading && !data)
|
||||
return <div className="p-8 text-muted">{t("scheduler.loading")}</div>;
|
||||
if (!data)
|
||||
return <div className="p-8 text-muted">{t("common.somethingWrong")}</div>;
|
||||
if (q.isLoading && !data) return <div className="p-8 text-muted">{t("scheduler.loading")}</div>;
|
||||
if (!data) return <div className="p-8 text-muted">{t("common.somethingWrong")}</div>;
|
||||
|
||||
const quotaPct = data.quota.daily_budget
|
||||
? Math.min(100, Math.round((data.quota.used_today / data.quota.daily_budget) * 100))
|
||||
@@ -472,7 +502,9 @@ export default function Scheduler() {
|
||||
|
||||
{/* Jobs */}
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.jobsTitle")}</div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">
|
||||
{t("scheduler.jobsTitle")}
|
||||
</div>
|
||||
<StatusLegend />
|
||||
<div className="space-y-1.5">
|
||||
{data.jobs.map((job) => (
|
||||
@@ -490,7 +522,9 @@ export default function Scheduler() {
|
||||
|
||||
{/* Queue */}
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.queueTitle")}</div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">
|
||||
{t("scheduler.queueTitle")}
|
||||
</div>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
|
||||
<Stat
|
||||
icon={Database}
|
||||
@@ -527,7 +561,9 @@ export default function Scheduler() {
|
||||
|
||||
{/* Quota */}
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.quotaTitle")}</div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">
|
||||
{t("scheduler.quotaTitle")}
|
||||
</div>
|
||||
<div className="glass-card rounded-xl p-4">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<Gauge className="w-4 h-4 text-muted shrink-0" />
|
||||
@@ -557,7 +593,9 @@ export default function Scheduler() {
|
||||
|
||||
{/* Maintenance settings */}
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.maintenance.title")}</div>
|
||||
<div className="text-xs uppercase tracking-wide text-muted mb-2">
|
||||
{t("scheduler.maintenance.title")}
|
||||
</div>
|
||||
<MaintenanceSettings
|
||||
m={data.maintenance}
|
||||
onSave={(batch) => batchMut.mutate(batch)}
|
||||
|
||||
Reference in New Issue
Block a user