feat(B08·B09): 표 칸 안내 · 경고 줄 맨 아래 · 박스보기 · 가로 열 수 보조 탭 줄 오른쪽(202-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018jonfdxn1Xit9bdkNJpE4G
This commit is contained in:
@@ -36,30 +36,30 @@
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* 171-3 묶음 탭 머리 — 안내 글 + 보기 단추 */
|
||||
.b09-estimation__bar {
|
||||
/* 202-1 보조 탭 줄 오른쪽 도구(박스보기 · 가로 열 수) — 빈 보조 줄에서도 보임 · 단추 · 글 한 줄 */
|
||||
.b09-estimation__tools {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
flex: none;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
gap: var(--spacing-8);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* 185-2 보기 단추 글 한 줄 */
|
||||
.b09-estimation__bar .ui-btn {
|
||||
.b09-estimation__tools .ui-btn,
|
||||
.b09-estimation__tools .ui-group-cards__label {
|
||||
flex: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 200-1 묶음 탭 도구 줄 — 안내 글 = 남는 자리 한 줄 · 넘치면 줄임표(전문 = 공용 호버) */
|
||||
.b09-estimation__bar {
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
/* 202-1 안내 줄 = 표 · 카드 판 아래(묶음 탭은 한 줄 줄임표 · 전문 = 공용 호버) */
|
||||
.b09-estimation .ui-data-table + .ui-general-block__empty,
|
||||
.b09-estimation .ui-group-cards + .ui-general-block__empty {
|
||||
margin: var(--spacing-8) 0 0;
|
||||
}
|
||||
|
||||
.b09-estimation__line-hint {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -184,6 +184,7 @@ export function renderB09Estimation(root: HTMLElement): void {
|
||||
const show = (tab: TabId, focus?: string): void => {
|
||||
current = tab;
|
||||
bars.draw(tab);
|
||||
bars.setTools([]); // 보기 단추 · 열 수는 묶음 탭만 다시 채움(202-1)
|
||||
if (!projectId) return void panel.replaceChildren(note("프로젝트를 먼저 고르세요."));
|
||||
if (!payload) return void panel.replaceChildren(note("원가 자료를 불러오는 중…"));
|
||||
const build = BUILDERS[tab];
|
||||
@@ -246,11 +247,20 @@ export function renderB09Estimation(root: HTMLElement): void {
|
||||
if (isGroupTab(tab)) {
|
||||
const redraw = (): void => show(tab);
|
||||
return void panel.replaceChildren(
|
||||
...renderGroupPanel({ tab, spec, hint, focus, goto, makeTable, redraw }),
|
||||
...renderGroupPanel({
|
||||
tab,
|
||||
spec,
|
||||
hint,
|
||||
focus,
|
||||
goto,
|
||||
makeTable,
|
||||
redraw,
|
||||
setTools: bars.setTools,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const table = makeTable();
|
||||
panel.replaceChildren(...(hint ? [hint] : []), table.root);
|
||||
panel.replaceChildren(table.root, ...(hint ? [hint] : [])); // 202-1 안내 줄 = 표 아래
|
||||
if (focus !== undefined) {
|
||||
const index = rowIndex(spec.rows, focus);
|
||||
if (index >= 0) requestAnimationFrame(() => table.focusRow(index));
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* 위 탭 = `TAB_GROUPS`(`…_UI_Tabs`) · 아래 탭 하나뿐인 위 탭 = 보이지 않는 sm 단추 한 줄(높이만 채움)
|
||||
* 위 탭 누름 = 그 묶음에서 마지막으로 본 아래 탭(이 화면 안 Map · 저장 안 함) · 없으면 첫 아래 탭
|
||||
* 탭 이동은 `draw(탭)` — 이동이 묶음을 넘어도 위 탭이 따라 켜짐
|
||||
* 보기 단추 · 가로 열 수(202-1) = 아래 줄 오른쪽 맞춤 자리(`setTools`) · 빈 줄에서도 보임
|
||||
* ========================================================================== */
|
||||
|
||||
import { createButton } from "@ui/ui_template_elements";
|
||||
@@ -15,6 +16,8 @@ export interface TabBars {
|
||||
sub: HTMLElement;
|
||||
/** 이 탭이 켜진 꼴로 두 줄을 다시 그림 */
|
||||
draw: (tab: TabId) => void;
|
||||
/** 아래 줄 오른쪽 도구(박스보기 · 가로 열 수) — 빈 목록 = 비움 */
|
||||
setTools: (tools: HTMLElement[]) => void;
|
||||
}
|
||||
|
||||
function tabButton(label: string, on: boolean, size: "sm" | undefined, pick: () => void) {
|
||||
@@ -35,6 +38,8 @@ export function createTabBars(onPick: (tab: TabId) => void): TabBars {
|
||||
top.setAttribute("role", "tablist");
|
||||
const sub = document.createElement("div");
|
||||
sub.className = "b09-estimation__tabs";
|
||||
const tools = document.createElement("div");
|
||||
tools.className = "b09-estimation__tools";
|
||||
const lastSeen = new Map<TabId, TabId>();
|
||||
|
||||
const draw = (tab: TabId): void => {
|
||||
@@ -53,11 +58,11 @@ export function createTabBars(onPick: (tab: TabId) => void): TabBars {
|
||||
const single = picked.length === 1;
|
||||
sub.classList.toggle("b09-estimation__tabs--blank", single);
|
||||
sub.setAttribute("role", single ? "presentation" : "tablist");
|
||||
sub.setAttribute("aria-hidden", String(single));
|
||||
if (single) {
|
||||
const ghost = createButton({ label: tabName(picked[0]), variant: "ghost", size: "sm" });
|
||||
ghost.tabIndex = -1;
|
||||
return void sub.replaceChildren(ghost);
|
||||
ghost.setAttribute("aria-hidden", "true"); // 도구는 보이는 줄이라 줄 전체를 숨기지 않음
|
||||
return void sub.replaceChildren(ghost, tools);
|
||||
}
|
||||
sub.replaceChildren(
|
||||
...picked.map((id) => {
|
||||
@@ -65,7 +70,9 @@ export function createTabBars(onPick: (tab: TabId) => void): TabBars {
|
||||
button.dataset.b09Tab = id;
|
||||
return button;
|
||||
}),
|
||||
tools,
|
||||
);
|
||||
};
|
||||
return { top, sub, draw };
|
||||
const setTools = (items: HTMLElement[]): void => tools.replaceChildren(...items);
|
||||
return { top, sub, draw, setTools };
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
* 머리 줄 = 묶음 첫 줄 · 합계 줄 = 키 끝 `|합계` · `|총계` · 그 밖 = 몸 줄(표 줄 번호 그대로)
|
||||
* 목록표에서 온 호표(181-2) = 박스 붉은 외곽선 · 표 보기 = 그 호표 줄 구간 전체 붉은 외곽선
|
||||
* 보기 · 가로 열 수 기억 = `b_page_state`(`b09-group-view` · `b09-group-cols` · 탭마다) · 못 읽으면 카드 · 2
|
||||
* 도구 줄(200-1) = 안내 글 + 가로 열 수 + 보기 단추 한 줄 · 안내 글 길면 줄임표 + 공용 호버로 전문
|
||||
* 보기 단추 · 가로 열 수(202-1) = 페이지 보조 탭 줄 오른쪽(`setTools`) · 안내 글 = 표 · 카드 판 맨 아래
|
||||
* 안내 글 길면 한 줄 줄임표 + 공용 호버로 전문(200-1)
|
||||
* ========================================================================== */
|
||||
|
||||
import type { DataRow, DataTable } from "@ui/ui_template_data_table";
|
||||
@@ -176,7 +177,7 @@ function numberFormat(spec: TabTable, key: string): (v: number | null | undefine
|
||||
|
||||
/* ── 그리기 ───────────────────────────────────────────────────────────── */
|
||||
|
||||
/** 안내 글 = 도구 줄 한 칸(줄임표) · 잘렸을 때만 마우스 올리면 전문(공용 호버 185-3) */
|
||||
/** 안내 글 = 한 줄(줄임표) · 잘렸을 때만 마우스 올리면 전문(공용 호버 185-3) */
|
||||
function lineHint(hint: HTMLElement | null): HTMLElement | null {
|
||||
if (!hint) return null;
|
||||
hint.classList.add("b09-estimation__line-hint");
|
||||
@@ -187,7 +188,7 @@ function lineHint(hint: HTMLElement | null): HTMLElement | null {
|
||||
/** 이 화면 안 보기(기억이 안 돼도 바꾼 보기 유지) */
|
||||
const chosen = new Map<TabId, GroupView>();
|
||||
|
||||
/** 묶음 탭 — 카드 = 카드 판(안내 · 가로 열 수 · 보기 단추 한 줄) · 표 = 머리(안내 + 보기 단추 한 줄) + 표 */
|
||||
/** 묶음 탭 — 카드 = 카드 판 + 안내 글 · 표 = 표 + 안내 글 · 보기 단추 · 열 수 = `setTools`(보조 탭 줄 오른쪽) */
|
||||
export function renderGroupPanel(o: {
|
||||
tab: TabId;
|
||||
spec: TabTable;
|
||||
@@ -196,6 +197,7 @@ export function renderGroupPanel(o: {
|
||||
goto: (link: Link | null) => void;
|
||||
makeTable: (rowClass?: (index: number) => string | null) => DataTable;
|
||||
redraw: () => void;
|
||||
setTools: (tools: HTMLElement[]) => void;
|
||||
}): HTMLElement[] {
|
||||
const view = chosen.get(o.tab) ?? readGroupView(o.tab);
|
||||
const lead = lineHint(o.hint);
|
||||
@@ -221,17 +223,15 @@ export function renderGroupPanel(o: {
|
||||
focus: at,
|
||||
money: numberFormat(o.spec, "sum"),
|
||||
qty: numberFormat(o.spec, "qty"),
|
||||
lead, // 200-1 안내 글도 같은 줄
|
||||
actions: [toggle], // 185-2 가로 열 수 단추와 한 줄
|
||||
actions: [toggle],
|
||||
placeTools: o.setTools, // 202-1 가로 열 수 · 보기 단추 = 보조 탭 줄 오른쪽
|
||||
});
|
||||
cards.dataset.b09Table = o.tab;
|
||||
return [cards];
|
||||
return [cards, ...(lead ? [lead] : [])];
|
||||
}
|
||||
const bar = document.createElement("div");
|
||||
bar.className = "b09-estimation__bar";
|
||||
bar.append(...(lead ? [lead] : []), toggle);
|
||||
o.setTools([toggle]);
|
||||
const range = pickRange(o.spec.rows, o.focus);
|
||||
const table = o.makeTable((i) => pickClass(range, i));
|
||||
if (at >= 0) requestAnimationFrame(() => table.focusRow(at));
|
||||
return [bar, table.root];
|
||||
return [table.root, ...(lead ? [lead] : [])];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user