diff --git a/system1-factory/web/js/schedule.js b/system1-factory/web/js/schedule.js index ffaccc9..7593838 100644 --- a/system1-factory/web/js/schedule.js +++ b/system1-factory/web/js/schedule.js @@ -28,6 +28,8 @@ document.addEventListener('DOMContentLoaded', async () => { document.getElementById('btnAddEntry').classList.remove('hidden'); document.getElementById('btnBatchAdd').classList.remove('hidden'); document.getElementById('btnAddMilestone').classList.remove('hidden'); + const btnGen = document.getElementById('btnGenTemplate'); + if (btnGen) btnGen.classList.remove('hidden'); } // Load collapse state diff --git a/system1-factory/web/pages/work/schedule.html b/system1-factory/web/pages/work/schedule.html index c4cf5ed..dddb138 100644 --- a/system1-factory/web/pages/work/schedule.html +++ b/system1-factory/web/pages/work/schedule.html @@ -110,6 +110,9 @@
+ @@ -315,7 +318,95 @@
+ + + + diff --git a/user-management/web/index.html b/user-management/web/index.html index b61499d..518a8f7 100644 --- a/user-management/web/index.html +++ b/user-management/web/index.html @@ -470,6 +470,12 @@ +
+ + +
@@ -1147,6 +1153,12 @@
+
+ + +
@@ -2393,7 +2405,7 @@ - + diff --git a/user-management/web/static/js/tkuser-projects.js b/user-management/web/static/js/tkuser-projects.js index 6693d3d..f51487f 100644 --- a/user-management/web/static/js/tkuser-projects.js +++ b/user-management/web/static/js/tkuser-projects.js @@ -1,5 +1,5 @@ /* ===== Projects CRUD ===== */ -let projects = [], projectsLoaded = false; +let projects = [], projectsLoaded = false, productTypesCache = []; function statusBadge(status, isActive) { if (!isActive || isActive === 0 || isActive === false) return '비활성'; @@ -7,8 +7,23 @@ function statusBadge(status, isActive) { return '진행중'; } +async function loadProductTypes() { + try { + const r = await api('/projects/product-types'); + productTypesCache = r.data || []; + ['newProductType', 'editProductType'].forEach(id => { + const sel = document.getElementById(id); if (!sel) return; + const val = sel.value; + sel.innerHTML = ''; + productTypesCache.forEach(pt => { const o = document.createElement('option'); o.value = pt.id; o.textContent = `${pt.code} - ${pt.name}`; sel.appendChild(o); }); + sel.value = val; + }); + } catch(e) { console.warn('제품유형 로드 실패:', e); } +} + async function loadProjects() { try { + await loadProductTypes(); const r = await api('/projects'); projects = r.data || r; projectsLoaded = true; displayProjects(); @@ -26,6 +41,7 @@ function displayProjects() {
${escapeHtml(p.project_name)}
${escapeHtml(p.job_no)} + ${p.product_type_code?`${escapeHtml(p.product_type_code)}`:''} ${p.site?`${escapeHtml(p.site)}`:''} ${p.pm?`${escapeHtml(p.pm)}`:''} ${statusBadge(p.project_status, p.is_active)} @@ -48,7 +64,8 @@ document.getElementById('addProjectForm').addEventListener('submit', async e => contract_date: document.getElementById('newContractDate').value || null, due_date: document.getElementById('newDueDate').value || null, site: document.getElementById('newSite').value.trim() || null, - pm: document.getElementById('newPm').value.trim() || null + pm: document.getElementById('newPm').value.trim() || null, + product_type_id: document.getElementById('newProductType').value ? parseInt(document.getElementById('newProductType').value) : null })}); showToast('프로젝트가 추가되었습니다.'); document.getElementById('addProjectForm').reset(); await loadProjects(); } catch(e) { showToast(e.message, 'error'); } @@ -63,6 +80,7 @@ function editProject(id) { document.getElementById('editDueDate').value = formatDate(p.due_date); document.getElementById('editSite').value = p.site || ''; document.getElementById('editPm').value = p.pm || ''; + document.getElementById('editProductType').value = p.product_type_id || ''; document.getElementById('editProjectStatus').value = p.project_status || 'active'; document.getElementById('editIsActive').value = p.is_active ? '1' : '0'; document.getElementById('editProjectModal').classList.remove('hidden'); @@ -79,6 +97,7 @@ document.getElementById('editProjectForm').addEventListener('submit', async e => due_date: document.getElementById('editDueDate').value || null, site: document.getElementById('editSite').value.trim() || null, pm: document.getElementById('editPm').value.trim() || null, + product_type_id: document.getElementById('editProductType').value ? parseInt(document.getElementById('editProductType').value) : null, project_status: document.getElementById('editProjectStatus').value, is_active: document.getElementById('editIsActive').value === '1' })});