- 해시 ?tab= 탭 줄(B08 단추 꼴) · 고른 탭 자료만 받음 · 설정 카드는 탭 줄 위 · 회사 고르기 알약은 탭 줄 오른쪽 하나 - 회사 없음 진입 두 곳(router · M02 Layer)은 ?tab=company · 회사 관리자 프로젝트 목록 한 번만 받음 - 개요 숫자 카드(단계별 · 실패 · 재확인 · 가입 대기 · 보관함 · 리소스) · 프로젝트 표 칸 보강 · 찾기 · 거르기 · 쪽 넘김 · 진행 현황 - 회사 정보 칸(사업자번호 · 대표 · 상태) · 팀원 읽기 · 자산 표 · 내 계정 마지막 로그인 · 시스템 리소스 7·30·90일 · 활성 추이 · 전체 회사 · 사용자 · 로그 쪽 · 고객 문의 - 시험 test_b01_dashboard_tabs 신규 · test_b01_settings_cards 고침 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
/* =============================================================================
|
|
* 쪽 넘김 표(92장) — 전용 탭에선 4줄 제한을 풀고 쪽으로 넘김.
|
|
* ========================================================================== */
|
|
|
|
import { createButton } from "@ui/ui_template_elements";
|
|
import { table } from "@ui/ui_template_general_blocks";
|
|
import { L } from "./B01_Dashboard_UI_Common";
|
|
|
|
export const PAGE_SIZE = 10;
|
|
|
|
/** 「‹ 이전 · 1 / 3 쪽 · 다음 ›」 줄 — 쪽이 하나뿐이면 건수만 */
|
|
export function buildPager(
|
|
page: number,
|
|
pages: number,
|
|
total: number,
|
|
onPage: (page: number) => void,
|
|
): HTMLElement {
|
|
const bar = document.createElement("div");
|
|
bar.className = "b01-dashboard__pager";
|
|
const count = document.createElement("span");
|
|
count.className = "b01-dashboard__pager-count";
|
|
count.textContent = L("B01_Pg_Total").replace("{count}", String(total));
|
|
bar.append(count);
|
|
if (pages <= 1) return bar;
|
|
const label = document.createElement("span");
|
|
label.className = "b01-dashboard__pager-page";
|
|
label.textContent = L("B01_Pg_Page")
|
|
.replace("{page}", String(page))
|
|
.replace("{pages}", String(pages));
|
|
const prev = createButton({
|
|
label: L("Common_Btn_Prev"),
|
|
variant: "ghost",
|
|
disabled: page <= 1,
|
|
onClick: () => onPage(page - 1),
|
|
});
|
|
const next = createButton({
|
|
label: L("Common_Btn_Next"),
|
|
variant: "ghost",
|
|
disabled: page >= pages,
|
|
onClick: () => onPage(page + 1),
|
|
});
|
|
bar.append(prev, label, next);
|
|
return bar;
|
|
}
|
|
|
|
export interface PagedTable<T> {
|
|
root: HTMLElement;
|
|
/** 목록을 바꿔 첫 쪽부터 다시 그림(찾기 · 거르기) */
|
|
setItems: (items: T[]) => void;
|
|
}
|
|
|
|
/** 받아 둔 목록을 `pageSize` 줄씩 나눠 그리는 표 */
|
|
export function createPagedTable<T>(
|
|
headers: string[],
|
|
rowOf: (item: T) => HTMLElement[],
|
|
items: T[],
|
|
pageSize = PAGE_SIZE,
|
|
): PagedTable<T> {
|
|
const root = document.createElement("div");
|
|
root.className = "b01-dashboard__paged";
|
|
let current = items;
|
|
let page = 1;
|
|
const draw = (): void => {
|
|
const pages = Math.max(1, Math.ceil(current.length / pageSize));
|
|
page = Math.min(page, pages);
|
|
const slice = current.slice((page - 1) * pageSize, page * pageSize);
|
|
root.replaceChildren(
|
|
table(headers, slice.map(rowOf)),
|
|
buildPager(page, pages, current.length, (next) => {
|
|
page = next;
|
|
draw();
|
|
}),
|
|
);
|
|
};
|
|
draw();
|
|
return {
|
|
root,
|
|
setItems: (next) => {
|
|
current = next;
|
|
page = 1;
|
|
draw();
|
|
},
|
|
};
|
|
}
|