diff --git a/studio/web/src/components/Field.tsx b/studio/web/src/components/Field.tsx index eb88649..7a5053e 100644 --- a/studio/web/src/components/Field.tsx +++ b/studio/web/src/components/Field.tsx @@ -642,6 +642,8 @@ function PathStringField({ return ( {/* resume_state / resume_lora:贴字段的 dropdown,按 version 分组列文件 */} @@ -669,31 +671,44 @@ function PathStringField({ } > - onChange(e.target.value)} - disabled={disabled} - aria-label={label} - title={text || undefined} - className={'ds-inp' + (kind === 'path' ? ' ds-mono' : '')} - /> - {(kind === 'path' || suffix) && ( - - {kind === 'path' && ( - - )} - {suffix} + {kind === 'path' ? ( + // input + folder button on one row, as in the mockup + + onChange(e.target.value)} + disabled={disabled} + aria-label={label} + title={text || undefined} + className="ds-inp ds-mono" + style={{ flex: 1 }} + /> + + ) : ( + onChange(e.target.value)} + disabled={disabled} + aria-label={label} + title={text || undefined} + className="ds-inp" + /> + )} + {suffix && ( + {suffix} )} ) diff --git a/studio/web/src/components/Sidebar.tsx b/studio/web/src/components/Sidebar.tsx index c7da735..915ca7c 100644 --- a/studio/web/src/components/Sidebar.tsx +++ b/studio/web/src/components/Sidebar.tsx @@ -309,7 +309,11 @@ function ProjectStepperNav({ pid, activeVid, currentStep, version, collapsed, in const overviewActive = inRoute && currentStep === null // ADR-0007 §11.5 cursor 派生:cursor 之前的 phase = done。 - const cursorPhase: VersionPhase = (version?.phase as VersionPhase | undefined) ?? 'curating' + // The cursor only means something while the version is being prepared; a + // trained / training version has every step behind it (same as Overview). + const cursorPhase: VersionPhase = !version + ? 'curating' + : version.status === 'preparing' ? version.phase : 'ready' const cursorIdx = PHASE_ORDER.indexOf(cursorPhase) const isStepDone = (key: string): boolean => { diff --git a/studio/web/src/components/StepShell.tsx b/studio/web/src/components/StepShell.tsx index 18985f5..2486c94 100644 --- a/studio/web/src/components/StepShell.tsx +++ b/studio/web/src/components/StepShell.tsx @@ -6,7 +6,7 @@ import TaskLogDrawer, { type LogSource } from './TaskLogDrawer' interface Props { idx: number | string title: string - subtitle?: string + subtitle?: ReactNode /** Caption above the title; defaults to "STEP N" for a numeric idx. */ eyebrow?: string /** Green eyebrow (the mockup's version steps). On unless set to false. */ diff --git a/studio/web/src/components/preprocess/PreprocessToolsBar.tsx b/studio/web/src/components/preprocess/PreprocessToolsBar.tsx index 9c97cf8..c84a693 100644 --- a/studio/web/src/components/preprocess/PreprocessToolsBar.tsx +++ b/studio/web/src/components/preprocess/PreprocessToolsBar.tsx @@ -178,7 +178,7 @@ export function PreprocessHeadTools({ projectId, versionId }: { projectId: numbe > {t('ppFrame.restoreAll')}{s.processed > 0 ? ` · ${s.processed}` : ''} - {t('ppFrame.next')} + {t('ppFrame.next')} ) } diff --git a/studio/web/src/i18n/locales/en.json b/studio/web/src/i18n/locales/en.json index 206b9d3..8f45e2f 100644 --- a/studio/web/src/i18n/locales/en.json +++ b/studio/web/src/i18n/locales/en.json @@ -1169,7 +1169,7 @@ "downloadFile": "Download", "folderOpened": "Opened {{path}}", "sourceLink": "Project #{{projectId}} / v#{{versionId}}", - "eyebrow": "Task · {{kind}}", + "eyebrow": "TASK · {{kind}}", "startedAtShort": "started {{time}}", "runningFor": "running {{time}}", "queuedAtShort": "queued since {{time}}", @@ -1927,7 +1927,7 @@ "deltaHint": "Net gain over the plain base model baseline", "deltaHintShort": "Δ against the plain base model", "waitingMetrics": "waiting for metrics", - "eyebrow": "Tools", + "eyebrow": "TOOLS", "title": "Monitor", "subtitle": "Checkpoint metrics against the validation set. Δ is the gain over the plain base model.", "pickCkptsBtn": "Pick checkpoints", @@ -2168,7 +2168,7 @@ "sweep": "Sweep:", "nCkpts": "{{count}} checkpoints", "versionTraining": "{{label}} (training)", - "eyebrow": "Tools", + "eyebrow": "TOOLS", "guidance": "Guidance", "randomSeed": "Random", "sizeNote": "multiple of 64 · {{mp}} MP", @@ -2773,7 +2773,7 @@ }, "reg": { "title": "Reg set", - "subtitle": "Booru scrape or a neutral base-model prior. Mirrors the train structure or one 1_data/ folder." + "subtitle": "Booru scrape or a neutral base-model prior. Mirrors the train structure or one 1_data/ folder." }, "train": { "title": "Train", @@ -3036,7 +3036,7 @@ "colRes": "Res", "selectHint": "Select a preset to see its summary.", "colName": "Name", - "eyebrow": "Tools", + "eyebrow": "TOOLS", "title": "Presets", "subtitle": "Global config templates. A project version takes a copy — edits there never change the preset.", "headMenu": "More: import, export YAML", @@ -3073,7 +3073,7 @@ "noPresetError": "Select a preset first", "enqueuedNav": "Queued #{{id}}, check progress in /queue", "scheduledNav": "Scheduled #{{id}} to start at {{time}}", - "startTrainBtn": "Start Training", + "startTrainBtn": "Start training", "scheduleBtn": "Schedule training", "scheduleHint": "Schedule training (delay by N hours or pick a time)", "scheduleDelaySection": "Start after", @@ -3133,7 +3133,7 @@ "pickerTitleConfigured": "Current version has its own config; click to pick a preset as a starting point to reset", "pickerTitleEmpty": "Click to pick a preset as a starting point and create the current version's config", "configChip": "config", - "scopedConfigLabel": "{{title}} / {{label}} config", + "scopedConfigLabel": "{{title}} · {{label}}", "notConfiguredLabel": "Not configured — pick a preset to start", "readPresetParams": "Read params from this preset", "estDuration": "Est. duration", diff --git a/studio/web/src/i18n/locales/ru.json b/studio/web/src/i18n/locales/ru.json index 79eb48c..818e8cc 100644 --- a/studio/web/src/i18n/locales/ru.json +++ b/studio/web/src/i18n/locales/ru.json @@ -134,7 +134,7 @@ }, "reg": { "title": "Reg-набор", - "subtitle": "Сбор с booru или нейтральный приор базовой модели. Повторяет структуру train либо одна папка 1_data/." + "subtitle": "Сбор с booru или нейтральный приор базовой модели. Повторяет структуру train либо одна папка 1_data/." }, "train": { "title": "Тренировка", @@ -320,7 +320,7 @@ "deltaHint": "Чистый прирост относительно чистой базовой модели", "deltaHintShort": "Δ относительно чистой базовой модели", "waitingMetrics": "жду метрики", - "eyebrow": "Инструменты", + "eyebrow": "ИНСТРУМЕНТЫ", "title": "Монитор", "subtitle": "Метрики чекпоинтов против validation-набора. Δ — прирост к чистой базовой модели.", "pickCkptsBtn": "Выбрать чекпоинты", @@ -446,7 +446,7 @@ "noPresetError": "Сначала выберите пресет", "enqueuedNav": "Поставлено в очередь #{{id}}, прогресс в /queue", "scheduledNav": "Запланировано #{{id}} на {{time}}", - "startTrainBtn": "Запустить тренировку", + "startTrainBtn": "Начать тренировку", "scheduleBtn": "Запланировать", "scheduleHint": "Запланировать тренировку (через N часов или на конкретное время)", "scheduleDelaySection": "Начать через", @@ -506,7 +506,7 @@ "pickerTitleConfigured": "У версии свой конфиг; нажмите, чтобы выбрать пресет как отправную точку для сброса", "pickerTitleEmpty": "Нажмите, чтобы выбрать пресет как отправную точку и создать конфиг версии", "configChip": "конфиг", - "scopedConfigLabel": "Конфиг {{title}} / {{label}}", + "scopedConfigLabel": "{{title}} · {{label}}", "notConfiguredLabel": "Не настроено — выберите пресет", "readPresetParams": "Прочитать параметры из этого пресета", "estDuration": "Примерно займёт", @@ -1624,7 +1624,7 @@ "addYAxis": "+ Добавить ось Y", "addLora": "+ Добавить LoRA", "versionTraining": "{{label}} (тренируется)", - "eyebrow": "Инструменты", + "eyebrow": "ИНСТРУМЕНТЫ", "singleMode": "Одиночно", "xyMode": "XY-перебор", "xyAxis": "Ось {{label}}", @@ -2838,7 +2838,7 @@ "copyFailed": "Не удалось скопировать", "defaultedFieldsBody": "Поля с недопустимыми значениями сброшены к значениям по умолчанию:", "droppedFieldsBody": "Поля, которых нет в этой версии, пропущены:", - "eyebrow": "Инструменты", + "eyebrow": "ИНСТРУМЕНТЫ", "title": "Пресеты", "subtitle": "Глобальные шаблоны конфига. Версия проекта берёт копию — правки в ней не меняют пресет.", "headMenu": "Ещё: импорт, экспорт YAML", @@ -2984,7 +2984,7 @@ "downloadFile": "Скачать", "folderOpened": "Открыто: {{path}}", "sourceLink": "Проект #{{projectId}} / v#{{versionId}}", - "eyebrow": "Задача · {{kind}}", + "eyebrow": "ЗАДАЧА · {{kind}}", "startedAtShort": "запущена {{time}}", "runningFor": "идёт {{time}}", "queuedAtShort": "в очереди с {{time}}", diff --git a/studio/web/src/i18n/locales/zh.json b/studio/web/src/i18n/locales/zh.json index 9711021..fd0cac8 100644 --- a/studio/web/src/i18n/locales/zh.json +++ b/studio/web/src/i18n/locales/zh.json @@ -2259,7 +2259,7 @@ }, "reg": { "title": "正则集(可选)", - "subtitle": "Booru 拉图或 base 模型自生成中性 prior;可镜像 train 结构或平铺单桶 1_data/" + "subtitle": "Booru 拉图或 base 模型自生成中性 prior;可镜像 train 结构或平铺单桶 1_data/" }, "train": { "title": "训练", @@ -2577,7 +2577,7 @@ "pickerTitleConfigured": "当前 version 私有配置;点击展开选预设作为起点重置", "pickerTitleEmpty": "点击选预设作为起点创建当前 version 配置", "configChip": "配置", - "scopedConfigLabel": "{{title}} / {{label}} 配置", + "scopedConfigLabel": "{{title}} · {{label}}", "notConfiguredLabel": "未配置 — 选预设作为起点", "readPresetParams": "读取此预设参数", "estDuration": "预计耗时", diff --git a/studio/web/src/pages/Projects.tsx b/studio/web/src/pages/Projects.tsx index 38c629c..197a918 100644 --- a/studio/web/src/pages/Projects.tsx +++ b/studio/web/src/pages/Projects.tsx @@ -817,7 +817,7 @@ function NewProjectDialog({ /> - +