- 새 UI_Side_Sangeun.ts — 서고 칸(716-4) kind sangeun · 목록표 고름 sangeunList - 새 Sangeun_View.ts — 이름 · 단위 · 바탕 · 덮개 · 더한 줄 · 뺀 줄 · 열린 입력 요약 + 상세 자리표(717-2b 가 갈음) - UI_Main 종류 sangeun 갈래 · 목록표 조건에 sangeun · Library_List 열 표(단가산출 = 바탕 · 고친 줄 · 쓰는 곳) · sangeunBlank(단위 식 · 바탕 없음) - UI_Page 단가산출 층 상태 sk · UI_Side 맨 위 칸 · reveal 「단가산출」 · Layer open 「단가산출」 · Api Kind sangeun - m_settings_nav 대시보드 마스터 템플릿 묶음 「단가산출」 줄(?open=단가산출) · locale_m2 키 - 낡은 글 대조 시험 넷 고침(197_1 · b01_settings_cards · m02_layer_screen · m02_precombo_scope) — 대시보드 줄 하나 늘고 OPENS · reveal · 목록 열 표 · 칸 차례가 바뀜 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
135 lines
5.5 KiB
TypeScript
135 lines
5.5 KiB
TypeScript
/* =============================================================================
|
|
* m_settings_nav.ts
|
|
* 시스템 설정 바로가기(334 · 요구 225-2 · 716-2) — 대시보드 설계 기본값 줄(`settingLinks` · 칸마다 한 줄 ·
|
|
* `?open=`) / M01 · M02 ☰ 메뉴(`pageLinks` · 페이지 둘 · `mountSettingsDrawer`).
|
|
* ========================================================================== */
|
|
|
|
import { ROUTES, type RoutePath } from "@config/config_frontend";
|
|
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
|
|
import { createStepBar } from "@ui/ui_template_workflow_layout";
|
|
import { setDrawerSteps } from "./app_shell";
|
|
import { currentRoute, navigateTo, takeLeaveGuard } from "./router";
|
|
|
|
interface SettingUser {
|
|
role?: string;
|
|
is_master?: boolean;
|
|
company_id?: number | null;
|
|
}
|
|
|
|
/** key = 페이지 열쇠(☰ · 「m01」 「m02」) 또는 칸 열쇠(대시보드 줄 · 계산 자리 「calcSites」 = 창 504-2) ·
|
|
* group = 대시보드 설계 기본값 묶음 제목 */
|
|
export interface SettingLink {
|
|
key: string;
|
|
title: string;
|
|
desc: string;
|
|
route: RoutePath;
|
|
query?: Record<string, string>;
|
|
group?: string;
|
|
}
|
|
|
|
function L(key: keyof typeof ui_locales): string {
|
|
return ui_locales[key][currentLanguageIndex];
|
|
}
|
|
|
|
const ICONS: Record<string, string> = { m01: "🗄️", m02: "🧱" };
|
|
|
|
/** 설계 기본값 줄(대시보드) — 칸마다 한 줄 · 역할로 숨김 · M01 줄 `?open=`(칸 고름) · M02 줄 `?open=&root=`(27-1d).
|
|
* 칸을 더할 때는 아래 표에 한 줄(m01 / m02 호출)만 더함. */
|
|
export function settingLinks(user: SettingUser, companyId: number | string | null): SettingLink[] {
|
|
// 시스템 관리자는 고른 회사를 해시에 실음(29-1)
|
|
const company: Record<string, string> =
|
|
user.role === "SYSTEM_ADMIN" && companyId ? { company: String(companyId) } : {};
|
|
const m01 = (key: string, title: string, desc: string, open?: string): SettingLink => ({
|
|
key,
|
|
title,
|
|
desc,
|
|
route: ROUTES.M01_MASTER_DATA,
|
|
query: open ? { open } : undefined,
|
|
group: "마스터 데이터",
|
|
});
|
|
const m02 = (title: string, open: string, root: string, desc: string): SettingLink => ({
|
|
key: open,
|
|
title,
|
|
desc,
|
|
route: ROUTES.M02_MASTER_TEMPLATE,
|
|
query: { open, root, ...company },
|
|
group: "마스터 템플릿",
|
|
});
|
|
// 구조물 조합 기본 층 = 개인(123-1 · 누구든) · 개인 층 없음(회사 없음) = 아래 역할 규칙
|
|
const comboRoot = (fallback: string): string => (user.company_id ? "personal" : fallback);
|
|
if (user.role === "SYSTEM_ADMIN") {
|
|
const desc = L("B01_Dashboard_PermMasterWrite");
|
|
const read = L("B01_Dashboard_PermSourceRead");
|
|
return [
|
|
m01("m01", L("M01_Title"), read),
|
|
m01("로직", L("B01_Dashboard_CardLogic"), read, "로직"),
|
|
m01("옵션", L("B01_Dashboard_CardStructOptionDef"), desc, "옵션"),
|
|
m01("별칭", L("B01_Dashboard_CardAliasLedger"), desc, "별칭"),
|
|
m02(L("B01_Dashboard_CardSangeun"), "단가산출", comboRoot("master"), desc),
|
|
m02(L("B01_Dashboard_CardPrecombo"), "일위대가조합", comboRoot("master"), desc),
|
|
m02(L("B01_Dashboard_CardStructCombo"), "구조물조합", comboRoot("master"), desc),
|
|
m02(L("B01_Dashboard_CardDrawing"), "도면", "master", desc),
|
|
{
|
|
key: "calcSites",
|
|
title: L("B01_CalcSites_Title"),
|
|
desc: L("B01_CalcSites_Desc"),
|
|
route: ROUTES.B01_ACCOUNT,
|
|
group: "계산",
|
|
},
|
|
];
|
|
}
|
|
// 회사 수정 = 회사 관리자 · 회사 마스터(M02 accessFor 와 같은 규칙)
|
|
const companyAdmin = user.role === "ADMIN" || user.is_master;
|
|
const root = companyAdmin ? "company" : "personal";
|
|
const desc = [
|
|
L("B01_Dashboard_PermMasterRead"),
|
|
L(companyAdmin ? "B01_Dashboard_PermCompanyWrite" : "B01_Dashboard_PermCompanyRead"),
|
|
L("B01_Dashboard_PermPersonalWrite"),
|
|
].join(" · ");
|
|
return [m02(L("B01_Dashboard_CardStructCombo"), "구조물조합", comboRoot(root), desc)];
|
|
}
|
|
|
|
/** ☰ 메뉴 — 페이지 둘만(M01 = 시스템 관리자 · M02 = 누구나) · 열쇠 「m01」 「m02」 */
|
|
export function pageLinks(user: SettingUser, companyId: number | string | null): SettingLink[] {
|
|
const combo = settingLinks(user, companyId).find((link) => link.key === "구조물조합");
|
|
const links: SettingLink[] = [];
|
|
if (user.role === "SYSTEM_ADMIN")
|
|
links.push({
|
|
key: "m01",
|
|
title: L("B01_Dashboard_MasterElements"),
|
|
desc: "",
|
|
route: ROUTES.M01_MASTER_DATA,
|
|
});
|
|
if (combo)
|
|
links.push({ ...combo, key: "m02", title: L("M02_Title"), desc: "", group: undefined });
|
|
return links;
|
|
}
|
|
|
|
/** ☰ 진행 단계 자리 — 🏠 대시보드 + 페이지 둘 · 지금 페이지 강조(`activeKey` = 「m01」 「m02」) ·
|
|
* 같은 길(M02 → M02)은 머리 가드가 안 물어 여기서 먼저 */
|
|
export function mountSettingsDrawer(
|
|
user: SettingUser,
|
|
activeKey: string,
|
|
companyId: number | string | null,
|
|
): void {
|
|
const links = pageLinks(user, companyId);
|
|
const bar = createStepBar(
|
|
links.map((link) => link.title),
|
|
links.findIndex((link) => link.key === activeKey),
|
|
{
|
|
orientation: "vertical",
|
|
icons: links.map((link) => ICONS[link.key] ?? ""),
|
|
routes: links.map((link) => link.route),
|
|
homeButton: true,
|
|
onStepClick: (index) => void go(links[index]),
|
|
},
|
|
);
|
|
setDrawerSteps(bar);
|
|
}
|
|
|
|
async function go(link: SettingLink): Promise<void> {
|
|
const guard = link.route === currentRoute() ? takeLeaveGuard() : null;
|
|
if (guard && !(await guard())) return;
|
|
navigateTo(link.route, link.query);
|
|
}
|