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:
@@ -1,9 +1,9 @@
|
||||
import { state } from '../../core/state';
|
||||
import { openHwModal } from '../../components/Modal/HWModal';
|
||||
import { formatInline, createBadge, sortAssets, dynamicSort } from '../../core/utils';
|
||||
import { formatInline, createBadge, sortAssets, dynamicSort, getActionButtonsHTML } from '../../core/utils';
|
||||
import { ASSET_SCHEMA, UI_TEXT } from '../../core/schema';
|
||||
import { setupTableSorting, SortState } from '../../core/tableHandler';
|
||||
import { createIcons, Paperclip, RefreshCcw } from 'lucide';
|
||||
import { createIcons, Paperclip, RefreshCcw, Download, Upload, FileSpreadsheet, Plus } from 'lucide';
|
||||
|
||||
/**
|
||||
* PC 자산 목록 뷰
|
||||
@@ -16,20 +16,21 @@ export function renderPcList(container: HTMLElement) {
|
||||
const filterBar = document.createElement('div');
|
||||
filterBar.className = 'search-bar';
|
||||
|
||||
const corps = Array.from(new Set(fullList.map(a => a[ASSET_SCHEMA.CORP.key]))).filter(Boolean).sort();
|
||||
const corps = Array.from(new Set(fullList.map(a => a[ASSET_SCHEMA.PURCHASE_CORP.key]))).filter(Boolean).sort();
|
||||
|
||||
filterBar.innerHTML = `
|
||||
<div class="search-item flex-1">
|
||||
<label>통합 검색 (${ASSET_SCHEMA.ASSET_CODE.ui}/${ASSET_SCHEMA.USER.ui}/${ASSET_SCHEMA.MANAGER_MAIN.ui})</label>
|
||||
<label>통합 검색 (${ASSET_SCHEMA.MODEL_NAME.ui}/${ASSET_SCHEMA.MANAGER_MAIN.ui}/${ASSET_SCHEMA.CURRENT_USER.ui})</label>
|
||||
<input type="text" id="filter-keyword" placeholder="검색어를 입력하세요..." autocomplete="off">
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<label>${ASSET_SCHEMA.CORP.ui}</label>
|
||||
<label>${ASSET_SCHEMA.PURCHASE_CORP.ui}</label>
|
||||
<select id="filter-corp"><option value="">전체 법인</option>${corps.map(c => `<option value="${c}">${c}</option>`).join('')}</select>
|
||||
</div>
|
||||
<button id="btn-reset-filters" class="btn btn-outline btn-reset">
|
||||
<i data-lucide="refresh-ccw"></i> ${UI_TEXT.ACTION.RESET_FILTER}
|
||||
</button>
|
||||
${getActionButtonsHTML()}
|
||||
`;
|
||||
container.appendChild(filterBar);
|
||||
|
||||
@@ -40,18 +41,19 @@ export function renderPcList(container: HTMLElement) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center; width:50px;">No</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.CORP.key}">${ASSET_SCHEMA.CORP.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.ORG.key}">${ASSET_SCHEMA.ORG.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.ASSET_CODE.key}">${ASSET_SCHEMA.ASSET_CODE.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.USER.key}">${ASSET_SCHEMA.USER.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MAINBOARD.key}">${ASSET_SCHEMA.MAINBOARD.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.CURRENT_DEPT.key}">${ASSET_SCHEMA.CURRENT_DEPT.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.CURRENT_USER.key}">${ASSET_SCHEMA.CURRENT_USER.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MANAGER_MAIN.key}">${ASSET_SCHEMA.MANAGER_MAIN.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.CPU.key}">${ASSET_SCHEMA.CPU.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MAINBOARD.key}">${ASSET_SCHEMA.MAINBOARD.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.RAM.key}">${ASSET_SCHEMA.RAM.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.STORAGE1.key}">Storage</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.PURCHASE_YM.key}">${ASSET_SCHEMA.PURCHASE_YM.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.PRICE.key}">${ASSET_SCHEMA.PRICE.ui}</th>
|
||||
<th style="text-align:center;">${ASSET_SCHEMA.DOC_NAME.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MANAGER_MAIN.key}">담당자(정/부)</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.GPU.key}">${ASSET_SCHEMA.GPU.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.SSD1.key}">SSD1</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.SSD2.key}">SSD2</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.HDD1.key}">HDD1</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.HDD2.key}">HDD2</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MAC_ADDR.key}">${ASSET_SCHEMA.MAC_ADDR.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MEMO.key}">${ASSET_SCHEMA.MEMO.ui}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dynamic-tbody"></tbody>
|
||||
@@ -70,11 +72,12 @@ export function renderPcList(container: HTMLElement) {
|
||||
|
||||
let filtered = fullList.filter(asset => {
|
||||
const matchKeyword = !keyword ||
|
||||
String(asset[ASSET_SCHEMA.ASSET_CODE.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.USER.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.ORG.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.MANAGER_MAIN.key]||'').toLowerCase().includes(keyword);
|
||||
const matchCorp = !corp || asset[ASSET_SCHEMA.CORP.key] === corp;
|
||||
String(asset[ASSET_SCHEMA.MANAGER_MAIN.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.CURRENT_DEPT.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.MODEL_NAME.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.MAC_ADDR.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.CURRENT_USER.key]||'').toLowerCase().includes(keyword);
|
||||
const matchCorp = !corp || asset[ASSET_SCHEMA.PURCHASE_CORP.key] === corp;
|
||||
return matchKeyword && matchCorp;
|
||||
});
|
||||
|
||||
@@ -84,7 +87,7 @@ export function renderPcList(container: HTMLElement) {
|
||||
|
||||
tbody.innerHTML = '';
|
||||
if (filtered.length === 0) {
|
||||
tbody.innerHTML = `<tr><td colspan="13" style="text-align:center; padding: 3rem; color: var(--text-muted);">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="14" style="text-align:center; padding: 3rem; color: var(--text-muted);">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,29 +95,21 @@ export function renderPcList(container: HTMLElement) {
|
||||
const tr = document.createElement('tr');
|
||||
tr.style.cursor = 'pointer';
|
||||
|
||||
const storage = [asset[ASSET_SCHEMA.STORAGE1.key], asset[ASSET_SCHEMA.STORAGE2.key]].filter(v => v).join(' / ');
|
||||
|
||||
const mainManager = asset[ASSET_SCHEMA.MANAGER_MAIN.key] || '';
|
||||
const subManager = asset[ASSET_SCHEMA.MANAGER_SUB.key] || '';
|
||||
const managerHtml = [
|
||||
mainManager ? `${createBadge('정', 'primary')} ${mainManager}` : '',
|
||||
subManager ? `${createBadge('부', 'muted')} ${subManager}` : ''
|
||||
].filter(v => v !== '').join(' / ');
|
||||
|
||||
tr.innerHTML = `
|
||||
<td style="text-align:center;">${idx+1}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.CORP.key]}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.ORG.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.ASSET_CODE.key]}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.USER.key]||''}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.MAINBOARD.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.CURRENT_DEPT.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.CURRENT_USER.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.MANAGER_MAIN.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.CPU.key]||''}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.MAINBOARD.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.RAM.key]||''}</td>
|
||||
<td style="text-align:center;">${formatInline(storage)}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.PURCHASE_YM.key] || ''}</td>
|
||||
<td style="text-align:right;">${Number(asset[ASSET_SCHEMA.PRICE.key]||0).toLocaleString()}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.DOC_NAME.key] ? '<i data-lucide="paperclip" class="text-primary"></i>' : '-'}</td>
|
||||
<td style="text-align:center;">${managerHtml || '-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.GPU.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.SSD1.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.SSD2.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.HDD1.key]||'-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.HDD2.key]||'-'}</td>
|
||||
<td style="text-align:center; font-family:monospace; font-size:11px;">${asset[ASSET_SCHEMA.MAC_ADDR.key]||'-'}</td>
|
||||
<td style="text-align:center;">${formatInline(asset[ASSET_SCHEMA.MEMO.key]||'-')}</td>
|
||||
`;
|
||||
tr.addEventListener('click', () => openHwModal(asset, 'view'));
|
||||
tbody.appendChild(tr);
|
||||
|
||||
Reference in New Issue
Block a user