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,34 +1,36 @@
|
||||
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, RefreshCcw } from 'lucide';
|
||||
import { createIcons, Paperclip, RefreshCcw, Download, Upload, FileSpreadsheet, Plus } from 'lucide';
|
||||
|
||||
/**
|
||||
* 모바일기기 자산 목록 뷰
|
||||
* 라인 정렬 보정 및 헤더 통일
|
||||
* 모바일 자산 목록 뷰 (레거시 지원용)
|
||||
*/
|
||||
export function renderMobileList(container: HTMLElement) {
|
||||
const fullList = sortAssets(state.masterData.mobile);
|
||||
// 모바일 데이터가 별도 테이블에 없으므로 일단 빈 배열 또는 장비군에서 필터링 시도
|
||||
const fullList = sortAssets(state.masterData.mobile || []);
|
||||
let sortState: SortState = { key: '', direction: 'asc' };
|
||||
|
||||
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: any) => 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.MODEL.ui}/${ASSET_SCHEMA.MANAGER_MAIN.ui})</label>
|
||||
<label>통합 검색 (${ASSET_SCHEMA.MODEL_NAME.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);
|
||||
|
||||
@@ -38,20 +40,19 @@ export function renderMobileList(container: HTMLElement) {
|
||||
table.innerHTML = `
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center" style="width:50px;">No.</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.STATUS.key}">${ASSET_SCHEMA.STATUS.ui}</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.CORP.key}">${ASSET_SCHEMA.CORP.ui}</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.ASSET_CODE.key}">${ASSET_SCHEMA.ASSET_CODE.ui}</th>
|
||||
<th data-sort="${ASSET_SCHEMA.MODEL.key}">${ASSET_SCHEMA.MODEL.ui}</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.STORE_LOC.key}">${ASSET_SCHEMA.STORE_LOC.ui}</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.MANAGER_MAIN.key}">담당자(정/부)</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.PURCHASE_YM.key}">${ASSET_SCHEMA.PURCHASE_YM.ui}</th>
|
||||
<th class="text-center" data-sort="${ASSET_SCHEMA.PRICE.key}">${ASSET_SCHEMA.PRICE.ui}</th>
|
||||
<th style="text-align:center; width:50px;">No</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.HW_STATUS.key}">${ASSET_SCHEMA.HW_STATUS.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.PURCHASE_CORP.key}">${ASSET_SCHEMA.PURCHASE_CORP.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.MODEL_NAME.key}">${ASSET_SCHEMA.MODEL_NAME.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.LOCATION.key}">${ASSET_SCHEMA.LOCATION.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.PURCHASE_DATE.key}">${ASSET_SCHEMA.PURCHASE_DATE.ui}</th>
|
||||
<th style="text-align:center;" data-sort="${ASSET_SCHEMA.PURCHASE_AMOUNT.key}">${ASSET_SCHEMA.PURCHASE_AMOUNT.ui}</th>
|
||||
<th style="text-align:center;">담당자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dynamic-tbody"></tbody>
|
||||
`;
|
||||
|
||||
|
||||
tableWrapper.appendChild(table);
|
||||
container.appendChild(tableWrapper);
|
||||
const tbody = table.querySelector('tbody')!;
|
||||
@@ -63,12 +64,10 @@ export function renderMobileList(container: HTMLElement) {
|
||||
const keyword = keywordInput ? keywordInput.value.toLowerCase().trim() : '';
|
||||
const corp = corpSelect ? corpSelect.value : '';
|
||||
|
||||
let filtered = fullList.filter(asset => {
|
||||
let filtered = fullList.filter((asset: any) => {
|
||||
const matchKeyword = !keyword ||
|
||||
String(asset[ASSET_SCHEMA.ASSET_CODE.key]||'').toLowerCase().includes(keyword) ||
|
||||
String(asset[ASSET_SCHEMA.MODEL.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.MODEL_NAME.key]||'').toLowerCase().includes(keyword);
|
||||
const matchCorp = !corp || asset[ASSET_SCHEMA.PURCHASE_CORP.key] === corp;
|
||||
return matchKeyword && matchCorp;
|
||||
});
|
||||
|
||||
@@ -78,36 +77,25 @@ export function renderMobileList(container: HTMLElement) {
|
||||
|
||||
tbody.innerHTML = '';
|
||||
if (filtered.length === 0) {
|
||||
tbody.innerHTML = `<tr><td colspan="9" class="text-center" style="padding: 3rem; color: var(--text-muted);">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="8" style="text-align:center; padding: 3rem; color: var(--text-muted);">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
filtered.forEach((asset, idx) => {
|
||||
filtered.forEach((asset: any, idx: number) => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.style.cursor = 'pointer';
|
||||
|
||||
const statusColors: Record<string, string> = { '대여중': 'primary', '보관중': 'success', '수리중': 'danger', '기타': 'muted' };
|
||||
const statusValue = asset[ASSET_SCHEMA.STATUS.key] || '보관중';
|
||||
const statusType = statusColors[statusValue] || 'muted';
|
||||
const statusBadge = `<span class="badge badge-${statusType}">${statusValue}</span>`;
|
||||
|
||||
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 class="text-center">${idx + 1}</td>
|
||||
<td class="text-center">${statusBadge}</td>
|
||||
<td class="text-center">${asset[ASSET_SCHEMA.CORP.key]}</td>
|
||||
<td class="text-center" style="font-family: monospace;">${asset[ASSET_SCHEMA.ASSET_CODE.key] || '-'}</td>
|
||||
<td>${formatInline(asset[ASSET_SCHEMA.MODEL.key] || asset.명칭)}</td>
|
||||
<td class="text-center">${asset[ASSET_SCHEMA.STORE_LOC.key] || '-'}</td>
|
||||
<td class="text-center">${managerHtml || '-'}</td>
|
||||
<td class="text-center">${asset[ASSET_SCHEMA.PURCHASE_YM.key] || ''}</td>
|
||||
<td class="text-right">${Number(asset[ASSET_SCHEMA.PRICE.key]||0).toLocaleString()}</td>
|
||||
<td style="text-align:center;">${idx+1}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.HW_STATUS.key] || '운영중'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.PURCHASE_CORP.key] || ''}</td>
|
||||
<td>${asset[ASSET_SCHEMA.MODEL_NAME.key] || ''}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.LOCATION.key] || '-'}</td>
|
||||
<td style="text-align:center;">${asset[ASSET_SCHEMA.PURCHASE_DATE.key] || ''}</td>
|
||||
<td style="text-align:right;">${Number(asset[ASSET_SCHEMA.PURCHASE_AMOUNT.key]||0).toLocaleString()}</td>
|
||||
<td style="text-align:center;">${mainManager}</td>
|
||||
`;
|
||||
tr.addEventListener('click', () => openHwModal(asset, 'view'));
|
||||
tbody.appendChild(tr);
|
||||
@@ -118,7 +106,7 @@ export function renderMobileList(container: HTMLElement) {
|
||||
updateTable();
|
||||
});
|
||||
|
||||
createIcons({ icons: { RefreshCcw } });
|
||||
createIcons({ icons: { Paperclip, RefreshCcw, Download, Upload, FileSpreadsheet, Plus } });
|
||||
};
|
||||
|
||||
document.getElementById('filter-keyword')?.addEventListener('input', updateTable);
|
||||
|
||||
Reference in New Issue
Block a user