2 lines
3.0 KiB
JavaScript
2 lines
3.0 KiB
JavaScript
frappe.pages["makap-health"].on_page_load=function(w){const p=frappe.ui.make_app_page({parent:w,title:"Workflow Health Dashboard",single_column:true});p.main.html(`<section class="makap-gov-shell health"><header class="makap-gov-head"><div><div class="makap-gov-eyebrow">End-to-end workflow audit</div><h1>Workflow Health Dashboard</h1><p>Audit the full MAKAP chain from customer demand to operating close-out and surface records that need attention.</p></div><button class="btn btn-default btn-sm" data-r><i class="fa fa-refresh"></i> Refresh</button></header><section class="makap-gov-metrics"><div><span>Workflow stages</span><strong data-m="stages">—</strong><small>Configured DocTypes</small></div><div class="good"><span>Available stages</span><strong data-m="available">—</strong><small>Installed and visible</small></div><div class="warn"><span>Health issues</span><strong data-m="issues">—</strong><small>Records requiring attention</small></div><div><span>Audited records</span><strong data-m="records">—</strong><small>Across the workflow</small></div></section><div class="makap-health-grid"><section><div class="health-title">Workflow chain</div><div data-chain class="makap-chain"></div></section><section><div class="health-title">Issues requiring attention</div><div data-issues class="makap-issues"></div></section></div></section>`);const r=p.main[0],chain=r.querySelector("[data-chain]"),issues=r.querySelector("[data-issues]");const esc=v=>frappe.utils.escape_html(String(v==null?"":v)),num=v=>new Intl.NumberFormat().format(Number(v||0)),call=(m,a={})=>new Promise((ok,no)=>frappe.call({method:m,args:a,callback:x=>x.exc?no(x.exc):ok(x.message)}));async function load(){chain.innerHTML=`<div class="makap-gov-empty"><div class="load-ring"></div><span>Auditing workflow...</span></div>`;try{const x=await call("makap_backend.governance_api.get_workflow_health");r.querySelector('[data-m="stages"]').textContent=num(x.workflow.length);r.querySelector('[data-m="available"]').textContent=num(x.workflow.filter(a=>a.available).length);r.querySelector('[data-m="issues"]').textContent=num(x.issue_count);r.querySelector('[data-m="records"]').textContent=num(x.workflow.reduce((a,b)=>a+(b.count||0),0));chain.innerHTML=x.workflow.map((a,i)=>`<a class="chain-step ${a.available?"available":"missing"}" href="${a.route}"><span>${i+1}</span><strong>${esc(a.label)}</strong><small>${a.available?`${num(a.count)} records`:"DocType missing"}</small></a>`).join("");issues.innerHTML=x.issues.length?x.issues.map(a=>`<a class="health-issue" href="/app/${a.type.toLowerCase().replaceAll(" ","-")}/${encodeURIComponent(a.name)}"><b>${esc(a.type)}</b><strong>${esc(a.name)}</strong><span>${esc(a.issue)} · ${esc(a.detail)}</span></a>`).join(""):`<div class="makap-gov-empty"><strong>No workflow issues found</strong><span>The audited workflow is healthy for the available checks.</span></div>`}catch(e){issues.innerHTML=`<div class="makap-gov-empty"><strong>Workflow audit unavailable</strong><span>${esc(e.message||"Check permissions.")}</span></div>`}}r.querySelector("[data-r]").onclick=load;load()};
|