import { state, saveJobSpec, deleteJobSpec } from '../../core/state'; import { BaseModal } from './BaseModal'; import { setFieldValue } from './ModalUtils'; import { UI_TEXT } from '../../core/schema'; import { calculatePcScoreDeductive } from '../../core/utils'; class JobSpecModal extends BaseModal { constructor() { super('job-spec', '직무별 기준 사양'); } protected renderFrameHTML(): string { const sharedStyle = 'height: 38px !important; box-sizing: border-box !important; font-size: 13px; margin: 0;'; const inputStyle = sharedStyle; return `
`; } protected initChildLogic(onSave: () => void, closeModals: () => void): void { const saveBtn = document.getElementById('btn-save-job-spec-asset')!; const revertBtn = document.getElementById('btn-revert-job-spec-edit')!; const deleteBtn = document.getElementById('btn-delete-job-spec-asset')!; saveBtn.addEventListener('click', async () => { if (!this.currentAsset) return; if (!this.isEditMode) { this.setEditLockMode('edit'); this.isEditMode = true; return; } const jobName = (document.getElementById('job-spec-job-name') as HTMLInputElement).value.trim(); const cpuStd = (document.getElementById('job-spec-cpu-standard') as HTMLInputElement).value.trim(); const ramStd = (document.getElementById('job-spec-ram-standard') as HTMLInputElement).value.trim(); const gpuStd = (document.getElementById('job-spec-gpu-standard') as HTMLInputElement).value.trim(); const minScoreStr = (document.getElementById('job-spec-min-score') as HTMLInputElement).value; const remarks = (document.getElementById('job-spec-remarks') as HTMLTextAreaElement).value.trim(); if (!jobName) { alert('직무명을 입력해 주세요.'); return; } const updated = { id: this.currentAsset.id || null, job_name: jobName, cpu_standard: cpuStd, ram_standard: ramStd, gpu_standard: gpuStd, min_score: minScoreStr !== '' ? parseInt(minScoreStr, 10) : 0, remarks: remarks }; if (await saveJobSpec(updated)) { alert(UI_TEXT.MESSAGES.SAVE_SUCCESS); onSave(); this.close(); closeModals(); } }); revertBtn.addEventListener('click', () => { this.setEditLockMode('view'); if (this.currentAsset) this.fillFormData(this.currentAsset); }); deleteBtn.addEventListener('click', async () => { if (!this.currentAsset || !this.currentAsset.id) return; if (!confirm('정말로 이 직무별 기준 사양을 삭제하시겠습니까?')) return; if (await deleteJobSpec(this.currentAsset.id)) { alert('성공적으로 삭제되었습니다.'); onSave(); this.close(); closeModals(); } }); // 자동완성 바인딩 this.bindAutocomplete('job-spec-cpu-standard', 'job-spec-cpu-autocomplete', 'CPU'); this.bindAutocomplete('job-spec-ram-standard', 'job-spec-ram-autocomplete', 'RAM'); this.bindAutocomplete('job-spec-gpu-standard', 'job-spec-gpu-autocomplete', 'GPU'); // 실시간 점수 계산 이벤트 바인딩 const inputs = ['job-spec-cpu-standard', 'job-spec-ram-standard', 'job-spec-gpu-standard']; inputs.forEach(id => { const el = document.getElementById(id); el?.addEventListener('input', () => this.updateMinScore()); el?.addEventListener('change', () => this.updateMinScore()); }); } private bindAutocomplete(inputId: string, autocompleteId: string, category: string) { const input = document.getElementById(inputId) as HTMLInputElement; const list = document.getElementById(autocompleteId) as HTMLDivElement; if (!input || !list) return; const showList = (filterText: string = '') => { if (!this.isEditMode) return; const items = (state.masterData.partsMaster || []).filter((c: any) => c.category === category); const filtered = filterText ? items.filter((c: any) => c.component_name.toLowerCase().includes(filterText.toLowerCase())) : items; if (filtered.length === 0) { list.innerHTML = '