feat(workspace,settings): model menu chip in the composer, compact settings panels

The workspace home's composer takes ONE Model chip (ModelMenu: model list
plus Effort) and moves AI Router / Permission / Local-New worktree into the
row under it; Settings drops the General-page cost card and export row,
PricingSettings and the empty states are compacted for settings panels.
This commit is contained in:
2026-10-02 17:49:05 +07:00
parent da1b17778c
commit fadecaddd0
23 changed files with 925 additions and 640 deletions
+50 -50
View File
@@ -392,22 +392,6 @@ export function Settings({
return (
<div className="animate-fade-in space-y-8">
{section === "general" && (
<div className="flex items-center justify-end gap-2">
<a
href={api.settings.exportData()}
download
className="inline-flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border border-border text-fg-secondary hover:text-fg-primary hover:border-border-light transition-colors"
>
<FileDown className="w-3.5 h-3.5" />
{t("exportData")}
</a>
<button onClick={load} className="btn-ghost">
<RefreshCw className="w-4 h-4" /> {t("common:refresh")}
</button>
</div>
)}
{error && (
<div className="px-4 py-2.5 bg-status-danger/10 border border-status-danger/20 rounded-lg text-sm text-status-danger">
{error}
@@ -433,35 +417,6 @@ export function Settings({
/>
</SettingsSection>
{/* Cost summary card */}
<div className="card p-6">
<div className="flex items-center justify-between flex-wrap gap-4">
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-xl bg-status-success/10 border border-status-success/20 flex items-center justify-center">
<DollarSign className="w-6 h-6 text-status-success" />
</div>
<div>
<p className="text-sm text-fg-muted">{t("common:cost.totalEstimatedCost")}</p>
<p className="text-2xl font-semibold text-fg-primary">
<Tip
raw={
totalCost !== null
? `$${totalCost.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
: undefined
}
>
{totalCost !== null ? fmtCost(animatedTotalCost) : "$-.--"}
</Tip>
</p>
</div>
</div>
<div className="text-right text-xs text-fg-muted">
<p>{t("acrossSessions")}</p>
<p>{t("basedOnUsage")}</p>
</div>
</div>
</div>
{/* ─── LANES ─── */}
<section id="lanes" className="scroll-mt-24">
<h3 className="text-sm font-medium text-fg-secondary flex items-center gap-2 mb-1">
@@ -752,13 +707,58 @@ export function Settings({
<>
{/* ─── DATA MANAGEMENT ─── */}
<section id="data" className="scroll-mt-24">
<h3 className="text-sm font-medium text-fg-secondary flex items-center gap-2 mb-1">
<Database className="w-4 h-4 text-fg-muted" />
{t("data.title")}
</h3>
<p className="text-xs text-fg-muted mb-4">{t("data.description")}</p>
<div className="mb-4 flex flex-wrap items-start justify-between gap-2">
<div>
<h3 className="text-sm font-medium text-fg-secondary flex items-center gap-2 mb-1">
<Database className="w-4 h-4 text-fg-muted" />
{t("data.title")}
</h3>
<p className="text-xs text-fg-muted">{t("data.description")}</p>
</div>
<div className="flex items-center gap-2">
<a
href={api.settings.exportData()}
download
className="inline-flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border border-border text-fg-secondary hover:text-fg-primary hover:border-border-light transition-colors"
>
<FileDown className="w-3.5 h-3.5" />
{t("exportData")}
</a>
<button onClick={load} className="btn-ghost">
<RefreshCw className="w-4 h-4" /> {t("common:refresh")}
</button>
</div>
</div>
<div className="space-y-4">
{/* Cost summary card */}
<div className="card p-6">
<div className="flex items-center justify-between flex-wrap gap-4">
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-xl bg-status-success/10 border border-status-success/20 flex items-center justify-center">
<DollarSign className="w-6 h-6 text-status-success" />
</div>
<div>
<p className="text-sm text-fg-muted">{t("common:cost.totalEstimatedCost")}</p>
<p className="text-2xl font-semibold text-fg-primary">
<Tip
raw={
totalCost !== null
? `$${totalCost.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
: undefined
}
>
{totalCost !== null ? fmtCost(animatedTotalCost) : "$-.--"}
</Tip>
</p>
</div>
</div>
<div className="text-right text-xs text-fg-muted">
<p>{t("acrossSessions")}</p>
<p>{t("basedOnUsage")}</p>
</div>
</div>
</div>
<div className="card p-5 space-y-4">
<div className="flex flex-wrap items-center justify-between gap-2">
<p className="text-xs text-fg-muted uppercase tracking-wider font-semibold flex-shrink-0">