From 2a8ae8572f8311d5d00007820bed536f39c00eb7 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Fri, 13 Mar 2026 18:29:40 +0900 Subject: [PATCH] =?UTF-8?q?feat(tkds):=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20UI=20=EA=B0=9C=EC=84=A0=20=E2=80=94=20=EC=97=AD?= =?UTF-8?q?=ED=95=A0=20=EA=B8=B0=EB=B0=98=20=EB=B0=94=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20+=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EC=9E=85?= =?UTF-8?q?=EA=B5=AC=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 4개 섹션(자주사용/일상업무/시스템/업무도구)을 2개(내 바로가기/시스템)로 재구성. 권한 기반 ALL_SHORTCUTS 17개 + SYSTEM_CARDS 7개 통합, 카테고리 그룹핑 지원. Co-Authored-By: Claude Opus 4.6 --- tkds/web/dashboard.html | 148 +++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/tkds/web/dashboard.html b/tkds/web/dashboard.html index c6c0c44..f95450b 100644 --- a/tkds/web/dashboard.html +++ b/tkds/web/dashboard.html @@ -193,6 +193,18 @@ .system-card .card-icon { font-size: 26px; } .system-card .card-name { font-size: 14px; font-weight: 600; } + /* Shortcut category labels */ + .shortcut-cat-label { + grid-column: 1 / -1; + font-size: 12px; + font-weight: 600; + color: #6b7280; + padding: 8px 0 2px; + border-bottom: 1px solid #e5e7eb; + margin-bottom: 4px; + } + .shortcut-cat-label:first-child { padding-top: 0; } + /* Coming soon */ .badge-soon { display: inline-block; @@ -253,22 +265,14 @@
- -
@@ -331,46 +335,45 @@ } // ===== Card Definitions ===== - var DAILY_CARDS = [ - { id: 'tbm', name: 'TBM', icon: '\uD83D\uDCCB', subdomain: 'tkfb', path: '/pages/work/tbm.html', pageKey: 's1.work.tbm' }, - { id: 'report', name: '\uC791\uC5C5\uBCF4\uACE0\uC11C', icon: '\uD83D\uDCDD', subdomain: 'tkfb', path: '/pages/work/report-create.html', pageKey: 's1.work.report_create' }, - { id: 'issue', name: '\uC548\uC804\uC2E0\uACE0', icon: '\u26A0\uFE0F', subdomain: 'tkreport', path: '/pages/safety/issue-report.html', accessKey: 'system2' }, - { id: 'checkin', name: '\uCD9C\uD1F4\uADFC \uCCB4\uD06C', icon: '\u23F0', subdomain: 'tkfb', path: '/pages/attendance/checkin.html', pageKey: 's1.inspection.checkin' }, - { id: 'vacation', name: '\uB0B4 \uC5F0\uCC28 \uC815\uBCF4', icon: '\uD83C\uDFD6\uFE0F', subdomain: 'tkfb', path: '/pages/attendance/my-vacation-info.html', pageKey: 's1.attendance.my_vacation_info' }, - { id: 'leave', name: '\uD734\uAC00 \uC2E0\uCCAD', icon: '\uD83D\uDCC5', subdomain: 'tkfb', path: '/pages/attendance/vacation-request.html', pageKey: 's1.attendance.vacation_request' } + var ALL_SHORTCUTS = [ + // 작업 관리 + { id: 'tbm', name: 'TBM', icon: '\uD83D\uDCCB', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/tbm.html', pageKey: 's1.work.tbm' }, + { id: 'report', name: '작업보고서', icon: '\uD83D\uDCDD', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/report-create.html', pageKey: 's1.work.report_create' }, + { id: 'analysis', name: '작업 분석', icon: '\uD83D\uDCCA', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/analysis.html', pageKey: 's1.work.analysis' }, + { id: 'nonconformity', name: '부적합 현황', icon: '\u26A0\uFE0F', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/nonconformity.html', pageKey: 's1.work.nonconformity' }, + + // 공장 관리 + { id: 'repair', name: '시설설비 관리', icon: '\uD83D\uDD27', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/admin/repair-management.html', pageKey: 's1.factory.repair_management' }, + { id: 'patrol', name: '일일순회점검', icon: '\uD83D\uDD0D', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/inspection/daily-patrol.html', pageKey: 's1.inspection.daily_patrol' }, + { id: 'checkin', name: '출퇴근 체크', icon: '\u23F0', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/attendance/checkin.html', pageKey: 's1.inspection.checkin' }, + { id: 'workstatus', name: '근무 현황', icon: '\uD83D\uDCBC', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/attendance/work-status.html', pageKey: 's1.inspection.work_status' }, + + // 근태 관리 + { id: 'vacation', name: '내 연차 정보', icon: '\uD83C\uDFD6\uFE0F', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/my-vacation-info.html', pageKey: 's1.attendance.my_vacation_info' }, + { id: 'monthly', name: '월간 근태', icon: '\uD83D\uDCC6', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/monthly.html', pageKey: 's1.attendance.monthly' }, + { id: 'leave', name: '휴가 신청', icon: '\uD83D\uDCC5', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/vacation-request.html', pageKey: 's1.attendance.vacation_request' }, + { id: 'vacmgmt', name: '휴가 관리', icon: '\u2699\uFE0F', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/vacation-management.html', pageKey: 's1.attendance.vacation_management' }, + + // 신고·안전 + { id: 'issue', name: '안전신고', icon: '\uD83D\uDEA8', cat: '신고·안전', subdomain: 'tkreport', path: '/pages/safety/issue-report.html', accessKey: 'system2' }, + { id: 'visit', name: '방문 관리', icon: '\uD83D\uDEAA', cat: '신고·안전', subdomain: 'tksafety', pageKey: 'safety_visit_management' }, + { id: 'education', name: '안전교육', icon: '\uD83C\uDF93', cat: '신고·안전', subdomain: 'tksafety', path: '/education.html', pageKey: 'safety_visit_management' }, + + // 구매·행정 + { id: 'daylabor', name: '일용공 신청', icon: '\uD83D\uDC77', cat: '구매·행정', subdomain: 'tkpurchase', path: '/daylabor.html', pageKey: 'purchasing_schedule' }, + { id: 'schedule', name: '작업일정', icon: '\uD83D\uDCC5', cat: '구매·행정', subdomain: 'tkpurchase', path: '/schedule.html', pageKey: 'purchasing_schedule' } ]; var SYSTEM_CARDS = [ - { id: 'factory', name: '\uACF5\uC7A5\uAD00\uB9AC', icon: '\uD83C\uDFED', subdomain: 'tkfb', path: '/pages/dashboard.html', pageKey: 's1.dashboard', color: '#1a56db' }, - { id: 'report_sys', name: '\uC2E0\uACE0', icon: '\uD83D\uDEA8', subdomain: 'tkreport', accessKey: 'system2', color: '#dc2626' }, - { id: 'quality', name: '\uBD80\uC801\uD569\uAD00\uB9AC', icon: '\uD83D\uDCCA', subdomain: 'tkqc', pageKey: 'issues_dashboard', color: '#059669' } + { id: 'factory', name: '공장관리', icon: '\uD83C\uDFED', subdomain: 'tkfb', path: '/pages/dashboard.html', pageKey: 's1.dashboard', color: '#1a56db' }, + { id: 'report_sys', name: '신고', icon: '\uD83D\uDEA8', subdomain: 'tkreport', accessKey: 'system2', color: '#dc2626' }, + { id: 'quality', name: '부적합관리', icon: '\uD83D\uDCCA', subdomain: 'tkqc', pageKey: 'issues_dashboard', color: '#059669' }, + { id: 'purchase', name: '구매관리', icon: '\uD83D\uDED2', subdomain: 'tkpurchase', pageKey: 'purchasing_schedule', color: '#d97706' }, + { id: 'safety', name: '안전관리', icon: '\uD83D\uDD27', subdomain: 'tksafety', pageKey: 'safety_visit_management', color: '#7c3aed' }, + { id: 'support', name: '행정지원', icon: '\uD83C\uDFE2', subdomain: 'tksupport', comingSoon: true, color: '#6b7280' }, + { id: 'admin', name: '통합관리', icon: '\u2699\uFE0F', subdomain: 'tkuser', pageKey: 'tkuser.users', color: '#0891b2' } ]; - var TOOL_CARDS = [ - { id: 'purchase', name: '\uAD6C\uB9E4\uAD00\uB9AC', icon: '\uD83D\uDED2', subdomain: 'tkpurchase', pageKey: 'purchasing_schedule' }, - { id: 'safety', name: '\uC548\uC804\uAD00\uB9AC', icon: '\uD83D\uDD27', subdomain: 'tksafety', pageKey: 'safety_visit_management' }, - { id: 'support', name: '\uD589\uC815\uC9C0\uC6D0', icon: '\uD83C\uDFE2', comingSoon: true }, - { id: 'admin', name: '\uD1B5\uD569\uAD00\uB9AC', icon: '\u2699\uFE0F', subdomain: 'tkuser', pageKey: 'tkuser.users' } - ]; - - // ===== Click Tracking ===== - function trackClick(linkId) { - var clicks = JSON.parse(localStorage.getItem('hub_clicks') || '{}'); - clicks[linkId] = (clicks[linkId] || 0) + 1; - localStorage.setItem('hub_clicks', JSON.stringify(clicks)); - } - - function getFrequentIds(limit) { - var clicks = JSON.parse(localStorage.getItem('hub_clicks') || '{}'); - if (Object.keys(clicks).length === 0) { - return ['tbm', 'report', 'checkin', 'vacation']; - } - return Object.entries(clicks) - .sort(function(a, b) { return b[1] - a[1]; }) - .slice(0, limit) - .map(function(e) { return e[0]; }); - } - // ===== Rendering ===== function resolveHref(card) { if (card.href) return card.href; @@ -395,7 +398,6 @@ a.onclick = function(e) { e.preventDefault(); }; } else { a.href = resolveHref(card); - a.onclick = function() { trackClick(card.id); }; } var iconSpan = document.createElement('span'); @@ -432,9 +434,31 @@ var grid = document.getElementById(gridId); grid.innerHTML = ''; - visible.forEach(function(card) { - grid.appendChild(createCardElement(card, isSystem)); - }); + + if (!isSystem && visible.length >= 10) { + // 카테고리별 그룹핑 + var categories = []; + var catMap = {}; + visible.forEach(function(c) { + var cat = c.cat || '기타'; + if (!catMap[cat]) { catMap[cat] = []; categories.push(cat); } + catMap[cat].push(c); + }); + categories.forEach(function(cat) { + var label = document.createElement('div'); + label.className = 'shortcut-cat-label'; + label.textContent = cat; + grid.appendChild(label); + catMap[cat].forEach(function(card) { + grid.appendChild(createCardElement(card, false)); + }); + }); + } else { + visible.forEach(function(card) { + grid.appendChild(createCardElement(card, isSystem)); + }); + } + document.getElementById(sectionId).style.display = ''; } @@ -470,29 +494,9 @@ if (systemAccess.system3 !== false) allowed.add('issues_dashboard'); } - // Render main sections - renderSection('dailySection', 'dailyGrid', DAILY_CARDS, allowed, systemAccess, false); + // Render sections + renderSection('shortcutSection', 'shortcutGrid', ALL_SHORTCUTS, allowed, systemAccess, false); renderSection('systemSection', 'systemGrid', SYSTEM_CARDS, allowed, systemAccess, true); - renderSection('toolSection', 'toolGrid', TOOL_CARDS, allowed, systemAccess, false); - - // Frequent section - var allCards = DAILY_CARDS.concat(TOOL_CARDS); - var cardMap = {}; - allCards.forEach(function(c) { cardMap[c.id] = c; }); - - var frequentIds = getFrequentIds(4); - var frequentCards = frequentIds - .map(function(id) { return cardMap[id]; }) - .filter(function(c) { return c && !c.comingSoon && isCardVisible(c, allowed, systemAccess); }); - - if (frequentCards.length > 0) { - var grid = document.getElementById('frequentGrid'); - grid.innerHTML = ''; - frequentCards.forEach(function(card) { - grid.appendChild(createCardElement(card, false)); - }); - document.getElementById('frequentSection').style.display = ''; - } } // ===== Login =====