chore(M02): 임시 시험 단추 호출부 · inspect 옵션 · 시험 정리(이어서)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168FQuoV7vDh5nhnSowW5cp
This commit is contained in:
@@ -51,16 +51,6 @@ export interface SpreadsheetOptions {
|
||||
onChange?: (book: Workbook) => void;
|
||||
/** 고름이 바뀜 — 시트 id · 활성 칸 A1 · 범위 A1 */
|
||||
onSelect?: (selection: { 시트: string; 칸: string; 범위: string }) => void;
|
||||
/** ⚠ 임시 — 브레인 브라우저 검증용: 문맥을 `window.__aisloSheet` 에 걺(book · 고름 · 명령 읽기).
|
||||
* M02 [스프레드시트 시험] 단추만 켬 · 산출근거 카드는 안 켬 · 1단계 검증 뒤 지움. */
|
||||
inspect?: boolean;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
/** ⚠ 임시 — `inspect` 로 연 표의 문맥(브레인 검증용) */
|
||||
__aisloSheet?: SpreadsheetContext;
|
||||
}
|
||||
}
|
||||
|
||||
export interface SpreadsheetHandle {
|
||||
@@ -144,7 +134,6 @@ export function createSpreadsheet(
|
||||
|
||||
grid.render();
|
||||
select(ctx.selection);
|
||||
if (opts.inspect) window.__aisloSheet = ctx; // ⚠ 임시 — 브레인 검증용
|
||||
|
||||
function notify(message: string): void {
|
||||
toast.textContent = message;
|
||||
@@ -252,7 +241,6 @@ export function createSpreadsheet(
|
||||
return ctx.engine.snapshot();
|
||||
},
|
||||
destroy() {
|
||||
if (window.__aisloSheet === ctx) delete window.__aisloSheet;
|
||||
clearTimeout(toastTimer);
|
||||
detachKeys();
|
||||
detachMouse();
|
||||
|
||||
@@ -118,11 +118,6 @@ export const createStructure = (column: string): Promise<TemplateDoc> =>
|
||||
export const fetchStructureNumbers = (): Promise<Record<string, string>> =>
|
||||
call("/structures/numbers");
|
||||
|
||||
/* --- ⚠ 임시 — [스프레드시트 시험] 단추(1단계 검증 뒤 지움) · 저장 자리 = 서버 tmp 견본 --- */
|
||||
export const readSpreadsheetTrial = (): Promise<{ 문서: unknown }> => call("/spreadsheet-trial");
|
||||
export const saveSpreadsheetTrial = (문서: unknown): Promise<{ 문서: unknown }> =>
|
||||
call("/spreadsheet-trial", { method: "PUT", body: JSON.stringify({ 문서 }) });
|
||||
|
||||
/* --- 프로젝트 층 단추 다섯 --- */
|
||||
const project = (id: string, tail: string): string => `/projects/${enc(id)}/templates/${tail}`;
|
||||
const post = (path: string, body: object = {}): Promise<unknown> =>
|
||||
|
||||
@@ -5,15 +5,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from common_util import common_util_spreadsheet as spreadsheet
|
||||
from common_util.common_util_json import atomic_write_json
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
|
||||
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete"])
|
||||
@@ -61,34 +57,3 @@ def put_template(kind: str, name: str, body: SaveBody) -> dict:
|
||||
def delete_template(kind: str, name: str, 판: str | None = None) -> dict:
|
||||
_call(store.delete, kind, name, 판)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
# ── ⚠ 임시(스프레드시트 시험 단추 · 사용자 지시 · 1단계 검증 뒤 지움) ──────────
|
||||
# 저장 자리 = `tmp/spreadsheet_trial.json`(git 밖) · 없으면 시트 셋 빈 통합문서.
|
||||
TRIAL_PATH = Path(__file__).resolve().parent.parent / "tmp" / "spreadsheet_trial.json"
|
||||
|
||||
|
||||
def _trial_doc() -> dict[str, Any]:
|
||||
sheets = [{"id": f"s{i}", "이름": f"시트{i}", "칸": {}} for i in (1, 2, 3)]
|
||||
return {"종류": "통합문서", "판": 1, "열": "시험", "서식": [{}], "시트": sheets, "활성": "s1"}
|
||||
|
||||
|
||||
@router.get("/spreadsheet-trial")
|
||||
def get_spreadsheet_trial() -> dict:
|
||||
if not TRIAL_PATH.is_file():
|
||||
return {"문서": _trial_doc()}
|
||||
return {"문서": json.loads(TRIAL_PATH.read_text(encoding="utf-8"))}
|
||||
|
||||
|
||||
class TrialBody(BaseModel):
|
||||
문서: dict[str, Any]
|
||||
|
||||
|
||||
@router.put("/spreadsheet-trial")
|
||||
def put_spreadsheet_trial(body: TrialBody) -> dict:
|
||||
try:
|
||||
doc = spreadsheet.with_server_values(body.문서)
|
||||
except spreadsheet.RecalcError as e:
|
||||
raise HTTPException(status_code=503, detail=str(e)) from e
|
||||
atomic_write_json(TRIAL_PATH, doc)
|
||||
return {"문서": doc}
|
||||
|
||||
@@ -22,9 +22,6 @@ import {
|
||||
type StructureColumn,
|
||||
type StructurePanelHandle,
|
||||
} from "./M02_MasterTemplete_Structure";
|
||||
// ⚠ 임시 — [스프레드시트 시험] 단추(1단계 검증 뒤 지움)
|
||||
import { mountSpreadsheetTrial } from "./M02_MasterTemplete_Spreadsheet_Trial";
|
||||
|
||||
export interface Selection {
|
||||
layer: Layer;
|
||||
projectId: string | null;
|
||||
@@ -81,9 +78,6 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
const title = el("h2", { className: "m02-main__title", text: L("M02_PickTemplate") });
|
||||
const reload = createButton({ label: L("M02_Reload"), variant: "ghost" });
|
||||
const save = createButton({ label: L("M02_Save"), variant: "filled" });
|
||||
// ⚠ 임시 — [스프레드시트 시험] 단추(사용자 지시 · 1단계 검증 뒤 지움)
|
||||
const trial = createButton({ label: "스프레드시트 시험", variant: "ghost" });
|
||||
trial.hidden = !isAdmin;
|
||||
const slot = el("div", { className: "m02-main__slot" }); // 도면 양식의 작도 영역 칸이 들어옴
|
||||
const notice = el("div", { className: "m02-main__notice", attrs: { hidden: "" } });
|
||||
const host = el("div", { className: "m02-main__host" });
|
||||
@@ -91,7 +85,7 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
const root = el("div", {
|
||||
className: "m02-main",
|
||||
children: [
|
||||
el("div", { className: "m02-main__head", children: [title, slot, reload, save, trial] }),
|
||||
el("div", { className: "m02-main__head", children: [title, slot, reload, save] }),
|
||||
notice,
|
||||
host,
|
||||
extra,
|
||||
@@ -276,18 +270,6 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
}
|
||||
|
||||
save.addEventListener("click", () => void doSave());
|
||||
// ⚠ 임시 — [스프레드시트 시험] 빈 통합문서(시트 셋)를 메인 칸에 넓게 엶 · 저장은 서버 tmp 견본 자리
|
||||
trial.addEventListener("click", async () => {
|
||||
if (!(await confirmLeave())) return;
|
||||
seq += 1;
|
||||
dirty = false;
|
||||
drop();
|
||||
showNotice([]);
|
||||
sel = null;
|
||||
bar();
|
||||
title.textContent = "스프레드시트 시험";
|
||||
editor = mountSpreadsheetTrial(host, (d) => (dirty = d));
|
||||
});
|
||||
reload.addEventListener("click", async () => {
|
||||
if (sel && (await confirmLeave())) void open(sel);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""F — 산출근거 저장(basis 종류) · 옛 산출근거 옮김 · [저장] 때 서버 계산값 · 임시 시험 주소.
|
||||
"""F — 산출근거 저장(basis 종류) · 옛 산출근거 옮김 · [저장] 때 서버 계산값.
|
||||
|
||||
서버 Node 풀이는 `test_spreadsheet_node.py` 가 따로 봄 — 여기는 `with_server_values` 를 바꿔 끼워
|
||||
「브라우저 값은 버리고 서버 값만 적는다」 · 「못 풀면 저장을 막는다」 만 잼.
|
||||
@@ -26,7 +26,6 @@ def client(tmp_path, monkeypatch):
|
||||
(tmp_path / kind).mkdir()
|
||||
shutil.copy(REAL / "table/구조물집계표.json", tmp_path / "table")
|
||||
monkeypatch.setattr(store, "FOLDER", tmp_path)
|
||||
monkeypatch.setattr(router_module, "TRIAL_PATH", tmp_path / "trial.json")
|
||||
|
||||
def fake(book):
|
||||
clean = {k: v for k, v in book.items() if k != "계산값"}
|
||||
@@ -127,12 +126,3 @@ def test_층_규칙과_프로젝트_복사(client, tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(layers, "SYSTEM_ROOT", tmp_path)
|
||||
copied = layers.seed_project(tmp_path / "project")
|
||||
assert "basis/rv" in copied["작업본"] and "basis/rv" in copied["초기"]
|
||||
|
||||
|
||||
def test_임시_시험_주소(client):
|
||||
first = client.get("/api/m02/spreadsheet-trial").json()["문서"]
|
||||
assert [s["이름"] for s in first["시트"]] == ["시트1", "시트2", "시트3"]
|
||||
first["시트"][0]["칸"] = {"A1": {"식": "1+41"}}
|
||||
saved = client.put("/api/m02/spreadsheet-trial", json={"문서": first}).json()["문서"]
|
||||
assert saved["계산값"] == SERVER
|
||||
assert client.get("/api/m02/spreadsheet-trial").json()["문서"] == saved
|
||||
|
||||
Reference in New Issue
Block a user