Files
Aislo/B01_Dashboard/B01_Dashboard_UI_View_Assigned.ts
T
eomsangdonandClaude Sonnet 5.5 7e34152de8 feat(B01): 받은 예정노선 · 임시 보관함 · 사람 · 회사 정보 · 회사 설계 기본값 세부 페이지 (549-1)
- 새 페이지 다섯(View_Assigned · Temp · People · Company · CompanyDefaults) · 등록부 다섯 줄 교체
- 표 줄 40 · 세로선 없음 · 줄 끝 ⋯ · 한글 배지 · 빈 상태 · 사람 탭 가입 요청 수 배지 · 보관함 남은 날 막대(7 일 안 빨강)
- 옛 구역 정리(Legacy · Company · AssignedPlans · TempUpload 다시 씀) · 시험 test_549 · test_546 stub 일반화

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 18:26:27 +09:00

82 lines
2.8 KiB
TypeScript

/* =============================================================================
* B01_Dashboard_UI_View_Assigned.ts
* 세부 페이지 「받은 예정노선」(549-1) — 산림청이 우리 회사에 지정한 예정노선 연도 표.
* 0 건이어도 메뉴 · 페이지 보임 · 줄 끝 ⋯ = 보기(D02) · 연결(모달)
* ========================================================================== */
import { ROUTES } from "@config/config_frontend";
import { goToWorkflowStage } from "../A00_Common/b_workflow_nav";
import { kstText } from "../common_util/common_util_time_kst";
import { fetchAssignedPlans, type AssignedPlan } from "./B01_Dashboard_UI_AssignedPlans";
import { L } from "./B01_Dashboard_UI_Common";
import {
badge,
dataTable,
emptyState,
nameCell,
pageFrame,
rowMenu,
type Cell,
type Column,
} from "./B01_Dashboard_UI_PageKit";
import { openPlanLinkModal } from "./B01_Dashboard_UI_PlanLink";
import type { ViewCtx } from "./B01_Dashboard_UI_Views";
const COLUMNS: Column[] = [
{ label: L("DE_New_Plan") },
{ label: L("DE_Assigned_Year"), width: "90px" },
{ label: L("D04_Col_Confirmed"), width: "150px" },
{ label: L("DE_Assigned_State"), width: "220px" },
{ label: "", width: "44px" },
];
function stateCell(plan: AssignedPlan): HTMLElement {
const cell = document.createElement("span");
cell.className = "b01-pg-inline";
cell.append(
plan.linked_project_id
? badge(L("DE_Assigned_Linked"), "success")
: badge(L("DE_Assigned_Unlinked"), "neutral"),
);
if (plan.update_available) cell.append(badge(L("DE_Assigned_Update"), "warning"));
return cell;
}
function planRow(plan: AssignedPlan): Cell[] {
const view = (): void => void goToWorkflowStage(plan.project_id, ROUTES.D02_PLAN_BASE);
return [
nameCell(plan.project_name),
String(plan.year),
kstText(plan.confirmed_at),
stateCell(plan),
rowMenu([
{ label: L("DE_Assigned_View"), onClick: view },
{
label: L("DE_Assigned_Link"),
onClick: () =>
void openPlanLinkModal(plan.assignee_id, `${plan.project_name} ${plan.year}`),
},
]),
];
}
export async function mountAssigned(host: HTMLElement, ctx: ViewCtx): Promise<void> {
const page = pageFrame(
host,
L("DE_Assigned_Title"),
"산림청이 지정한 예정노선이 여기 모임 · 연결하면 임도 설계가 그 노선으로 시작됨",
);
const plans = await fetchAssignedPlans().catch(() => []);
if (!host.isConnected) return;
page.body.append(
plans.length
? dataTable(COLUMNS, plans.map(planRow))
: emptyState({
icon: "route",
text: "아직 받은 예정노선이 없음",
hint: "산림청이 우리 회사에 예정노선을 지정하면 여기에 나타남",
onGuide: () => ctx.go("guide"),
}),
);
}