-
-
-
+
์ด์ ๋ฐ ์ํ ๊ด๋ฆฌ
+
+
+
+
+
+
+
+
+
+
๋คํธ์ํฌ ์ ๋ณด (Connectivity)
+
+
+
+
+
+
+
+
์์คํ
์ฌ์ (Specifications)
+
+
+
+
+
+
+
+
+
+
์ค์น ์์น ๋ฐ ๊ด๋ฆฌ
+
+
+
+
+
+
+
+
+
`;
@@ -369,16 +141,13 @@ const HW_MODAL_HTML = `
function renderHwHistory(assetId: string) {
const container = document.getElementById('hw-history-list');
if (!container) return;
- const logs = (state.masterData.logs || []).filter(l => l.assetId === assetId);
- if (logs.length === 0) {
- container.innerHTML = '
๊ธฐ๋ก๋ ์ด๋ ฅ์ด ์์ต๋๋ค.
';
- return;
- }
+ const logs = (state.masterData.logs || []).filter(l => l.assetId === assetId).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}
+
${l.details.replace(/\n/g, '
')}
`).join('');
}
@@ -399,7 +168,8 @@ function applyTypeSpecificUI(type: string) {
ssd1: document.getElementById('hw-ssd1-group'),
ssd2: document.getElementById('hw-ssd2-group'),
hwSpec: document.getElementById('hw-hwspec-group'),
- monitoring: document.getElementById('hw-monitoring-group')
+ monitoring: document.getElementById('hw-monitoring-group'),
+ user: document.querySelector('.pc-only') as HTMLElement
};
const serverOnly = document.querySelectorAll('.server-only');
@@ -407,7 +177,7 @@ function applyTypeSpecificUI(type: string) {
const opOnly = document.querySelectorAll('.op-only');
const standardLoc = document.querySelectorAll('.loc-standard');
- // 1. ์ด๊ธฐํ (๋ชจ๋ ์จ๊น ๋ฐ ๋ผ๋ฒจ ์๋ณต)
+ // ์ด๊ธฐํ
serverOnly.forEach(el => (el as HTMLElement).style.display = 'none');
nonServer.forEach(el => (el as HTMLElement).style.display = 'none');
opOnly.forEach(el => (el as HTMLElement).style.display = 'none');
@@ -421,68 +191,54 @@ function applyTypeSpecificUI(type: string) {
if (ramLabel) ramLabel.innerText = 'RAM ์ฉ๋';
if (modelLabel) modelLabel.innerText = '๋ชจ๋ธ๋ช
';
- // 2. ๋ถ๋ฅ ํ๋ณ
const isMobileGroup = ['๋ชจ๋ฐ์ผ', 'ํ๋ธ๋ฆฟ', 'ํด๋ํฐ'].some(t => upperType.includes(t));
const isEquipGroup = ['CPU', 'RAM', 'HDD', 'GPU'].some(t => upperType.includes(t)) || upperType.includes('๋นํ');
const isOpType = isMobileGroup || isEquipGroup;
const isPcType = upperType === 'PC' || upperType === '๊ฐ์ธPC' || upperType === '๋
ธํธ๋ถ';
- // 3. ๋ ์ด์์ ์ ์ฉ
- if (groups.opTitle) groups.opTitle.style.display = 'flex';
+ if (groups.opTitle) groups.opTitle.style.display = isOpType ? 'flex' : 'none';
if (isOpType) {
opOnly.forEach(el => (el as HTMLElement).style.display = 'flex');
standardLoc.forEach(el => (el as HTMLElement).style.display = 'none');
-
if (groups.specTitle) groups.specTitle.style.display = 'flex';
if (groups.model) groups.model.style.display = 'flex';
- // ํน์ ๋ถํ ์ ํ์ ๋ฐ๋ฅธ ๋ผ๋ฒจ ๋ฐ ํ๋ ์ ์ด
- const isCpuGpu = ['CPU', 'GPU'].some(t => upperType.includes(t));
- const isRamHdd = ['RAM', 'HDD'].some(t => upperType.includes(t));
-
- if (isCpuGpu) {
- if (groups.os && osLabel) {
- osLabel.innerText = '์ถ์์ฐ์';
- groups.os.style.display = 'flex';
- }
- } else if (isRamHdd) {
- if (groups.ram && ramLabel) {
- ramLabel.innerText = '์ฉ๋';
- groups.ram.style.display = 'flex';
- }
- // HDD์ธ ๊ฒฝ์ฐ ๋ชจ๋ธ๋ช
๋ผ๋ฒจ์ S/N์ผ๋ก ๋ณ๊ฒฝ
- if (upperType.includes('HDD') && modelLabel) {
- modelLabel.innerText = 'S/N';
- }
+ if (['CPU', 'GPU'].some(t => upperType.includes(t))) {
+ if (groups.os && osLabel) { osLabel.innerText = '์ถ์์ฐ์'; groups.os.style.display = 'flex'; }
+ } else if (['RAM', 'HDD'].some(t => upperType.includes(t))) {
+ if (groups.ram && ramLabel) { ramLabel.innerText = '์ฉ๋'; groups.ram.style.display = 'flex'; }
+ if (upperType.includes('HDD') && modelLabel) modelLabel.innerText = 'S/N';
} else {
if (groups.hwSpec) groups.hwSpec.style.display = 'flex';
}
}
else if (isPcType) {
- if (groups.detailPurpose) groups.detailPurpose.style.display = 'flex';
+ if (groups.user) groups.user.style.display = 'flex';
if (groups.specTitle) groups.specTitle.style.display = 'flex';
- if (detailPurpose === '์๋ฒ') {
- serverOnly.forEach(el => (el as HTMLElement).style.display = 'flex');
- if (groups.networkTitle) groups.networkTitle.style.display = 'flex';
- ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'monitoring'].forEach(k => {
- if (groups[k]) groups[k]!.style.display = 'flex';
- });
- } else {
+ // ๋
ธํธ๋ถ์ ์์ธ์ ํ ์ ํ์ฐฝ ์จ๊น
+ if (upperType === '๋
ธํธ๋ถ') {
+ if (groups.detailPurpose) groups.detailPurpose.style.display = 'none';
nonServer.forEach(el => (el as HTMLElement).style.display = 'flex');
- ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'hwSpec'].forEach(k => {
- if (groups[k]) groups[k]!.style.display = 'flex';
- });
+ ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'hwSpec'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; });
+ } else {
+ if (groups.detailPurpose) groups.detailPurpose.style.display = 'flex';
+ if (detailPurpose === '์๋ฒ') {
+ serverOnly.forEach(el => (el as HTMLElement).style.display = 'flex');
+ if (groups.networkTitle) groups.networkTitle.style.display = 'flex';
+ ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'monitoring'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; });
+ } else {
+ nonServer.forEach(el => (el as HTMLElement).style.display = 'flex');
+ ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'hwSpec'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; });
+ }
}
}
- else if (upperType.includes('์๋ฒ') || ['์คํ ๋ฆฌ์ง', 'NAS', 'DAS'].includes(upperType)) {
+ else {
serverOnly.forEach(el => (el as HTMLElement).style.display = 'flex');
if (groups.networkTitle) groups.networkTitle.style.display = 'flex';
if (groups.specTitle) groups.specTitle.style.display = 'flex';
- ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'monitoring'].forEach(k => {
- if (groups[k]) groups[k]!.style.display = 'flex';
- });
+ ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'monitoring'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; });
}
}
@@ -493,11 +249,18 @@ export function openHwModal(asset: HardwareAsset, mode: 'view' | 'add' = 'view')
setEditLock('hw-asset-form', mode, {
saveBtnId: 'btn-save-hw-asset',
revertBtnId: 'btn-revert-hw-edit',
- generateBtnId: 'btn-generate-hw-code'
+ generateBtnId: 'btn-generate-hw-code',
+ addLogBtnId: 'btn-add-hw-log'
});
isEditMode = (mode === 'add');
- fillHwFormData(asset);
+
+ // ๋ฐ์ดํฐ ์ฑ์ฐ๊ธฐ (์๋ ๋งคํ)
+ autoFillForm('hw', asset, HW_FIELD_MAP);
+ setFieldValue('hw-๋ช
์นญ', asset.๋ช
์นญ || asset.๋ชจ๋ธ๋ช
);
+ if (!asset.๊ตฌ๋งค์ฐ์ && asset.๊ตฌ๋งค์ผ) setFieldValue('hw-๊ตฌ๋งค์ผ', asset.๊ตฌ๋งค์ผ);
+
+ parseAndSetLocation(asset.์์น, 'hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ-group', 'hw-์์น-๊ธฐํ');
applyTypeSpecificUI(asset.type);
renderHwHistory(asset.id);
@@ -505,42 +268,30 @@ export function openHwModal(asset: HardwareAsset, mode: 'view' | 'add' = 'view')
createIcons({ icons: { X, Save, Edit2, RotateCcw, History, Plus, Paperclip } });
}
-function fillHwFormData(asset: HardwareAsset) {
- setFieldValue('hw-asset-id', asset.id);
- setFieldValue('hw-asset-type', asset.type);
- setFieldValue('hw-๋ฒ์ธ', asset.๋ฒ์ธ);
- setFieldValue('hw-์์ฐ์ฝ๋', asset.์์ฐ์ฝ๋);
- setFieldValue('hw-ํ์ฌ์ฉ์กฐ์ง', asset.ํ์ฌ์ฉ์กฐ์ง);
- setFieldValue('hw-์ด์ ์ฌ์ฉ์กฐ์ง', asset.์ด์ ์ฌ์ฉ์กฐ์ง);
- setFieldValue('hw-์์ธ์ฉ๋', (asset as any).์์ธ์ฉ๋);
- setFieldValue('hw-์ ํ', asset.type);
- setFieldValue('hw-๋ชจ๋ธ๋ช
', asset.๋ชจ๋ธ๋ช
);
- setFieldValue('hw-๋ช
์นญ', asset.๋ช
์นญ || asset.๋ชจ๋ธ๋ช
);
- setFieldValue('hw-๋ณด๊ด์์น', asset.๋ณด๊ด์์น || '');
- setFieldValue('hw-ํ์ฌ์ํ', asset.ํ์ฌ์ํ || '๋ณด๊ด์ค');
- setFieldValue('hw-IP์ฃผ์', asset.IP์ฃผ์);
- setFieldValue('hw-IP2', (asset as any).IP2);
- setFieldValue('hw-์๊ฒฉ์ ์', (asset as any).์๊ฒฉ์ ์);
- setFieldValue('hw-์๋ฒID', (asset as any).์๋ฒID);
- setFieldValue('hw-์๋ฒPW', (asset as any).์๋ฒPW);
- setFieldValue('hw-๋ชจ๋ํฐ๋ง', (asset as any).๋ชจ๋ํฐ๋ง);
- setFieldValue('hw-OS', asset.OS);
- setFieldValue('hw-CPU', asset.CPU);
- setFieldValue('hw-RAM', asset.RAM);
- setFieldValue('hw-SSD1', asset.SSD1);
- setFieldValue('hw-SSD2', asset.SSD2);
- setFieldValue('hw-HW์ฌ์', asset.HW์ฌ์);
- setFieldValue('hw-๋ด๋น์_์ ', asset.๋ด๋น์_์ || asset.๊ด๋ฆฌ์);
- setFieldValue('hw-๊ตฌ๋งค์ผ', asset.๊ตฌ๋งค์ผ);
- setFieldValue('hw-๊ธ์ก', asset.๊ธ์ก);
- setFieldValue('hw-๋น๊ณ ', asset.๋น๊ณ );
-
- parseAndSetLocation(asset.์์น, 'hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ-group', 'hw-์์น-๊ธฐํ');
-}
-
-export function initHwModal(onSave: () => void, closeModals: () => void) {
+export function initHwModal(onSave: () => void, closeModalsCb: () => void) {
if (!document.getElementById('hw-asset-modal')) {
- document.body.insertAdjacentHTML('beforeend', HW_MODAL_HTML);
+ const html = createModalFrameHTML('hw', '์์ฐ ์์ธ ์ ๋ณด', HW_FORM_HTML, {
+ historyTitle: '๋ถ์ถ ๋ฐ ๋ณ๊ฒฝ ์ด๋ ฅ',
+ addLogBtnId: 'btn-add-hw-log'
+ });
+ document.body.insertAdjacentHTML('beforeend', html);
+
+ // ์ด๋ ฅ ์ถ๊ฐ ๋ชจ๋ฌ HTML๋ ํจ๊ป ์ถ๊ฐ
+ const logModalHTML = `
+
+ `;
+ document.body.insertAdjacentHTML('beforeend', logModalHTML);
}
const form = document.getElementById('hw-asset-form') as HTMLFormElement;
@@ -558,80 +309,158 @@ export function initHwModal(onSave: () => void, closeModals: () => void) {
bindLocationEvents('hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ-group', 'hw-์์น-๊ธฐํ');
- const closeModalAction = () => { closeModals(); isEditMode = false; };
+ const closeModalAction = () => { closeModalsCb(); isEditMode = false; };
document.getElementById('btn-close-hw-modal')?.addEventListener('click', closeModalAction);
document.getElementById('btn-cancel-hw-modal')?.addEventListener('click', closeModalAction);
revertBtn.addEventListener('click', () => {
- setEditLock('hw-asset-form', 'view', { saveBtnId: 'btn-save-hw-asset', revertBtnId: 'btn-revert-hw-edit' });
+ setEditLock('hw-asset-form', 'view', {
+ saveBtnId: 'btn-save-hw-asset',
+ revertBtnId: 'btn-revert-hw-edit',
+ generateBtnId: 'btn-generate-hw-code',
+ addLogBtnId: 'btn-add-hw-log'
+ });
isEditMode = false;
- if (currentAsset) fillHwFormData(currentAsset);
+ if (currentAsset) openHwModal(currentAsset, 'view');
});
document.getElementById('btn-generate-hw-code')?.addEventListener('click', async () => {
const typeValue = typeSelect.value;
const purchaseDate = getFieldValue('hw-๊ตฌ๋งค์ผ');
const typeCode = TYPE_PREFIX_MAP[typeValue] || 'ETC';
-
- // ๊ตฌ๋งค์ผ์์ ์ฐ์(YYMM) ์ถ์ถ (์: 2026-04-21 -> 2604)
const dateStr = purchaseDate.replace(/[^0-9]/g, '');
- if (dateStr.length < 4) {
- alert('์ฌ๋ฐ๋ฅธ ๊ตฌ๋งค์ผ(์ฐ์)์ ์
๋ ฅํด์ฃผ์ธ์. (์: 2026-04-21)');
- return;
- }
- const prefix = `${typeCode}-${dateStr.substring(2, 6)}-`;
-
+ 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('hw-์์ฐ์ฝ๋', data.nextCode);
- }
- } catch (err) {
- console.error('โ ์์ฐ๋ฒํธ ์์ฑ ์คํจ:', err);
- alert('์์ฐ๋ฒํธ ์์ฑ์ ์คํจํ์ต๋๋ค.');
- }
+ if (data.nextCode) setFieldValue('hw-์์ฐ์ฝ๋', data.nextCode);
+ } catch (err) { alert('์์ฐ๋ฒํธ ์์ฑ์ ์คํจํ์ต๋๋ค.'); }
+ });
+
+ // YYYYMM ์
๋ ฅ ์ ํ ๋ก์ง (์ซ์ 6์๋ฆฌ)
+ ['hw-๊ตฌ๋งค์ผ', 'hw-OS'].forEach(id => {
+ const el = document.getElementById(id) as HTMLInputElement;
+ el?.addEventListener('input', (e) => {
+ const target = e.target as HTMLInputElement;
+ const label = document.querySelector(`label[for="${id}"]`) as HTMLElement;
+ // OS ํ๋์ ๊ฒฝ์ฐ ๋ผ๋ฒจ์ด '์ถ์์ฐ์'์ผ ๋๋ง ์ซ์ ์ ํ ์ ์ฉ
+ if (id === 'hw-OS' && label?.innerText !== '์ถ์์ฐ์') return;
+
+ target.value = target.value.replace(/[^0-9]/g, '').substring(0, 6);
+ });
});
saveBtn.addEventListener('click', () => {
if (!currentAsset) return;
if (!isEditMode) {
- setEditLock('hw-asset-form', 'edit', { saveBtnId: 'btn-save-hw-asset', revertBtnId: 'btn-revert-hw-edit' });
+ setEditLock('hw-asset-form', 'edit', {
+ saveBtnId: 'btn-save-hw-asset',
+ revertBtnId: 'btn-revert-hw-edit',
+ generateBtnId: 'btn-generate-hw-code',
+ addLogBtnId: 'btn-add-hw-log'
+ });
isEditMode = true;
applyTypeSpecificUI(getFieldValue('hw-์ ํ'));
return;
}
- const type = getFieldValue('hw-์ ํ');
- const storageLoc = getFieldValue('hw-๋ณด๊ด์์น');
- const isOpType = ['CPU', 'RAM', 'HDD', 'GPU'].some(t => type.toUpperCase().includes(t)) || type.includes('๋นํ') || ['๋ชจ๋ฐ์ผ', 'ํ๋ธ๋ฆฟ', '๋
ธํธ๋ถ'].some(t => type.includes(t));
+ // ๋ฐ์ดํฐ ์ถ์ถ (์๋ ๋งคํ)
+ const extracted = autoExtractForm('hw', HW_FIELD_MAP);
+
+ if (!extracted.์์ฐ์ฝ๋) {
+ alert('์์ฐ๋ฒํธ๊ฐ ์์ต๋๋ค. [์์ฑ] ๋ฒํผ์ ๋๋ฌ ์์ฐ๋ฒํธ๋ฅผ ๋จผ์ ๋ถ์ฌํด์ฃผ์ธ์.');
+ return;
+ }
+
+ const upperType = (extracted.type || '').toUpperCase();
+ const isOpType = ['CPU', 'RAM', 'HDD', 'GPU'].some(t => upperType.includes(t)) || upperType.includes('๋นํ') || ['๋ชจ๋ฐ์ผ', 'ํ๋ธ๋ฆฟ', 'ํด๋ํฐ'].some(t => upperType.includes(t));
+
+ // --- ์๋ ๋ณ๊ฒฝ ์ด๋ ฅ ์์ฑ ๋ก์ง ---
+ // ๋ชจ๋ ํ๋์จ์ด ์ ํ์ ๋ํด ์๋ ๋ก๊น
์ ์ฉ
+ if (HW_TYPE_LIST.includes(extracted.type) || extracted.type === '๊ฐ์ธPC') {
+ const diffLogs: string[] = [];
+ const compareFields = [
+ { key: 'ํ์ฌ์ฉ์กฐ์ง', label: 'ํ์ฌ์ฉ์กฐ์ง' },
+ { key: '์์น', label: '์ค์น์์น' },
+ { key: '๊ด๋ฆฌ์', label: '๋ด๋น์' },
+ { key: 'ํ์ฌ์ํ', label: '์ํ' },
+ { key: 'IP์ฃผ์', label: 'IP' },
+ { key: '์์ธ์ฉ๋', label: '์์ธ์ ํ' },
+ { key: '๋ชจ๋ธ๋ช
', label: '๋ชจ๋ธ๋ช
' }
+ ];
+
+ const currentIp = currentAsset.IP์ฃผ์ || '';
+ const newIp = getFieldValue('hw-IP์ฃผ์') || getFieldValue('hw-IP์ฃผ์-non-server');
+ const currentLocation = currentAsset.์์น || '';
+ const newLocation = isOpType ? extracted.๋ณด๊ด์์น : getCombinedLocation('hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ');
+
+ compareFields.forEach(f => {
+ let oldVal = '';
+ let newVal = '';
+
+ if (f.key === 'IP์ฃผ์') {
+ oldVal = currentIp;
+ newVal = newIp;
+ } else if (f.key === '์์น') {
+ oldVal = currentLocation;
+ newVal = newLocation;
+ } else if (f.key === '๊ด๋ฆฌ์') {
+ oldVal = currentAsset.๋ด๋น์_์ || '';
+ newVal = extracted.๋ด๋น์_์ || '';
+ } else if (f.key === '์์ธ์ฉ๋') {
+ oldVal = currentAsset.์์ธ์ฉ๋ || '';
+ // ๋น PC ์์ฐ์ ์ ํ์ ์์ธ์ ํ์ผ๋ก ๊ฐ์ฃผ
+ newVal = (extracted.type !== 'PC' && extracted.type !== '๊ฐ์ธPC') ? extracted.type : (extracted.์์ธ์ฉ๋ || '');
+ } else {
+ oldVal = (currentAsset as any)[f.key] || '';
+ newVal = extracted[f.key] || '';
+ }
+
+ if (oldVal !== newVal) {
+ diffLogs.push(`${f.label}: ${oldVal || '(์์)'} โ ${newVal || '(์์)'}`);
+ }
+ });
+
+ if (diffLogs.length > 0) {
+ state.masterData.logs = state.masterData.logs || [];
+ state.masterData.logs.push({
+ id: Math.random().toString(36).substring(2, 9),
+ assetId: currentAsset.id,
+ date: new Date().toISOString().split('T')[0],
+ user: '๊ด๋ฆฌ์',
+ details: diffLogs.join('\n')
+ });
+ }
+ }
+ // ----------------------------
const updated: any = {
...currentAsset,
- ๋ฒ์ธ: getFieldValue('hw-๋ฒ์ธ'),
- ์์ฐ์ฝ๋: getFieldValue('hw-์์ฐ์ฝ๋'),
- ํ์ฌ์ฉ์กฐ์ง: getFieldValue('hw-ํ์ฌ์ฉ์กฐ์ง'),
- type: type,
- ์์ธ์ฉ๋: getFieldValue('hw-์์ธ์ฉ๋'),
- ๋ช
์นญ: getFieldValue('hw-๋ช
์นญ'),
- ๋ณด๊ด์์น: storageLoc,
- ํ์ฌ์ํ: getFieldValue('hw-ํ์ฌ์ํ'),
- OS: getFieldValue('hw-OS'),
- CPU: getFieldValue('hw-CPU'),
- RAM: getFieldValue('hw-RAM'),
- SSD1: getFieldValue('hw-SSD1'),
- SSD2: getFieldValue('hw-SSD2'),
+ ...extracted,
IP์ฃผ์: getFieldValue('hw-IP์ฃผ์') || getFieldValue('hw-IP์ฃผ์-non-server'),
- ๋ด๋น์_์ : getFieldValue('hw-๋ด๋น์_์ '),
- ๊ตฌ๋งค์ผ: getFieldValue('hw-๊ตฌ๋งค์ผ'),
- ๊ธ์ก: getFieldValue('hw-๊ธ์ก'),
- ๋น๊ณ : getFieldValue('hw-๋น๊ณ '),
- ์์น: isOpType ? storageLoc : getCombinedLocation('hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ')
+ ๊ด๋ฆฌ์: extracted.๋ด๋น์_์ ,
+ ์์น: isOpType ? extracted.๋ณด๊ด์์น : getCombinedLocation('hw-์์น-๋น๋ฉ', 'hw-์์น-์์ธ', 'hw-์์น-๊ธฐํ')
};
+ // ํ ์ฌ์ฉ์กฐ์ง ๋ณ๊ฒฝ ์ ์ด์ ์ฌ์ฉ์กฐ์ง ์๋ ์
๋ฐ์ดํธ
+ if (currentAsset.ํ์ฌ์ฉ์กฐ์ง && currentAsset.ํ์ฌ์ฉ์กฐ์ง !== extracted.ํ์ฌ์ฉ์กฐ์ง) {
+ updated.์ด์ ์ฌ์ฉ์กฐ์ง = currentAsset.ํ์ฌ์ฉ์กฐ์ง;
+ }
+
+ // ๋น PC ์์ฐ์ ๋ํด ์์ธ์ ํ(์์ธ์ฉ๋)์ ์ ํ๊ณผ ๋๊ธฐํ
+ if (updated.type !== 'PC') {
+ updated.์์ธ์ฉ๋ = updated.type;
+ }
+
saveHardwareAsset(updated);
onSave();
- setEditLock('hw-asset-form', 'view', { saveBtnId: 'btn-save-hw-asset', revertBtnId: 'btn-revert-hw-edit' });
+ setEditLock('hw-asset-form', 'view', {
+ saveBtnId: 'btn-save-hw-asset',
+ revertBtnId: 'btn-revert-hw-edit',
+ generateBtnId: 'btn-generate-hw-code',
+ addLogBtnId: 'btn-add-hw-log'
+ });
isEditMode = false;
});
@@ -651,13 +480,11 @@ export function initHwModal(onSave: () => void, closeModals: () => void) {
document.getElementById('btn-close-hw-log')?.addEventListener('click', () => logModal.classList.add('hidden'));
document.getElementById('btn-cancel-hw-log')?.addEventListener('click', () => logModal.classList.add('hidden'));
-
document.getElementById('btn-confirm-hw-log')?.addEventListener('click', () => {
if (!currentAsset) return;
const date = (document.getElementById('new-hw-log-date') as HTMLInputElement).value;
const details = (document.getElementById('new-hw-log-details') as HTMLTextAreaElement).value;
if (!date || !details) return;
-
state.masterData.logs = state.masterData.logs || [];
state.masterData.logs.push({ id: Math.random().toString(36).substring(2, 9), assetId: currentAsset.id, date, user: '๊ด๋ฆฌ์', details });
logModal.classList.add('hidden');
diff --git a/src/components/Modal/ModalUtils.ts b/src/components/Modal/ModalUtils.ts
index 6cc8842..cd39927 100644
--- a/src/components/Modal/ModalUtils.ts
+++ b/src/components/Modal/ModalUtils.ts
@@ -103,13 +103,15 @@ export function setEditLock(
options: {
saveBtnId: string,
revertBtnId: string,
- generateBtnId?: string
+ generateBtnId?: string,
+ addLogBtnId?: string
}
) {
const form = document.getElementById(formId) as HTMLFormElement;
const saveBtn = document.getElementById(options.saveBtnId);
const revertBtn = document.getElementById(options.revertBtnId);
const generateBtn = options.generateBtnId ? document.getElementById(options.generateBtnId) : null;
+ const addLogBtn = options.addLogBtnId ? document.getElementById(options.addLogBtnId) : null;
if (!form || !saveBtn || !revertBtn) return;
@@ -118,10 +120,14 @@ export function setEditLock(
form.classList.remove('is-view-mode');
form.classList.add('is-edit-mode');
saveBtn.textContent = '์ ์ฅ';
- revertBtn.classList.toggle('hidden', mode === 'add'); // ์ ๊ท ์ถ๊ฐ ์์๋ ์ทจ์ ๋ฒํผ ์จ๊น (๋ซ๊ธฐ๊ฐ ๋์ ํจ)
+ revertBtn.classList.toggle('hidden', mode === 'add'); // ์ ๊ท ์ถ๊ฐ ์์๋ ์ทจ์ ๋ฒํผ ์จ๊น
- // ๋ฒํธ ์์ฑ ๋ฒํผ์ '์ถ๊ฐ' ์์๋ง ๋
ธ์ถ
- if (generateBtn) generateBtn.classList.toggle('hidden', mode !== 'add');
+ // ๋ฒํธ ์์ฑ ๋ฒํผ์ '์ถ๊ฐ(add)' ์์๋ง ๋
ธ์ถ
+ if (generateBtn) {
+ generateBtn.style.display = mode === 'add' ? 'flex' : 'none';
+ }
+ // ๋ด์ญ ์ถ๊ฐ ๋ฒํผ ๋
ธ์ถ
+ if (addLogBtn) addLogBtn.style.display = 'flex';
} else {
// ์กฐํ ๋ชจ๋ (์ ๊ธ)
form.classList.remove('is-edit-mode');
@@ -129,7 +135,79 @@ export function setEditLock(
saveBtn.textContent = '์์ ';
revertBtn.classList.add('hidden');
- // ์กฐํ ๋ชจ๋์์๋ ๋ฒํธ ์์ฑ ๋ฒํผ ๋ฌด์กฐ๊ฑด ์จ๊น
- if (generateBtn) generateBtn.classList.add('hidden');
+ // ์กฐํ ๋ชจ๋์์๋ ๋ฒํผ๋ค ์จ๊น
+ if (generateBtn) generateBtn.style.display = 'none';
+ if (addLogBtn) addLogBtn.style.display = 'none';
}
}
+
+/**
+ * 8. ๊ณตํต ๋ชจ๋ฌ ํ๋ ์ ํ
ํ๋ฆฟ ์์ฑ
+ * @param idPrefix ํ๋ ID์ ์ ๋์ฌ (์: 'hw', 'sw', 'pc')
+ * @param title ๋ชจ๋ฌ ์ ๋ชฉ
+ * @param formContent ๊ฐ ๋ชจ๋ฌ๋ง๋ค ๋ค๋ฅธ ํผ ๋ณธ๋ฌธ HTML
+ * @param options ์ค์ (์ด๋ ฅ ์์ญ ์ ๋ชฉ ๋ฑ)
+ */
+export function createModalFrameHTML(
+ idPrefix: string,
+ title: string,
+ formContent: string,
+ options: { historyTitle: string, addLogBtnId: string }
+): string {
+ return `
+
+ `;
+}
+
+/**
+ * 9. ๋ฐ์ดํฐ โ ํผ ์๋ ๋งคํ (์ ์ง๋ณด์ ํต์ฌ)
+ */
+export function autoFillForm(idPrefix: string, data: any, fieldMap: Record
) {
+ Object.entries(fieldMap).forEach(([fieldId, dataKey]) => {
+ setFieldValue(`${idPrefix}-${fieldId}`, data[dataKey]);
+ });
+}
+
+export function autoExtractForm(idPrefix: string, fieldMap: Record): any {
+ const result: any = {};
+ Object.entries(fieldMap).forEach(([fieldId, dataKey]) => {
+ result[dataKey] = getFieldValue(`${idPrefix}-${fieldId}`);
+ });
+ return result;
+}
+
diff --git a/src/components/Modal/PCModal.ts b/src/components/Modal/PCModal.ts
deleted file mode 100644
index 461fa43..0000000
--- a/src/components/Modal/PCModal.ts
+++ /dev/null
@@ -1,362 +0,0 @@
-import { state, saveHardwareAsset, deleteHardwareAsset } from '../../core/state';
-import { HardwareAsset } from '../../core/excelHandler';
-import { openModal, closeModals } from './BaseModal';
-import { createIcons, History, X, Paperclip } from 'lucide';
-import { CORP_LIST, ORG_LIST, HW_TYPE_LIST, LOCATION_DATA } from './SharedData';
-import {
- generateOptionsHTML,
- setFieldValue,
- getFieldValue,
- parseAndSetLocation,
- bindLocationEvents,
- getCombinedLocation
-} from './ModalUtils';
-
-let currentAsset: HardwareAsset | null = null;
-let isEditMode = false;
-
-const PC_MODAL_HTML = `
-
-
-
-
-
-
-
-
-
-
์ด๋ ฅ์ด ์์ต๋๋ค.
-
-
-
-
-
-
-
-`;
-
-export function openPcModal(asset: HardwareAsset, mode: 'view' | 'add' = 'view') {
- currentAsset = asset;
- const modal = document.getElementById('pc-asset-modal');
- if (!modal) return;
-
- const form = document.getElementById('pc-asset-form') as HTMLFormElement;
- const saveBtn = document.getElementById('btn-save-pc-asset')!;
- const revertBtn = document.getElementById('btn-revert-pc-edit')!;
-
- if (form) form.reset();
-
- if (mode === 'add') {
- isEditMode = true;
- if (form) {
- form.classList.remove('is-view-mode');
- form.classList.add('is-edit-mode');
- }
- saveBtn.textContent = '์ ์ฅ';
- revertBtn.classList.add('hidden');
- const prevOrgGroup = document.getElementById('pc-์ด์ ์ฌ์ฉ์กฐ์ง-group');
- if (prevOrgGroup) prevOrgGroup.style.display = 'none';
- } else {
- isEditMode = false;
- if (form) {
- form.classList.remove('is-edit-mode');
- form.classList.add('is-view-mode');
- }
- saveBtn.textContent = '์์ ';
- revertBtn.classList.add('hidden');
- const prevOrgGroup = document.getElementById('pc-์ด์ ์ฌ์ฉ์กฐ์ง-group');
- if (prevOrgGroup) prevOrgGroup.style.display = 'flex';
- }
-
- fillFormData(asset);
- renderHistory(asset.id);
-
- modal.classList.remove('hidden');
- applyPcTypeSpecificUI();
- createIcons({ icons: { X, History, Paperclip } });
-}
-
-function applyPcTypeSpecificUI() {
- const type = getFieldValue('pc-์ ํ');
- const detailPurpose = getFieldValue('pc-์์ธ์ฉ๋');
-
- const modelGroup = document.getElementById('pc-๋ชจ๋ธ๋ช
')?.closest('.form-group') as HTMLElement;
- const osGroup = document.getElementById('pc-OS')?.closest('.form-group') as HTMLElement;
- const cpuGroup = document.getElementById('pc-CPU')?.closest('.form-group') as HTMLElement;
- const ramGroup = document.getElementById('pc-RAM')?.closest('.form-group') as HTMLElement;
- const ssd1Group = document.getElementById('pc-SSD1')?.closest('.form-group') as HTMLElement;
- const ssd2Group = document.getElementById('pc-SSD2')?.closest('.form-group') as HTMLElement;
- const locationFields = document.querySelectorAll('.pc-location-field');
- const etcGroup = document.getElementById('pc-์์น-๊ธฐํ-group');
-
- // ์ด๊ธฐํ (์จ๊น)
- [modelGroup, osGroup, cpuGroup, ramGroup, ssd1Group, ssd2Group].forEach(g => { if(g) g.style.display = 'none'; });
- locationFields.forEach(el => (el as HTMLElement).style.display = 'none');
- if (etcGroup) etcGroup.style.display = 'none';
-
- if (type === '์๋ฒ') {
- [modelGroup, osGroup, cpuGroup, ramGroup, ssd1Group, ssd2Group].forEach(g => { if(g) g.style.display = 'flex'; });
- locationFields.forEach(el => (el as HTMLElement).style.display = 'flex');
- }
- else if (['์คํ ๋ฆฌ์ง', 'NAS', 'DAS'].includes(type)) {
- [modelGroup, ssd1Group, ssd2Group].forEach(g => { if(g) g.style.display = 'flex'; });
- locationFields.forEach(el => (el as HTMLElement).style.display = 'flex');
- }
- else if (type === 'PC' || type === '๋
ธํธ๋ถ') {
- [modelGroup, osGroup, cpuGroup, ramGroup, ssd1Group, ssd2Group].forEach(g => { if(g) g.style.display = 'flex'; });
- if (detailPurpose === '์๋ฒ') {
- locationFields.forEach(el => (el as HTMLElement).style.display = 'flex');
- }
- }
- else if (['CPU', 'GPU', '๋ชจ๋ฐ์ผ'].includes(type)) {
- if (modelGroup) modelGroup.style.display = 'flex';
- }
- else if (type === 'RAM') {
- if (ramGroup) ramGroup.style.display = 'flex';
- }
- else if (type === 'HDD') {
- if (ssd1Group) ssd1Group.style.display = 'flex';
- }
- else if (type === 'ํ๋ธ๋ฆฟ') {
- if (modelGroup) modelGroup.style.display = 'flex';
- if (ssd1Group) ssd1Group.style.display = 'flex';
- }
-}
-
-function fillFormData(asset: HardwareAsset) {
- setFieldValue('pc-asset-id', asset.id);
- setFieldValue('pc-๋ฒ์ธ', asset.๋ฒ์ธ);
- setFieldValue('pc-์์ฐ์ฝ๋', asset.์์ฐ์ฝ๋);
- setFieldValue('pc-์ ํ', asset.type);
- setFieldValue('pc-์ฌ์ฉ์', asset.์ฌ์ฉ์);
- setFieldValue('pc-ํ์ฌ์ฉ์กฐ์ง', asset.ํ์ฌ์ฉ์กฐ์ง);
- setFieldValue('pc-์ด์ ์ฌ์ฉ์กฐ์ง', asset.์ด์ ์ฌ์ฉ์กฐ์ง);
- setFieldValue('pc-์์ธ์ฉ๋', (asset as any).์์ธ์ฉ๋);
-
- parseAndSetLocation(asset.์์น, 'pc-์์น-๋น๋ฉ', 'pc-์์น-์์ธ', 'pc-์์น-๊ธฐํ-group', 'pc-์์น-๊ธฐํ');
-
- setFieldValue('pc-๋ชจ๋ธ๋ช
', asset.๋ชจ๋ธ๋ช
);
- setFieldValue('pc-OS', asset.OS);
- setFieldValue('pc-CPU', asset.CPU);
- setFieldValue('pc-RAM', asset.RAM);
- setFieldValue('pc-SSD1', asset.SSD1);
- setFieldValue('pc-SSD2', asset.SSD2);
- setFieldValue('pc-๊ตฌ๋งค์ผ', asset.๊ตฌ๋งค์ผ);
- setFieldValue('pc-๊ธ์ก', asset.๊ธ์ก);
- setFieldValue('pc-๋ฉํ์
์ฒด', asset.๋ฉํ์
์ฒด);
- setFieldValue('pc-ํ์์๋ช
', asset.ํ์์๋ช
);
-}
-
-export function initPcModal(onSave: () => void, closeModalsCb: () => void) {
- if (!document.getElementById('pc-asset-modal')) {
- document.body.insertAdjacentHTML('beforeend', PC_MODAL_HTML);
- }
-
- const pcForm = document.getElementById('pc-asset-form') as HTMLFormElement;
- const saveBtn = document.getElementById('btn-save-pc-asset');
- const revertBtn = document.getElementById('btn-revert-pc-edit');
- const deleteBtn = document.getElementById('btn-delete-pc-asset');
-
- // ์ ํ ๋ฐ ์์ธ์ฉ๋ ๋ฆฌ์ค๋
- const typeSelect = document.getElementById('pc-์ ํ') as HTMLSelectElement;
- const detailPurposeSelect = document.getElementById('pc-์์ธ์ฉ๋') as HTMLSelectElement;
-
- [typeSelect, detailPurposeSelect].forEach(el => {
- el?.addEventListener('change', () => applyPcTypeSpecificUI());
- });
-
- bindLocationEvents('pc-์์น-๋น๋ฉ', 'pc-์์น-์์ธ', 'pc-์์น-๊ธฐํ-group', 'pc-์์น-๊ธฐํ');
-
- const handleClose = () => { closeModalsCb(); isEditMode = false; };
- document.getElementById('btn-close-pc-modal')?.addEventListener('click', handleClose);
- document.getElementById('btn-cancel-pc-modal')?.addEventListener('click', handleClose);
- revertBtn?.addEventListener('click', () => {
- isEditMode = false;
- pcForm.classList.replace('is-edit-mode', 'is-view-mode');
- if (saveBtn) saveBtn.textContent = '์์ ';
- revertBtn.classList.add('hidden');
- if (currentAsset) fillFormData(currentAsset);
- });
-
- saveBtn?.addEventListener('click', () => {
- if (!currentAsset) return;
- if (!isEditMode) {
- isEditMode = true;
- pcForm.classList.replace('is-view-mode', 'is-edit-mode');
- saveBtn.textContent = '์ ์ฅ';
- revertBtn?.classList.remove('hidden');
- return;
- }
-
- const type = getFieldValue('pc-์ ํ');
- const detailPurpose = getFieldValue('pc-์์ธ์ฉ๋');
-
- const updated: any = {
- ...currentAsset,
- ๋ฒ์ธ: getFieldValue('pc-๋ฒ์ธ'),
- ์์ฐ์ฝ๋: getFieldValue('pc-์์ฐ์ฝ๋'),
- ํ์ฌ์ฉ์กฐ์ง: getFieldValue('pc-ํ์ฌ์ฉ์กฐ์ง'),
- ์ด์ ์ฌ์ฉ์กฐ์ง: getFieldValue('pc-์ด์ ์ฌ์ฉ์กฐ์ง'),
- ์ฌ์ฉ์: getFieldValue('pc-์ฌ์ฉ์'),
- ์์ธ์ฉ๋: detailPurpose,
- ์์น: getCombinedLocation('pc-์์น-๋น๋ฉ', 'pc-์์น-์์ธ', 'pc-์์น-๊ธฐํ'),
- ๋ชจ๋ธ๋ช
: getFieldValue('pc-๋ชจ๋ธ๋ช
'),
- OS: getFieldValue('pc-OS'),
- CPU: getFieldValue('pc-CPU'),
- RAM: getFieldValue('pc-RAM'),
- SSD1: getFieldValue('pc-SSD1'),
- SSD2: getFieldValue('pc-SSD2'),
- ๊ตฌ๋งค์ผ: getFieldValue('pc-๊ตฌ๋งค์ผ'),
- ๊ธ์ก: getFieldValue('pc-๊ธ์ก'),
- ๋ฉํ์
์ฒด: getFieldValue('pc-๋ฉํ์
์ฒด'),
- type: type || 'PC'
- };
-
- saveHardwareAsset(updated);
- onSave();
- isEditMode = false;
- pcForm.classList.replace('is-edit-mode', 'is-view-mode');
- saveBtn.textContent = '์์ ';
- revertBtn?.classList.add('hidden');
- });
-
- deleteBtn?.addEventListener('click', () => {
- if (!currentAsset) return;
- if (confirm('์ญ์ ํ์๊ฒ ์ต๋๊น?')) {
- deleteHardwareAsset(currentAsset.id);
- onSave();
- handleClose();
- }
- });
-}
-
-function renderHistory(assetId: string) {
- const historyList = document.getElementById('pc-history-list');
- if (!historyList) return;
- const logs = state.masterData.logs
- .filter(l => l.assetId === assetId)
- .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
-
- if (logs.length === 0) {
- historyList.innerHTML = '์ด๋ ฅ์ด ์์ต๋๋ค.
';
- return;
- }
- historyList.innerHTML = logs.map(log => `
-
-
${log.date}
-
์์ ์: ${log.user}
-
${log.details.replace(/\n/g, '
')}
-
- `).join('');
-}
diff --git a/src/components/Modal/SWModal.ts b/src/components/Modal/SWModal.ts
index f144971..50170b5 100644
--- a/src/components/Modal/SWModal.ts
+++ b/src/components/Modal/SWModal.ts
@@ -1,184 +1,120 @@
import { state } from '../../core/state';
import { SoftwareAsset } from '../../core/excelHandler';
-import { openModal, closeModals } from './BaseModal';
+import { closeModals } from './BaseModal';
import { openSwUserModal } from './SWUserModal';
import { createIcons, History, Plus, X, Save, Edit2, RotateCcw } from 'lucide';
-import { CORP_LIST } from './SharedData';
+import { CORP_LIST, TYPE_PREFIX_MAP } from './SharedData';
import {
generateOptionsHTML,
setFieldValue,
getFieldValue,
- setEditLock
+ setEditLock,
+ createModalFrameHTML,
+ autoFillForm,
+ autoExtractForm
} from './ModalUtils';
let currentSwAsset: SoftwareAsset | null = null;
let isEditMode = false;
-const SW_MODAL_HTML = `
-
-
-
-
-
+const SW_FORM_HTML = `
+
+
๊ธฐ๋ณธ ์ ๋ณด (Identity)
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
๋ผ์ด์ ์ค ๋ฐ ๊ณ์ฝ ์ ๋ณด
+
+
+
+
+
+
+
+
+
+
+
+
+
๊ด๋ฆฌ ๋ฐ ๋น๊ณ
+
+
+
+
+
+
`;
+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 c59d849..e0e78e3 100644
--- a/src/core/excelHandler.ts
+++ b/src/core/excelHandler.ts
@@ -27,7 +27,7 @@ export interface HardwareAsset {
์ฉ๋?: string;
๋ด๋น์_์ ?: string;
๋ด๋น์_๋ถ?: string;
- ๊ตฌ๋งค์ผ?: string;
+ ๊ตฌ๋งค์ฐ์?: string;
๊ธ์ก?: string;
๋ฉํ์
์ฒด: string;
ํ์์๋ช
: string;
@@ -51,7 +51,7 @@ export interface SoftwareAsset {
๋ฒ์ธ: string;
๋ถ์?: string;
์ ํ๋ช
: string;
- ๊ตฌ๋งค์ผ: string;
+ ๊ตฌ๋งค์ฐ์: string;
๊ตฌ๋
์ผ?: string;
๋ง๋ฃ์ผ?: string;
๋ผ์ด์ ์ค์ ํ?: string;
@@ -105,14 +105,14 @@ export interface MasterAssetData {
const HW_TABS = ['๊ฐ์ธPC', '์๋ฒ', '์คํ ๋ฆฌ์ง', '์ ์ฐ๋นํ', '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ'];
const SW_TABS = ['๊ตฌ๋
SW', '์๊ตฌSW', 'ํด๋ผ์ฐ๋'];
-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 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 SUB_SW_HEADERS = ['ID', '๋ถ์ผ', '๋ฒ์ธ', '๋ถ์', '์ ํ๋ช
', '๊ตฌ๋งค์ฐ์', '๋ง๋ฃ์ผ', '๋ผ์ด์ ์ค์ ํ', '๊ธ์ก', '์๋', '๊ณ์ ๋ช
', '๋ฉํ์
์ฒด', '๋น๊ณ '];
+const PERM_SW_HEADERS = ['ID', '๋ถ์ผ', '๋ฒ์ธ', '๋ถ์', '์ ํ๋ช
', '๊ตฌ๋งค์ฐ์', '๋ผ์ด์ ์คํค', '๊ธ์ก', '์๋', '๊ณ์ ๋ช
', '๋ฉํ์
์ฒด', '๋น๊ณ '];
const CLOUD_HEADERS = ['ID', 'ํ๋ซํผ๋ช
', '๋ฒ์ธ', '๋ถ์', '์ฌ์ฉ์ฉ๋(์ ํ๋ช
)', '๊ณ์ ๋ช
', '๊ฒฐ์ ์๋จ', '๊ฒฐ์ ์ผ', '์ฐ๊ฒฐ์นด๋๋ฒํธ', '๋น์์ฒญ๊ตฌ์ก', '๋น๊ณ '];
export function downloadTemplate() {
@@ -144,13 +144,13 @@ export function downloadTemplate() {
export function exportToExcel(masterData: MasterAssetData) {
const wb = XLSX.utils.book_new();
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.storage์ ํ || '๋ฌผ๋ฆฌ', 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.HDD1, a.๋ชจ๋ํฐ๋ง, a.๋น๊ณ ] },
- { tab: '์คํ ๋ฆฌ์ง', list: masterData.storage, headers: STORAGE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.storage์ ํ, a.์์ฐ์ฝ๋, 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.MACaddress, a.HW์ฌ์, a.OS, a.๊ตฌ๋งค์ผ, a.๊ธ์ก, a.๋ฉํ์
์ฒด, a.ํ์์๋ช
, a.๋น๊ณ ] },
- { tab: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', list: masterData.mobile, headers: MOBILE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ์ฝ๋, a.๋ช
์นญ, a.์์น, a.๊ด๋ฆฌ์, a.type, a.OS, a.๊ตฌ๋งค์ผ, a.๊ธ์ก, 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.๋น๊ณ ] }
+ { 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.storage์ ํ || '๋ฌผ๋ฆฌ', 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.HDD1, a.๋ชจ๋ํฐ๋ง, a.๋น๊ณ ] },
+ { tab: '์คํ ๋ฆฌ์ง', list: masterData.storage, headers: STORAGE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.storage์ ํ, a.์์ฐ์ฝ๋, 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.MACaddress, a.HW์ฌ์, a.OS, a.๊ตฌ๋งค์ฐ์, a.๊ธ์ก, a.๋ฉํ์
์ฒด, a.ํ์์๋ช
, a.๋น๊ณ ] },
+ { tab: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', list: masterData.mobile, headers: MOBILE_HEADERS, map: (a: any) => [a.๋ฒ์ธ, a.์์ฐ์ฝ๋, a.๋ช
์นญ, a.์์น, a.๊ด๋ฆฌ์, a.type, a.OS, a.๊ตฌ๋งค์ฐ์, a.๊ธ์ก, 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.๋น๊ณ ] }
];
exportMap.forEach(m => {
@@ -170,19 +170,19 @@ export async function parseExcel(file: File): Promise {
workbook.SheetNames.forEach(sheetName => {
const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]) as any[];
if (sheetName === '๊ฐ์ธPC') {
- rows.forEach(r => data.pc.push({ id: Math.random().toString(36).substring(2, 9), type: '๊ฐ์ธPC', ๋ฒ์ธ: r['๋ฒ์ธ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ์ฌ์ฉ์: r['์ฌ์ฉ์']||'', ์์น: r['์์น']||'', CPU: r['CPU']||'', GPU: r['GPU']||'', RAM: r['RAM']||'', SSD1: r['SSD1']||'', SSD2: r['SSD2']||'', HDD1: r['HDD1']||'', HDD2: r['HDD2']||'', IP์ฃผ์: r['IP์ฃผ์']||'', HW์ฌ์: r['HW์ฌ์']||'', ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'', ๊ด๋ฆฌ์: '', MACaddress: '', OS: '', ๋ช
์นญ: '' }));
+ rows.forEach(r => data.pc.push({ id: Math.random().toString(36).substring(2, 9), type: '๊ฐ์ธPC', ๋ฒ์ธ: r['๋ฒ์ธ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ์ฌ์ฉ์: r['์ฌ์ฉ์']||'', ์์น: r['์์น']||'', CPU: r['CPU']||'', GPU: r['GPU']||'', RAM: r['RAM']||'', SSD1: r['SSD1']||'', SSD2: r['SSD2']||'', HDD1: r['HDD1']||'', HDD2: r['HDD2']||'', IP์ฃผ์: r['IP์ฃผ์']||'', HW์ฌ์: r['HW์ฌ์']||'', ๊ตฌ๋งค์ฐ์: 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['๊ตฌ๋งค์ผ']||'', storage์ ํ: 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']||'', GPU: r['GPU']||'', SSD1: r['Storage 1']||r['SSD1']||'', SSD2: r['Storage 2']||r['SSD2']||'', HDD1: r['Storage 3']||r['HDD1']||'', ๋ชจ๋ํฐ๋ง: r['๋ชจ๋ํฐ๋ง']||'', ๋น๊ณ : r['๋น๊ณ ']||'', ๊ด๋ฆฌ์: '', ๋ช
์นญ: '', MACaddress: '', HW์ฌ์: '', ๊ธ์ก: '', ๋ฉํ์
์ฒด: '', ํ์์๋ช
: '' }));
+ rows.forEach(r => data.server.push({ id: Math.random().toString(36).substring(2, 9), type: '์๋ฒ', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', ์์ฐ์ฝ๋: r['์์ฐ๋ฒํธ']||r['์์ฐ์ฝ๋']||'', ๊ตฌ๋งค์ฐ์: r['๊ตฌ๋งค์ฐ์']||r['๊ตฌ๋งค์ผ์']||r['๊ตฌ๋งค์ผ']||'', storage์ ํ: 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']||'', GPU: r['GPU']||'', SSD1: r['Storage 1']||r['SSD1']||'', SSD2: r['Storage 2']||r['SSD2']||'', HDD1: r['Storage 3']||r['HDD1']||'', ๋ชจ๋ํฐ๋ง: r['๋ชจ๋ํฐ๋ง']||'', ๋น๊ณ : r['๋น๊ณ ']||'', ๊ด๋ฆฌ์: '', ๋ช
์นญ: '', MACaddress: '', HW์ฌ์: '', ๊ธ์ก: '', ๋ฉํ์
์ฒด: '', ํ์์๋ช
: '' }));
} else if (sheetName === '์คํ ๋ฆฌ์ง') {
- rows.forEach(r => data.storage.push({ id: Math.random().toString(36).substring(2, 9), type: '์คํ ๋ฆฌ์ง', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', storage์ ํ: r['์ ํ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
']||'', ์ฉ๋: r['์ฉ๋']||'', ๋ด๋น์_์ : r['๋ด๋น์(์ )']||'', ๋ด๋น์_๋ถ: r['๋ด๋น์(๋ถ)']||'', IP์ฃผ์: r['IP์ฃผ์']||'', MACaddress: r['MAC์ฃผ์']||'', ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'', HW์ฌ์: '', OS: '', ๊ด๋ฆฌ์: '' }));
+ rows.forEach(r => data.storage.push({ id: Math.random().toString(36).substring(2, 9), type: '์คํ ๋ฆฌ์ง', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', storage์ ํ: r['์ ํ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๋ชจ๋ธ๋ช
: r['๋ชจ๋ธ๋ช
']||'', ์ฉ๋: r['์ฉ๋']||'', ๋ด๋น์_์ : r['๋ด๋น์(์ )']||'', ๋ด๋น์_๋ถ: r['๋ด๋น์(๋ถ)']||'', IP์ฃผ์: r['IP์ฃผ์']||'', MACaddress: r['MAC์ฃผ์']||'', ๊ตฌ๋งค์ฐ์: r['๊ตฌ๋งค์ฐ์']||r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'', HW์ฌ์: '', OS: '', ๊ด๋ฆฌ์: '' }));
} else if (sheetName === '์ ์ฐ๋นํ') {
- rows.forEach(r => data.equip.push({ id: Math.random().toString(36).substring(2, 9), type: '์ ์ฐ๋นํ', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', ๋นํ์ ํ: r['๋นํ์ ํ']||r['์ ํ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๊ด๋ฆฌ์: r['๊ด๋ฆฌ์']||'', IP์ฃผ์: r['IP์ฃผ์']||'', MACaddress: r['MACaddress']||'', HW์ฌ์: r['HW์ฌ์']||'', OS: r['OS']||'', ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'' }));
+ rows.forEach(r => data.equip.push({ id: Math.random().toString(36).substring(2, 9), type: '์ ์ฐ๋นํ', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', ๋นํ์ ํ: r['๋นํ์ ํ']||r['์ ํ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๊ด๋ฆฌ์: r['๊ด๋ฆฌ์']||'', IP์ฃผ์: r['IP์ฃผ์']||'', MACaddress: r['MACaddress']||'', HW์ฌ์: r['HW์ฌ์']||'', OS: r['OS']||'', ๊ตฌ๋งค์ฐ์: r['๊ตฌ๋งค์ฐ์']||r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'' }));
} else if (sheetName === '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ') {
- rows.forEach(r => data.mobile.push({ id: Math.random().toString(36).substring(2, 9), type: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๊ด๋ฆฌ์: r['๊ด๋ฆฌ์']||'', OS: r['OS']||'', ๊ตฌ๋งค์ผ: r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'', IP์ฃผ์: '', MACaddress: '', HW์ฌ์: '' }));
+ rows.forEach(r => data.mobile.push({ id: Math.random().toString(36).substring(2, 9), type: '๋ชจ๋ฐ์ผ๊ธฐ๊ธฐ', ๋ฒ์ธ: r['๊ตฌ๋งค๋ฒ์ธ']||r['๋ฒ์ธ']||'', ์์ฐ์ฝ๋: r['์์ฐ์ฝ๋']||'', ๋ช
์นญ: r['๋ช
์นญ']||'', ์์น: r['์์น']||'', ๊ด๋ฆฌ์: r['๊ด๋ฆฌ์']||'', OS: r['OS']||'', ๊ตฌ๋งค์ฐ์: r['๊ตฌ๋งค์ฐ์']||r['๊ตฌ๋งค์ผ']||'', ๊ธ์ก: r['๊ธ์ก']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ํ์์๋ช
: r['ํ์์๋ช
']||'', ๋น๊ณ : r['๋น๊ณ ']||'', IP์ฃผ์: '', MACaddress: '', HW์ฌ์: '' }));
} 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['๊ธ์ก']||'', ์๋: parseInt(r['์๋']||'1'), ๊ณ์ ๋ช
: r['๊ณ์ ๋ช
']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ๋น๊ณ : r['๋น๊ณ ']||'' }));
+ 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['๊ธ์ก']||'', ์๋: parseInt(r['์๋']||'1'), ๊ณ์ ๋ช
: 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['๊ธ์ก']||'', ์๋: parseInt(r['์๋']||'1'), ๊ณ์ ๋ช
: r['๊ณ์ ๋ช
']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ๋น๊ณ : r['๋น๊ณ ']||'' }));
+ 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['๊ธ์ก']||'', ์๋: parseInt(r['์๋']||'1'), ๊ณ์ ๋ช
: r['๊ณ์ ๋ช
']||'', ๋ฉํ์
์ฒด: r['๋ฉํ์
์ฒด']||'', ๋น๊ณ : r['๋น๊ณ ']||'' }));
}
});
resolve(data);
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 73c2557..a122ba5 100644
--- a/src/styles/modal.css
+++ b/src/styles/modal.css
@@ -167,6 +167,10 @@
background-color: var(--white);
}
+.form-group textarea {
+ resize: none;
+}
+
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
@@ -213,6 +217,9 @@
}
.history-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
margin-bottom: 1rem;
}
@@ -225,6 +232,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 ? '๊ตฌ๋
์ผ | ' : ''}
๊ธ์ก |
์๋ |