Skip to content

Commit 4daead1

Browse files
committed
feat(plugins): Enhance badge fetching with conditional JSON and GraphQL support
1 parent 48454f6 commit 4daead1

File tree

2 files changed

+60
-13
lines changed

2 files changed

+60
-13
lines changed

front/pluginsCore.php

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -348,28 +348,68 @@ function postPluginGraphQL(gqlField, prefix, foreignKey, dtRequest, callback) {
348348
});
349349
}
350350

351-
// Fetch the lightweight plugins_stats.json (~1KB) and populate all badge
352-
// and sub-tab counts instantly — no GraphQL, no 250MB file loads.
351+
// Fetch badge counts for every plugin and populate sidebar + sub-tab counters.
352+
// Fast path: static JSON (~1KB) when no MAC filter is active.
353+
// Filtered path: batched GraphQL aliases when a foreignKey (MAC) is set.
353354
async function prefetchPluginBadges() {
355+
const mac = $("#txtMacFilter").val();
356+
const foreignKey = (mac && mac !== "--") ? mac : null;
357+
358+
const prefixes = pluginDefinitions
359+
.filter(p => p.show_ui)
360+
.map(p => p.unique_prefix);
361+
362+
if (prefixes.length === 0) return;
363+
354364
try {
355-
const stats = await fetchJson('table_plugins_stats.json');
356-
// Build lookup: { ARPSCAN: { objects: 42, events: 3, history: 100 }, ... }
357-
const counts = {};
358-
for (const row of stats.data) {
359-
const p = row.tableName; // 'objects' | 'events' | 'history'
360-
const plugin = row.plugin;
361-
if (!counts[plugin]) counts[plugin] = { objects: 0, events: 0, history: 0 };
362-
counts[plugin][p] = row.cnt;
365+
let counts = {}; // { PREFIX: { objects: N, events: N, history: N } }
366+
367+
if (!foreignKey) {
368+
// ---- FAST PATH: lightweight pre-computed JSON ----
369+
const stats = await fetchJson('table_plugins_stats.json');
370+
for (const row of stats.data) {
371+
const p = row.tableName; // 'objects' | 'events' | 'history'
372+
const plugin = row.plugin;
373+
if (!counts[plugin]) counts[plugin] = { objects: 0, events: 0, history: 0 };
374+
counts[plugin][p] = row.cnt;
375+
}
376+
} else {
377+
// ---- FILTERED PATH: GraphQL with foreignKey ----
378+
const apiToken = getSetting("API_TOKEN");
379+
const apiBase = getApiBase();
380+
const fkOpt = `, foreignKey: "${foreignKey}"`;
381+
const fragments = prefixes.map(p => [
382+
`${p}_obj: pluginsObjects(options: {plugin: "${p}", page: 1, limit: 1${fkOpt}}) { dbCount }`,
383+
`${p}_evt: pluginsEvents(options: {plugin: "${p}", page: 1, limit: 1${fkOpt}}) { dbCount }`,
384+
`${p}_hist: pluginsHistory(options: {plugin: "${p}", page: 1, limit: 1${fkOpt}}) { dbCount }`,
385+
].join('\n ')).join('\n ');
386+
387+
const query = `query BadgeCounts {\n ${fragments}\n }`;
388+
const response = await $.ajax({
389+
method: "POST",
390+
url: `${apiBase}/graphql`,
391+
headers: { "Authorization": `Bearer ${apiToken}`, "Content-Type": "application/json" },
392+
data: JSON.stringify({ query }),
393+
});
394+
if (response.errors) { console.error("[plugins] badge GQL errors:", response.errors); return; }
395+
for (const p of prefixes) {
396+
counts[p] = {
397+
objects: response.data[`${p}_obj`]?.dbCount ?? 0,
398+
events: response.data[`${p}_evt`]?.dbCount ?? 0,
399+
history: response.data[`${p}_hist`]?.dbCount ?? 0,
400+
};
401+
}
363402
}
403+
404+
// Update DOM
364405
for (const [prefix, c] of Object.entries(counts)) {
365406
$(`#badge_${prefix}`).text(c.objects);
366407
$(`#objCount_${prefix}`).text(c.objects);
367408
$(`#evtCount_${prefix}`).text(c.events);
368409
$(`#histCount_${prefix}`).text(c.history);
369410
}
370-
// Set 0 for plugins with no rows in any table
371-
pluginDefinitions.filter(p => p.show_ui).forEach(p => {
372-
const prefix = p.unique_prefix;
411+
// Zero out plugins with no rows in any table
412+
prefixes.forEach(prefix => {
373413
if (!counts[prefix]) {
374414
$(`#badge_${prefix}`).text(0);
375415
$(`#objCount_${prefix}`).text(0);

server/api.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ def update_api(
7676
["custom_endpoint", conf.API_CUSTOM_SQL],
7777
]
7878

79+
# plugins_stats is derived from plugins_objects/events/history —
80+
# ensure it is refreshed when any of its sources are partially updated.
81+
_STATS_SOURCES = {"plugins_objects", "plugins_events", "plugins_history"}
82+
if updateOnlyDataSources and _STATS_SOURCES & set(updateOnlyDataSources):
83+
if "plugins_stats" not in updateOnlyDataSources:
84+
updateOnlyDataSources = list(updateOnlyDataSources) + ["plugins_stats"]
85+
7986
# Save selected database tables
8087
for dsSQL in dataSourcesSQLs:
8188
if not updateOnlyDataSources or dsSQL[0] in updateOnlyDataSources:

0 commit comments

Comments
 (0)