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:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user