Improve CEO cockpit clarity and Revenue visuals, with Hermes briefing.
Tighten overview KPIs/pipeline height, add selectable Revenue views and a resizable sidebar, and keep supporting Hermes/Wereldexport updates.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
var WIDGET_META = {
|
||||
kpis: { title: 'CEO KPI\'s', icon: '📊' },
|
||||
executive: { title: 'Alles op een rij', icon: '📋' },
|
||||
briefing: { title: 'Herman briefing', icon: '📝' },
|
||||
retail: { title: 'Retail operatie', icon: '🏪' },
|
||||
briefing: { title: 'Focus & trends', icon: '🎯' },
|
||||
news: { title: 'Laatste nieuws', icon: '📰' },
|
||||
analytics: { title: 'Data & analytics', icon: '📈' },
|
||||
approvals: { title: 'Agent goedkeuringen', icon: '✓' },
|
||||
feed: { title: 'Agent feed', icon: '⚡' },
|
||||
@@ -26,10 +26,16 @@
|
||||
nas_docs: { label: 'NAS documenten', sub: 'geanalyseerd', icon: '📊', color: '#818cf8', link: '/documents' },
|
||||
promo_campaigns: { label: 'Promo campagnes', sub: 'actief', icon: '📁', color: '#c084fc', link: '/marketing?tab=reclame' },
|
||||
market_best: { label: 'Aandeel top', sub: 'retail markt', icon: '📈', color: '#34d399', link: '/analytics' },
|
||||
margin_month: { label: 'Marge / mnd', sub: 'Revenue Cockpit', icon: '💶', color: '#fbbf24', link: '/revenue-cockpit' },
|
||||
margin_year: { label: 'Marge / jr', sub: 'Revenue Cockpit', icon: '📅', color: '#38bdf8', link: '/revenue-cockpit' },
|
||||
open_steps: { label: 'Open stappen', sub: 'opvolging nodig', icon: '🎯', color: '#f472b6', link: '/revenue-cockpit' },
|
||||
revenue_deals: { label: 'Actieve deals', sub: 'met marge', icon: '💼', color: '#4ade80', link: '/revenue-cockpit' },
|
||||
};
|
||||
|
||||
var DEFAULT_LAYOUT = Object.keys(WIDGET_META);
|
||||
var DEFAULT_KPIS = ['pipeline', 'clients_active', 'crm_partnerships', 'supermarkets', 'trending_food', 'pending_approvals'];
|
||||
var DEFAULT_LAYOUT = ['kpis', 'executive', 'analytics', 'briefing', 'news', 'approvals', 'feed'];
|
||||
var CEO_LAYOUT = ['kpis', 'executive', 'analytics', 'briefing', 'news'];
|
||||
var DEFAULT_KPIS = ['margin_month', 'margin_year', 'open_steps', 'revenue_deals', 'crm_partnerships', 'supermarkets'];
|
||||
var CEO_KPIS = ['margin_month', 'margin_year', 'open_steps', 'revenue_deals', 'crm_partnerships', 'supermarkets'];
|
||||
|
||||
function loadPrefs() {
|
||||
return fetch('/api/preferences/ui').then(function (r) { return r.json(); }).catch(function () {
|
||||
@@ -73,21 +79,42 @@
|
||||
return savePrefs(patch);
|
||||
}
|
||||
|
||||
function ceoKpis(prefs) {
|
||||
var k = (prefs && prefs.dashboard_kpis) || [];
|
||||
if (!k.length || k.indexOf('margin_month') < 0) return CEO_KPIS.slice();
|
||||
// ensure core revenue KPIs present without dropping user extras
|
||||
var need = ['margin_month', 'open_steps', 'revenue_deals'];
|
||||
need.forEach(function (id) {
|
||||
if (k.indexOf(id) < 0) k = [id].concat(k);
|
||||
});
|
||||
return k.slice(0, 6);
|
||||
}
|
||||
|
||||
function visibleLayout(prefs) {
|
||||
var layout = prefs.dashboard_layout || DEFAULT_LAYOUT.slice();
|
||||
var widgets = prefs.dashboard_widgets || defaultWidgets();
|
||||
return layout.filter(function (id) { return widgets[id] !== false; });
|
||||
var rest = (prefs.dashboard_layout || DEFAULT_LAYOUT.slice()).filter(function (id) {
|
||||
return CEO_LAYOUT.indexOf(id) < 0 && widgets[id] !== false;
|
||||
});
|
||||
var top = CEO_LAYOUT.filter(function (id) { return widgets[id] !== false; });
|
||||
return top.concat(rest);
|
||||
}
|
||||
|
||||
function applyOrder(container, order) {
|
||||
if (!container) return;
|
||||
var map = {};
|
||||
var leftovers = [];
|
||||
Array.from(container.children).forEach(function (el) {
|
||||
if (el.dataset && el.dataset.widget) map[el.dataset.widget] = el;
|
||||
else leftovers.push(el);
|
||||
});
|
||||
order.forEach(function (id) {
|
||||
if (map[id]) container.appendChild(map[id]);
|
||||
var seen = {};
|
||||
(order || []).forEach(function (id) {
|
||||
if (map[id]) { container.appendChild(map[id]); seen[id] = true; }
|
||||
});
|
||||
Object.keys(map).forEach(function (id) {
|
||||
if (!seen[id]) container.appendChild(map[id]);
|
||||
});
|
||||
leftovers.forEach(function (el) { container.appendChild(el); });
|
||||
}
|
||||
|
||||
function applyVisibility(container, widgets) {
|
||||
@@ -257,12 +284,15 @@
|
||||
WIDGET_META: WIDGET_META,
|
||||
KPI_META: KPI_META,
|
||||
DEFAULT_KPIS: DEFAULT_KPIS,
|
||||
CEO_KPIS: CEO_KPIS,
|
||||
ceoKpis: ceoKpis,
|
||||
loadPrefs: loadPrefs,
|
||||
saveLayout: saveLayout,
|
||||
saveViz: saveViz,
|
||||
savePrefs: savePrefs,
|
||||
saveDashboardConfig: saveDashboardConfig,
|
||||
visibleLayout: visibleLayout,
|
||||
CEO_LAYOUT: CEO_LAYOUT,
|
||||
applyOrder: applyOrder,
|
||||
applyVisibility: applyVisibility,
|
||||
initDrag: initDrag,
|
||||
|
||||
Reference in New Issue
Block a user