Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
window.beursHub = function () {
|
||||
return {
|
||||
tab: new URLSearchParams(location.search).get('tab') || 'beurs',
|
||||
busy: false,
|
||||
lastRefresh: '',
|
||||
listed: [],
|
||||
unlisted: [],
|
||||
summary: {},
|
||||
trends: { halal_meat_trends: [], top_dishes: [], market_trends: [] },
|
||||
concepts: [],
|
||||
events: [],
|
||||
platformStats: {},
|
||||
eventFilter: '',
|
||||
pollTimer: null,
|
||||
indicatorStyle: { left: '0%', width: '25%' },
|
||||
|
||||
init() {
|
||||
this.updateIndicator();
|
||||
this.refreshAll();
|
||||
this.pollTimer = setInterval(() => {
|
||||
if (this.tab === 'events') this.loadEvents(false);
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
setTab(t) {
|
||||
this.tab = t;
|
||||
const url = new URL(location.href);
|
||||
url.searchParams.set('tab', t);
|
||||
history.replaceState({}, '', url);
|
||||
this.updateIndicator();
|
||||
if (t === 'trends' && !this.trends.halal_meat_trends?.length) this.loadTrends();
|
||||
if (t === 'concepten' && !this.concepts.length) this.loadConcepts();
|
||||
if (t === 'events') this.loadEvents();
|
||||
},
|
||||
|
||||
updateIndicator() {
|
||||
const tabs = ['beurs', 'trends', 'concepten', 'events'];
|
||||
const i = tabs.indexOf(this.tab);
|
||||
const w = 100 / tabs.length;
|
||||
this.indicatorStyle = { left: (i * w) + '%', width: w + '%' };
|
||||
},
|
||||
|
||||
sparkPoints(arr) {
|
||||
if (!arr || !arr.length) return '';
|
||||
const min = Math.min.apply(null, arr);
|
||||
const max = Math.max.apply(null, arr);
|
||||
const range = max - min || 1;
|
||||
return arr.map(function (v, idx) {
|
||||
var x = (idx / (arr.length - 1 || 1)) * 100;
|
||||
var y = 28 - ((v - min) / range) * 24;
|
||||
return x.toFixed(1) + ',' + y.toFixed(1);
|
||||
}).join(' ');
|
||||
},
|
||||
|
||||
async refreshAll() {
|
||||
this.busy = true;
|
||||
try {
|
||||
await Promise.all([
|
||||
this.loadMarket(),
|
||||
this.loadTrends(),
|
||||
this.loadConcepts(),
|
||||
this.loadEvents(false),
|
||||
]);
|
||||
this.lastRefresh = new Date().toLocaleString('nl-NL');
|
||||
if (typeof Cockpit !== 'undefined') Cockpit.toast('Beurs data bijgewerkt', 'success');
|
||||
} catch (e) {
|
||||
if (typeof Cockpit !== 'undefined') Cockpit.toast(e.message, 'error');
|
||||
}
|
||||
this.busy = false;
|
||||
},
|
||||
|
||||
async loadMarket() {
|
||||
const d = await fetch('/api/retail/market/supermarkets').then(function (r) { return r.json(); });
|
||||
this.listed = d.listed || [];
|
||||
this.unlisted = d.unlisted_nl || [];
|
||||
this.summary = d.summary || {};
|
||||
},
|
||||
|
||||
async loadTrends() {
|
||||
const d = await fetch('/api/retail/market/food-trends').then(function (r) { return r.json(); });
|
||||
this.trends = d;
|
||||
},
|
||||
|
||||
async loadConcepts() {
|
||||
const d = await fetch('/api/retail/market/concepts?limit=6').then(function (r) { return r.json(); });
|
||||
this.concepts = d.concepts || [];
|
||||
},
|
||||
|
||||
async loadEvents(toast) {
|
||||
var q = this.eventFilter ? '?limit=80&agent=' + encodeURIComponent(this.eventFilter) : '?limit=80';
|
||||
try {
|
||||
var r = await fetch('/api/live/platform' + q).then(function (x) { return x.json(); });
|
||||
this.events = r.events || [];
|
||||
this.platformStats = r.stats || {};
|
||||
} catch (e) {
|
||||
if (toast !== false && typeof Cockpit !== 'undefined') Cockpit.toast(e.message, 'error');
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user