fix(M02): 양식 가져오기 목록이 서버 묶음(층 · 사람 · 프로젝트)을 그대로 펴서 보임 (PLAN 10-1)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0148XFUpPfpiuTjxF1EK9c95
This commit is contained in:
@@ -101,16 +101,6 @@ export const saveProjectAs = (
|
||||
이름: string,
|
||||
): Promise<unknown> => post(project(id, "save-as"), { to, 종류, 이름 });
|
||||
|
||||
export interface SourceItem {
|
||||
from: Layer;
|
||||
label?: string;
|
||||
user_id?: string;
|
||||
project_id?: string;
|
||||
종류?: Kind;
|
||||
이름?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export const fetchSources = (id: string): Promise<unknown> => call(`/projects/${enc(id)}/sources`);
|
||||
|
||||
/** 설계값을 채운 표 문서 — 서버가 그때그때 채움 · 저장 안 함 */
|
||||
|
||||
@@ -91,17 +91,35 @@ const why = (error: unknown): string => (error instanceof Error ? error.message
|
||||
const failed = (error: unknown): void =>
|
||||
showToast(L("M02_ActionFailed").replace("{value}", why(error)), "error");
|
||||
|
||||
/** 가져올 곳 목록 — 모양이 배열이든 묶음 객체든 한 줄씩 펴서 받음(길이 채워지면 맞춤) */
|
||||
function flatten(raw: unknown): Record<string, unknown>[] {
|
||||
if (Array.isArray(raw)) {
|
||||
return raw.filter((x): x is Record<string, unknown> => !!x && typeof x === "object");
|
||||
type ApplyFrom = Parameters<typeof applyToProject>[1];
|
||||
interface Source {
|
||||
label: string;
|
||||
body: ApplyFrom;
|
||||
}
|
||||
|
||||
/** 가져올 곳 — 서버 `sources` 는 층마다 묶음 · 개인·프로젝트는 사람·프로젝트 아래 양식 목록 */
|
||||
function sourceItems(raw: unknown): Source[] {
|
||||
const group = (raw ?? {}) as Record<string, Record<string, unknown>[] | undefined>;
|
||||
const layerName: Record<string, string> = {
|
||||
system: L("M02_LayerSystem"),
|
||||
company: L("M02_LayerCompany"),
|
||||
personal: L("M02_LayerPersonal"),
|
||||
project: L("M02_LayerProject"),
|
||||
};
|
||||
const out: Source[] = [];
|
||||
for (const from of ["system", "company", "personal", "project"] as const) {
|
||||
for (const entry of group[from] ?? []) {
|
||||
const templates = (Array.isArray(entry.양식) ? entry.양식 : [entry]) as TemplateInfo[];
|
||||
const owner = entry.name ? ` · ${String(entry.name)}` : "";
|
||||
for (const t of templates) {
|
||||
const body: ApplyFrom = { from, 종류: t.종류, 이름: t.이름 };
|
||||
if (entry.user_id != null) body.user_id = String(entry.user_id);
|
||||
if (entry.project_id != null) body.project_id = String(entry.project_id);
|
||||
out.push({ label: `${layerName[from]}${owner} · ${t.이름}`, body });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (raw && typeof raw === "object") {
|
||||
return Object.entries(raw).flatMap(([from, v]) =>
|
||||
flatten(v).map((item) => ({ from: item.from ?? from, ...item })),
|
||||
);
|
||||
}
|
||||
return [];
|
||||
return out;
|
||||
}
|
||||
|
||||
export function buildSide(opt: SideOptions): SideHandle {
|
||||
@@ -337,9 +355,9 @@ export function buildSide(opt: SideOptions): SideHandle {
|
||||
}
|
||||
});
|
||||
projectButton(L("M02_ProjectImport"), async () => {
|
||||
let sources: Record<string, unknown>[] = [];
|
||||
let sources: Source[] = [];
|
||||
try {
|
||||
sources = flatten(await fetchSources(projectId));
|
||||
sources = sourceItems(await fetchSources(projectId));
|
||||
} catch (error) {
|
||||
return failed(error);
|
||||
}
|
||||
@@ -352,12 +370,14 @@ export function buildSide(opt: SideOptions): SideHandle {
|
||||
body.append(el("p", { className: "m02-side__empty", text: L("M02_ImportNone") }));
|
||||
}
|
||||
for (const src of sources) {
|
||||
const text = String(src.label ?? src.이름 ?? src.from ?? JSON.stringify(src));
|
||||
const b = el("button", { className: "m02-side__item", text, attrs: { type: "button" } });
|
||||
const b = el("button", {
|
||||
className: "m02-side__item",
|
||||
text: src.label,
|
||||
attrs: { type: "button" },
|
||||
});
|
||||
b.addEventListener("click", () => {
|
||||
close();
|
||||
const { label: _label, ...rest } = src;
|
||||
void act(() => applyToProject(projectId, rest as never));
|
||||
void act(() => applyToProject(projectId, src.body));
|
||||
});
|
||||
body.append(b);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user