Merge remote-tracking branch 'origin/dev' into sub_laptop_2

This commit is contained in:
2026-10-04 20:48:49 +09:00
4 changed files with 24 additions and 8 deletions
@@ -4,7 +4,7 @@
* 몸 = 일위대가 보기 갈래(`Labor_View` · 고치기 없음) · 틀 = 공용 사이드바 카드 · 접기 손잡이 · 폭 손잡이
* (폭 · 접힘 기억은 옛 조합 패널 키 그대로).
* · 줄 누름 = 칸 지정 모달(`AreaLink` · 그 줄 알약 키를 면적 칸에 잇기 · 풀기)
* · 시트 칸 값이 바뀌면 `refresh` — 받은 기준에 바로 곱함(서버 안 부름 · `Labor_View.setQty`)
* · 시트 칸 값 · 연결이 바뀌면 `refresh` — 받은 기준에 바로 곱함 · 칸 주소도 넘김(서버 안 부름 · `Labor_View.setQty`)
* ========================================================================== */
import { el, showToast } from "@ui/ui_template_elements";
@@ -57,6 +57,13 @@ function quantities(sheet: SpreadsheetHandle | null): Record<string, number> {
return out;
}
/** 시트 연결 → `{알약 키: 칸 주소}` — 저장 전 잇기 · 풀기도(줄 아래 「수량 B6 = …」) */
function cellsOf(sheet: SpreadsheetHandle | null): Record<string, string> {
const out: Record<string, string> = {};
for (const s of sheet?.getDoc().시트 ?? []) for (const l of s.연결 ?? []) out[l.키] = l.칸;
return out;
}
export function buildAreaPanel(opts: AreaPanelOptions): AreaPanel {
const openLink = (row: LaborViewRow): void => {
const sheet = opts.sheet();
@@ -112,10 +119,12 @@ export function buildAreaPanel(opts: AreaPanelOptions): AreaPanel {
setCollapsed(readStateRaw("m02-combo-panel-collapsed") === "true");
// 처음 = 저장 안 한 시트 칸 값으로 셈(서버 calc 한 번)
const refresh = (): void => view.setQty(quantities(opts.sheet()), cellsOf(opts.sheet()));
void view.show(opts.layer, opts.column, quantities(opts.sheet()));
refresh(); // 칸 주소는 지금 시트 것 — 보기가 저장본 대신 씀
return {
root,
refresh: () => view.setQty(quantities(opts.sheet())),
refresh,
destroy: () => {
view.destroy();
resizer.dispose();
+8 -3
View File
@@ -88,9 +88,14 @@ def _list(client: TestClient) -> list[dict]:
def _edit(client: TestClient, key: str, version: str, row: dict, want: int = 200) -> dict:
res = client.put(f"{SYS}/{key}", json={"combo": row, "판": version})
assert res.status_code == want, res.text
return res.json()
"""조합 고치기 길(PUT)은 은퇴(39-1d) — 저장소 함수(실무문서 고치기)를 바로 부름."""
try:
done = combo_store.combo_edit(key, version, row, row.get("소유") or "")
except store.StoreError as error:
assert error.status == want, error.detail
return {"detail": error.detail}
assert want == 200
return done
def _inputs(key: str) -> dict:
+3 -2
View File
@@ -144,5 +144,6 @@ def test_본뜬키는_목록에_나오고_없는_키_자기_키는_400(own) -> N
assert own.post(SYS, json={"combo": bad}).status_code == 400
version = own.get(f"{SYS}/{base}").json()["판"]
me = {"이름": "원본", "본뜬키": base, "담은로직": combo["담은로직"]}
res = own.put(f"{SYS}/{base}", json={"combo": me, "판": version})
assert res.status_code == 400
with pytest.raises(store.StoreError) as caught: # 조합 고치기 길(PUT) 은퇴 — 저장소 함수로
combo_store.combo_edit(base, version, me)
assert caught.value.status == 400
+2 -1
View File
@@ -33,7 +33,8 @@ def test_패널_몸은_보기_갈래_줄_누름은_칸_지정():
panel = _text("M02_MasterTemplete_AreaPanel.ts")
assert "createLaborView(openLink)" in panel
assert "void view.show(opts.layer, opts.column, quantities(opts.sheet()));" in panel
assert "refresh: () => view.setQty(quantities(opts.sheet()))," in panel
assert "view.setQty(quantities(opts.sheet()), cellsOf(opts.sheet()))" in panel
assert panel.index("void view.show(") < panel.index("refresh(); // 칸 주소")
assert "openAreaLink({" in panel and "if (!row.pill) return showToast(TEXT.noPill" in panel
for gone in ("fetchUsableCombos", "setColumnCombo", "branchCombo"):
assert gone not in panel