-
-
-
+
+
๋ผ์ด์ ์ค ๋ฐ ๊ณ์ฝ ์ ๋ณด
+
+
+
+
+
+
+
+
+
+
+
+
+
๊ด๋ฆฌ ๋ฐ ๋น๊ณ
+
+
+
+
+
+
`;
+function renderSwHistory(swId: string) {
+ const container = document.getElementById('sw-history-list');
+ if (!container) return;
+ const logs = (state.masterData.logs || []).filter(l => l.assetId === swId).sort((a,b) => new Date(b.date).getTime() - new Date(a.date).getTime());
+ if (logs.length === 0) { container.innerHTML = '
์์ ์ด๋ ฅ์ด ์์ต๋๋ค.
'; return; }
+ container.innerHTML = logs.map(l => `
+
+
${l.date}
+
${l.user}
+
${l.details.replace(/\n/g, '
')}
+
+ `).join('');
+}
+
+function renderUserSummary(swId: string) {
+ const container = document.getElementById('sw-assigned-users-summary');
+ if (!container) return;
+ const userMapping = state.masterData.swUsers.find(u => u.sw_id === swId);
+ if (!userMapping || !userMapping.userData || userMapping.userData.length === 0) {
+ container.innerHTML = '
ํ ๋น๋ ์ฌ์ฉ์๊ฐ ์์ต๋๋ค.
';
+ return;
+ }
+ container.innerHTML = userMapping.userData.map(u => `
+
${u[3] || '์ด๋ฆ์์'}${u[1] || '๋ถ์์์'}
+ `).join('');
+}
+
function applySwTypeUI(type: string) {
const cloudFields = document.querySelectorAll('.cloud-only');
const swFields = document.querySelectorAll('.sw-standard-field');
@@ -195,7 +131,6 @@ function applySwTypeUI(type: string) {
cloudFields.forEach(el => (el as HTMLElement).style.display = 'none');
swFields.forEach(el => (el as HTMLElement).style.display = 'flex');
if (userSection) userSection.style.display = 'block';
-
if (type === '๊ตฌ๋
SW') {
if (keyGroup) keyGroup.style.display = 'none';
if (typeGroup) typeGroup.style.display = 'flex';
@@ -208,92 +143,41 @@ function applySwTypeUI(type: string) {
}
}
-function fillSwFormData(asset: SoftwareAsset) {
- setFieldValue('sw-asset-id', asset.id);
- setFieldValue('sw-asset-type', asset.type);
- setFieldValue('sw-๋ฒ์ธ', asset.๋ฒ์ธ);
- setFieldValue('sw-์์ฐ๋ฒํธ', asset.์์ฐ๋ฒํธ || '');
- setFieldValue('sw-์ ํ๋ช
', asset.์ ํ๋ช
);
- setFieldValue('sw-์๋', asset.์๋);
- setFieldValue('sw-๊ธ์ก', asset.๊ธ์ก);
- setFieldValue('sw-๊ตฌ๋งค์ผ', asset.๊ตฌ๋งค์ผ || '');
- setFieldValue('sw-๋ฉํ์
์ฒด', asset.๋ฉํ์
์ฒด || '');
- setFieldValue('sw-๋น๊ณ ', asset.๋น๊ณ || '');
-
- if (asset.type === 'ํด๋ผ์ฐ๋') {
- setFieldValue('sw-ํ๋ซํผ๋ช
', (asset as any).ํ๋ซํผ๋ช
|| '');
- setFieldValue('sw-๋ถ์', (asset as any).๋ถ์ || '');
- setFieldValue('sw-๊ณ์ ๋ช
', (asset as any).๊ณ์ ๋ช
|| '');
- setFieldValue('sw-๊ฒฐ์ ์๋จ', (asset as any).๊ฒฐ์ ์๋จ || '');
- setFieldValue('sw-์ฐ๊ฒฐ์นด๋๋ฒํธ', (asset as any).์ฐ๊ฒฐ์นด๋๋ฒํธ || '');
- setFieldValue('sw-๊ฒฐ์ ์ผ', (asset as any).๊ฒฐ์ ์ผ || '');
- setFieldValue('sw-๋น์์ฒญ๊ตฌ์ก', (asset as any).๋น์์ฒญ๊ตฌ์ก || '');
- } else if (asset.type === '๊ตฌ๋
SW') {
- setFieldValue('sw-๋ผ์ด์ ์ค์ ํ', (asset as any).๋ผ์ด์ ์ค์ ํ || '');
- setFieldValue('sw-๋ง๋ฃ์ผ', (asset as any).๋ง๋ฃ์ผ || '');
- } else {
- setFieldValue('sw-๋ผ์ด์ ์คํค', (asset as any).๋ผ์ด์ ์คํค || '');
- }
-
- renderUserSummary(asset.id);
- renderSwHistory(asset.id);
-}
-
-function renderUserSummary(swId: string) {
- const container = document.getElementById('sw-assigned-users-summary');
- if (!container) return;
- const userMapping = state.masterData.swUsers.find(u => u.sw_id === swId);
- if (!userMapping || !userMapping.userData || userMapping.userData.length === 0) {
- container.innerHTML = '
ํ ๋น๋ ์ฌ์ฉ์๊ฐ ์์ต๋๋ค.
';
- return;
- }
- container.innerHTML = userMapping.userData.map(u => `
-
- ${u[3] || '์ด๋ฆ์์'}
- ${u[1] || '๋ถ์์์'}
-
- `).join('');
-}
-
-function renderSwHistory(swId: string) {
- const container = document.getElementById('sw-history-list');
- if (!container) return;
- const logs = (state.masterData.logs || []).filter(l => l.assetId === swId);
- if (logs.length === 0) {
- container.innerHTML = '
์์ ์ด๋ ฅ์ด ์์ต๋๋ค.
';
- return;
- }
- container.innerHTML = logs.map(l => `
-
-
${l.date}
-
${l.user}
-
${l.details}
-
- `).join('');
-}
-
export function openSwModal(asset: SoftwareAsset, mode: 'view' | 'add' = 'view') {
currentSwAsset = asset;
const modal = document.getElementById('sw-asset-modal')!;
-
- // ์์ ์ ๊ธ ์ํ ์ ์ด
setEditLock('sw-asset-form', mode, {
saveBtnId: 'btn-save-sw-asset',
- revertBtnId: 'btn-revert-sw-edit'
+ revertBtnId: 'btn-revert-sw-edit',
+ generateBtnId: 'btn-generate-sw-code',
+ addLogBtnId: 'btn-add-sw-log'
});
-
isEditMode = (mode === 'add');
-
- fillSwFormData(asset);
+ autoFillForm('sw', asset, SW_FIELD_MAP);
applySwTypeUI(asset.type);
-
+ renderUserSummary(asset.id);
+ renderSwHistory(asset.id);
modal.classList.remove('hidden');
createIcons({ icons: { X, History, Plus } });
}
-export function initSwModal(onSave: () => void, closeModals: () => void) {
+export function initSwModal(onSave: () => void, closeModalsCb: () => void) {
if (!document.getElementById('sw-asset-modal')) {
- document.body.insertAdjacentHTML('beforeend', SW_MODAL_HTML);
+ const html = createModalFrameHTML('sw', '์ํํธ์จ์ด ์์ธ ์ ๋ณด', SW_FORM_HTML, {
+ historyTitle: '์
๋ฐ์ดํธ ๋ด์ญ',
+ addLogBtnId: 'btn-add-sw-log'
+ });
+ document.body.insertAdjacentHTML('beforeend', html);
+ const logModalHTML = `
+
+ `;
+ document.body.insertAdjacentHTML('beforeend', logModalHTML);
}
const form = document.getElementById('sw-asset-form') as HTMLFormElement;
@@ -302,123 +186,100 @@ export function initSwModal(onSave: () => void, closeModals: () => void) {
const deleteBtn = document.getElementById('btn-delete-sw-asset')!;
const userUpdateBtn = document.getElementById('btn-open-sw-update')!;
const logAddBtn = document.getElementById('btn-add-sw-log')!;
+ const logModal = document.getElementById('sw-log-modal')!;
- const closeModalAction = () => { closeModals(); isEditMode = false; };
+ const closeModalAction = () => { closeModalsCb(); isEditMode = false; };
document.getElementById('btn-close-sw-modal')?.addEventListener('click', closeModalAction);
document.getElementById('btn-cancel-sw-modal')?.addEventListener('click', closeModalAction);
revertBtn.addEventListener('click', () => {
- setEditLock('sw-asset-form', 'view', {
- saveBtnId: 'btn-save-sw-asset',
- revertBtnId: 'btn-revert-sw-edit'
+ setEditLock('sw-asset-form', 'view', {
+ saveBtnId: 'btn-save-sw-asset',
+ revertBtnId: 'btn-revert-sw-edit',
+ generateBtnId: 'btn-generate-sw-code',
+ addLogBtnId: 'btn-add-sw-log'
});
isEditMode = false;
- if (currentSwAsset) fillSwFormData(currentSwAsset);
+ if (currentSwAsset) openSwModal(currentSwAsset, 'view');
+ });
+
+ document.getElementById('btn-generate-sw-code')?.addEventListener('click', async () => {
+ const typeValue = getFieldValue('sw-asset-type');
+ const purchaseDate = getFieldValue('sw-๊ตฌ๋งค์ผ');
+ const typeCode = TYPE_PREFIX_MAP[typeValue] || 'SW';
+ const dateStr = purchaseDate.replace(/[^0-9]/g, '');
+ if (dateStr.length < 6) { alert('์ฌ๋ฐ๋ฅธ ๊ตฌ๋งค์ฐ์(YYYYMM)์ ์
๋ ฅํด์ฃผ์ธ์.'); return; }
+ const prefix = `${typeCode}-${dateStr.substring(0, 6)}-`;
+ try {
+ const res = await fetch(`http://localhost:3000/api/generate-asset-code?prefix=${prefix}`);
+ const data = await res.json();
+ if (data.nextCode) setFieldValue('sw-์์ฐ๋ฒํธ', data.nextCode);
+ } catch (err) { alert('์์ฐ๋ฒํธ ์์ฑ์ ์คํจํ์ต๋๋ค.'); }
+ });
+
+ // YYYYMM ์
๋ ฅ ์ ํ ๋ก์ง (์ซ์ 6์๋ฆฌ)
+ document.getElementById('sw-๊ตฌ๋งค์ผ')?.addEventListener('input', (e) => {
+ const target = e.target as HTMLInputElement;
+ target.value = target.value.replace(/[^0-9]/g, '').substring(0, 6);
});
saveBtn.addEventListener('click', () => {
if (!currentSwAsset) return;
if (!isEditMode) {
- setEditLock('sw-asset-form', 'edit', {
- saveBtnId: 'btn-save-sw-asset',
- revertBtnId: 'btn-revert-sw-edit'
+ setEditLock('sw-asset-form', 'edit', {
+ saveBtnId: 'btn-save-sw-asset',
+ revertBtnId: 'btn-revert-sw-edit',
+ generateBtnId: 'btn-generate-sw-code',
+ addLogBtnId: 'btn-add-sw-log'
});
isEditMode = true;
return;
}
+ const extracted = autoExtractForm('sw', SW_FIELD_MAP);
+ const updated = { ...currentSwAsset, ...extracted, ์๋: parseInt(extracted.์๋ || '0') };
- const type = getFieldValue('sw-asset-type');
- const updated: any = {
- ...currentSwAsset,
- ๋ฒ์ธ: getFieldValue('sw-๋ฒ์ธ'),
- ์์ฐ๋ฒํธ: getFieldValue('sw-์์ฐ๋ฒํธ'),
- ์ ํ๋ช
: getFieldValue('sw-์ ํ๋ช
'),
- ์๋: parseInt(getFieldValue('sw-์๋') || '0'),
- ๊ธ์ก: getFieldValue('sw-๊ธ์ก'),
- ๊ตฌ๋งค์ผ: getFieldValue('sw-๊ตฌ๋งค์ผ'),
- ๋ฉํ์
์ฒด: getFieldValue('sw-๋ฉํ์
์ฒด'),
- ๋น๊ณ : getFieldValue('sw-๋น๊ณ '),
- type: type
- };
-
- if (type === 'ํด๋ผ์ฐ๋') {
- updated.ํ๋ซํผ๋ช
= getFieldValue('sw-ํ๋ซํผ๋ช
');
- updated.๋ถ์ = getFieldValue('sw-๋ถ์');
- updated.๊ณ์ ๋ช
= getFieldValue('sw-๊ณ์ ๋ช
');
- updated.๊ฒฐ์ ์๋จ = getFieldValue('sw-๊ฒฐ์ ์๋จ');
- updated.์ฐ๊ฒฐ์นด๋๋ฒํธ = getFieldValue('sw-์ฐ๊ฒฐ์นด๋๋ฒํธ');
- updated.๊ฒฐ์ ์ผ = getFieldValue('sw-๊ฒฐ์ ์ผ');
- updated.๋น์์ฒญ๊ตฌ์ก = getFieldValue('sw-๋น์์ฒญ๊ตฌ์ก');
- } else if (type === '๊ตฌ๋
SW') {
- updated.๋ผ์ด์ ์ค์ ํ = getFieldValue('sw-๋ผ์ด์ ์ค์ ํ');
- updated.๋ง๋ฃ์ผ = getFieldValue('sw-๋ง๋ฃ์ผ');
- } else {
- updated.๋ผ์ด์ ์คํค = getFieldValue('sw-๋ผ์ด์ ์คํค');
- }
-
- // ๋ฐ์ดํฐ ์ ์ฅ ๋ก์ง (state ์
๋ฐ์ดํธ)
let targetList: SoftwareAsset[] = [];
- if (type === '๊ตฌ๋
SW') targetList = state.masterData.subSw;
- else if (type === '์๊ตฌSW') targetList = state.masterData.permSw;
- else if (type === 'ํด๋ผ์ฐ๋') targetList = state.masterData.cloud;
+ if (updated.type === '๊ตฌ๋
SW') targetList = state.masterData.subSw;
+ else if (updated.type === '์๊ตฌSW') targetList = state.masterData.permSw;
+ else targetList = (state.masterData as any).cloud || [];
const idx = targetList.findIndex(a => a.id === updated.id);
- if (idx > -1) targetList[idx] = updated;
- else targetList.push(updated);
+ if (idx > -1) targetList[idx] = updated; else targetList.push(updated);
onSave();
- setEditLock('sw-asset-form', 'view', {
- saveBtnId: 'btn-save-sw-asset',
- revertBtnId: 'btn-revert-sw-edit'
+ setEditLock('sw-asset-form', 'view', {
+ saveBtnId: 'btn-save-sw-asset',
+ revertBtnId: 'btn-revert-sw-edit',
+ generateBtnId: 'btn-generate-sw-code',
+ addLogBtnId: 'btn-add-sw-log'
});
isEditMode = false;
});
deleteBtn.addEventListener('click', () => {
- if (!currentSwAsset) return;
- if (confirm('์ญ์ ํ์๊ฒ ์ต๋๊น?')) {
+ if (currentSwAsset && confirm('์ญ์ ํ์๊ฒ ์ต๋๊น?')) {
const type = currentSwAsset.type;
if (type === '๊ตฌ๋
SW') state.masterData.subSw = state.masterData.subSw.filter(a => a.id !== currentSwAsset!.id);
else if (type === '์๊ตฌSW') state.masterData.permSw = state.masterData.permSw.filter(a => a.id !== currentSwAsset!.id);
- else if (type === 'ํด๋ผ์ฐ๋') state.masterData.cloud = state.masterData.cloud.filter(a => a.id !== currentSwAsset!.id);
- onSave();
- closeModalAction();
+ onSave(); closeModalAction();
}
});
- userUpdateBtn.addEventListener('click', () => {
- if (currentSwAsset) openSwUserModal(currentSwAsset);
- });
-
- // ์ด๋ ฅ ์ถ๊ฐ ๋ชจ๋ฌ ๋ก์ง
- const logModal = document.getElementById('sw-log-modal')!;
+ userUpdateBtn.addEventListener('click', () => { if (currentSwAsset) openSwUserModal(currentSwAsset); });
logAddBtn.addEventListener('click', () => {
logModal.classList.remove('hidden');
(document.getElementById('new-log-date') as HTMLInputElement).value = new Date().toISOString().split('T')[0];
(document.getElementById('new-log-details') as HTMLTextAreaElement).value = '';
});
-
document.getElementById('btn-close-sw-log')?.addEventListener('click', () => logModal.classList.add('hidden'));
document.getElementById('btn-cancel-sw-log')?.addEventListener('click', () => logModal.classList.add('hidden'));
-
document.getElementById('btn-confirm-sw-log')?.addEventListener('click', () => {
if (!currentSwAsset) return;
const date = (document.getElementById('new-log-date') as HTMLInputElement).value;
const details = (document.getElementById('new-log-details') as HTMLTextAreaElement).value;
-
- if (!date || !details) { alert('๋ ์ง์ ๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์.'); return; }
-
+ if (!date || !details) return;
state.masterData.logs = state.masterData.logs || [];
- state.masterData.logs.push({
- id: Math.random().toString(36).substring(2, 9),
- assetId: currentSwAsset.id,
- date,
- user: '๊ด๋ฆฌ์',
- details
- });
-
- logModal.classList.add('hidden');
- renderSwHistory(currentSwAsset.id);
+ state.masterData.logs.push({ id: Math.random().toString(36).substring(2, 9), assetId: currentSwAsset.id, date, user: '๊ด๋ฆฌ์', details });
+ logModal.classList.add('hidden'); renderSwHistory(currentSwAsset.id);
});
}
-
diff --git a/src/components/Modal/SharedData.ts b/src/components/Modal/SharedData.ts
index af6eeb0..65a2f19 100644
--- a/src/components/Modal/SharedData.ts
+++ b/src/components/Modal/SharedData.ts
@@ -29,5 +29,6 @@ export const TYPE_PREFIX_MAP: Record
= {
'์๋ฒ': 'SVR', 'PC': 'PC', 'NAS': 'NAS', 'DAS': 'DAS', '์คํ ๋ฆฌ์ง': 'STO',
'CPU': 'CPU', 'HDD': 'HDD', 'RAM': 'RAM', 'GPU': 'GPU',
'๋ชจ๋ฐ์ผ': 'MOB', '๋
ธํธ๋ถ': 'PC', 'ํ๋ธ๋ฆฟ': 'TAB',
- '๊ฐ์ธPC': 'PC', '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ': 'MOB'
+ '๊ฐ์ธPC': 'PC', '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ': 'MOB',
+ '๊ตฌ๋
SW': 'SSW', '์๊ตฌSW': 'PSW'
};
diff --git a/src/core/excelHandler.ts b/src/core/excelHandler.ts
index faadf1c..92b34e4 100644
--- a/src/core/excelHandler.ts
+++ b/src/core/excelHandler.ts
@@ -1,6 +1,43 @@
import * as XLSX from 'xlsx';
import { HardwareAsset, SoftwareAsset, SWUser, HardwareLog, MasterAssetData } from './state';
+const PC_HEADERS = ['๋ฒ์ธ', '์์ฐ์ฝ๋', '์ฌ์ฉ์', '์์น', 'CPU', 'GPU', 'RAM', 'SSD1', 'SSD2', 'HDD1', 'HDD2', 'IP์ฃผ์', 'HW์ฌ์', '๊ตฌ๋งค์ผ', '๊ธ์ก', '๋ฉํ์
์ฒด', 'ํ์์๋ช
', '๋น๊ณ '];
+const SERVER_HEADERS = ['๊ตฌ๋งค๋ฒ์ธ', '์์ฐ๋ฒํธ', '๊ตฌ๋งค์ผ์', '์ ํ', '์ฉ๋', '์์ธ๋ด์ฉ', 'ํ์ฌ์ฉ์กฐ์ง', '์ด์ ์ฌ์ฉ์กฐ์ง', '์ค์น์์น', '๋ด๋น์(์ )', '๋ด๋น์(๋ถ)', 'IP ์ฃผ์ 1', 'IP ์ฃผ์ 2', '์๊ฒฉ๋๊ตฌ', '์๋ฒ ID', '์๋ฒ PW', '๋ชจ๋ธ๋ช
', 'OS', 'CPU', 'RAM', 'GPU', 'Storage 1', 'Storage 2', 'Storage 3', '๋ชจ๋ํฐ๋ง', '๋น๊ณ '];
+const STORAGE_HEADERS = ['๊ตฌ๋งค๋ฒ์ธ', '์ ํ', '์์ฐ์ฝ๋', '๋ช
์นญ', '์์น', '๋ชจ๋ธ๋ช
', '์ฉ๋', '๋ด๋น์(์ )', '๋ด๋น์(๋ถ)', 'IP์ฃผ์', 'MAC์ฃผ์', '๊ตฌ๋งค์ผ', '๊ธ์ก', '๋ฉํ์
์ฒด', 'ํ์์๋ช
', '๋น๊ณ '];
+const EQUIP_HEADERS = ['๊ตฌ๋งค๋ฒ์ธ', '๋นํ์ ํ', '์์ฐ์ฝ๋', '๋ช
์นญ', '์์น', '๊ด๋ฆฌ์', 'IP์ฃผ์', 'MACaddress', 'HW์ฌ์', 'OS', '๊ตฌ๋งค์ผ', '๊ธ์ก', '๋ฉํ์
์ฒด', 'ํ์์๋ช
', '๋น๊ณ '];
+const MOBILE_HEADERS = ['๊ตฌ๋งค๋ฒ์ธ', '์์ฐ์ฝ๋', '๋ช
์นญ', '์์น', '๊ด๋ฆฌ์', '๊ธฐ๊ธฐ์ ํ', 'OS', '๊ตฌ๋งค์ผ', '๊ธ์ก', '๋ฉํ์
์ฒด', 'ํ์์๋ช
', '๋น๊ณ '];
+
+const SUB_SW_HEADERS = ['ID', '๋ถ์ผ', '๋ฒ์ธ', '๋ถ์', '์ ํ๋ช
', '๊ตฌ๋งค์ผ', '๋ง๋ฃ์ผ', '๋ผ์ด์ ์ค์ ํ', '๊ธ์ก', '์๋', '๊ณ์ ๋ช
', '๋ฉํ์
์ฒด', '๋น๊ณ '];
+const PERM_SW_HEADERS = ['ID', '๋ถ์ผ', '๋ฒ์ธ', '๋ถ์', '์ ํ๋ช
', '๊ตฌ๋งค์ผ', '๋ผ์ด์ ์คํค', '๊ธ์ก', '์๋', '๊ณ์ ๋ช
', '๋ฉํ์
์ฒด', '๋น๊ณ '];
+const CLOUD_HEADERS = ['ID', 'ํ๋ซํผ๋ช
', '๋ฒ์ธ', '๋ถ์', '์ฌ์ฉ์ฉ๋(์ ํ๋ช
)', '๊ณ์ ๋ช
', '๊ฒฐ์ ์๋จ', '๊ฒฐ์ ์ผ', '์ฐ๊ฒฐ์นด๋๋ฒํธ', '๋น์์ฒญ๊ตฌ์ก', '๋น๊ณ '];
+
+export function downloadTemplate() {
+ const wb = XLSX.utils.book_new();
+ const tabConfigs = [
+ { name: '๊ฐ์ธPC', headers: PC_HEADERS },
+ { name: '์๋ฒ', headers: SERVER_HEADERS },
+ { name: '์คํ ๋ฆฌ์ง', headers: STORAGE_HEADERS },
+ { name: '์ ์ฐ๋นํ', headers: EQUIP_HEADERS },
+ { name: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', headers: MOBILE_HEADERS }
+ ];
+
+ tabConfigs.forEach(config => {
+ const ws = XLSX.utils.aoa_to_sheet([config.headers]);
+ ws['!cols'] = Array(config.headers.length).fill({ wch: 18 });
+ XLSX.utils.book_append_sheet(wb, ws, config.name);
+ });
+
+ const SW_TABS = ['๊ตฌ๋
SW', '์๊ตฌSW', 'ํด๋ผ์ฐ๋'];
+ SW_TABS.forEach(tab => {
+ let hd = tab === '๊ตฌ๋
SW' ? SUB_SW_HEADERS : (tab === 'ํด๋ผ์ฐ๋' ? CLOUD_HEADERS : PERM_SW_HEADERS);
+ const ws = XLSX.utils.aoa_to_sheet([hd]);
+ ws['!cols'] = Array(hd.length).fill({ wch: 18 });
+ XLSX.utils.book_append_sheet(wb, ws, tab);
+ });
+
+ XLSX.writeFile(wb, 'itam_assets_template_full.xlsx');
+}
+
export async function parseExcel(file: File): Promise {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@@ -26,122 +63,137 @@ export async function parseExcel(file: File): Promise {
rows.forEach(r => data.pc.push({
id: Math.random().toString(36).substring(2, 9),
type: '๊ฐ์ธPC',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ๊ด๋ฆฌ๋ฒํธ: r['๊ด๋ฆฌ๋ฒํธ'] || r['๊ด๋ฆฌ์ฝ๋'] || '',
- ์ค์ฌ์ฉ์กฐ์ง: r['์ค์ฌ์ฉ์กฐ์ง'] || '',
- ๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
'] || '',
- OS: r['OS'] || '',
+ ๋ฒ์ธ: r['๋ฒ์ธ'] || '',
+ ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋'] || '',
+ ์ฌ์ฉ์: r['์ฌ์ฉ์'] || '',
+ ์์น: r['์์น'] || '',
CPU: r['CPU'] || '',
+ GPU: r['GPU'] || '',
RAM: r['RAM'] || '',
SSD1: r['SSD1'] || '',
SSD2: r['SSD2'] || '',
HDD1: r['HDD1'] || '',
IP์ฃผ์: r['IP์ฃผ์'] || '',
HW์ฌ์: r['HW์ฌ์'] || '',
- ๋์
์ผ: r['๋์
์ผ'] || '',
- ๊ตฌ๋งค๊ฐ: r['๊ตฌ๋งค๊ฐ'] || r['๊ธ์ก'] || '',
- ๋น๊ณ : r['๋น๊ณ '] || ''
+ ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ'] || '',
+ ๊ธ์ก: r['๊ธ์ก'] || '',
+ ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด'] || '',
+ ํ์์๋ช
: r['ํ์์๋ช
'] || '',
+ ๋น๊ณ : r['๋น๊ณ '] || '',
+ MACaddress: '', OS: '', ๋ช
์นญ: ''
}));
} else if (sheetName === '์๋ฒ') {
rows.forEach(r => data.server.push({
id: Math.random().toString(36).substring(2, 9),
type: '์๋ฒ',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ๊ด๋ฆฌ๋ฒํธ: r['๊ด๋ฆฌ๋ฒํธ'] || r['๊ด๋ฆฌ์ฝ๋'] || '',
- ์๋ฒ์ฉ๋: r['์๋ฒ์ฉ๋'] || r['์ฉ๋'] || '',
- ์ํ: r['์ํ'] || r['์ด์๋จ๊ณ'] || '',
- ์ค์ฌ์ฉ์กฐ์ง: r['์ค์ฌ์ฉ์กฐ์ง'] || r['์ฌ์ฉ์กฐ์ง'] || '',
- ๊ด๋ฆฌ์กฐ์ง: r['๊ด๋ฆฌ์กฐ์ง'] || '',
- ์ค์น์ฅ์: r['์ค์น์ฅ์'] || r['์์น'] || '',
- ์ธ๋ถ์์น: r['์ธ๋ถ์์น'] || '',
- IP์ฃผ์: r['IP์ฃผ์'] || r['IP ์ฃผ์ 1'] || '',
- IP2: r['IP2'] || r['IP ์ฃผ์ 2'] || '',
- ์๊ฒฉ๋ฐฉ๋ฒ: r['์๊ฒฉ๋ฐฉ๋ฒ'] || r['์๊ฒฉ์ ์'] || '',
- ์๋ฒID: r['์๋ฒID'] || '',
- ์๋ฒPW: r['์๋ฒPW'] || '',
+ ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ'] || r['๋ฒ์ธ'] || '',
+ ์์ฐ์ฝ๋: r['์์ฐ๋ฒํธ'] || r['์์ฐ์ฝ๋'] || '',
+ ๋์
์ผ: r['๊ตฌ๋งค์ผ์'] || r['๊ตฌ๋งค์ผ'] || '',
+ ์๋ฒ์ฉ๋: r['์ฉ๋'] || r['์๋ฒ์ฉ๋'] || '',
+ ์์ธ: r['์์ธ๋ด์ฉ'] || '',
+ ์ค์ฌ์ฉ์กฐ์ง: r['ํ์ฌ์ฉ์กฐ์ง'] || r['์ค์ฌ์ฉ์กฐ์ง'] || '',
+ ์ด์ ์ฌ์ฉ์กฐ์ง: r['์ด์ ์ฌ์ฉ์กฐ์ง'] || '',
+ ์์น: r['์ค์น์์น'] || r['์์น'] || '',
+ ๊ด๋ฆฌ์กฐ์ง: r['๋ด๋น์(์ )'] || r['๊ด๋ฆฌ์กฐ์ง'] || '',
+ IP์ฃผ์: r['IP ์ฃผ์ 1'] || r['IP์ฃผ์'] || '',
+ IP2: r['IP ์ฃผ์ 2'] || '',
+ ์๊ฒฉ๋ฐฉ๋ฒ: r['์๊ฒฉ๋๊ตฌ'] || r['์๊ฒฉ๋ฐฉ๋ฒ'] || '',
+ ์๋ฒID: r['์๋ฒ ID'] || r['์๋ฒID'] || '',
+ ์๋ฒPW: r['์๋ฒ PW'] || r['์๋ฒPW'] || '',
๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
'] || '',
OS: r['OS'] || '',
CPU: r['CPU'] || '',
RAM: r['RAM'] || '',
- SSD1: r['SSD1'] || r['Storage 1'] || '',
- SSD2: r['SSD2'] || r['Storage 2'] || '',
+ GPU: r['GPU'] || '',
+ SSD1: r['Storage 1'] || r['SSD1'] || '',
+ SSD2: r['Storage 2'] || r['SSD2'] || '',
๋ชจ๋ํฐ๋ง: r['๋ชจ๋ํฐ๋ง'] || '',
- ๋น๊ณ : r['๋น๊ณ '] || ''
+ ๋น๊ณ : r['๋น๊ณ '] || '',
+ ์์ฐ๊ตฌ๋ถ: '์๋ฒ'
}));
} else if (sheetName === '์คํ ๋ฆฌ์ง') {
rows.forEach(r => data.storage.push({
id: Math.random().toString(36).substring(2, 9),
type: '์คํ ๋ฆฌ์ง',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ๊ด๋ฆฌ๋ฒํธ: r['๊ด๋ฆฌ๋ฒํธ'] || '',
+ ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ'] || r['๋ฒ์ธ'] || '',
+ ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋'] || '',
+ ๋ช
์นญ: r['๋ช
์นญ'] || '',
+ ์์น: r['์์น'] || '',
๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
'] || '',
์ฉ๋: r['์ฉ๋'] || '',
IP์ฃผ์: r['IP์ฃผ์'] || '',
- ๋์
์ผ: r['๋์
์ผ'] || '',
- ๊ตฌ๋งค๊ฐ: r['๊ตฌ๋งค๊ฐ'] || r['๊ธ์ก'] || '',
- ๋น๊ณ : r['๋น๊ณ '] || ''
+ MACaddress: r['MAC์ฃผ์'] || '',
+ ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ'] || '',
+ ๊ธ์ก: r['๊ธ์ก'] || '',
+ ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด'] || '',
+ ํ์์๋ช
: r['ํ์์๋ช
'] || '',
+ ๋น๊ณ : r['๋น๊ณ '] || '',
+ ์์ฐ๊ตฌ๋ถ: '์คํ ๋ฆฌ์ง'
}));
- } else if (sheetName === '๊ธฐํ์์ฐ') {
+ } else if (sheetName === '๊ธฐ๊ธฐ' || sheetName === '์ ์ฐ๋นํ') {
rows.forEach(r => data.equip.push({
id: Math.random().toString(36).substring(2, 9),
- type: '๊ธฐํ์์ฐ',
- ์์ฐ๊ตฌ๋ถ: r['์์ฐ๊ตฌ๋ถ'] || r['๊ตฌ๋ถ'] || '',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ๊ด๋ฆฌ๋ฒํธ: r['๊ด๋ฆฌ๋ฒํธ'] || '',
- ๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
'] || '',
+ type: '์ ์ฐ๋นํ',
+ ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ'] || r['๋ฒ์ธ'] || '',
+ ์์ฐ๋ฒํธ: r['์์ฐ์ฝ๋'] || '',
+ ์์ฐ๊ตฌ๋ถ: r['๋นํ์ ํ'] || r['์ ํ'] || '',
+ ๋ช
์นญ: r['๋ช
์นญ'] || '',
+ ์์น: r['์์น'] || '',
+ ์ฌ์ฉ์: r['๊ด๋ฆฌ์'] || '',
IP์ฃผ์: r['IP์ฃผ์'] || '',
+ HW์ฌ์: r['HW์ฌ์'] || '',
OS: r['OS'] || '',
- ๋์
์ผ: r['๋์
์ผ'] || '',
- ๊ตฌ๋งค๊ฐ: r['๊ตฌ๋งค๊ฐ'] || r['๊ธ์ก'] || '',
+ ๋์
์ผ: r['๊ตฌ๋งค์ผ'] || '',
+ ๊ตฌ๋งค๊ฐ: r['๊ธ์ก'] || '',
๋น๊ณ : r['๋น๊ณ '] || ''
}));
- } else if (sheetName === '๋ชจ๋ฐ์ผ') {
+ } else if (sheetName === '๋ชจ๋ฐ์ผ' || sheetName === '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ') {
rows.forEach(r => data.mobile.push({
id: Math.random().toString(36).substring(2, 9),
type: '๋ชจ๋ฐ์ผ',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ๊ด๋ฆฌ๋ฒํธ: r['๊ด๋ฆฌ๋ฒํธ'] || '',
- ๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
'] || '',
- ์ฌ์ฉ์: r['์ฌ์ฉ์'] || '',
- ๋์
์ผ: r['๋์
์ผ'] || '',
- ๊ตฌ๋งค๊ฐ: r['๊ตฌ๋งค๊ฐ'] || r['๊ธ์ก'] || '',
+ ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ'] || r['๋ฒ์ธ'] || '',
+ ์์ฐ๋ฒํธ: r['์์ฐ์ฝ๋'] || '',
+ ๋ช
์นญ: r['๋ช
์นญ'] || '',
+ ์์น: r['์์น'] || '',
+ ์ฌ์ฉ์: r['๊ด๋ฆฌ์'] || '',
+ OS: r['OS'] || '',
+ ๋์
์ผ: r['๊ตฌ๋งค์ผ'] || '',
+ ๊ตฌ๋งค๊ฐ: r['๊ธ์ก'] || '',
๋น๊ณ : r['๋น๊ณ '] || ''
}));
} else if (sheetName === '๊ตฌ๋
SW') {
rows.forEach(r => data.subSw.push({
id: r['ID'] || Math.random().toString(36).substring(2, 9),
type: '๊ตฌ๋
SW',
+ ๋ถ์ผ: r['๋ถ์ผ'] || '',
+ ๋ฒ์ธ: r['๋ฒ์ธ'] || '',
๋ถ์: r['๋ถ์'] || '',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ์ํํธ์จ์ด๋ช
: r['์ํํธ์จ์ด๋ช
'] || '',
+ ์ ํ๋ช
: r['์ ํ๋ช
'] || '',
๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ'] || '',
๋ง๋ฃ์ผ: r['๋ง๋ฃ์ผ'] || '',
+ ๋ผ์ด์ ์ค์ ํ: r['๋ผ์ด์ ์ค์ ํ'] || '',
๊ธ์ก: r['๊ธ์ก'] || '',
์๋: parseInt(r['์๋'] || '1', 10),
+ ๊ณ์ ๋ช
: r['๊ณ์ ๋ช
'] || '',
+ ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด'] || '',
๋น๊ณ : r['๋น๊ณ '] || ''
}));
} else if (sheetName === '์๊ตฌSW') {
rows.forEach(r => data.permSw.push({
id: r['ID'] || Math.random().toString(36).substring(2, 9),
type: '์๊ตฌSW',
+ ๋ถ์ผ: r['๋ถ์ผ'] || '',
+ ๋ฒ์ธ: r['๋ฒ์ธ'] || '',
๋ถ์: r['๋ถ์'] || '',
- ์์ฐ๋ฒํธ: r['์์ฐ๋ฒํธ'] || '',
- ์ํํธ์จ์ด๋ช
: r['์ํํธ์จ์ด๋ช
'] || '',
+ ์ ํ๋ช
: r['์ ํ๋ช
'] || '',
๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ'] || '',
+ ๋ผ์ด์ ์คํค: r['๋ผ์ด์ ์คํค'] || '',
๊ธ์ก: r['๊ธ์ก'] || '',
์๋: parseInt(r['์๋'] || '1', 10),
+ ๊ณ์ ๋ช
: r['๊ณ์ ๋ช
'] || '',
+ ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด'] || '',
๋น๊ณ : r['๋น๊ณ '] || ''
}));
- } else if (sheetName === 'SW_์ฌ์ฉํํฉ') {
- rows.forEach(r => data.swUsers.push({
- id: r['id'] || Math.random().toString(36).substring(2, 9),
- swId: r['swId'] || '',
- ๋ถ์: r['๋ถ์'] || '',
- ์ด๋ฆ: r['์ด๋ฆ'] || '',
- ์ง๊ธ: r['์ง๊ธ'] || '',
- ์ฌ๋ฒ: r['์ฌ๋ฒ'] || '',
- ์ฌ์ฉ๊ธฐ๊ฐ: r['์ฌ์ฉ๊ธฐ๊ฐ'] || ''
- }));
} else if (sheetName === 'History') {
rows.forEach(r => data.logs.push({
id: r['id'] || Math.random().toString(36).substring(2, 9),
@@ -161,23 +213,21 @@ export async function parseExcel(file: File): Promise {
});
}
-export function exportToExcel(data: any, fileName: string) {
+export function exportToExcel(masterData: MasterAssetData) {
const wb = XLSX.utils.book_new();
-
- // HW Tabs
- if (data.pc) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.pc), '๊ฐ์ธPC');
- if (data.server) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.server), '์๋ฒ');
- if (data.storage) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.storage), '์คํ ๋ฆฌ์ง');
- if (data.equip) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.equip), '๊ธฐํ์์ฐ');
- if (data.mobile) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.mobile), '๋ชจ๋ฐ์ผ');
-
- // SW Tabs
- if (data.subSw) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.subSw), '๊ตฌ๋
SW');
- if (data.permSw) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.permSw), '์๊ตฌSW');
- if (data.swUsers) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.swUsers), 'SW_์ฌ์ฉํํฉ');
-
- // Logs
- if (data.logs) XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data.logs), 'History');
+ const exportMap = [
+ { tab: '๊ฐ์ธPC', list: masterData.pc, headers: PC_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ์ฝ๋, a.์ฌ์ฉ์, a.์์น, a.CPU, a.GPU, a.RAM, a.SSD1, a.SSD2, a.HDD1, a.HDD2, a.IP์ฃผ์, a.HW์ฌ์, a.๊ตฌ๋งค์ผ, a.๊ธ์ก, a.๋ฉํ์
์ฒด, a.ํ์์๋ช
, a.๋น๊ณ ] },
+ { tab: '์๋ฒ', list: masterData.server, headers: SERVER_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ์ฝ๋, a.๋์
์ผ, '๋ฌผ๋ฆฌ', a.์๋ฒ์ฉ๋, a.์์ธ, a.์ค์ฌ์ฉ์กฐ์ง, a.์ด์ ์ฌ์ฉ์กฐ์ง, a.์์น, a.๊ด๋ฆฌ์กฐ์ง, '', a.IP์ฃผ์, a.IP2, a.์๊ฒฉ๋ฐฉ๋ฒ, a.์๋ฒID, a.์๋ฒPW, a.๋ชจ๋ธ๋ช
, a.OS, a.CPU, a.RAM, a.GPU, a.SSD1, a.SSD2, '', a.๋ชจ๋ํฐ๋ง, a.๋น๊ณ ] },
+ { tab: '์คํ ๋ฆฌ์ง', list: masterData.storage, headers: STORAGE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, '์คํ ๋ฆฌ์ง', a.์์ฐ์ฝ๋, a.๋ช
์นญ, a.์์น, a.๋ชจ๋ธ๋ช
, a.์ฉ๋, '', '', a.IP์ฃผ์, a.MACaddress, a.๊ตฌ๋งค์ผ, a.๊ธ์ก, a.๋ฉํ์
์ฒด, a.ํ์์๋ช
, a.๋น๊ณ ] },
+ { tab: '์ ์ฐ๋นํ', list: masterData.equip, headers: EQUIP_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ๊ตฌ๋ถ, a.์์ฐ๋ฒํธ, a.๋ช
์นญ, a.์์น, a.์ฌ์ฉ์, a.IP์ฃผ์, '', a.HW์ฌ์, a.OS, a.๋์
์ผ, a.๊ตฌ๋งค๊ฐ, '', '', a.๋น๊ณ ] },
+ { tab: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', list: masterData.mobile, headers: MOBILE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ๋ฒํธ, a.๋ช
์นญ, a.์์น, a.์ฌ์ฉ์, '๋ชจ๋ฐ์ผ', a.OS, a.๋์
์ผ, a.๊ตฌ๋งค๊ฐ, '', '', a.๋น๊ณ ] },
+ { tab: '๊ตฌ๋
SW', list: masterData.subSw, headers: SUB_SW_HEADERS, map: (a: any) => [a.id, a.๋ถ์ผ, a.๋ฒ์ธ, a.๋ถ์, a.์ ํ๋ช
, a.๊ตฌ๋งค์ผ, a.๋ง๋ฃ์ผ, a.๋ผ์ด์ ์ค์ ํ, a.๊ธ์ก, a.์๋, a.๊ณ์ ๋ช
, a.๋ฉํ์
์ฒด, a.๋น๊ณ ] },
+ { tab: '์๊ตฌSW', list: masterData.permSw, headers: PERM_SW_HEADERS, map: (a: any) => [a.id, a.๋ถ์ผ, a.๋ฒ์ธ, a.๋ถ์, a.์ ํ๋ช
, a.๊ตฌ๋งค์ผ, a.๋ผ์ด์ ์คํค, a.๊ธ์ก, a.์๋, a.๊ณ์ ๋ช
, a.๋ฉํ์
์ฒด, a.๋น๊ณ ] }
+ ];
- XLSX.writeFile(wb, fileName);
+ exportMap.forEach(m => {
+ const ws = XLSX.utils.aoa_to_sheet([m.headers, ...m.list.map(m.map)]);
+ XLSX.utils.book_append_sheet(wb, ws, m.tab);
+ });
+ XLSX.writeFile(wb, `itam_master_full_${new Date().toISOString().split('T')[0]}.xlsx`);
}
diff --git a/src/main.ts b/src/main.ts
index 0953898..c010547 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -4,7 +4,6 @@ import { renderDashboard } from './views/DashboardView';
import { renderSWTable } from './views/SW_Table';
import { downloadTemplate, exportToExcel, parseExcel, HardwareAsset, SoftwareAsset, SWUser } from './core/excelHandler';
import { initBaseModal } from './components/Modal/BaseModal';
-import { initPcModal } from './components/Modal/PCModal';
import { initHwModal, openHwModal } from './components/Modal/HWModal';
import { initSwModal, openSwModal } from './components/Modal/SWModal';
import { initSwUserModal } from './components/Modal/SWUserModal';
@@ -75,7 +74,6 @@ function initApp() {
});
// ๋ชจ๋ฌ ์ด๊ธฐํ
- initPcModal(() => { saveAllHardwareToDB(); renderSWTable(mainContent); }, closeAllModals);
initHwModal(() => { saveAllHardwareToDB(); renderSWTable(mainContent); }, closeAllModals);
initSwModal(() => {
@@ -125,8 +123,14 @@ function initApp() {
const cat = state.activeCategory;
if (cat === 'hw') {
- // ํ๋์จ์ด ๋์๋ณด๋ ๋๋ ๊ฐ๋ณ ํญ์์ ์ถ๊ฐ
- const defaultType = (tab === '๋์๋ณด๋') ? '' : tab;
+ // ํญ ๋ช
์นญ์ ์ค์ ์ ํ๋ช
์ผ๋ก ๋งคํ
+ let defaultType = '';
+ if (tab === '๊ฐ์ธPC') defaultType = 'PC';
+ else if (tab === '์๋ฒ') defaultType = '์๋ฒ';
+ else if (tab === '์คํ ๋ฆฌ์ง') defaultType = '์คํ ๋ฆฌ์ง';
+ else if (tab === '์ ์ฐ๋นํ') defaultType = 'CPU';
+ else if (tab === '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ') defaultType = '๋ชจ๋ฐ์ผ';
+
openHwModal({
id: Math.random().toString(36).substring(2, 9),
type: defaultType,
diff --git a/src/styles/modal.css b/src/styles/modal.css
index f1be292..49fe7a8 100644
--- a/src/styles/modal.css
+++ b/src/styles/modal.css
@@ -180,6 +180,10 @@
background-color: var(--white);
}
+.form-group textarea {
+ resize: none;
+}
+
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
@@ -226,6 +230,9 @@
}
.history-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
margin-bottom: 1rem;
}
@@ -238,6 +245,35 @@
color: var(--text-main);
}
+/* ์ฝ๊ธฐ ์ ์ฉ ํ๋ (์์ฐ๋ฒํธ ๋ฑ) ํต์ผ ์คํ์ผ */
+.is-readonly-field {
+ border-color: transparent !important;
+ background-color: transparent !important;
+ pointer-events: none !important;
+ color: var(--text-main) !important;
+ font-weight: 600 !important;
+ cursor: default;
+ padding-left: 0 !important;
+}
+
+/* ์
๋ ฅ ํ๋ + ๋ฒํผ ๊ทธ๋ฃน (์์ฐ๋ฒํธ ์์ฑ ๋ฑ) */
+.input-with-btn {
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+ width: 100%;
+}
+
+.input-with-btn input {
+ flex: 1;
+ min-width: 0; /* flex ์ปจํ
์ด๋ ์์์ ๋๋น ์์ถ ๋ฐฉ์ง */
+}
+
+.input-with-btn .btn {
+ flex-shrink: 0;
+ white-space: nowrap;
+}
+
.history-timeline {
flex: 1;
overflow-y: auto;
diff --git a/src/views/Dashboard/HwDashboard.ts b/src/views/Dashboard/HwDashboard.ts
index c124dcf..d0466c7 100644
--- a/src/views/Dashboard/HwDashboard.ts
+++ b/src/views/Dashboard/HwDashboard.ts
@@ -105,7 +105,7 @@ export function renderHwDashboard(container: HTMLElement) {
์ ํ |
๋ชจ๋ธ๋ช
|
์ฌ์ฉ์/๋ด๋น์ |
- ๊ตฌ๋งค์ผ |
+ ๊ตฌ๋งค์ฐ์ |
์ฐ๋ น |
diff --git a/src/views/List/EquipmentListView.ts b/src/views/List/EquipmentListView.ts
index 812f084..37bd4b0 100644
--- a/src/views/List/EquipmentListView.ts
+++ b/src/views/List/EquipmentListView.ts
@@ -22,6 +22,9 @@ export function renderEquipmentList(container: HTMLElement) {
+
`;
container.appendChild(filterBar);
@@ -39,7 +42,7 @@ export function renderEquipmentList(container: HTMLElement) {
๋ชจ๋ธ๋ช
|
๋ณด๊ด์์น |
๊ด๋ฆฌ์ |
- ๊ตฌ๋งค์ผ |
+ ๊ตฌ๋งค์ฐ์ |
๊ธ์ก |
diff --git a/src/views/List/MobileListView.ts b/src/views/List/MobileListView.ts
index c991143..4ab2bac 100644
--- a/src/views/List/MobileListView.ts
+++ b/src/views/List/MobileListView.ts
@@ -22,6 +22,9 @@ export function renderMobileList(container: HTMLElement) {
+
`;
container.appendChild(filterBar);
@@ -38,7 +41,7 @@ export function renderMobileList(container: HTMLElement) {
๋ช
์นญ |
๋ณด๊ด์์น |
๊ด๋ฆฌ์ |
- ๊ตฌ๋งค์ผ |
+ ๊ตฌ๋งค์ฐ์ |
๊ธ์ก |
@@ -106,7 +109,8 @@ export function renderMobileList(container: HTMLElement) {
(document.getElementById('filter-keyword') as HTMLInputElement).value = '';
(document.getElementById('filter-corp') as HTMLSelectElement).value = '';
updateTable();
- });
+ });
+
+ updateTable();
+ }
- updateTable();
-}
diff --git a/src/views/List/PcListView.ts b/src/views/List/PcListView.ts
index 77b5abf..4b97b64 100644
--- a/src/views/List/PcListView.ts
+++ b/src/views/List/PcListView.ts
@@ -1,5 +1,5 @@
import { state } from '../../core/state';
-import { openPcModal } from '../../components/Modal/PCModal';
+import { openHwModal } from '../../components/Modal/HWModal';
import { formatInline, sortAssets } from '../../core/utils';
import { createIcons, Paperclip, RefreshCcw } from 'lucide';
@@ -28,7 +28,7 @@ export function renderPcList(container: HTMLElement) {
const tableWrapper = document.createElement('div');
tableWrapper.className = 'table-container';
const table = document.createElement('table');
- table.innerHTML = `| No | ๊ตฌ๋งค๋ฒ์ธ | ํ ์ฌ์ฉ์กฐ์ง | ์์ฐ์ฝ๋ | ์ฌ์ฉ์ | ์์น | CPU | RAM | Storage | ๊ตฌ๋งค์ผ | ๊ธ์ก | ํ์์ | ๊ด๋ฆฌ |
`;
+ table.innerHTML = `| No | ๊ตฌ๋งค๋ฒ์ธ | ํ ์ฌ์ฉ์กฐ์ง | ์์ฐ์ฝ๋ | ์ฌ์ฉ์ | ์์น | CPU | RAM | Storage | ๊ตฌ๋งค์ฐ์ | ๊ธ์ก | ํ์์ | ๊ด๋ฆฌ |
`;
tableWrapper.appendChild(table);
container.appendChild(tableWrapper);
@@ -69,12 +69,12 @@ export function renderPcList(container: HTMLElement) {
${asset.CPU||''} |
${asset.RAM||''} |
${formatInline(storage)} |
- ${asset.๊ตฌ๋งค์ผ||''} |
+ ${asset.๊ตฌ๋งค์ฐ์ || asset.๊ตฌ๋งค์ผ || ''} |
${asset.๊ธ์ก||''} |
${asset.ํ์์๋ช
? '' : '-'} |
|
`;
- tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openPcModal(asset, 'view'); });
+ tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openHwModal(asset, 'view'); });
tbody.appendChild(tr);
});
createIcons({ icons: { Paperclip } });
diff --git a/src/views/List/ServerListView.ts b/src/views/List/ServerListView.ts
index 6b41f9a..829436c 100644
--- a/src/views/List/ServerListView.ts
+++ b/src/views/List/ServerListView.ts
@@ -102,7 +102,8 @@ export function renderServerList(container: HTMLElement) {
(document.getElementById('filter-corp') as HTMLSelectElement).value = '';
(document.getElementById('filter-org-unit') as HTMLSelectElement).value = '';
updateTable();
- });
+ });
+
+ updateTable();
+ }
- updateTable();
-}
diff --git a/src/views/List/SwListView.ts b/src/views/List/SwListView.ts
index 0f7a87e..41c1a81 100644
--- a/src/views/List/SwListView.ts
+++ b/src/views/List/SwListView.ts
@@ -49,7 +49,7 @@ export function renderSwList(container: HTMLElement) {
๊ตฌ๋งค๋ฒ์ธ |
๋ถ์ |
์ ํ๋ช
|
- ๊ตฌ๋งค์ผ |
+ ๊ตฌ๋งค์ฐ์ |
${isSub ? '๊ตฌ๋
์ผ | ' : ''}
๊ธ์ก |
์๋ |