mirror of
https://github.com/sotam0316/drawNET_test.git
synced 2026-04-25 12:08:37 +09:00
100 lines
3.5 KiB
JavaScript
100 lines
3.5 KiB
JavaScript
import { state } from '../state.js';
|
|
|
|
/**
|
|
* initGlobalSearch - Initializes the canvas-wide search and highlight functionality
|
|
*/
|
|
export function initGlobalSearch() {
|
|
const searchInput = document.getElementById('global-search');
|
|
if (!searchInput) return;
|
|
|
|
searchInput.addEventListener('input', (e) => {
|
|
const query = e.target.value.toLowerCase().trim();
|
|
if (!state.graph) return;
|
|
|
|
const allNodes = state.graph.getNodes();
|
|
|
|
if (query === '') {
|
|
allNodes.forEach(node => {
|
|
node.attr('body/opacity', 1);
|
|
node.attr('image/opacity', 1);
|
|
node.attr('label/opacity', 1);
|
|
node.removeTools();
|
|
});
|
|
return;
|
|
}
|
|
|
|
allNodes.forEach(node => {
|
|
const data = node.getData() || {};
|
|
const label = (node.attr('label/text') || '').toLowerCase();
|
|
const id = node.id.toLowerCase();
|
|
|
|
// PM 전용 표준 속성 검색 대상 포함
|
|
const searchFields = [
|
|
id, label,
|
|
(data.type || '').toLowerCase(),
|
|
(data.ip || '').toLowerCase(),
|
|
(data.model || '').toLowerCase(),
|
|
(data.vendor || '').toLowerCase(),
|
|
(data.asset_tag || '').toLowerCase(),
|
|
(data.serial || '').toLowerCase(),
|
|
(data.project || '').toLowerCase(),
|
|
(data.tags || []).join(' ').toLowerCase()
|
|
];
|
|
|
|
const isMatch = searchFields.some(field => field.includes(query));
|
|
|
|
if (isMatch) {
|
|
node.attr('body/opacity', 1);
|
|
node.attr('image/opacity', 1);
|
|
node.attr('label/opacity', 1);
|
|
|
|
// 검색 강조 툴 추가
|
|
node.addTools({
|
|
name: 'boundary',
|
|
args: {
|
|
padding: 5,
|
|
attrs: {
|
|
fill: 'none',
|
|
stroke: '#3b82f6',
|
|
strokeWidth: 3,
|
|
strokeDasharray: '0',
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
node.attr('body/opacity', 0.1);
|
|
node.attr('image/opacity', 0.1);
|
|
node.attr('label/opacity', 0.1);
|
|
node.removeTools();
|
|
}
|
|
});
|
|
});
|
|
|
|
// 엔터 키 입력 시 검색된 첫 번째 항목으로 포커싱
|
|
searchInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') {
|
|
const query = e.target.value.toLowerCase().trim();
|
|
if (!query || !state.graph) return;
|
|
|
|
const matches = state.graph.getNodes().filter(node => {
|
|
const data = node.getData() || {};
|
|
const label = (node.attr('label/text') || '').toLowerCase();
|
|
const searchFields = [
|
|
node.id.toLowerCase(), label,
|
|
(data.ip || ''), (data.asset_tag || ''), (data.model || '')
|
|
];
|
|
return searchFields.some(f => f.toLowerCase().includes(query));
|
|
});
|
|
|
|
if (matches.length > 0) {
|
|
// 첫 번째 매치된 항목으로 줌인
|
|
state.graph.zoomToCell(matches[0], {
|
|
padding: 100,
|
|
animation: { duration: 600 }
|
|
});
|
|
state.graph.select(matches[0]);
|
|
}
|
|
}
|
|
});
|
|
}
|