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:
2026-07-21 02:26:40 +02:00
parent 04ecd8b3a7
commit e257e2aca0
101 changed files with 4388 additions and 2641 deletions
+54 -16
View File
@@ -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)}