fix: restore exact matching logic for map locations

This commit is contained in:
2026-06-18 17:04:25 +09:00
parent 309c400ee2
commit e77c4854cb
8 changed files with 422 additions and 315 deletions

View File

@@ -3,55 +3,55 @@
{
"x": "50.78",
"y": "1.53",
"w": "45.83",
"h": "6.10"
"w": "46.10",
"h": "6.27"
},
{
"x": "50.67",
"x": "50.78",
"y": "10.35",
"w": "45.95",
"h": "5.99"
"w": "46.10",
"h": "6.27"
},
{
"x": "50.78",
"y": "19.06",
"w": "45.83",
"h": "6.32"
"w": "46.10",
"h": "6.50"
},
{
"x": "50.67",
"x": "50.78",
"y": "27.89",
"w": "46.06",
"h": "6.32"
"w": "46.10",
"h": "6.50"
},
{
"x": "50.78",
"y": "36.71",
"w": "45.95",
"h": "6.21"
"w": "46.10",
"h": "6.50"
},
{
"x": "50.78",
"y": "45.64",
"w": "45.83",
"w": "46.10",
"h": "6.32"
},
{
"x": "50.67",
"x": "50.78",
"y": "54.25",
"w": "46.06",
"w": "46.10",
"h": "6.54"
},
{
"x": "50.90",
"x": "50.78",
"y": "63.29",
"w": "45.72",
"h": "5.99"
"w": "46.10",
"h": "6.50"
},
{
"x": "50.90",
"x": "50.78",
"y": "72.00",
"w": "45.72",
"w": "46.10",
"h": "6.32"
},
{
@@ -61,212 +61,218 @@
"h": "15.58"
},
{
"x": "78.67",
"y": "82.03",
"w": "17.94",
"h": "15.25"
"x": "78.62",
"y": "81.92",
"w": "18.31",
"h": "15.58"
}
],
"img/location_photo/IDC/서관202.png": [
{
"x": "56.35",
"x": "58.35",
"y": "64.02",
"w": "40.41",
"h": "5.89"
"w": "40.87",
"h": "6.24"
},
{
"x": "56.35",
"y": "71.57",
"w": "40.66",
"h": "5.89"
"w": "40.87",
"h": "6.24"
},
{
"x": "56.23",
"y": "79.25",
"w": "40.53",
"h": "5.76"
"x": "56.35",
"y": "79.17",
"w": "40.87",
"h": "6.24"
},
{
"x": "55.98",
"y": "86.42",
"w": "41.15",
"h": "6.27"
"x": "56.35",
"y": "86.66",
"w": "40.87",
"h": "6.24"
},
{
"x": "56.35",
"y": "32.01",
"w": "40.87",
"h": "6.24"
}
],
"img/location_photo/IDC/서관203.png": [
{
"x": "56.07",
"y": "2.44",
"w": "40.91",
"h": "6.40"
"y": "2.54",
"w": "41.11",
"h": "6.52"
},
{
"x": "56.07",
"y": "10.12",
"w": "40.79",
"h": "6.27"
"w": "41.11",
"h": "6.52"
},
{
"x": "55.95",
"x": "56.07",
"y": "17.80",
"w": "41.04",
"h": "6.14"
"w": "41.11",
"h": "6.52"
},
{
"x": "55.95",
"x": "56.07",
"y": "63.51",
"w": "40.91",
"h": "6.14"
"w": "41.11",
"h": "6.52"
},
{
"x": "55.95",
"x": "56.07",
"y": "71.19",
"w": "41.04",
"h": "6.14"
"w": "41.11",
"h": "6.52"
},
{
"x": "56.07",
"y": "87.70",
"w": "40.91",
"h": "6.02"
"w": "41.11",
"h": "6.52"
}
],
"img/location_photo/IDC/서관204.png": [
{
"x": "48.87",
"y": "2.57",
"w": "47.40",
"h": "6.14"
"y": "2.73",
"w": "47.80",
"h": "6.27"
},
{
"x": "49.01",
"x": "48.87",
"y": "10.38",
"w": "47.40",
"h": "5.89"
"w": "47.80",
"h": "6.27"
},
{
"x": "48.87",
"y": "17.93",
"w": "47.40",
"h": "5.89"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.73",
"x": "48.87",
"y": "25.49",
"w": "47.69",
"h": "6.27"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.87",
"y": "33.17",
"w": "47.40",
"h": "6.02"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.87",
"y": "40.59",
"w": "47.54",
"h": "6.40"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.87",
"y": "48.40",
"w": "47.54",
"h": "6.14"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.73",
"x": "48.87",
"y": "55.95",
"w": "47.69",
"h": "6.14"
"w": "47.80",
"h": "6.50"
},
{
"x": "49.01",
"x": "48.87",
"y": "63.63",
"w": "47.40",
"h": "6.14"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.73",
"x": "48.87",
"y": "71.06",
"w": "47.54",
"h": "6.27"
"w": "47.80",
"h": "6.50"
},
{
"x": "48.87",
"y": "78.74",
"w": "47.40",
"h": "6.27"
"w": "47.80",
"h": "6.50"
},
{
"x": "49.01",
"x": "48.87",
"y": "86.68",
"w": "18.76",
"h": "12.29"
"w": "18.99",
"h": "12.62"
}
],
"img/location_photo/IDC/동관53.png": [
{
"x": "61.62",
"y": "3.08",
"w": "35.63",
"h": "7.55"
"w": "35.96",
"h": "7.90"
},
{
"x": "61.53",
"x": "61.62",
"y": "12.68",
"w": "35.80",
"h": "7.30"
"w": "35.96",
"h": "7.90"
},
{
"x": "61.70",
"y": "21.65",
"w": "35.63",
"h": "7.68"
"x": "61.62",
"y": "21.75",
"w": "35.96",
"h": "7.90"
}
],
"img/location_photo/IDC/동관54.png": [
{
"x": "54.71",
"y": "2.57",
"w": "42.21",
"h": "6.27"
"w": "42.42",
"h": "6.50"
},
{
"x": "54.71",
"y": "10.38",
"w": "42.21",
"h": "6.14"
"w": "42.42",
"h": "6.50"
},
{
"x": "54.71",
"y": "27.15",
"w": "41.97",
"h": "6.27"
"w": "42.42",
"h": "6.62"
},
{
"x": "54.71",
"y": "43.54",
"w": "42.09",
"h": "6.02"
"w": "42.42",
"h": "6.50"
},
{
"x": "54.71",
"y": "54.93",
"w": "42.09",
"h": "6.40"
"w": "42.42",
"h": "6.50"
},
{
"x": "54.83",
"x": "54.71",
"y": "70.16",
"w": "42.09",
"h": "6.27"
"w": "42.42",
"h": "6.50"
},
{
"x": "54.71",
"y": "79.51",
"w": "42.09",
"h": "6.14"
"w": "42.42",
"h": "6.50"
}
],
"img/location_photo/기술개발센터/서버실_1.png": [
@@ -421,286 +427,286 @@
{
"x": "49.33",
"y": "14.99",
"w": "7.13",
"h": "11.01"
"w": "7.35",
"h": "11.22"
},
{
"x": "59.23",
"y": "14.73",
"w": "7.13",
"h": "11.14"
"y": "14.99",
"w": "7.35",
"h": "11.22"
},
{
"x": "69.22",
"y": "14.86",
"w": "7.13",
"h": "11.14"
"y": "14.99",
"w": "7.35",
"h": "11.22"
},
{
"x": "78.96",
"y": "14.99",
"w": "7.30",
"h": "11.01"
"w": "7.35",
"h": "11.22"
},
{
"x": "89.03",
"y": "14.99",
"w": "7.05",
"h": "11.14"
"w": "7.35",
"h": "11.22"
},
{
"x": "48.57",
"y": "34.19",
"w": "7.39",
"h": "11.14"
"y": "34.11",
"w": "7.52",
"h": "11.44"
},
{
"x": "56.80",
"y": "34.06",
"w": "7.22",
"h": "11.27"
"y": "34.11",
"w": "7.52",
"h": "11.44"
},
{
"x": "64.94",
"y": "34.19",
"w": "7.30",
"h": "11.01"
"y": "34.11",
"w": "7.52",
"h": "11.44"
},
{
"x": "72.83",
"y": "34.19",
"w": "7.47",
"h": "10.88"
"x": "72.89",
"y": "34.11",
"w": "7.56",
"h": "11.44"
},
{
"x": "81.22",
"y": "34.06",
"w": "7.22",
"h": "11.14"
"w": "7.52",
"h": "11.44"
},
{
"x": "89.36",
"y": "34.19",
"w": "7.13",
"h": "11.01"
"y": "34.06",
"w": "7.52",
"h": "11.44"
},
{
"x": "48.66",
"y": "53.52",
"x": "48.57",
"y": "53.06",
"w": "9.06",
"h": "20.99"
},
{
"x": "58.48",
"y": "53.27",
"w": "9.15",
"h": "21.12"
"y": "53.06",
"w": "9.06",
"h": "20.99"
},
{
"x": "68.55",
"y": "53.27",
"y": "53.06",
"w": "9.06",
"h": "21.12"
"h": "20.99"
},
{
"x": "78.54",
"y": "53.39",
"w": "8.90",
"h": "21.25"
"y": "53.06",
"w": "9.01",
"h": "20.99"
},
{
"x": "89.36",
"y": "53.27",
"w": "7.39",
"h": "9.99"
"y": "53.22",
"w": "7.45",
"h": "10.11"
},
{
"x": "89.36",
"y": "64.92",
"w": "7.39",
"h": "9.60"
"w": "7.45",
"h": "9.81"
},
{
"x": "48.57",
"y": "77.08",
"w": "9.40",
"h": "21.38"
"y": "77.41",
"w": "9.18",
"h": "21.45"
},
{
"x": "58.56",
"y": "77.20",
"y": "77.41",
"w": "9.23",
"h": "21.12"
"h": "21.45"
},
{
"x": "68.63",
"y": "77.33",
"y": "77.41",
"w": "9.06",
"h": "21.12"
"h": "21.45"
},
{
"x": "78.71",
"y": "77.46",
"y": "77.41",
"w": "8.98",
"h": "20.99"
"h": "21.45"
}
],
"img/location_photo/한맥빌딩/MDF실/MDF_2.png": [
{
"x": "56.59",
"y": "44.43",
"w": "40.35",
"h": "6.78"
"y": "44.53",
"w": "40.65",
"h": "6.90"
},
{
"x": "56.71",
"x": "56.59",
"y": "54.80",
"w": "40.24",
"h": "6.53"
"w": "40.65",
"h": "6.90"
},
{
"x": "56.71",
"x": "56.59",
"y": "65.94",
"w": "40.24",
"h": "6.40"
"w": "40.65",
"h": "6.90"
}
],
"img/location_photo/한맥빌딩/MDF실/MDF_3.png": [
{
"x": "56.71",
"y": "13.20",
"w": "40.24",
"h": "6.78"
"w": "40.58",
"h": "6.90"
},
{
"x": "56.48",
"x": "56.71",
"y": "23.57",
"w": "40.58",
"h": "6.53"
"h": "6.90"
},
{
"x": "56.59",
"x": "56.71",
"y": "34.57",
"w": "40.58",
"h": "6.27"
"h": "6.90"
},
{
"x": "56.59",
"x": "56.71",
"y": "44.69",
"w": "40.46",
"h": "6.66"
"w": "40.58",
"h": "6.90"
},
{
"x": "56.71",
"y": "54.80",
"w": "40.24",
"h": "6.66"
"w": "40.58",
"h": "6.90"
},
{
"x": "56.71",
"y": "65.81",
"w": "40.24",
"h": "6.53"
"w": "40.58",
"h": "6.90"
},
{
"x": "56.59",
"x": "56.71",
"y": "76.05",
"w": "40.35",
"h": "6.53"
"w": "40.58",
"h": "6.90"
}
],
"img/location_photo/한맥빌딩/MDF실/MDF_4.png": [
{
"x": "52.36",
"y": "64.02",
"w": "44.38",
"h": "6.53"
"w": "44.60",
"h": "6.73"
}
],
"img/location_photo/기술개발센터/서버실/서버실_1.png": [
{
"x": "69.53",
"y": "1.42",
"w": "8.58",
"h": "11.45"
"x": "69.40",
"y": "3.06",
"w": "8.61",
"h": "11.57"
},
{
"x": "79.21",
"y": "1.55",
"w": "11.97",
"h": "11.32"
"x": "79.00",
"y": "3.06",
"w": "12.05",
"h": "11.57"
},
{
"x": "90.24",
"y": "23.30",
"x": "90.19",
"y": "25.69",
"w": "8.50",
"h": "21.49"
"h": "21.48"
},
{
"x": "53.07",
"y": "53.28",
"w": "8.74",
"h": "21.62"
"y": "52.94",
"w": "8.50",
"h": "21.25"
},
{
"x": "62.28",
"y": "53.41",
"w": "8.82",
"h": "21.49"
"y": "52.94",
"w": "8.50",
"h": "21.25"
},
{
"x": "71.50",
"y": "53.28",
"w": "8.90",
"h": "21.75"
"y": "52.94",
"w": "8.50",
"h": "21.25"
},
{
"x": "80.87",
"y": "53.15",
"w": "8.66",
"h": "21.75"
"y": "52.94",
"w": "8.50",
"h": "21.25"
},
{
"x": "90.08",
"y": "53.54",
"w": "8.90",
"h": "21.49"
"y": "52.94",
"w": "8.50",
"h": "21.25"
},
{
"x": "43.86",
"y": "76.32",
"w": "8.82",
"h": "21.75"
"y": "78.30",
"w": "8.50",
"h": "21.20"
},
{
"x": "53.15",
"y": "76.45",
"w": "8.66",
"h": "21.49"
},
{
"x": "62.52",
"y": "76.57",
"w": "8.58",
"h": "21.62"
},
{
"x": "71.65",
"y": "76.45",
"w": "8.66",
"h": "21.62"
},
{
"x": "80.94",
"y": "76.57",
"w": "8.74",
"h": "21.49"
},
{
"x": "90.24",
"y": "76.57",
"y": "78.30",
"w": "8.50",
"h": "21.36"
"h": "21.20"
},
{
"x": "62.32",
"y": "78.30",
"w": "8.50",
"h": "21.20"
},
{
"x": "71.35",
"y": "78.30",
"w": "8.50",
"h": "21.20"
},
{
"x": "80.58",
"y": "78.30",
"w": "8.50",
"h": "21.20"
},
{
"x": "89.79",
"y": "78.30",
"w": "8.50",
"h": "21.20"
}
],
"img/location_photo/기술개발센터/서버실/서버실_2.png": [
@@ -714,13 +720,13 @@
"x": "49.47",
"y": "12.04",
"w": "47.49",
"h": "6.91"
"h": "7.04"
},
{
"x": "49.60",
"x": "49.47",
"y": "21.52",
"w": "47.35",
"h": "6.91"
"w": "47.49",
"h": "6.97"
},
{
"x": "49.47",
@@ -729,40 +735,40 @@
"h": "7.04"
},
{
"x": "49.60",
"x": "49.47",
"y": "39.82",
"w": "47.49",
"h": "6.91"
"h": "7.04"
},
{
"x": "49.47",
"y": "50.06",
"w": "47.62",
"h": "6.91"
},
{
"x": "49.74",
"y": "59.28",
"w": "47.22",
"h": "6.91"
},
{
"x": "49.34",
"y": "68.37",
"w": "47.75",
"w": "47.49",
"h": "7.04"
},
{
"x": "49.60",
"y": "77.97",
"w": "47.22",
"h": "6.91"
"x": "49.47",
"y": "59.28",
"w": "47.49",
"h": "7.04"
},
{
"x": "49.60",
"x": "49.47",
"y": "68.37",
"w": "47.49",
"h": "7.04"
},
{
"x": "49.47",
"y": "77.97",
"w": "47.49",
"h": "6.97"
},
{
"x": "49.47",
"y": "86.93",
"w": "47.35",
"h": "7.17"
"w": "47.49",
"h": "7.04"
}
]
}

View File

@@ -675,16 +675,44 @@ app.delete('/api/system-users/:id', async (req, res) => {
}
});
app.post('/api/maps/save', (req, res) => {
app.post('/api/maps/save', async (req, res) => {
let connection;
try {
const { path, boxes } = req.body;
if (!path) return res.status(400).json({ error: 'Path is required' });
let config = {};
if (fs.existsSync('map_config.json')) config = JSON.parse(fs.readFileSync('map_config.json', 'utf8') || '{}');
config[path] = boxes;
fs.writeFileSync('map_config.json', JSON.stringify(config, null, 2));
res.json({ success: true });
} catch (err) { handleError(res, err, 'SAVE MAPS'); }
// 1. Get old config to track movements
let oldConfig = {};
if (fs.existsSync('map_config.json')) {
oldConfig = JSON.parse(fs.readFileSync('map_config.json', 'utf8') || '{}');
}
const oldBoxes = oldConfig[path] || [];
// 2. Save new config to file
oldConfig[path] = boxes;
fs.writeFileSync('map_config.json', JSON.stringify(oldConfig, null, 2));
// 3. Sync Database Assets (asset_location table)
connection = await pool.getConnection();
for (let i = 0; i < boxes.length; i++) {
const newBox = boxes[i];
const oldBox = oldBoxes[i];
if (oldBox && (String(oldBox.x) !== String(newBox.x) || String(oldBox.y) !== String(newBox.y))) {
console.log(`Syncing moved box #${i+1} on ${path}: [${oldBox.x}, ${oldBox.y}] -> [${newBox.x}, ${newBox.y}]`);
await connection.query(
'UPDATE asset_location SET loc_x = ?, loc_y = ? WHERE loc_x = ? AND loc_y = ? AND is_active = 1',
[newBox.x, newBox.y, oldBox.x, oldBox.y]
);
}
}
res.json({ success: true, message: 'Map and Database synced successfully' });
} catch (err) {
handleError(res, err, 'SAVE MAPS SYNC');
} finally {
if (connection) connection.release();
}
});
// 7. File Upload API (Base64)

View File

@@ -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();
});
}

View File

@@ -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); }

View File

@@ -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>`;
}
}

View File

@@ -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 =>

View File

@@ -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
}
});
});
}
}

View File

@@ -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);