Rework device type view to group by deviceType tag
- /api/devices now groups hosts by deviceType tag instead of host group; hosts without the tag are skipped - /api/detail device lookup filters by deviceType tag instead of groupid - getTag() is now case-insensitive on the tag name - Removed selectHostGroups from fetchKFCData (no longer needed) - Frontend: hex id and Zabbix deep-link use deviceType instead of groupid - Smaller hex label (1.2rem) for device type view via hex-item--device class - Skip DOM re-render on auto-refresh when data is unchanged (lastDataKey diff) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
30
server.js
30
server.js
@@ -29,7 +29,8 @@ async function zabbix(method, params) {
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function getTag(tags, name) {
|
||||
const t = tags.find(t => t.tag === name);
|
||||
const lower = name.toLowerCase();
|
||||
const t = tags.find(t => t.tag.toLowerCase() === lower);
|
||||
return t ? t.value : null;
|
||||
}
|
||||
|
||||
@@ -48,10 +49,9 @@ function problemCount(triggers) {
|
||||
|
||||
async function fetchKFCData() {
|
||||
const hosts = await zabbix('host.get', {
|
||||
output: ['hostid', 'host', 'name'],
|
||||
tags: [{ tag: 'customer', value: CUSTOMER_TAG_VALUE, operator: '1' }],
|
||||
selectTags: 'extend',
|
||||
selectHostGroups: ['groupid', 'name'],
|
||||
output: ['hostid', 'host', 'name'],
|
||||
tags: [{ tag: 'customer', value: CUSTOMER_TAG_VALUE, operator: '1' }],
|
||||
selectTags: 'extend',
|
||||
});
|
||||
|
||||
if (hosts.length === 0) return { hosts: [], triggersByHost: {} };
|
||||
@@ -158,22 +158,20 @@ app.get('/api/restaurants', async (req, res) => {
|
||||
|
||||
app.get('/api/devices', async (req, res) => {
|
||||
try {
|
||||
const country = req.query.country || '';
|
||||
const { hosts, triggersByHost } = await fetchKFCData();
|
||||
|
||||
const map = {};
|
||||
for (const host of hosts) {
|
||||
const hostCountry = getTag(host.tags, COUNTRY_TAG);
|
||||
if (country && hostCountry && hostCountry.toLowerCase() !== country.toLowerCase()) continue;
|
||||
const deviceType = getTag(host.tags, 'deviceType');
|
||||
if (!deviceType) continue;
|
||||
|
||||
for (const group of host.hostgroups) {
|
||||
const key = `${group.groupid}__${hostCountry || ''}`;
|
||||
if (!map[key]) {
|
||||
map[key] = { groupid: group.groupid, name: group.name, country: hostCountry, hosts: [], triggers: [] };
|
||||
}
|
||||
map[key].hosts.push(host);
|
||||
map[key].triggers.push(...(triggersByHost[host.hostid] || []));
|
||||
const key = `${deviceType}__${hostCountry || ''}`;
|
||||
if (!map[key]) {
|
||||
map[key] = { deviceType, name: deviceType, country: hostCountry, hosts: [], triggers: [] };
|
||||
}
|
||||
map[key].hosts.push(host);
|
||||
map[key].triggers.push(...(triggersByHost[host.hostid] || []));
|
||||
}
|
||||
|
||||
const result = Object.values(map)
|
||||
@@ -193,7 +191,7 @@ app.get('/api/devices', async (req, res) => {
|
||||
}
|
||||
problems.sort((a, b) => b.priority - a.priority || b.lastchange - a.lastchange);
|
||||
return {
|
||||
groupid: g.groupid,
|
||||
deviceType: g.deviceType,
|
||||
name: g.name,
|
||||
country: g.country,
|
||||
hostCount: g.hosts.length,
|
||||
@@ -220,7 +218,7 @@ app.get('/api/detail', async (req, res) => {
|
||||
|
||||
const filtered = type === 'restaurant'
|
||||
? hosts.filter(h => getTag(h.tags, 'location') === id)
|
||||
: hosts.filter(h => h.hostgroups.some(g => g.groupid === id));
|
||||
: hosts.filter(h => getTag(h.tags, 'deviceType') === id);
|
||||
|
||||
const items = filtered.map(host => ({
|
||||
hostid: host.hostid,
|
||||
|
||||
Reference in New Issue
Block a user