SysOps: approved_backup — 2026-08-16 11:01 UTC
This commit is contained in:
@@ -3,7 +3,9 @@ function revenueCockpit() {
|
||||
loading: false,
|
||||
saving: false,
|
||||
savedAt: '',
|
||||
_pollStop: null,
|
||||
viewMode: 'cockpit',
|
||||
visualMode: 'table',
|
||||
goals: { vision_text: '', horizon_text: '', mid_text: '', tagline: '' },
|
||||
projects: [],
|
||||
dbProjects: [],
|
||||
@@ -44,8 +46,20 @@ function revenueCockpit() {
|
||||
|
||||
async init() {
|
||||
localStorage.setItem('foodlinkk-persona', 'ceo');
|
||||
const saved = localStorage.getItem('rc-visual-mode');
|
||||
if (saved === 'table' || saved === 'bars' || saved === 'cards') {
|
||||
this.visualMode = saved;
|
||||
} else if (window.matchMedia('(max-width: 768px)').matches) {
|
||||
this.visualMode = 'cards';
|
||||
}
|
||||
await this.loadLive();
|
||||
await this.loadDbQuiet();
|
||||
if (window.CockpitLive) {
|
||||
this._pollStop = CockpitLive.startPolling(async () => {
|
||||
await this.loadLive();
|
||||
await this.loadDbQuiet();
|
||||
}, 45000);
|
||||
}
|
||||
},
|
||||
|
||||
projectKey(p) {
|
||||
@@ -119,6 +133,53 @@ function revenueCockpit() {
|
||||
return t.length <= n ? t : t.slice(0, n).trim() + '…';
|
||||
},
|
||||
|
||||
|
||||
setVisualMode(mode) {
|
||||
if (mode !== 'table' && mode !== 'bars' && mode !== 'cards') return;
|
||||
this.visualMode = mode;
|
||||
localStorage.setItem('rc-visual-mode', mode);
|
||||
},
|
||||
|
||||
styleLabel(style) {
|
||||
const map = { green: 'Live', red: 'Inactief', orange: 'Oranje', yellow: 'Strategisch', blue: 'Blauw', white: 'Neutraal' };
|
||||
return map[style] || 'Neutraal';
|
||||
},
|
||||
|
||||
rankedRows() {
|
||||
const rows = this.visualRows().slice();
|
||||
rows.sort((a, b) => (Number(b.margin_month) || 0) - (Number(a.margin_month) || 0));
|
||||
return rows;
|
||||
},
|
||||
|
||||
cardRows() {
|
||||
return this.rankedRows().filter((r) => r.margin_month != null || (r.next_steps || '').trim());
|
||||
},
|
||||
|
||||
async setCockpitStyle(style) {
|
||||
const p = this.selectedProject;
|
||||
if (!p) return;
|
||||
if (!p.db_id) {
|
||||
p.row_style = style;
|
||||
if (window.Cockpit) Cockpit.toast('Lokaal gezet — sync DB om te bewaren', 'info');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await fetch('/api/revenue-cockpit/projects/' + p.db_id, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ row_style: style }),
|
||||
});
|
||||
p.row_style = style;
|
||||
const pi = this.projects.findIndex((x) => this.projectKey(x) === this.projectKey(p));
|
||||
if (pi >= 0) this.projects[pi].row_style = style;
|
||||
const di = this.dbProjects.findIndex((x) => x.id === p.db_id);
|
||||
if (di >= 0) this.dbProjects[di].row_style = style;
|
||||
if (window.Cockpit) Cockpit.toast('Status → ' + this.styleLabel(style), 'success');
|
||||
} catch (e) {
|
||||
if (window.Cockpit) Cockpit.toast('Kleur wijzigen mislukt', 'error');
|
||||
}
|
||||
},
|
||||
|
||||
styleColor(style) {
|
||||
const map = {
|
||||
green: '#22c55e', red: '#ef4444', orange: '#f59e0b',
|
||||
@@ -167,7 +228,7 @@ function revenueCockpit() {
|
||||
donutStyle(p) {
|
||||
const pct = this.sharePct(p);
|
||||
const color = this.styleColor(p.row_style);
|
||||
return 'background:conic-gradient(' + color + ' 0% ' + pct + '%, rgba(148,163,184,0.15) ' + pct + '% 100%)';
|
||||
return 'background:conic-gradient(' + color + ' 0% ' + pct + '%, #2d3748 ' + pct + '% 100%)';
|
||||
},
|
||||
|
||||
toggleExpand(p) {
|
||||
|
||||
Reference in New Issue
Block a user