feat(z01): 열 제목 눌러 차례 — 누르기 전엔 표시 없음(원본 차례) · 오름→내림→원본 · 세우기는 서버 몫(sort·desc 보냄 · 서버가 거절하면 누른 표시 지움) · 제목은 서버가 준 sortable 열만 눌림(눌렀는데 그대로인 화면 막음)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
2026-09-16 10:59:36 +09:00
co-authored by Claude Opus 5
parent d4aa466b60
commit 3a61d4c158
5 changed files with 79 additions and 4 deletions
+28 -2
View File
@@ -16,6 +16,7 @@ import {
clampPage,
columnTitle,
latestOnly,
nextSort,
noticeLines,
outdatedBanner,
pageCount,
@@ -25,6 +26,7 @@ import {
valueWithUnit,
type CellInfo,
type MasterColumn,
type SortOrder,
} from "./Z01_MasterData_UI_Cells";
const PAGE_SIZE = 50;
@@ -69,7 +71,7 @@ function stateText(info: CellInfo, column: MasterColumn): string {
export function buildRowsView(): RowsView {
let source: RowsSource | null = null;
const state = { page: 1, q: "" };
const state = { page: 1, q: "", sort: null as SortOrder | null };
let showHidden = false;
let last: MasterRows | null = null;
let selected: { index: number; key: string } | null = null;
@@ -150,13 +152,24 @@ export function buildRowsView(): RowsView {
async function load(): Promise<void> {
if (!source) return;
const asked = state.sort;
grid.classList.add("is-loading");
let data: MasterRows | undefined;
try {
data = await fetchLatest(source, { page: state.page, size: PAGE_SIZE, q: state.q });
data = await fetchLatest(source, {
page: state.page,
size: PAGE_SIZE,
q: state.q,
sort: state.sort,
});
} catch (error) {
grid.classList.remove("is-loading");
showToast(error instanceof Error ? error.message : L("Z01_MasterData_LoadFailed"), "error");
// 서버가 그 열로는 못 세운다고 하면(400) 누른 표시를 지움 — 눌렀는데 안 바뀐 것처럼 두지 않음.
if (asked && state.sort === asked) {
state.sort = null;
draw();
}
return;
}
// 옛 요청 — 로딩 표시는 뒤 요청 몫이라 그대로 둠.
@@ -184,6 +197,18 @@ export function buildRowsView(): RowsView {
if (column.label !== column.key) {
th.append(el("span", { className: "z01-master__key", text: column.key }));
}
// 차례 — 누르기 전에는 아무 표시도 없음(원본 차례라는 것이 보이게 · 2026-09-16 브레인).
if (meta.sortable?.includes(column.key)) {
th.classList.add("is-sortable");
if (state.sort?.key === column.key) {
th.append(el("span", { className: "z01-master__sort", text: state.sort.desc ? "▼" : "▲" }));
}
th.addEventListener("click", () => {
state.sort = nextSort(state.sort, column.key);
state.page = 1;
void load();
});
}
return th;
}
@@ -368,6 +393,7 @@ export function buildRowsView(): RowsView {
function show(picked: RowsSource): void {
source = picked;
state.page = 1;
state.sort = null;
title.textContent = picked.title;
titleKey.textContent = picked.key;
notice.hidden = true;