diff --git a/apps/web/app.js b/apps/web/app.js index 545b6fb..897fac2 100644 --- a/apps/web/app.js +++ b/apps/web/app.js @@ -240,6 +240,7 @@ function renderReport(id,title,payload){const el=$(id);if(!el)return;const rows=reportRows(payload);const obj=payload?.summary||payload?.counts||payload||{};const fallback=Object.entries(obj).filter(([,v])=>typeof v==='number').slice(0,8);const entries=rows.length?rows.map(r=>[r.label||r.name||r.stage||r.outcome||r.type||'Metric',r.count??r.total??r.value??0]):fallback;if(!entries.length){el.innerHTML=`

${title}

No ${title.toLowerCase()} data returned.

`;return;}el.innerHTML=`

REPORT

${title}

API summary
${entries.map(([label,value])=>`
${esc(crmLabel(label))}${esc(value)}
`).join('')}

Tenant-scoped API results. Loading, unavailable, and empty are distinct states.

`;} async function loadReports(){[['pipelineReport','pipeline report'],['outcomesReport','outcomes report'],['activityReport','activity report']].forEach(([id,title])=>{const el=$(id);if(el)el.innerHTML=`
Loading ${title}…
`;});try{const [pipeline,outcomes,activity]=await Promise.all([jsonRequest('/api/v1/reports/pipeline'),jsonRequest('/api/v1/reports/outcomes'),jsonRequest('/api/v1/reports/activity')]);renderReport('pipelineReport','Pipeline',pipeline);renderReport('outcomesReport','Outcomes',outcomes);renderReport('activityReport','Activity',activity);}catch(error){if(error.message!=='unauthorized')[['pipelineReport','pipeline'],['outcomesReport','outcomes'],['activityReport','activity']].forEach(([id,label])=>{const el=$(id);if(el)el.innerHTML=``;});}} + let jobs = [], selectedJobId = null, jobPollTimer = null; const jobStatuses = ['queued','running','succeeded','failed','cancelled']; const jobRole = () => String(currentUser?.role || currentUser?.roles?.[0] || '').toLowerCase(); const canManageJobs = () => ['admin','owner','operator','manager'].includes(jobRole()) || Boolean(currentUser?.permissions?.includes?.('jobs:manage')); diff --git a/apps/web/asset-manifest.json b/apps/web/asset-manifest.json index 3bc9f64..a9470cb 100644 --- a/apps/web/asset-manifest.json +++ b/apps/web/asset-manifest.json @@ -13,10 +13,10 @@ "healthz" ], "integrity": { - "config.js": "sha256-6d49ab0825feb44111d960cd8d676e005c4f1a06271265277c0d00458236a441", - "app.js": "sha256-450c2041d7a87465e5471e5b96faf9d3c27e973d49cbc9a5bdc19fd42a3ec339", + "config.js": "sha256-26e69a9af2abda4ac16d5b7c7eed5d69ad578c7f386af5fa62b42475a7318ea6", + "app.js": "sha256-7a2a8c1275f97d4485a2c833cbdb205ac163c5b7f4a52c131484fabfa6a6e29d", "styles.css": "sha256-c1b192a15de735819fbb7ec3cddc9574808ae366a8255b4f690a7a40bc21caba", - "index.html": "sha256-b8665be623e6e093e9a2d7532276289ebaeaaa0a905263ac3bbd9a3c595f4120", + "index.html": "sha256-83f010d3c68cef9b1f3a5ae8a50960156b52ef342944ef906804266e76220227", "health.html": "sha256-c352a6f37aa24628cfc8d5709a70ff2d94181d192ed5fe00916cca9378a61d81", "error.html": "sha256-f3cc28d2dfc9e8af112d0257c6ee47b9e9146e5da8590a754dd589bf43702aaf", "healthz": "sha256-dc51b8c96c2d745df3bd5590d990230a482fd247123599548e0632fdbf97fc22" diff --git a/apps/web/config.js b/apps/web/config.js index 650f905..4a34c4a 100644 --- a/apps/web/config.js +++ b/apps/web/config.js @@ -1,5 +1,5 @@ /* Public, non-secret runtime configuration. Replace this file at deploy time if needed. */ window.__PROSPECT_CONFIG__ = Object.freeze({ apiBase: '', - assetVersion: 'phase-36' + assetVersion: 'phase-40' }); diff --git a/apps/web/index.html b/apps/web/index.html index 978533e..01bae53 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -135,7 +135,7 @@ - - + +