Files
Aislo/B01_Dashboard/B01_Dashboard_UI_Common.ts
T
2026-07-17 12:51:47 +09:00

123 lines
3.7 KiB
TypeScript

import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
import {
createButton,
createCard,
hideLoadingOverlay,
showLoadingOverlay,
showToast,
} from "@ui/ui_template_elements";
import type { DashboardUser } from "./B01_Dashboard_Api_Fetch";
export function L(key: keyof typeof ui_locales): string {
return ui_locales[key][currentLanguageIndex];
}
export function buildSectionHeader(
titleText: string,
actionButtons: HTMLElement[] = [],
): HTMLElement {
const header = document.createElement("div");
header.className = "b01-dashboard__section-header";
header.style.display = "flex";
header.style.justifyContent = "space-between";
header.style.alignItems = "center";
header.style.marginBottom = "var(--spacing-16)";
const title = document.createElement("h3");
title.className = "ui-card__title";
title.style.margin = "0";
title.textContent = titleText;
const actions = document.createElement("div");
actions.className = "b01-dashboard__actions";
actions.append(...actionButtons);
header.append(title, actions);
return header;
}
export function section(
title: string,
body: HTMLElement,
wide = false,
actions: HTMLElement[] = [],
): HTMLElement {
const header = buildSectionHeader(title, actions);
const card = createCard({ body: [header, body], raised: true });
card.classList.add("b01-dashboard__section");
if (wide) card.classList.add("b01-dashboard__section--wide");
return card;
}
export function roleLabel(role: DashboardUser["role"]): string {
if (role === "SYSTEM_ADMIN") return L("B01_Dashboard_Role_SystemAdmin");
if (role === "ADMIN") return L("B01_Dashboard_Role_Admin");
return L("B01_Dashboard_Role_User");
}
export function table(headers: string[], rows: HTMLElement[][]): HTMLElement {
if (!rows.length) {
const empty = document.createElement("p");
empty.className = "b01-dashboard__empty";
empty.textContent = L("Common_Status_Empty");
return empty;
}
const wrap = document.createElement("div");
wrap.className = "b01-dashboard__table-wrap";
const tableEl = document.createElement("table");
tableEl.className = "b01-dashboard__table";
const thead = document.createElement("thead");
const headRow = document.createElement("tr");
for (const header of headers) {
const th = document.createElement("th");
th.textContent = header;
headRow.append(th);
}
thead.append(headRow);
const tbody = document.createElement("tbody");
for (const row of rows) {
const tr = document.createElement("tr");
for (const cell of row) {
const td = document.createElement("td");
td.append(cell);
tr.append(td);
}
tbody.append(tr);
}
tableEl.append(thead, tbody);
wrap.append(tableEl);
return wrap;
}
export function text(value: unknown): HTMLElement {
const span = document.createElement("span");
span.textContent = value == null || value === "" ? "-" : String(value);
return span;
}
export function actionPair(approve: () => void, reject: () => void): HTMLElement {
const row = document.createElement("div");
row.className = "b01-dashboard__actions";
row.append(
createButton({ label: L("B01_Dashboard_Approve"), variant: "ghost", onClick: approve }),
createButton({ label: L("B01_Dashboard_Reject"), variant: "danger", onClick: reject }),
);
return row;
}
export async function runRequest(action: () => Promise<unknown>): Promise<void> {
showLoadingOverlay();
try {
await action();
showToast(L("B01_Dashboard_Saved"), "success");
} catch (error) {
showToast(error instanceof Error ? error.message : L("B01_Dashboard_RequestFailed"), "error");
} finally {
hideLoadingOverlay();
}
}
export function formatDate(value?: string | null): string {
return value ? value.slice(0, 10) : "-";
}