ui(onboarding): flat tab navigation + fix vertical-stacked button text
Onboarding was a 7-step linear wizard, same information hierarchy as Settings but behaving like a modal. Replace with the SettingsShell tab pattern: one row of six tabs (nodecheck / providers / company / modelpool / executionmode / mission), free navigation, per-tab completion ticks derived from the wizard's own validation rules. Sub-fixes on the same pass: - ActionButton: add whitespace-nowrap + shrink-0 so "选择" never stacks vertically on narrow containers. Global — every caller gets the correct behavior - CompanyStep: CEO Runtime Provider/Model go vertical (space-y-3 instead of grid-cols-2) so long names like "Fireworks AI" / "Kimi K2.5 Turbo Preview 0911" stay readable; workspace-path Input wrapped in min-w-0 flex-1 container so it yields, not the button - MarkdownBody: render react-markdown in chat bubbles (was plain text) i18n: added onboarding.stepsAria for the tablist label.
This commit is contained in:
1 parent
ff5e22092a
commit
c83d670050
16 files changed
+352
-60
No files matched your search
@@ -30,7 +30,7 @@ export function StatusBadge({ status }: { status: ConnectorStatus }) {
|
||||
const t = useT();
|
||||
if (status === "ready") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full bg-success-muted px-2 py-0.5 text-[11px] font-medium text-success">
|
||||
<span className="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-success-muted px-2 py-0.5 text-[11px] font-medium text-success">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-success" />
|
||||
{t("models.ready")}
|
||||
</span>
|
||||
@@ -38,7 +38,7 @@ export function StatusBadge({ status }: { status: ConnectorStatus }) {
|
||||
}
|
||||
if (status === "not_installed") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
|
||||
<span className="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-muted-foreground" />
|
||||
{t("models.notInstalled")}
|
||||
</span>
|
||||
@@ -46,7 +46,7 @@ export function StatusBadge({ status }: { status: ConnectorStatus }) {
|
||||
}
|
||||
if (status === "auth_required") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full bg-warning-muted px-2 py-0.5 text-[11px] font-medium text-warning">
|
||||
<span className="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-warning-muted px-2 py-0.5 text-[11px] font-medium text-warning">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-warning" />
|
||||
{t("models.authRequired")}
|
||||
</span>
|
||||
@@ -54,14 +54,14 @@ export function StatusBadge({ status }: { status: ConnectorStatus }) {
|
||||
}
|
||||
if (status === "detected" || (status as string) === "checking") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
|
||||
<span className="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
|
||||
<span className="h-3 w-3 animate-spin rounded-full border-[1.5px] border-muted-foreground border-t-primary" />
|
||||
{t("models.checking")}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full bg-caution-muted px-2 py-0.5 text-[11px] font-medium text-caution">
|
||||
<span className="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-caution-muted px-2 py-0.5 text-[11px] font-medium text-caution">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-caution" />
|
||||
{status.replaceAll("_", " ")}
|
||||
</span>
|
||||
@@ -153,12 +153,8 @@ export function ModelToggleList({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const enabledCount = models.filter((m) => m.enabled).length;
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-1.5 text-[12px] font-medium text-muted-foreground">
|
||||
{t("models.label")} ({t("models.enabledCount").replace("{enabled}", String(enabledCount)).replace("{total}", String(models.length))})
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
{models.map((m) => (
|
||||
<div
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useT } from "../../i18n"
|
||||
import { formatTime } from "../../lib/formatters"
|
||||
import { unwrap } from "../../lib/desktop"
|
||||
import { ActionButton, InlineNotice } from "../ui"
|
||||
import { MarkdownBody } from "../ui/MarkdownBody"
|
||||
import { describeActionError } from "./execution-utils"
|
||||
|
||||
export function TaskComments({ taskId, companyId, agents, comments, onRefresh }: {
|
||||
@@ -44,7 +45,9 @@ export function TaskComments({ taskId, companyId, agents, comments, onRefresh }:
|
||||
{agent && <span className="text-[10px] text-muted-foreground">{agent.role}</span>}
|
||||
<span className="text-[10px] text-muted-foreground">{formatTime(comment.createdAt)}</span>
|
||||
</div>
|
||||
<div className="mt-1 whitespace-pre-wrap text-[13px] text-foreground">{comment.body}</div>
|
||||
<div className="mt-1 text-[13px] text-foreground">
|
||||
<MarkdownBody body={comment.body} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in new issue
Block a user