fix(B01): 항목별 탭 화면 다듬음 — 회사 정보 칸 줄맞춤 · 리소스 기간 글 · 프로젝트 표 단계 막대 두 줄 · 찾기 줄 정렬 (92-1·92-2)

- 정보 칸 라벨 · 값 한 쌍씩 묶음 · 리소스 그래프 글이 고른 기간을 따름 · 프로젝트 표 가로 여백 줄임
- 화면 검증(ORCA) 권한 셋 · 밝음 · 어두움 · 390px 끝 — PLAN 92장 검증완료

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
2026-10-08 14:10:03 +09:00
co-authored by Claude Sonnet 5.5
parent 2a2c4d0f62
commit 22266508d4
6 changed files with 39 additions and 12 deletions
+12 -9
View File
@@ -23,12 +23,14 @@ import { formatDate, L, runRequest } from "./B01_Dashboard_UI_Common";
import { createPagedTable } from "./B01_Dashboard_UI_Paging";
/** 라벨 + 값 한 칸 — 회사 정보 격자 */
function infoItem(label: string, value: unknown): HTMLElement[] {
function infoItem(label: string, value: unknown): HTMLElement {
const item = document.createElement("div");
const term = document.createElement("dt");
term.textContent = label;
const detail = document.createElement("dd");
detail.textContent = value == null || value === "" ? "-" : String(value);
return [term, detail];
item.append(term, detail);
return item;
}
export function buildCompanyPanel(state: DashboardState): HTMLElement {
@@ -54,15 +56,16 @@ export function buildCompanyPanel(state: DashboardState): HTMLElement {
const info = document.createElement("dl");
info.className = "b01-dashboard__info";
info.append(
...infoItem(L("B01_Dashboard_Table_Company"), company.name),
...infoItem(L("B01_Dashboard_Field_BusinessNumber"), company.business_registration_number),
...infoItem(L("B01_Co_Owner"), company.business_owner),
...infoItem(L("B01_Co_Status"), company.business_status),
...infoItem(L("B01_Dashboard_Field_Address"), company.business_address),
...infoItem(L("B01_Co_Members"), company.user_count ?? 0),
...infoItem(L("B01_Co_Projects"), company.project_count ?? 0),
infoItem(L("B01_Dashboard_Table_Company"), company.name),
infoItem(L("B01_Dashboard_Field_BusinessNumber"), company.business_registration_number),
infoItem(L("B01_Co_Owner"), company.business_owner),
infoItem(L("B01_Co_Status"), company.business_status),
infoItem(L("B01_Dashboard_Field_Address"), company.business_address),
infoItem(L("B01_Co_Members"), company.user_count ?? 0),
infoItem(L("B01_Co_Projects"), company.project_count ?? 0),
);
const box = document.createElement("div");
box.className = "b01-dashboard__stack";
box.append(info, wrap);
// 회사 정보 수정 (2026-09-06 사용자 지시) — 관리자만 보인다.
if (state.user.role !== "USER") {
+3 -1
View File
@@ -121,11 +121,13 @@ export function buildAccountInfo(user: DashboardUser): HTMLElement {
[L("B01_Ac_AuthExpires"), formatDate(user.auth_expires_at)],
];
for (const [label, value] of rows) {
const item = document.createElement("div");
const term = document.createElement("dt");
term.textContent = label;
const detail = document.createElement("dd");
detail.textContent = value;
info.append(term, detail);
item.append(term, detail);
info.append(item);
}
return info;
}
@@ -96,6 +96,7 @@ export function buildProjectsTab(state: DashboardState, projects: ProjectItem[])
);
const progress = createPagedTable(progressHeaders(), progressRow, projects);
list.root.classList.add("b01-dashboard__paged--dense");
let filter: ProjectFilter = parseFilter(currentQuery().get("filter"));
const query = createInputField({
label: L("B01_Pj_Search"),
+1 -1
View File
@@ -66,7 +66,7 @@ function buildResourceMetrics(resources: ResourceData | null): HTMLElement {
function buildResourceChart(resources: ResourceData | null, days: number): HTMLElement {
return buildTrendChart(resources, days, {
caption: L("B01_Dashboard_Resources_ChartCaption"),
caption: L("B01_Sy_ResourceCaption").replace("{days}", String(days)),
ariaLabel: L("B01_Dashboard_Resources_ChartAria"),
series: [
{ name: L("B01_Dashboard_Metric_Cpu"), colorIndex: 0, pick: (h) => h.cpu_usage_percent },
+21 -1
View File
@@ -66,11 +66,15 @@
gap: var(--spacing-8);
}
.b01-dashboard__overview {
gap: var(--spacing-24);
}
/* 찾기 · 거르기 줄 */
.b01-dashboard__filters {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
align-items: flex-start;
gap: var(--spacing-16);
margin-bottom: var(--spacing-16);
}
@@ -102,6 +106,12 @@
margin: 0 0 var(--spacing-16);
}
.b01-dashboard__stack {
display: flex;
flex-direction: column;
gap: var(--spacing-16);
}
.b01-dashboard__info dt {
color: var(--color-text-secondary);
font-size: var(--text-caption);
@@ -154,3 +164,13 @@
vertical-align: bottom;
white-space: nowrap;
}
/* 칸이 많은 표(프로젝트) — 가로 여백을 줄이고 단계 막대가 두 줄 안에 들어오게 */
.b01-dashboard__paged--dense .b01-dashboard__table th,
.b01-dashboard__paged--dense .b01-dashboard__table td {
padding: var(--spacing-8);
}
.b01-dashboard__paged--dense .ui-workflow-layout__steps {
min-width: 400px;
}
@@ -77,6 +77,7 @@ export const ui_locales_b1_tabs = {
/* --- 시스템 --- */
B01_Sy_Period: ["기간", "Period"],
B01_Sy_Days: ["{days}일", "{days} days"],
B01_Sy_ResourceCaption: ["최근 {days}일 리소스 사용률", "Resource usage, last {days} days"],
B01_Sy_ActiveTrend: ["활성 추이", "Activity trend"],
B01_Sy_TrendCaption: ["활성 사용자 · 활성 프로젝트 수", "Active users and active projects"],
B01_Sy_AllCompanies: ["전체 회사", "All companies"],