diff --git a/frontend/src/app/router.ts b/frontend/src/app/router.ts index 185407ec..8a809c12 100644 --- a/frontend/src/app/router.ts +++ b/frontend/src/app/router.ts @@ -22,6 +22,8 @@ export const router = createRouter({ // KBX v60 Pages { path: '/model-ops/shadow-run-jobs', component: () => import('../features/shadow-run/pages/ShadowRunQueue.vue'), meta: { screenId: 'model-ops.shadow-run.queue', module: 'ModelOps', title: 'Shadow Run Jobs', permissions: ['model.read'] } }, { path: '/model-ops/models-master', component: () => import('../features/models/pages/ModelList.vue'), meta: { screenId: 'model-ops.models.master', module: 'ModelOps', title: 'Models (Master-Detail)', permissions: ['model.read'] } }, + { path: '/system/common-codes', component: () => import('../features/system/pages/CommonCodeManagementPage.vue'), meta: { screenId: 'SCR-SYS-001', templateId: 'T01', module: 'System', section: 'System', title: '공통코드 관리', order: 1, favoriteAllowed: true } }, { path: '/governance/approvals', component: () => import('../features/approval/pages/ApprovalQueue.vue'), meta: { screenId: 'governance.approval.queue', module: 'Governance', title: 'Approval Queue', permissions: ['approval.review'] } } ] }) + diff --git a/frontend/src/design-system/base.css b/frontend/src/design-system/base.css index bf4947ab..bb57b6ce 100644 --- a/frontend/src/design-system/base.css +++ b/frontend/src/design-system/base.css @@ -7,9 +7,45 @@ body { background: var(--ks-color-canvas); color: var(--ks-color-text); font-family: Inter, Pretendard, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - font-size: var(--ks-font-body); - line-height: var(--ks-line-body); + font-size: var(--ks-font-body, 12px); + line-height: var(--ks-line-body, 16px); } + +/* KBX v60 Global Typography Token Scale Standard (표준 폰트 크기 계층 규격) */ +h1, .ks-title { + font-size: var(--ks-font-page, 16px) !important; + line-height: var(--ks-line-page, 22px) !important; + font-weight: 700 !important; +} + +h2, .ks-section-title { + font-size: var(--ks-font-section, 14px) !important; + line-height: var(--ks-line-section, 18px) !important; + font-weight: 700 !important; +} + +h3, h4, dt, legend { + font-size: var(--ks-font-section, 14px) !important; + line-height: var(--ks-line-section, 18px) !important; + font-weight: 600 !important; +} + +p, span, li, td, input, select, button, label, .ks-font-body { + font-size: var(--ks-font-body, 12px); + line-height: var(--ks-line-body, 16px); +} + +th, .ag-header-cell-text { + font-size: var(--ks-font-grid, 12px) !important; + line-height: var(--ks-line-grid, 16px) !important; + font-weight: 700 !important; +} + +caption, .hint, .note, .ks-caption, small, .help-text, .ks-font-caption { + font-size: var(--ks-font-caption, 11px) !important; + line-height: var(--ks-line-caption, 14px) !important; +} + button, input, select, textarea { font: inherit; } a { color: var(--ks-color-action); } :focus-visible { outline: var(--ks-focus-ring-width) solid color-mix(in srgb, var(--ks-color-focus) 55%, transparent); outline-offset: var(--ks-focus-ring-offset); } @@ -56,7 +92,79 @@ input[type="text"], input[type="number"], input[type="date"], select, textarea, box-sizing: border-box; } -/* Default Width Standards for Form & Filter Controls (기본 넓이 표준 규격) */ +/* Automatic Global Inline Rule for Filter Container Slots */ +.ks-page__filters .ks-text-field, +.ks-page__filters .ks-select, +.ks-page__filters .ks-date-field { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + gap: var(--ks-space-2, 6px) !important; +} + +.ks-page__filters:empty, +.ks-page__command-bar:empty, +.ks-page__summary:empty { + display: none !important; + min-height: 0 !important; + padding: 0 !important; + margin: 0 !important; + border: none !important; +} + + +.ks-page__filters .ks-text-field__label, +.ks-page__filters .ks-select__label, +.ks-page__filters .ks-date-field__label, +.ks-text-field--inline .ks-text-field__label, +.ks-select--inline .ks-select__label, +.ks-date-field--inline .ks-date-field__label { + width: var(--ks-field-label-width, 72px) !important; + min-width: var(--ks-field-label-width, 72px) !important; + max-width: var(--ks-field-label-width, 72px) !important; + text-align: left !important; + white-space: nowrap !important; + flex-shrink: 0 !important; + margin-bottom: 0 !important; + font-size: var(--ks-font-body) !important; +} + +.ks-page__filters .ks-text-field__container, +.ks-page__filters .ks-select__container, +.ks-page__filters .ks-date-field__container, +.ks-text-field--inline .ks-text-field__container, +.ks-select--inline .ks-select__container, +.ks-date-field--inline .ks-date-field__container { + flex: 1 1 auto !important; + min-width: 0 !important; + max-width: 100% !important; + width: 100% !important; +} + + +.ks-set-sm, .ks-filter-sm { + width: var(--ks-set-width-sm, 200px) !important; + min-width: var(--ks-set-width-sm, 200px) !important; + max-width: var(--ks-set-width-sm, 200px) !important; + flex-shrink: 0 !important; +} + +.ks-set-md, .ks-filter-md { + width: var(--ks-set-width-md, 260px) !important; + min-width: var(--ks-set-width-md, 260px) !important; + max-width: var(--ks-set-width-md, 260px) !important; + flex-shrink: 0 !important; +} + +.ks-set-lg, .ks-filter-lg { + width: var(--ks-set-width-lg, 340px) !important; + min-width: var(--ks-set-width-lg, 340px) !important; + max-width: var(--ks-set-width-lg, 340px) !important; + flex-shrink: 0 !important; +} + + + select, .p-select, .p-dropdown, .ks-select, .status-select { width: var(--ks-control-width-select); max-width: 100%; @@ -75,10 +183,11 @@ input[type="date"] { .filters, .ks-page__filters form, .ks-page__filters section { display: flex; align-items: center; - gap: var(--ks-space-2); - flex-wrap: wrap; + gap: var(--ks-space-3); + flex-wrap: nowrap; } + button, .p-button, .ks-button { height: var(--ks-control-height) !important; font-size: var(--ks-font-body) !important; diff --git a/frontend/src/design-system/tokens.css b/frontend/src/design-system/tokens.css index 39b0914f..bf9cdc6b 100644 --- a/frontend/src/design-system/tokens.css +++ b/frontend/src/design-system/tokens.css @@ -59,9 +59,14 @@ /* KBX v60 ERP/OMS/WMS Ultra-Dense Control & Layout Heights & Default Widths */ --ks-control-height: 28px; /* ERP/OMS Input Control 28px */ + --ks-field-label-width: 72px; /* Standardized Inline Field Label Fixed Width 72px */ + --ks-set-width-sm: 200px; /* Standardized Compact Field Set Width 200px */ + --ks-set-width-md: 260px; /* Standardized Default Field Set Width 260px */ + --ks-set-width-lg: 340px; /* Standardized Wide Field Set Width 340px */ --ks-control-width-select: 160px; /* Standard Select/Dropdown Default Width 160px */ --ks-control-width-search: 220px; /* Standard Search Input Default Width 220px */ --ks-control-width-date: 140px; /* Standard Date Field Default Width 140px */ + --ks-grid-row-height: 28px; /* Ultra-Dense Grid Row 28px */ --ks-grid-header-height: 30px; /* Grid Header 30px */ --ks-content-max: 100%; /* Full Screen Utilization */ @@ -266,34 +271,90 @@ } /* Raw Table Standard Grid Class for legacy fallback tables */ -.grid-table, .kbx-grid-table, .models-table, .shadow-runs-table { +.grid-table, .kbx-grid-table, .models-table, .shadow-runs-table, .ks-grid-table { width: 100%; border-collapse: collapse; font-size: var(--ks-font-grid); background: var(--ks-color-surface); - border: 1px solid var(--ks-color-border); + border: 1px solid var(--ks-color-border-strong); border-radius: var(--ks-radius-sm); } -.grid-table th, .kbx-grid-table th, .models-table th, .shadow-runs-table th { - height: 30px; +.grid-table th, .kbx-grid-table th, .models-table th, .shadow-runs-table th, .ks-grid-table th { + height: var(--ks-grid-header-height, 30px); padding: 0 10px; - background-color: var(--ks-color-canvas); - border-bottom: 1px solid var(--ks-color-border); - font-weight: 600; + background-color: #f1f5f9; + border-bottom: 2px solid var(--ks-color-border-strong); + font-weight: 700; text-align: left; - color: var(--ks-color-text-muted); + color: var(--ks-color-neutral-900); } -.grid-table td, .kbx-grid-table td, .models-table td, .shadow-runs-table td { - height: 28px; +[data-theme='dark'] .grid-table th, +[data-theme='dark'] .kbx-grid-table th, +[data-theme='dark'] .models-table th, +[data-theme='dark'] .shadow-runs-table th, +[data-theme='dark'] .ks-grid-table th { + background-color: #1e293b; + color: #f8fafc; + border-bottom: 2px solid #475569; +} + +.grid-table td, .kbx-grid-table td, .models-table td, .shadow-runs-table td, .ks-grid-table td { + height: var(--ks-grid-row-height, 28px); padding: 0 10px; border-bottom: 1px solid var(--ks-color-border); - color: var(--ks-color-text); - box-sizing: border-box; + color: var(--ks-color-neutral-950); + box-sizing: border-border-box; } -.grid-table tr:hover, .kbx-grid-table tr:hover, .models-table tr:hover, .shadow-runs-table tr:hover { - background-color: var(--ks-color-neutral-100); +[data-theme='dark'] .grid-table td, +[data-theme='dark'] .kbx-grid-table td, +[data-theme='dark'] .models-table td, +[data-theme='dark'] .shadow-runs-table td, +[data-theme='dark'] .ks-grid-table td { + color: #f8fafc; + border-bottom: 1px solid #334155; } +/* Zebra Stripes & Hover & Selection Rules */ +.grid-table tr:nth-child(even), .kbx-grid-table tr:nth-child(even), .ks-grid-table tr:nth-child(even) { + background-color: #ffffff; +} + +.grid-table tr:nth-child(odd), .kbx-grid-table tr:nth-child(odd), .ks-grid-table tr:nth-child(odd) { + background-color: #f8fafc; +} + +[data-theme='dark'] .grid-table tr:nth-child(even), +[data-theme='dark'] .kbx-grid-table tr:nth-child(even), +[data-theme='dark'] .ks-grid-table tr:nth-child(even) { + background-color: #0f172a; +} + +[data-theme='dark'] .grid-table tr:nth-child(odd), +[data-theme='dark'] .kbx-grid-table tr:nth-child(odd), +[data-theme='dark'] .ks-grid-table tr:nth-child(odd) { + background-color: #090d16; +} + +.grid-table tr:hover, .kbx-grid-table tr:hover, .models-table tr:hover, .shadow-runs-table tr:hover, .ks-grid-table tr:hover, .ks-grid-row:hover { + background-color: #e0f2fe !important; +} + +[data-theme='dark'] .grid-table tr:hover, +[data-theme='dark'] .kbx-grid-table tr:hover, +[data-theme='dark'] .models-table tr:hover, +[data-theme='dark'] .shadow-runs-table tr:hover, +[data-theme='dark'] .ks-grid-table tr:hover, +[data-theme='dark'] .ks-grid-row:hover { + background-color: #334155 !important; +} + +.grid-table tr.selected, .ks-grid-table tr.selected, .ks-grid-row.selected { + background-color: #dbeafe !important; + color: #1e3a8a !important; + font-weight: 700; +} + + diff --git a/frontend/src/shared/shell/AppLayout.vue b/frontend/src/shared/shell/AppLayout.vue index e83124af..13607615 100644 --- a/frontend/src/shared/shell/AppLayout.vue +++ b/frontend/src/shared/shell/AppLayout.vue @@ -40,9 +40,6 @@ const toggleDarkMode = () => {
- - -