- 새 A00_Common/m_settings_nav: settingLinks = 대시보드 카드 역할 규칙 한 벌 · mountSettingsDrawer = ☰ 진행 단계 자리 - B01 시스템 설정 카드가 settingLinks 로만 그림(화면 그대로) - M01 · M02 page 한 줄씩(M02 = 진입 open · company 이어 실음) - test_b01_settings_cards 가 옮긴 함수 소스를 같이 실음(기대값 그대로) · test_225 뒷부분 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfHKQs7J3hQELKMWQMUJEy
99 lines
4.0 KiB
TypeScript
99 lines
4.0 KiB
TypeScript
/* =============================================================================
|
|
* m_settings_nav.ts
|
|
* 시스템 설정 바로가기(334 · 요구 225-2) — 대시보드 「시스템 설정」 카드 · M01 · M02 ☰ 가 같이 쓰는
|
|
* 역할 규칙 한 벌(`settingLinks`) · ☰ 진행 단계 자리에 🏠 대시보드 + 카드(`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 은 「m01」 · M02 는 진입 인자 `open` */
|
|
export interface SettingLink {
|
|
key: string;
|
|
title: string;
|
|
desc: string;
|
|
route: RoutePath;
|
|
query?: Record<string, string>;
|
|
}
|
|
|
|
function L(key: keyof typeof ui_locales): string {
|
|
return ui_locales[key][currentLanguageIndex];
|
|
}
|
|
|
|
const ICONS: Record<string, string> = { m01: "🗄️", 구조물조합: "🧱", 옵션: "🎛️", 도면: "📑" };
|
|
|
|
/** 시스템 설정 — 역할로 카드 숨김 · M02 카드는 `?open=&root=` 로 진입(27-1d) */
|
|
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 m02 = (title: string, open: string, root: string, desc: string): SettingLink => ({
|
|
key: open,
|
|
title,
|
|
desc,
|
|
route: ROUTES.M02_MASTER_TEMPLATE,
|
|
query: { open, root, ...company },
|
|
});
|
|
// 구조물 조합 기본 층 = 개인(123-1 · 누구든) · 개인 층 없음(회사 없음) = 아래 역할 규칙
|
|
const comboRoot = (fallback: string): string => (user.company_id ? "personal" : fallback);
|
|
if (user.role === "SYSTEM_ADMIN") {
|
|
const desc = L("B01_Dashboard_PermMasterWrite");
|
|
return [
|
|
{
|
|
key: "m01",
|
|
title: L("B01_Dashboard_MasterElements"),
|
|
desc: L("B01_Dashboard_PermSourceRead"),
|
|
route: ROUTES.M01_MASTER_DATA,
|
|
},
|
|
m02(L("B01_Dashboard_CardStructCombo"), "구조물조합", comboRoot("master"), desc),
|
|
m02(L("B01_Dashboard_CardStructOption"), "옵션", "master", desc),
|
|
m02(L("B01_Dashboard_CardDrawing"), "도면", "master", desc),
|
|
];
|
|
}
|
|
// 회사 수정 = 회사 관리자 · 회사 마스터(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)];
|
|
}
|
|
|
|
/** ☰ 진행 단계 자리 — 🏠 대시보드 + 카드 · 지금 칸 강조 · 같은 길(M02 → M02)은 머리 가드가 안 물어 여기서 먼저 */
|
|
export function mountSettingsDrawer(
|
|
user: SettingUser,
|
|
activeKey: string,
|
|
companyId: number | string | null,
|
|
): void {
|
|
const links = settingLinks(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);
|
|
}
|