-
Notifications
You must be signed in to change notification settings - Fork 0
Step card: operation params line from last run #704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
237edf9
52e47b2
292a3c4
8767729
8ecd84f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| import { describe, it, expect } from "vitest"; | ||
| import { stepMetaLine, type StepMetaLabels } from "./stepMetaLine"; | ||
| import type { OperationRun } from "@/lib/api"; | ||
|
|
||
| const L: StepMetaLabels = { | ||
| holes: "отв.", | ||
| tools: (n) => `${n} св.`, | ||
| dur: { h: "ч", m: "м", s: "с" }, | ||
| sec: "с", | ||
| side: (s) => (s === "top" ? "Верх" : "Низ"), | ||
| }; | ||
|
|
||
| function run(p: Partial<OperationRun>): OperationRun { | ||
| return { | ||
| runUid: "u", | ||
| projectPath: "/p", | ||
| opType: "drill", | ||
| startedAt: 0, | ||
| endedAt: 100, | ||
| outcome: "completed", | ||
| progressTotal: 84, | ||
| progressDone: 84, | ||
| paramsJson: "{}", | ||
| summaryJson: null, | ||
| ...p, | ||
| }; | ||
| } | ||
|
|
||
| describe("stepMetaLine", () => { | ||
| it("null run → null", () => { | ||
| expect(stepMetaLine(null, L)).toBeNull(); | ||
| }); | ||
| it("drill: holes + tools + estimate", () => { | ||
| const r = run({ opType: "drill", progressTotal: 84, paramsJson: JSON.stringify({ toolCount: 2, estimateSec: 74 }) }); | ||
| expect(stepMetaLine(r, L)).toBe("84 отв. · 2 св. · ≈ 1 м 14 с"); | ||
| }); | ||
| it("drill: holes only when params empty", () => { | ||
| const r = run({ opType: "drill", progressTotal: 84, paramsJson: "{}" }); | ||
| expect(stepMetaLine(r, L)).toBe("84 отв."); | ||
| }); | ||
| it("drill: skips zero/absent estimate", () => { | ||
| const r = run({ opType: "drill", progressTotal: 10, paramsJson: JSON.stringify({ toolCount: 1, estimateSec: 0 }) }); | ||
| expect(stepMetaLine(r, L)).toBe("10 отв. · 1 св."); | ||
| }); | ||
| it("drill: malformed params → holes only, no crash", () => { | ||
| const r = run({ opType: "drill", progressTotal: 12, paramsJson: "{not json" }); | ||
| expect(stepMetaLine(r, L)).toBe("12 отв."); | ||
| }); | ||
| it("expose: side + exposure seconds", () => { | ||
| const r = run({ opType: "expose", progressTotal: null, paramsJson: JSON.stringify({ side: "top", exposureS: 45 }) }); | ||
| expect(stepMetaLine(r, L)).toBe("Верх · 45 с"); | ||
| }); | ||
| it("expose: bottom only when no exposure", () => { | ||
| const r = run({ opType: "expose", progressTotal: null, paramsJson: JSON.stringify({ side: "bottom" }) }); | ||
| expect(stepMetaLine(r, L)).toBe("Низ"); | ||
| }); | ||
| it("mill → null", () => { | ||
| const r = run({ opType: "mill", progressTotal: null, paramsJson: "{}" }); | ||
| expect(stepMetaLine(r, L)).toBeNull(); | ||
| }); | ||
| it("drill with nothing extractable → null", () => { | ||
| const r = run({ opType: "drill", progressTotal: null, paramsJson: "{}" }); | ||
| expect(stepMetaLine(r, L)).toBeNull(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import type { OperationRun } from "@/lib/api"; | ||
| import { formatDuration, type DurationLabels } from "@/lib/runHistoryFormat"; | ||
|
|
||
| /** Labels resolved by the caller (component owns the i18n namespace; keeping i18n | ||
| * out of this module lets the static i18n checker scope keys correctly). */ | ||
| export interface StepMetaLabels { | ||
| /** "отв." */ | ||
| holes: string; | ||
| /** Pluralized tool count, e.g. (2) => "2 сверла". */ | ||
| tools: (n: number) => string; | ||
| /** {h,m,s} short unit labels for the estimate. */ | ||
| dur: DurationLabels; | ||
| /** "с" (seconds suffix for exposure time). */ | ||
| sec: string; | ||
| /** Copper side label, e.g. ("top") => "Верх". */ | ||
| side: (s: string) => string; | ||
| } | ||
|
|
||
| /** Cheap per-step parameter line from the LAST run (no fresh planner). Returns null | ||
| * when there's no run or nothing extractable. drill → holes · tools · ≈estimate; | ||
| * expose → side · exposure; mill (not journalled) and everything else → null. */ | ||
| export function stepMetaLine(run: OperationRun | null, L: StepMetaLabels): string | null { | ||
| if (!run) return null; | ||
| const parts: string[] = []; | ||
|
|
||
| if (run.opType === "drill") { | ||
| if (run.progressTotal != null) parts.push(`${run.progressTotal} ${L.holes}`); | ||
| try { | ||
| const p = JSON.parse(run.paramsJson) as { toolCount?: number; estimateSec?: number }; | ||
| if (p.toolCount != null && p.toolCount > 0) parts.push(L.tools(p.toolCount)); | ||
| if (p.estimateSec != null && p.estimateSec > 0) { | ||
| parts.push(`≈ ${formatDuration(p.estimateSec, L.dur)}`); | ||
| } | ||
| } catch { | ||
| /* ignore malformed params */ | ||
| } | ||
| } else if (run.opType === "expose") { | ||
| try { | ||
| const p = JSON.parse(run.paramsJson) as { side?: string; exposureS?: number }; | ||
| if (p.side) parts.push(L.side(p.side)); | ||
| if (p.exposureS != null && p.exposureS > 0) parts.push(`${p.exposureS} ${L.sec}`); | ||
| } catch { | ||
| /* ignore malformed params */ | ||
| } | ||
| } | ||
|
|
||
| return parts.length ? parts.join(" · ") : null; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -293,6 +293,14 @@ | |
| "hole": "Hole", | ||
| "tool": "Drill Ø{{mm}} mm", | ||
| "stop": "Stop" | ||
| }, | ||
| "meta": { | ||
| "holes": "holes", | ||
| "tools_one": "{{count}} drill", | ||
| "tools_few": "{{count}} drills", | ||
| "tools_many": "{{count}} drills", | ||
| "tools_other": "{{count}} drills", | ||
| "side": { "top": "Top", "bottom": "Bottom" } | ||
| } | ||
|
Comment on lines
+297
to
304
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== i18n init / plural options =="
rg -n -C3 'i18next|init\(|plural|compatibilityJSON|pluralSeparator' cuprum-ui/src
echo
echo "== tools plural keys in locales =="
rg -n '"tools_(one|few|many|other)"' cuprum-ui/src/locales/en/project.json cuprum-ui/src/locales/ru/project.json
echo
echo "== calls that rely on count pluralization =="
rg -n -C2 'operations\.meta\.tools|t\(".*tools".*count' cuprum-ui/srcRepository: fixcik/cuprum Length of output: 50369 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== i18next init configuration ==="
sed -n '10,25p' cuprum-ui/src/i18n/index.ts
echo
echo "=== Check for plural-related config ==="
rg -A 10 'i18n\.use.*init' cuprum-ui/src/i18n/index.ts
echo
echo "=== tools keys in en/project.json ==="
grep -o '"tools[^"]*"' cuprum-ui/src/locales/en/project.json | sort | uniq
echo
echo "=== tools keys in ru/project.json ==="
grep -o '"tools[^"]*"' cuprum-ui/src/locales/ru/project.json | sort | uniq
echo
echo "=== StepCard usage of operations.meta.tools ==="
rg -B5 -A5 'operations\.meta\.tools|meta\.tools' cuprum-ui/src/components/operations/StepCard.tsxRepository: fixcik/cuprum Length of output: 1247 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Full i18n/index.ts file ==="
cat cuprum-ui/src/i18n/index.ts
echo
echo "=== Check for any compatibility or plural settings ==="
rg -r 'compatibilityJSON|pluralSeparator|load.*plural|cldr' cuprum-ui/src/i18n/
echo
echo "=== Check exact en/project.json lines around tools ==="
sed -n '295,310p' cuprum-ui/src/locales/en/project.json
echo
echo "=== Check exact ru/project.json lines around tools ==="
sed -n '295,310p' cuprum-ui/src/locales/ru/project.jsonRepository: fixcik/cuprum Length of output: 748 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== en/project.json around tools keys ==="
cat cuprum-ui/src/locales/en/project.json | jq '.operations.meta' 2>/dev/null || sed -n '290,310p' cuprum-ui/src/locales/en/project.json
echo
echo "=== ru/project.json around tools keys ==="
cat cuprum-ui/src/locales/ru/project.json | jq '.operations.meta' 2>/dev/null || sed -n '290,310p' cuprum-ui/src/locales/ru/project.json
echo
echo "=== Check if i18next package.json has plural rules info ==="
rg -A2 -B2 '"i18next"' cuprum-ui/package.jsonRepository: fixcik/cuprum Length of output: 718 Добавьте Стандартные CLDR правила pluralization для английского используют только Измените en/project.json с: "tools_one": "{{count}} drill",
"tools_few": "{{count}} drills",
"tools_many": "{{count}} drills",На: "tools_one": "{{count}} drill",
"tools_other": "{{count}} drills",🤖 Prompt for AI Agents |
||
| }, | ||
| "setup": { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не подставляйте
bottomдля неизвестногоside.Сейчас любое значение, отличное от
"top", отображается как"bottom", что даёт неверную мета-строку при неожиданных данных.Предлагаемый фикс
🤖 Prompt for AI Agents