fix: restore exact matching logic for map locations
This commit is contained in:
20
src/main.ts
20
src/main.ts
@@ -156,7 +156,6 @@ function initRoleSwitcher() {
|
||||
if (!checkbox || !userLabel || !adminLabel) return;
|
||||
|
||||
checkbox.addEventListener('change', () => {
|
||||
const mainContent = document.getElementById('main-content')!;
|
||||
if (checkbox.checked) {
|
||||
state.currentUserRole = 'admin';
|
||||
userLabel.classList.remove('active');
|
||||
@@ -166,14 +165,6 @@ function initRoleSwitcher() {
|
||||
// 관리자 모드 전환 시 대시보드로 이동
|
||||
state.activeCategory = 'hw';
|
||||
state.activeSubTab = '대시보드';
|
||||
refreshView();
|
||||
renderNavigation((tab) => {
|
||||
if (tab === '대시보드') {
|
||||
renderDashboard(mainContent);
|
||||
} else {
|
||||
renderSWTable(mainContent);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
state.currentUserRole = 'user';
|
||||
adminLabel.classList.remove('active');
|
||||
@@ -183,15 +174,10 @@ function initRoleSwitcher() {
|
||||
// 실무자 모드 전환 시 서버 목록으로 이동
|
||||
state.activeCategory = 'hw';
|
||||
state.activeSubTab = '서버';
|
||||
refreshView();
|
||||
renderNavigation((tab) => {
|
||||
if (tab === '대시보드') {
|
||||
renderDashboard(mainContent);
|
||||
} else {
|
||||
renderSWTable(mainContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
// 모든 렌더링을 refreshView 하나로 통합하여 규격 유지
|
||||
renderNavigation(() => refreshView());
|
||||
refreshView();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -88,11 +88,52 @@
|
||||
.box-item {
|
||||
font-family: monospace;
|
||||
font-size: 11px;
|
||||
padding: 6px;
|
||||
padding: 10px 6px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.box-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.box-index {
|
||||
font-weight: bold;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.box-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.input-group label {
|
||||
color: var(--text-muted);
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.input-group input {
|
||||
width: 100%;
|
||||
padding: 2px 4px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 2px;
|
||||
font-size: 10px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-group input:focus {
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.box-item:hover { background: var(--white); }
|
||||
|
||||
@@ -3,12 +3,11 @@ import { renderHwDashboard } from './Dashboard/HwDashboard';
|
||||
import { renderSwDashboard } from './Dashboard/SwDashboard';
|
||||
|
||||
/**
|
||||
* 대시보드 렌더링 통합 허브
|
||||
* 대시보드 렌더링 통합 허브 (Vercel Style Normalized)
|
||||
*/
|
||||
export function renderDashboard(mainContent: HTMLElement) {
|
||||
if (!mainContent) return;
|
||||
mainContent.innerHTML = '';
|
||||
|
||||
|
||||
// 기존 차트 리소스 해제
|
||||
if (state.activeCharts) {
|
||||
state.activeCharts.forEach((c: any) => {
|
||||
@@ -17,11 +16,21 @@ export function renderDashboard(mainContent: HTMLElement) {
|
||||
}
|
||||
state.activeCharts = [];
|
||||
|
||||
mainContent.innerHTML = `
|
||||
<div class="view-content-wrapper">
|
||||
<div id="dashboard-scroll-container" class="table-container" style="padding: 0;">
|
||||
<div id="dashboard-inner-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const innerContent = document.getElementById('dashboard-inner-content')!;
|
||||
|
||||
if (state.activeCategory === 'hw') {
|
||||
renderHwDashboard(mainContent);
|
||||
renderHwDashboard(innerContent);
|
||||
} else if (state.activeCategory === 'sw') {
|
||||
renderSwDashboard(mainContent);
|
||||
renderSwDashboard(innerContent);
|
||||
} else {
|
||||
mainContent.innerHTML = `<div class="dashboard-section-title" style="padding:2rem;">운영 서비스 대시보드는 준비 중입니다.</div>`;
|
||||
innerContent.innerHTML = `<div class="dashboard-section-title" style="padding:2rem;">해당 카테고리의 대시보드는 준비 중입니다.</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function renderLocationView(container: HTMLElement) {
|
||||
: [];
|
||||
const mapPath = locImages[currentPage] || '';
|
||||
|
||||
// 자산이 등록된 구역만 필터링
|
||||
// 조회 모드: 자산이 등록된 구역만 필터링하여 노출
|
||||
const allBoxes = mapConfig[mapPath] || [];
|
||||
const boxes = allBoxes.filter((box: any) =>
|
||||
state.masterData.hw.some(a =>
|
||||
|
||||
@@ -213,10 +213,45 @@ export class MapEditor {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'box-item';
|
||||
item.innerHTML = `
|
||||
<span>#${i+1}: [${box.x}, ${box.y}]</span>
|
||||
<button class="btn-del" onclick="removeBox(${i})">×</button>
|
||||
<div class="box-header">
|
||||
<span class="box-index">#${i+1}</span>
|
||||
<button class="btn-del" onclick="removeBox(${i})">×</button>
|
||||
</div>
|
||||
<div class="box-inputs">
|
||||
<div class="input-group">
|
||||
<label>X</label>
|
||||
<input type="number" step="0.01" value="${box.x}" data-index="${i}" data-prop="x">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>Y</label>
|
||||
<input type="number" step="0.01" value="${box.y}" data-index="${i}" data-prop="y">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>W</label>
|
||||
<input type="number" step="0.01" value="${box.w}" data-index="${i}" data-prop="w">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>H</label>
|
||||
<input type="number" step="0.01" value="${box.h}" data-index="${i}" data-prop="h">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
this.boxListEl.appendChild(item);
|
||||
});
|
||||
|
||||
// Add events to new inputs
|
||||
this.boxListEl.querySelectorAll('input').forEach(input => {
|
||||
input.addEventListener('change', (e) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const index = parseInt(target.dataset.index!);
|
||||
const prop = target.dataset.prop!;
|
||||
const val = parseFloat(target.value).toFixed(2);
|
||||
|
||||
if (this.boxes[index]) {
|
||||
this.boxes[index][prop] = val;
|
||||
this.render(); // Re-render to update the map and sync other inputs
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,18 +15,22 @@ import { renderGiftList } from './List/GiftListView';
|
||||
import { renderFacilityList } from './List/FacilityListView';
|
||||
import { renderCostList } from './List/CostListView';
|
||||
import { renderUserList } from './List/UserListView';
|
||||
import { createIcons, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, RefreshCcw, Settings } from 'lucide';
|
||||
import { createIcons, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, RefreshCcw, BookOpen, Settings } from 'lucide';
|
||||
|
||||
/**
|
||||
* 자산 목록 테이블 렌더링 통합 허브
|
||||
* 자산 목록 테이블 렌더링 통합 허브 (Vercel Style Normalized)
|
||||
*/
|
||||
export function renderSWTable(mainContent: HTMLElement) {
|
||||
if (!mainContent) return;
|
||||
console.log(`📂 Rendering Table for: ${state.activeCategory} / ${state.activeSubTab}`);
|
||||
|
||||
mainContent.innerHTML = '';
|
||||
const container = document.createElement('div');
|
||||
container.className = 'view-container';
|
||||
mainContent.innerHTML = `
|
||||
<div class="view-content-wrapper">
|
||||
<div id="list-view-container" style="flex: 1; display: flex; flex-direction: column; overflow: hidden;"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const container = document.getElementById('list-view-container')!;
|
||||
|
||||
try {
|
||||
const tab = state.activeSubTab;
|
||||
@@ -69,11 +73,9 @@ export function renderSWTable(mainContent: HTMLElement) {
|
||||
}
|
||||
}
|
||||
|
||||
mainContent.appendChild(container);
|
||||
|
||||
// 전역 아이콘 초기화 (한 번 더 실행하여 누락 방지)
|
||||
// 전역 아이콘 초기화
|
||||
createIcons({
|
||||
icons: { Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, RefreshCcw, Settings }
|
||||
icons: { Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, RefreshCcw, BookOpen, Settings }
|
||||
});
|
||||
} catch (err: any) {
|
||||
console.error('❌ Error rendering table view:', err);
|
||||
|
||||
Reference in New Issue
Block a user