feat: restructure navigation, customize list columns, and move action buttons to search bar

1. Restructured navigation hierarchy (Hardware, Software, Ops Support, etc.).
2. Customized table columns for all asset categories according to new specs.
3. Moved Template/Upload/Export/Add buttons to search bar with layout optimization.
4. Hidden Asset Code and Previous User from list views (Modal only).
5. Added Current/Previous User and detailed PC spec fields (GPU, HDD3/4).
This commit is contained in:
2026-05-20 14:34:07 +09:00
parent 2af79cdad3
commit d34ebb8500
23 changed files with 1509 additions and 964 deletions

View File

@@ -1,5 +1,6 @@
import { HardwareAsset, SoftwareAsset } from '../../core/excelHandler';
import { state } from '../../core/state';
import { ASSET_SCHEMA } from '../../core/schema';
import { createIcons, X } from 'lucide';
const DASHBOARD_DETAIL_MODAL_HTML = `
<div id="dashboard-detail-modal" class="modal-overlay hidden">
@@ -37,9 +38,11 @@ export function initDashboardDetailModal() {
closeBtn.addEventListener('click', closeModal);
cancelBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
createIcons({ icons: { X } });
}
export function openDashboardDetail(title: string, list: HardwareAsset[]) {
export function openDashboardDetail(title: string, list: any[]) {
const modal = document.getElementById('dashboard-detail-modal');
if (!modal) return;
const titleEl = document.getElementById('dashboard-detail-modal-title');
@@ -49,23 +52,23 @@ export function openDashboardDetail(title: string, list: HardwareAsset[]) {
if (!thead) return;
titleEl.textContent = title;
thead.innerHTML = `<tr><th>No</th><th>유형</th><th>자산코드</th><th>명칭/모델</th><th>위치</th><th>담당/사용자</th><th>구매연월</th><th>금액</th></tr>`;
thead.innerHTML = `<tr><th>No</th><th>유형</th><th>명칭/모델</th><th>위치</th><th>담당/사용자</th><th>구매일자</th><th>금액</th></tr>`;
tbody.innerHTML = '';
if (list.length === 0) {
tbody.innerHTML = `<tr><td colspan="8" style="text-align:center; padding: 2rem;">해당 조건의 자산이 없습니다.</td></tr>`;
tbody.innerHTML = `<tr><td colspan="7" style="text-align:center; padding: 2rem;">해당 조건의 자산이 없습니다.</td></tr>`;
} else {
list.forEach((asset, idx) => {
let manager = asset. || asset. || asset._정 || '-';
let name = asset. || asset. || '-';
let manager = asset[ASSET_SCHEMA.MANAGER_MAIN.key] || asset.current_user || '-';
let name = asset[ASSET_SCHEMA.MODEL_NAME.key] || asset[ASSET_SCHEMA.ASSET_NAME.key] || '-';
const tr = document.createElement('tr');
tr.innerHTML = `<td>${idx+1}</td><td>${asset.type}</td><td>${asset.}</td><td>${name}</td><td>${asset.||'-'}</td><td>${manager}</td><td>${asset.||'-'}</td><td>${asset.||'-'}</td>`;
tr.innerHTML = `<td>${idx+1}</td><td>${asset.category || asset[ASSET_SCHEMA.ASSET_TYPE.key]}</td><td>${name}</td><td>${asset[ASSET_SCHEMA.LOCATION.key]||'-'}</td><td>${manager}</td><td>${asset[ASSET_SCHEMA.PURCHASE_DATE.key]||'-'}</td><td>${asset[ASSET_SCHEMA.PURCHASE_AMOUNT.key]||'-'}</td>`;
tbody.appendChild(tr);
});
}
modal.classList.remove('hidden');
}
export function openSwDashboardDetail(title: string, list: SoftwareAsset[]) {
export function openSwDashboardDetail(title: string, list: any[]) {
const modal = document.getElementById('dashboard-detail-modal');
if (!modal) return;
const titleEl = document.getElementById('dashboard-detail-modal-title');
@@ -79,13 +82,13 @@ export function openSwDashboardDetail(title: string, list: SoftwareAsset[]) {
tbody.innerHTML = '';
list.forEach((sw, idx) => {
const tr = document.createElement('tr');
tr.innerHTML = `<td>${idx+1}</td><td>${sw.type}</td><td>${sw.}</td><td>${sw.}</td><td>${sw.}</td><td>${sw.}</td>`;
tr.innerHTML = `<td>${idx+1}</td><td>${sw.asset_type || sw.type}</td><td>${sw[ASSET_SCHEMA.PURCHASE_CORP.key]}</td><td>${sw[ASSET_SCHEMA.PRODUCT_NAME.key]}</td><td>${sw[ASSET_SCHEMA.ASSET_COUNT.key]}</td><td>${sw[ASSET_SCHEMA.PURCHASE_AMOUNT.key]}</td>`;
tbody.appendChild(tr);
});
modal.classList.remove('hidden');
}
export function openSwUsageDetail(title: string, list: SoftwareAsset[]) {
export function openSwUsageDetail(title: string, list: any[]) {
const modal = document.getElementById('dashboard-detail-modal');
if (!modal) return;
const titleEl = document.getElementById('dashboard-detail-modal-title');
@@ -99,14 +102,15 @@ export function openSwUsageDetail(title: string, list: SoftwareAsset[]) {
tbody.innerHTML = '';
list.forEach((sw, idx) => {
const assigned = state.masterData.swUsers.filter(u => u.sw_id === sw.id).length;
const qty = Number(sw[ASSET_SCHEMA.ASSET_COUNT.key] || 0);
const tr = document.createElement('tr');
tr.innerHTML = `<td>${idx+1}</td><td>${sw.}</td><td>${sw.}</td><td>${sw.}</td><td>${assigned}</td><td>${Number(sw.) - assigned}</td>`;
tr.innerHTML = `<td>${idx+1}</td><td>${sw[ASSET_SCHEMA.PURCHASE_CORP.key]}</td><td>${sw[ASSET_SCHEMA.PRODUCT_NAME.key]}</td><td>${qty}</td><td>${assigned}</td><td>${qty - assigned}</td>`;
tbody.appendChild(tr);
});
modal.classList.remove('hidden');
}
export function openCloudDashboardDetail(title: string, list: SoftwareAsset[]) {
export function openCloudDashboardDetail(title: string, list: any[]) {
const modal = document.getElementById('dashboard-detail-modal');
if (!modal) return;
const titleEl = document.getElementById('dashboard-detail-modal-title');
@@ -116,15 +120,15 @@ export function openCloudDashboardDetail(title: string, list: SoftwareAsset[]) {
if (!thead) return;
titleEl.textContent = title;
thead.innerHTML = `<tr><th>No</th><th>플랫폼</th><th>법인</th><th>제품명</th><th>결제일</th><th>당월청구액(원)</th></tr>`;
thead.innerHTML = `<tr><th>No</th><th>플랫폼/목적</th><th>법인</th><th>제품명</th><th>결제일</th><th>당월청구액(원)</th></tr>`;
tbody.innerHTML = '';
if (list.length === 0) {
tbody.innerHTML = `<tr><td colspan="6" style="text-align:center; padding: 2rem;">해당 내역이 없습니다.</td></tr>`;
} else {
list.forEach((sw, idx) => {
const priceStr = sw. ? Number(sw..replace(/[^0-9]/g, '')).toLocaleString() : '0';
const priceStr = sw[ASSET_SCHEMA.PURCHASE_AMOUNT.key] ? Number(String(sw[ASSET_SCHEMA.PURCHASE_AMOUNT.key]).replace(/[^0-9]/g, '')).toLocaleString() : '0';
const tr = document.createElement('tr');
tr.innerHTML = `<td>${idx+1}</td><td>${sw.||'-'}</td><td>${sw.||'-'}</td><td>${sw.||'-'}</td><td>${sw. ? sw. + '일' : '-'}</td><td>₩ ${priceStr}</td>`;
tr.innerHTML = `<td>${idx+1}</td><td>${sw[ASSET_SCHEMA.DEV_OBJ.key]||'-'}</td><td>${sw[ASSET_SCHEMA.PURCHASE_CORP.key]||'-'}</td><td>${sw[ASSET_SCHEMA.PRODUCT_NAME.key]||'-'}</td><td>${sw.pay_day ? sw.pay_day + '일' : '-'}</td><td>₩ ${priceStr}</td>`;
tbody.appendChild(tr);
});
}