feat(M02): 「전체 항목」 화면 — 구조물 도면 · 일위대가 · 면적산출 하위 목록을 상세 칸에 · 줄 누름 = 그 항목 상세
39-5 H2 — 좌측 onAll(39-2) 이음 · 제목 「하위 · 전체 항목」 · 목록 = ItemList(M01 꼴). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
@@ -35,6 +35,7 @@ const TEXT = {
|
||||
none: "항목이 없음",
|
||||
noMatch: "맞는 항목이 없음",
|
||||
loading: "불러오는 중",
|
||||
failed: "목록을 못 받음",
|
||||
};
|
||||
|
||||
const SIZE = 30;
|
||||
@@ -111,6 +112,22 @@ export function pageOf<R>(
|
||||
export const loadItems = async (layer: Layer, owner: string | null): Promise<ItemRow[]> =>
|
||||
(await fetchTree(layer, owner)).items as ItemRow[];
|
||||
|
||||
/** 「전체 항목」 화면(39-5) — 한 층 · 한 하위 목록 · 줄 누름 = 그 항목 상세(좌측 열 줄 누름과 같음) */
|
||||
export function buildAllItems(
|
||||
kind: ListKind,
|
||||
layer: Layer,
|
||||
owner: string | null,
|
||||
onOpen: (row: ItemRow) => void,
|
||||
): HTMLElement {
|
||||
const list = buildItemList();
|
||||
loadItems(layer, owner).then(
|
||||
(rows) => list.show(rows, ITEM_COLS[kind], onOpen),
|
||||
(error: unknown) =>
|
||||
list.message(`${TEXT.failed} — ${error instanceof Error ? error.message : String(error)}`),
|
||||
);
|
||||
return list.root;
|
||||
}
|
||||
|
||||
export interface ItemListHandle {
|
||||
root: HTMLElement;
|
||||
/** 줄 · 칸 · 누를 일을 바꿔 그림(찾는 글은 그대로 · 쪽은 1) */
|
||||
|
||||
@@ -15,7 +15,7 @@ import { t as L } from "@ui/ui_template_locale";
|
||||
import { createWorkflowOverlays } from "@ui/ui_template_overlay";
|
||||
import { navigateTo, type MountedPage } from "../A00_Common/router";
|
||||
import { fetchSessionUser } from "../A06_Login/A06_Login_Api_Fetch";
|
||||
import { fetchOwners, setActiveLayer } from "./M02_MasterTemplete_Api_Fetch";
|
||||
import { fetchOwners, setActiveLayer, type Kind } from "./M02_MasterTemplete_Api_Fetch";
|
||||
import {
|
||||
accessFor,
|
||||
buildReadOnlyBar,
|
||||
@@ -41,9 +41,17 @@ import {
|
||||
seesOthers,
|
||||
} from "./M02_MasterTemplete_TreePanel_Roots";
|
||||
import { canEdit, createMain, newItemButton, type Selection } from "./M02_MasterTemplete_UI_Main";
|
||||
import { buildSide } from "./M02_MasterTemplete_UI_Side";
|
||||
import { buildSide, type AllKind } from "./M02_MasterTemplete_UI_Side";
|
||||
import { buildAllItems } from "./M02_MasterTemplete_ItemList";
|
||||
import "./M02_MasterTemplete_UI_Style.css";
|
||||
|
||||
/** 「전체 항목」 화면 제목 앞마디 — 하위 이름 */
|
||||
const ALL_TITLE = {
|
||||
structure: "M02_KindStructure",
|
||||
labor: "M02_KindLabor",
|
||||
area: "M02_KindArea",
|
||||
} as const satisfies Record<AllKind, string>;
|
||||
|
||||
export async function renderM02MasterTemplate(root: HTMLElement): Promise<MountedPage> {
|
||||
const user = await fetchSessionUser().catch(() => null);
|
||||
const entry = entryFromHash();
|
||||
@@ -155,6 +163,20 @@ export async function renderM02MasterTemplate(root: HTMLElement): Promise<Mounte
|
||||
layerBar("구조물조합", tree.add, () => void main.openTable(layer)),
|
||||
peopleTree("구조물조합", tree.root),
|
||||
],
|
||||
// 「전체 항목」(39-5) — 메인 칸에 그 하위 목록 · 줄 누름 = 그 항목 상세(좌측 열 줄과 같은 `open`)
|
||||
onAll: (kind) =>
|
||||
void main.showView(
|
||||
`${L(ALL_TITLE[kind])} · ${L("M02_ItemsAll")}`,
|
||||
buildAllItems(kind, layer, owner, (row) => {
|
||||
void main.open({
|
||||
layer,
|
||||
projectId: null,
|
||||
kind: kind as Kind,
|
||||
name: row.열,
|
||||
label: row.이름,
|
||||
});
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const layout = el("div", { className: "ui-workflow-layout m02-master" });
|
||||
|
||||
Reference in New Issue
Block a user