@object-ui/plugin-report 16.1.0 → 17.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,5 +55,5 @@ ${e.description?`<p class="description">${w(e.description)}</p>`:``}
55
55
  </body>
56
56
  </html>`),o.document.close(),o.onload=()=>{o.print()}}function S(e,t,n){let r=e.fields||[],i=r.map(e=>e.label||e.name),a=t.map(e=>r.map(t=>{let n=e[t.name];return n=T(n),typeof n==`string`&&(n.includes(`,`)||n.includes(`"`)||n.includes(`
57
57
  `)||n.includes(` `))?`"${n.replace(/"/g,`""`)}"`:n??``}));O(``+[...n?.includeHeaders===!1?[]:[i.join(` `)],...a.map(e=>e.join(` `))].join(`
58
- `),n?.filename||`${e.title||`report`}.tsv`,`text/tab-separated-values`)}function C(e,t,n,r){switch(e){case`csv`:v(t,n,r);break;case`json`:y(t,n,r);break;case`html`:b(t,n,r);break;case`pdf`:x(t,n,r);break;case`excel`:S(t,n,r);break;default:console.warn(`Unsupported export format: ${e}`)}}function w(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`)}function T(e){if(typeof e==`string`&&e.length>0){let t=e.charAt(0);if(t===`=`||t===`+`||t===`-`||t===`@`||t===`|`)return`\t${e}`}return e}function E(e){return[`A4`,`A3`,`Letter`,`Legal`].includes(e||``)?e:`A4`}function D(e){return e===`landscape`?`landscape`:`portrait`}function O(e,t,n){let r=new Blob([e],{type:`${n};charset=utf-8`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}function k(e,t){if(e==null||e===``)return``;let n=t?.type,r=t?.format;if(n===`date`||r===`date`||A(e))return j(e);if(n===`number`||typeof e==`number`){let t=typeof e==`number`?e:Number(e);return isNaN(t)?String(e):r===`currency`||r===`currency_cny`?`¥${t.toLocaleString(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0})}`:r===`currency_usd`?`$${t.toLocaleString(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0})}`:r===`percent`?`${t.toLocaleString(`en-US`,{minimumFractionDigits:1,maximumFractionDigits:1})}%`:t.toLocaleString(`en-US`)}return String(e)}function A(e){return typeof e==`string`&&/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/.test(e)}function j(e){try{let t=new Date(e);return isNaN(t.getTime())?String(e):`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}catch{return String(e)}}function M(e,t){if(!t||t.length===0||!e||e.length===0)return null;let n=t[0],r=n.field,i=new Map;for(let t of e){let e=String(t[r]??`(empty)`);i.has(e)||i.set(e,[]),i.get(e).push(t)}let a=[];for(let[e,t]of i)a.push({key:e,label:`${n.label||r}: ${e}`,rows:t});let o=n.sort===`desc`?-1:1;return a.sort((e,t)=>e.key.localeCompare(t.key)*o),a}var N=({schema:e,onRefresh:r})=>{let{report:l,data:u,showToolbar:d=!0,allowExport:f=!0,allowPrint:p=!0,loading:m=!1}=e,h=e=>{if(!l){console.warn(`ReportViewer: Cannot export, no report defined`);return}C(e,l,u||[],l.exportConfigs?.[e])},g=()=>{window.print()},_=()=>{r?.()},v=(e,t)=>{if(!u)return 0;let n=u.map(t=>Number(t[e])||0);switch(t){case`count`:return u.length;case`sum`:return n.reduce((e,t)=>e+t,0);case`avg`:return n.length>0?(n.reduce((e,t)=>e+t,0)/n.length).toFixed(2):0;case`min`:return n.length>0?Math.min(...n):0;case`max`:return n.length>0?Math.max(...n):0;default:return``}},y=(e,t)=>{let n=l?.conditionalFormatting;if(!(!n||!Array.isArray(n)))for(let r of n){if(r.field!==e)continue;let n=String(t??``),i=String(r.value??``),a=!1;switch(r.operator){case`equals`:a=n===i;break;case`not_equals`:a=n!==i;break;case`contains`:a=n.includes(i);break;case`greater_than`:a=Number(t)>Number(r.value);break;case`less_than`:a=Number(t)<Number(r.value);break}if(a){let e={};return r.backgroundColor&&(e.backgroundColor=r.backgroundColor),r.textColor&&(e.color=r.textColor),e}}},b=(e,t)=>{if(e==null||e===``)return``;if(t.renderAs===`badge`&&(!t.type||t.type===`string`||t.type===`text`))return(0,o.jsx)(a.Badge,{className:t.colorMap?.[String(e)]||``,children:String(e)});if(t.aggregation)return k(e,t);if(t.type){let n={...t};return t.colorMap&&!n.options&&(n.options=Object.entries(t.colorMap).map(([e,t])=>({value:e,label:e,color:t}))),(0,o.jsx)((0,c.getCellRenderer)((0,c.resolveCellRendererType)(n)),{value:e,field:n})}return k(e,t)};return l?(0,o.jsxs)(`div`,{className:`space-y-4`,children:[d&&(0,o.jsxs)(`div`,{className:`flex items-center justify-between gap-2 p-4 bg-card rounded-lg border`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h2`,{className:`text-lg font-semibold`,children:l.title}),l.description&&(0,o.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:l.description})]}),(0,o.jsxs)(`div`,{className:`flex items-center gap-2`,children:[l.refreshInterval&&(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:_,children:[(0,o.jsx)(s.RefreshCw,{className:`h-4 w-4 mr-2`}),`Refresh`]}),p&&(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:g,children:[(0,o.jsx)(s.Printer,{className:`h-4 w-4 mr-2`}),`Print`]}),f&&l.showExportButtons&&(0,o.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>h(`pdf`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`PDF`]}),(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>h(`excel`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`Excel`]}),(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>h(`csv`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`CSV`]})]})]})]}),(0,o.jsxs)(a.Card,{children:[(0,o.jsxs)(a.CardHeader,{children:[!d&&l.title&&(0,o.jsx)(a.CardTitle,{children:l.title}),!d&&l.description&&(0,o.jsx)(a.CardDescription,{children:l.description})]}),(0,o.jsxs)(a.CardContent,{className:`space-y-6`,children:[m&&(0,o.jsxs)(`div`,{className:`space-y-6`,children:[(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-4`,children:[1,2,3].map(e=>(0,o.jsx)(a.Card,{children:(0,o.jsxs)(a.CardContent,{className:`p-4 space-y-2`,children:[(0,o.jsx)(a.Skeleton,{className:`h-4 w-20`}),(0,o.jsx)(a.Skeleton,{className:`h-8 w-28`})]})},e))}),(0,o.jsxs)(`div`,{className:`space-y-2`,children:[(0,o.jsx)(a.Skeleton,{className:`h-10 w-full`}),[1,2,3,4,5].map(e=>(0,o.jsx)(a.Skeleton,{className:`h-8 w-full`},e))]})]}),!m&&l.sections?.map((e,r)=>e.visible===!1?null:(0,o.jsxs)(`div`,{className:`space-y-2`,children:[e.title&&e.type!==`header`&&(0,o.jsx)(`h3`,{className:`text-lg font-semibold border-b pb-2`,children:e.title}),e.type===`header`&&e.title&&(0,o.jsx)(`div`,{className:`text-2xl font-bold py-4`,children:e.title}),e.type===`summary`&&(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-4`,children:l.fields?.filter(e=>e.showInSummary).map((e,t)=>(0,o.jsx)(a.Card,{children:(0,o.jsxs)(a.CardContent,{className:`p-4`,children:[(0,o.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:e.label||e.name}),(0,o.jsx)(`div`,{className:`text-2xl font-bold`,children:k(v(e.name,e.aggregation),e)})]})},t))}),e.type===`chart`&&e.chart&&(0,o.jsx)(`div`,{className:`min-h-[300px]`,children:(()=>{let n=e.chart.type,r=!!e.chart.chartType;!n&&r&&(n=`chart`),n&&t.ComponentRegistry.get(n)||(n=`chart`);let a=n===`chart`?{xAxisKey:e.chart.xAxisKey||e.chart.xAxisField||`name`,series:e.chart.series||(e.chart.yAxisFields?e.chart.yAxisFields.map(e=>({dataKey:e})):[]),chartType:e.chart.chartType||`bar`}:{};return(0,o.jsx)(i.SchemaRenderer,{schema:{...e.chart,type:n,...a,data:u||e.chart.data,className:e.chart.className||`w-full h-[350px]`}})})()}),e.type===`table`&&(0,o.jsx)(`div`,{className:`border rounded-lg overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-sm min-w-[600px]`,children:[(0,o.jsx)(`thead`,{className:`bg-muted`,children:(0,o.jsx)(`tr`,{children:e.columns?.map((e,t)=>(0,o.jsx)(`th`,{className:`px-4 py-2 font-medium ${e.type===`number`?`text-right`:`text-left`}`,children:e.label||e.name},t))})}),(0,o.jsx)(`tbody`,{children:(()=>{let t=M(u||[],l.groupBy||[]);return t?t.map(t=>(0,o.jsxs)(n.default.Fragment,{children:[(0,o.jsx)(`tr`,{className:`bg-muted/60`,children:(0,o.jsxs)(`td`,{colSpan:e.columns?.length||1,className:`px-4 py-2 font-semibold text-sm`,children:[t.label,` (`,t.rows.length,`)`]})}),t.rows.map((t,n)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:e.columns?.map((e,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${e.type===`number`?`text-right tabular-nums`:``}`,style:y(e.name,t[e.name]),children:b(t[e.name],e)},n))},n))]},t.key)):u?.map((t,n)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:e.columns?.map((e,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${e.type===`number`?`text-right tabular-nums`:``}`,style:y(e.name,t[e.name]),children:b(t[e.name],e)},n))},n))})()})]})}),e.type===`text`&&e.text&&(0,o.jsx)(`div`,{className:`prose max-w-none`,children:(0,o.jsx)(`p`,{children:e.text})}),e.type===`page-break`&&(0,o.jsx)(`div`,{className:`border-t-2 border-dashed my-8 print:page-break-after-always`}),e.content&&(0,o.jsx)(i.SchemaRenderer,{schema:e.content})]},r)),!l.sections&&u&&u.length>0&&(0,o.jsx)(`div`,{className:`border rounded-lg overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-sm min-w-[600px]`,children:[(0,o.jsx)(`thead`,{className:`bg-muted`,children:(0,o.jsx)(`tr`,{children:l.fields?.map((e,t)=>(0,o.jsx)(`th`,{className:`px-4 py-2 font-medium ${e.type===`number`?`text-right`:`text-left`}`,children:e.label||e.name},t))})}),(0,o.jsx)(`tbody`,{children:u.map((e,t)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:l.fields?.map((t,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${t.type===`number`?`text-right tabular-nums`:``}`,style:y(t.name,e[t.name]),children:b(e[t.name],t)},n))},t))})]})})]})]})]}):(0,o.jsx)(a.Card,{children:(0,o.jsx)(a.CardContent,{className:`p-8 text-center text-muted-foreground`,children:`No report to display`})})};function P(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.dataset==`string`&&t.dataset.length>0||t.type===`joined`&&Array.isArray(t.blocks)&&t.blocks.some(e=>typeof e?.dataset==`string`)}function F(e,t){return e?typeof e==`string`?e:typeof e==`object`&&typeof e.default==`string`?e.default:t:t}function I(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&!!e):[]}function L(e,t,r,i,a,o){let[s,c]=n.useState({status:`idle`,rows:[]}),l=JSON.stringify(i??null),u=JSON.stringify(o??null),d=`${e}|${t.join(`,`)}|${r.join(`,`)}|${l}|${u}`;return n.useEffect(()=>{let n=a;if(!n||typeof n.queryDataset!=`function`){c({status:`error`,rows:[],error:`This data source does not support dataset queries.`});return}if(!e||r.length===0){c({status:`idle`,rows:[]});return}let s=!1;return c({status:`loading`,rows:[]}),n.queryDataset(e,{dimensions:t,measures:r,...i&&Object.keys(i).length>0?{runtimeFilter:i}:{},...o?{totals:{groupings:o}}:{}}).then(e=>{s||c({status:`ok`,rows:Array.isArray(e?.rows)?e.rows:[],fields:Array.isArray(e?.fields)?e.fields:[],object:e?.object,dimensionFields:e?.dimensionFields,drillRawRows:Array.isArray(e?.drillRawRows)?e.drillRawRows:void 0,drillRanges:Array.isArray(e?.drillRanges)?e.drillRanges:void 0,totals:Array.isArray(e?.totals)?e.totals:void 0})}).catch(e=>{s||c({status:`error`,rows:[],error:String(e?.message??e)})}),()=>{s=!0}},[d]),s}function R({dataset:e}){return(0,o.jsxs)(`div`,{className:`flex items-center justify-center rounded-md border border-dashed bg-muted/20 p-4 text-xs text-muted-foreground`,children:[`This report binds the “`,e,`” dataset — choose at least one measure (values) to render.`]})}function z({status:e,error:t}){return e===`error`?(0,o.jsxs)(`div`,{role:`alert`,className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive`,children:[(0,o.jsx)(s.AlertTriangle,{className:`h-3.5 w-3.5 mt-0.5 shrink-0`}),(0,o.jsx)(`span`,{className:`break-words`,children:t})]}):(0,o.jsxs)(`div`,{className:`flex items-center gap-2 p-4 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Loader2,{className:`h-4 w-4 animate-spin`}),` Running report…`]})}function B(){return(0,o.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 rounded-md border border-dashed bg-muted/20 p-6 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Table2,{className:`h-6 w-6`}),` The dataset returned no rows for this report’s scope.`]})}var V=`cursor-pointer hover:bg-accent/40`;function H({dataset:e,rows:n,values:r,runtimeFilter:i,dataSource:a,onDrill:s}){let c=L(e,n,r,i,a),{fieldLabel:u}=(0,l.useSafeFieldLabel)();if(r.length===0)return(0,o.jsx)(R,{dataset:e});if(c.status===`loading`||c.status===`idle`)return(0,o.jsx)(z,{status:c.status});if(c.status===`error`)return(0,o.jsx)(z,{status:`error`,error:c.error});if(c.rows.length===0)return(0,o.jsx)(B,{});let d=!!s&&n.length>0,f=c.dimensionFields?n.filter(e=>e in c.dimensionFields):[],p=(r,a)=>{let o={};for(let e of n)o[e]=r[e];let l=c.drillRanges?.[a],u=!!l&&Object.keys(l).length>0,d=c.object&&(f.length>0||u)?(0,t.buildDatasetDrillFilter)(c.drillRawRows?.[a],f,c.dimensionFields??{},i,l):void 0;s({dataset:e,groupKey:o,runtimeFilter:i,object:c.object,objectFilter:d})},{measureField:m,headerLabel:h}=(0,t.buildDatasetFieldHelpers)(c.fields,c.object,u),g=[...n,...r];return(0,o.jsx)(`div`,{className:`overflow-auto max-h-[70vh] rounded-md border`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{className:`bg-muted/40`,children:(0,o.jsx)(`tr`,{children:g.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium whitespace-nowrap`,children:h(e)},e))})}),(0,o.jsx)(`tbody`,{children:c.rows.map((e,n)=>(0,o.jsx)(`tr`,{className:`border-t${d?` ${V}`:``}`,"data-testid":d?`dataset-drill-row`:void 0,onClick:d?()=>p(e,n):void 0,children:g.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 tabular-nums whitespace-nowrap`,children:r.includes(n)?(0,t.formatMeasure)(e[n],m(n)?.format,m(n)?.currency):(0,t.formatDimensionValue)(e[n])},n))},n))})]})})}function U(e){switch(e){case`line`:return`line`;case`area`:return`area`;case`pie`:return`pie`;case`donut`:return`donut`;case`radar`:return`radar`;case`scatter`:return`scatter`;default:return`bar`}}function W(e){let[,r]=n.useReducer(e=>e+1,0);return n.useEffect(()=>{if(t.ComponentRegistry.get(e))return;let n=typeof t.ComponentRegistry.subscribe==`function`?t.ComponentRegistry.subscribe(()=>{t.ComponentRegistry.get(e)&&r()}):void 0,i=t.ComponentRegistry.loadLazy?.(e);return i&&typeof i.then==`function`&&i.then(()=>r()).catch(()=>{}),n},[e]),t.ComponentRegistry.get(e)}function G({dataset:e,chart:t,runtimeFilter:n,dataSource:r}){let i=typeof t.xAxis==`string`?t.xAxis:``,a=typeof t.yAxis==`string`?t.yAxis:``,c=L(e,i?[i]:[],a?[a]:[],n,r),l=W(`chart`);if(!i||!a)return null;if(c.status===`loading`||c.status===`idle`)return(0,o.jsxs)(`div`,{className:`flex items-center gap-2 p-4 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Loader2,{className:`h-4 w-4 animate-spin`}),` Loading chart…`]});if(c.status===`error`||c.rows.length===0||!l)return null;let u=typeof t.title==`string`?t.title:void 0;return(0,o.jsxs)(`div`,{className:`rounded-md border bg-card p-3`,"data-testid":`dataset-report-chart`,children:[u?(0,o.jsx)(`h3`,{className:`mb-2 text-sm font-semibold`,children:u}):null,(0,o.jsx)(l,{schema:{chartType:U(t.type),data:c.rows,xAxisKey:i,series:[{dataKey:a}],height:typeof t.height==`number`?t.height:280,isAnimationActive:!1}})]})}function K(e,t){return e.map(e=>String(t[e]??`∅`)).join(``)}function q(e,n){return e.map(e=>(0,t.formatDimensionValue)(n[e])).join(` / `)}function J({dataset:e,rows:r,columnsAcross:i,values:a,runtimeFilter:s,dataSource:c,onDrill:u}){let d=L(e,[...r,...i],a,s,c,[r,i,[]]),f=(0,l.useSafeTranslate)(),{fieldLabel:p}=(0,l.useSafeFieldLabel)(),m=n.useMemo(()=>{if(d.status!==`ok`)return null;let e=[],t=[],n=new Set,a=new Set,o=new Map;return d.rows.forEach((s,c)=>{let l=K(r,s),u=K(i,s);if(!n.has(l)){n.add(l);let t={};for(let e of r)t[e]=s[e];e.push({id:l,label:q(r,s),key:t})}if(!a.has(u)){a.add(u);let e={};for(let t of i)e[t]=s[t];t.push({id:u,label:q(i,s),key:e})}o.set(`${l} ${u}`,{row:s,index:c})}),{rowHeaders:e,colHeaders:t,cells:o}},[d,r,i]);if(a.length===0)return(0,o.jsx)(R,{dataset:e});if(d.status===`loading`||d.status===`idle`)return(0,o.jsx)(z,{status:d.status});if(d.status===`error`)return(0,o.jsx)(z,{status:`error`,error:d.error});if(!m||m.rowHeaders.length===0)return(0,o.jsx)(B,{});let{measureField:h,headerLabel:g}=(0,t.buildDatasetFieldHelpers)(d.fields,d.object,p),_=f(`report.total`,`Total`),v=!!u,y=d.dimensionFields?[...r,...i].filter(e=>e in d.dimensionFields):[],b=(n,r,i)=>{let a=d.drillRanges?.[i],o=!!a&&Object.keys(a).length>0,c=d.object&&(y.length>0||o)?(0,t.buildDatasetDrillFilter)(d.drillRawRows?.[i],y,d.dimensionFields??{},s,a):void 0;u({dataset:e,groupKey:{...n,...r},runtimeFilter:s,object:d.object,objectFilter:c})},x=m.colHeaders.flatMap(e=>a.map(t=>({col:e,measure:t,header:a.length===1?e.label:`${e.label} · ${g(t)}`}))),S=e=>d.totals?.find(t=>Array.isArray(t.dimensions)&&t.dimensions.join(`,`)===e.join(`,`))?.rows,C=new Map;for(let e of S(r)??[])C.set(K(r,e),e);let w=new Map;for(let e of S(i)??[])w.set(K(i,e),e);let T=S([])?.[0],E=C.size>0,D=w.size>0;return(0,o.jsx)(`div`,{className:`overflow-auto max-h-[70vh] rounded-md border`,"data-testid":`dataset-matrix`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{className:`bg-muted/40`,children:(0,o.jsxs)(`tr`,{children:[r.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium whitespace-nowrap`,children:g(e)},e)),x.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-right font-medium whitespace-nowrap`,children:e.header},`${e.col.id}-${e.measure}`)),E&&a.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-right font-medium whitespace-nowrap`,"data-testid":`matrix-total-col-header`,children:a.length===1?_:`${_} · ${g(e)}`},`total-${e}`))]})}),(0,o.jsxs)(`tbody`,{children:[m.rowHeaders.map(e=>(0,o.jsxs)(`tr`,{className:`border-t`,children:[r.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 whitespace-nowrap font-medium`,children:(0,t.formatDimensionValue)(e.key[n])},n)),x.map(n=>{let r=m.cells.get(`${e.id} ${n.col.id}`),i=r?.row[n.measure],a=v&&r!=null;return(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap${a?` ${V}`:``}`,"data-testid":a?`dataset-drill-cell`:void 0,onClick:a?()=>b(e.key,n.col.key,r.index):void 0,children:(0,t.formatMeasure)(i,h(n.measure)?.format,h(n.measure)?.currency)},`${n.col.id}-${n.measure}`)}),E&&a.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap font-medium`,"data-testid":`matrix-row-total`,children:(0,t.formatMeasure)(C.get(e.id)?.[n],h(n)?.format,h(n)?.currency)},`total-${n}`))]},e.id)),D&&(0,o.jsxs)(`tr`,{className:`border-t bg-muted/30 font-medium`,"data-testid":`matrix-total-row`,children:[r.length>0&&(0,o.jsx)(`td`,{colSpan:r.length,className:`px-2 py-1 whitespace-nowrap`,children:_}),x.map(e=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap`,children:(0,t.formatMeasure)(w.get(e.col.id)?.[e.measure],h(e.measure)?.format,h(e.measure)?.currency)},`${e.col.id}-${e.measure}`)),E&&a.map(e=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap`,"data-testid":`matrix-grand-total`,children:(0,t.formatMeasure)(T?.[e],h(e)?.format,h(e)?.currency)},`grand-${e}`))]})]})]})})}var Y=({report:e,dataSource:n,runtimeFilter:r,onDrill:i,className:a})=>{let s=(0,t.mergeFilters)(e.runtimeFilter??e.filter,r),c=e.drilldown===!1?void 0:i;if(e.type===`joined`&&Array.isArray(e.blocks))return(0,o.jsx)(`div`,{className:a,"data-testid":`dataset-joined-report`,"data-report-name":e.name,style:{display:`flex`,flexDirection:`column`,gap:24},children:e.blocks.map((e,r)=>{let i=(0,t.mergeFilters)(s,e.runtimeFilter??e.filter),a=I(e.columns),l=e.type===`matrix`&&a.length>0?(0,o.jsx)(J,{dataset:String(e.dataset??``),rows:I(e.rows),columnsAcross:a,values:I(e.values),runtimeFilter:i,dataSource:n,onDrill:c}):(0,o.jsx)(H,{dataset:String(e.dataset??``),rows:I(e.rows),values:I(e.values),runtimeFilter:i,dataSource:n,onDrill:c});return(0,o.jsxs)(`section`,{"data-testid":`dataset-report-block`,"data-block-id":e.name??`block-${r}`,className:`flex flex-col gap-2 rounded-lg border bg-card p-4`,children:[(0,o.jsxs)(`header`,{className:`flex flex-col gap-0.5`,children:[(0,o.jsx)(`h3`,{className:`text-sm font-semibold`,children:F(e.label,e.name??`Block ${r+1}`)}),e.description?(0,o.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:F(e.description,``)}):null]}),l]},e.name??`block-${r}`)})});let l=I(e.columns);if(e.type===`matrix`&&l.length>0)return(0,o.jsx)(`div`,{className:a,"data-testid":`dataset-report`,"data-report-name":e.name,children:(0,o.jsx)(J,{dataset:String(e.dataset??``),rows:I(e.rows),columnsAcross:l,values:I(e.values),runtimeFilter:s,dataSource:n,onDrill:c})});let u=e.chart&&typeof e.chart==`object`&&e.chart.type?e.chart:null;return(0,o.jsxs)(`div`,{className:`${a??``} flex flex-col gap-3`,"data-testid":`dataset-report`,"data-report-name":e.name,children:[u?(0,o.jsx)(G,{dataset:String(e.dataset??``),chart:u,runtimeFilter:s,dataSource:n}):null,(0,o.jsx)(H,{dataset:String(e.dataset??``),rows:I(e.rows),values:I(e.values),runtimeFilter:s,dataSource:n,onDrill:c})]})},X=e=>{let{dataSource:t,rows:a,runtimeFilter:s,onDrill:c,className:l}=e,u=n.useContext(i.SchemaRendererContext),d=t??u?.dataSource,f=e.schema;return f&&typeof f==`object`&&f.type===`spec-report`&&f.report&&typeof f.report==`object`&&(f=f.report),P(f)?(0,o.jsx)(Y,{report:f,dataSource:d,runtimeFilter:s,onDrill:c,className:l}):(0,r.isSpecReport)(f)?(0,o.jsx)(`div`,{className:l,"data-testid":`report-presentation-bridge`,children:(0,o.jsx)(N,{schema:{type:`report-viewer`,report:(0,r.specReportToPresentation)(f),data:a??[],showToolbar:!1}})}):(0,o.jsx)(_,{schema:f})};async function Z(e,t){let{dataSource:n,resource:r,queryParams:i,format:a,exportConfig:o}=t,s=a||e.defaultExportFormat||`pdf`;try{let t=(await n.find(r,i)).data||[];return C(s,e,t,{format:s,...e.exportConfigs?.[s],...o}),{success:!0,recordCount:t.length,format:s}}catch(e){return{success:!1,recordCount:0,format:s,error:e.message}}}function Q(e,t,n={}){let{columns:r,filename:i,includeAggregationRow:a=!1}=n,o=r||(e.fields||[]).map(ee),s=o.map(e=>e.header),c=t.map((e,t)=>o.map(n=>{if(n.formula)return n.formula.replace(/\{ROW\}/g,String(t+2));let r=e[n.name];return te(r,n.numberFormat)}));if(a&&t.length>0){let n=o.map((n,r)=>{let i=(e.fields||[]).find(e=>e.name===n.name);if(i?.aggregation){let e=re(r),n=t.length+1;switch(i.aggregation){case`sum`:return`=SUM(${e}2:${e}${n})`;case`avg`:return`=AVERAGE(${e}2:${e}${n})`;case`count`:return`=COUNTA(${e}2:${e}${n})`;case`min`:return`=MIN(${e}2:${e}${n})`;case`max`:return`=MAX(${e}2:${e}${n})`;default:return``}}return``});c.push(n)}ae(``+[s.join(` `),...c.map(e=>e.join(` `))].join(`
59
- `),i||`${e.title||`report`}.tsv`,`text/tab-separated-values`)}function $(e,t,n,r){return async()=>{let i=e.schedule;if(!i?.enabled)return[];let a=i.formats||[e.defaultExportFormat||`pdf`],o=[];for(let r of a){let i=await Z(e,{dataSource:t,resource:n,format:r});o.push(i)}return r(e,i),o}}function ee(e){return{name:e.name,header:e.label||e.name}}function te(e,t){return e==null?``:typeof e==`number`&&t?e.toLocaleString(`en-US`,ne(t)):ie(String(e))}function ne(e){if(e.includes(`%`))return{style:`percent`,minimumFractionDigits:0};let t=(e.match(/0/g)||[]).length;return{minimumFractionDigits:Math.max(0,t-1),maximumFractionDigits:Math.max(0,t-1)}}function re(e){let t=``,n=e;for(;n>=0;)t=String.fromCharCode(n%26+65)+t,n=Math.floor(n/26)-1;return t}function ie(e){if(e.length>0){let t=e.charAt(0);if(t===`=`||t===`+`||t===`-`||t===`@`||t===`|`)return`'${e}`}return e}function ae(e,t,n){let r=new Blob([e],{type:`${n};charset=utf-8`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}t.ComponentRegistry.register(`report`,X,{namespace:`report`,label:`Report`,category:`Report`,inputs:[{name:`title`,type:`string`,label:`Title`},{name:`description`,type:`string`,label:`Description`},{name:`chart`,type:`code`,label:`Chart Configuration`}]}),t.ComponentRegistry.register(`spec-report`,X,{namespace:`report`,label:`Spec Report`,category:`Report`,inputs:[{name:`dataset`,type:`string`,label:`Dataset`},{name:`type`,type:`string`,label:`Report Type`}]}),t.ComponentRegistry.register(`report-viewer`,N,{namespace:`report`,label:`Report Viewer`,category:`Report`,inputs:[{name:`report`,type:`code`,label:`Report Definition`},{name:`showToolbar`,type:`boolean`,label:`Show Toolbar`}]}),e.DatasetReportRenderer=Y,e.LegacyReportRenderer=_,e.ReportRenderer=X,e.ReportViewer=N,e.createScheduleTrigger=$,e.exportAsCSV=v,e.exportAsExcel=S,e.exportAsHTML=b,e.exportAsJSON=y,e.exportAsPDF=x,e.exportExcelWithFormulas=Q,e.exportReport=C,e.exportWithLiveData=Z,e.formatValue=k,e.isDatasetReport=P,Object.defineProperty(e,"mergeFilters",{enumerable:!0,get:function(){return t.mergeFilters}})});
58
+ `),n?.filename||`${e.title||`report`}.tsv`,`text/tab-separated-values`)}function C(e,t,n,r){switch(e){case`csv`:v(t,n,r);break;case`json`:y(t,n,r);break;case`html`:b(t,n,r);break;case`pdf`:x(t,n,r);break;case`excel`:S(t,n,r);break;default:console.warn(`Unsupported export format: ${e}`)}}function w(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`)}function T(e){if(typeof e==`string`&&e.length>0){let t=e.charAt(0);if(t===`=`||t===`+`||t===`-`||t===`@`||t===`|`)return`\t${e}`}return e}function E(e){return[`A4`,`A3`,`Letter`,`Legal`].includes(e||``)?e:`A4`}function D(e){return e===`landscape`?`landscape`:`portrait`}function O(e,t,n){let r=new Blob([e],{type:`${n};charset=utf-8`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}function k(e,t){if(e==null||e===``)return``;let n=t?.type,r=t?.format;if(n===`date`||r===`date`||A(e))return j(e);if(n===`number`||typeof e==`number`){let t=typeof e==`number`?e:Number(e);return isNaN(t)?String(e):r===`currency`||r===`currency_cny`?`¥${t.toLocaleString(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0})}`:r===`currency_usd`?`$${t.toLocaleString(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0})}`:r===`percent`?`${t.toLocaleString(`en-US`,{minimumFractionDigits:1,maximumFractionDigits:1})}%`:t.toLocaleString(`en-US`)}return String(e)}function A(e){return typeof e==`string`&&/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/.test(e)}function j(e){try{let t=new Date(e);return isNaN(t.getTime())?String(e):`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}catch{return String(e)}}function ee(e,t){if(!t||t.length===0||!e||e.length===0)return null;let n=t[0],r=n.field,i=new Map;for(let t of e){let e=String(t[r]??`(empty)`);i.has(e)||i.set(e,[]),i.get(e).push(t)}let a=[];for(let[e,t]of i)a.push({key:e,label:`${n.label||r}: ${e}`,rows:t});let o=n.sort===`desc`?-1:1;return a.sort((e,t)=>e.key.localeCompare(t.key)*o),a}function M(e,t,n){if(!e)return 0;let r=e.map(e=>Number(e[t])||0);switch(n){case`count`:return e.length;case`sum`:return r.reduce((e,t)=>e+t,0);case`avg`:return r.length>0?(r.reduce((e,t)=>e+t,0)/r.length).toFixed(2):0;case`min`:return r.length>0?Math.min(...r):0;case`max`:return r.length>0?Math.max(...r):0;case`distinct`:return new Set(e.map(e=>e[t])).size;default:return``}}var N=({schema:e,onRefresh:t})=>{let{report:r,data:l,showToolbar:u=!0,allowExport:d=!0,allowPrint:f=!0,loading:p=!1}=e,m=e=>{if(!r){console.warn(`ReportViewer: Cannot export, no report defined`);return}C(e,r,l||[],r.exportConfigs?.[e])},h=()=>{window.print()},g=()=>{t?.()},_=(e,t)=>M(l,e,t),v=(e,t)=>{let n=r?.conditionalFormatting;if(!(!n||!Array.isArray(n)))for(let r of n){if(r.field!==e)continue;let n=String(t??``),i=String(r.value??``),a=!1;switch(r.operator){case`equals`:a=n===i;break;case`not_equals`:a=n!==i;break;case`contains`:a=n.includes(i);break;case`greater_than`:a=Number(t)>Number(r.value);break;case`less_than`:a=Number(t)<Number(r.value);break}if(a){let e={};return r.backgroundColor&&(e.backgroundColor=r.backgroundColor),r.textColor&&(e.color=r.textColor),e}}},y=(e,t)=>{if(e==null||e===``)return``;if(t.renderAs===`badge`&&(!t.type||t.type===`string`||t.type===`text`))return(0,o.jsx)(a.Badge,{className:t.colorMap?.[String(e)]||``,children:String(e)});if(t.aggregation)return k(e,t);if(t.type){let n={...t};return t.colorMap&&!n.options&&(n.options=Object.entries(t.colorMap).map(([e,t])=>({value:e,label:e,color:t}))),(0,o.jsx)((0,c.getCellRenderer)((0,c.resolveCellRendererType)(n)),{value:e,field:n})}return k(e,t)};return r?(0,o.jsxs)(`div`,{className:`space-y-4`,children:[u&&(0,o.jsxs)(`div`,{className:`flex items-center justify-between gap-2 p-4 bg-card rounded-lg border`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h2`,{className:`text-lg font-semibold`,children:r.title}),r.description&&(0,o.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:r.description})]}),(0,o.jsxs)(`div`,{className:`flex items-center gap-2`,children:[r.refreshInterval&&(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:g,children:[(0,o.jsx)(s.RefreshCw,{className:`h-4 w-4 mr-2`}),`Refresh`]}),f&&(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:h,children:[(0,o.jsx)(s.Printer,{className:`h-4 w-4 mr-2`}),`Print`]}),d&&r.showExportButtons&&(0,o.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>m(`pdf`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`PDF`]}),(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>m(`excel`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`Excel`]}),(0,o.jsxs)(a.Button,{variant:`outline`,size:`sm`,onClick:()=>m(`csv`),children:[(0,o.jsx)(s.Download,{className:`h-4 w-4 mr-2`}),`CSV`]})]})]})]}),(0,o.jsxs)(a.Card,{children:[(0,o.jsxs)(a.CardHeader,{children:[!u&&r.title&&(0,o.jsx)(a.CardTitle,{children:r.title}),!u&&r.description&&(0,o.jsx)(a.CardDescription,{children:r.description})]}),(0,o.jsxs)(a.CardContent,{className:`space-y-6`,children:[p&&(0,o.jsxs)(`div`,{className:`space-y-6`,children:[(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-4`,children:[1,2,3].map(e=>(0,o.jsx)(a.Card,{children:(0,o.jsxs)(a.CardContent,{className:`p-4 space-y-2`,children:[(0,o.jsx)(a.Skeleton,{className:`h-4 w-20`}),(0,o.jsx)(a.Skeleton,{className:`h-8 w-28`})]})},e))}),(0,o.jsxs)(`div`,{className:`space-y-2`,children:[(0,o.jsx)(a.Skeleton,{className:`h-10 w-full`}),[1,2,3,4,5].map(e=>(0,o.jsx)(a.Skeleton,{className:`h-8 w-full`},e))]})]}),!p&&r.sections?.map((e,t)=>e.visible===!1?null:(0,o.jsxs)(`div`,{className:`space-y-2`,children:[e.title&&e.type!==`header`&&(0,o.jsx)(`h3`,{className:`text-lg font-semibold border-b pb-2`,children:e.title}),e.type===`header`&&e.title&&(0,o.jsx)(`div`,{className:`text-2xl font-bold py-4`,children:e.title}),e.type===`summary`&&(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-4`,children:r.fields?.filter(e=>e.showInSummary).map((e,t)=>(0,o.jsx)(a.Card,{children:(0,o.jsxs)(a.CardContent,{className:`p-4`,children:[(0,o.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:e.label||e.name}),(0,o.jsx)(`div`,{className:`text-2xl font-bold`,children:k(_(e.name,e.aggregation),e)})]})},t))}),e.type===`table`&&(0,o.jsx)(`div`,{className:`border rounded-lg overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-sm min-w-[600px]`,children:[(0,o.jsx)(`thead`,{className:`bg-muted`,children:(0,o.jsx)(`tr`,{children:e.columns?.map((e,t)=>(0,o.jsx)(`th`,{className:`px-4 py-2 font-medium ${e.type===`number`?`text-right`:`text-left`}`,children:e.label||e.name},t))})}),(0,o.jsx)(`tbody`,{children:(()=>{let t=ee(l||[],r.groupBy||[]);return t?t.map(t=>(0,o.jsxs)(n.default.Fragment,{children:[(0,o.jsx)(`tr`,{className:`bg-muted/60`,children:(0,o.jsxs)(`td`,{colSpan:e.columns?.length||1,className:`px-4 py-2 font-semibold text-sm`,children:[t.label,` (`,t.rows.length,`)`]})}),t.rows.map((t,n)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:e.columns?.map((e,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${e.type===`number`?`text-right tabular-nums`:``}`,style:v(e.name,t[e.name]),children:y(t[e.name],e)},n))},n))]},t.key)):l?.map((t,n)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:e.columns?.map((e,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${e.type===`number`?`text-right tabular-nums`:``}`,style:v(e.name,t[e.name]),children:y(t[e.name],e)},n))},n))})()})]})}),e.type===`text`&&e.text&&(0,o.jsx)(`div`,{className:`prose max-w-none`,children:(0,o.jsx)(`p`,{children:e.text})}),e.type===`page-break`&&(0,o.jsx)(`div`,{className:`border-t-2 border-dashed my-8 print:page-break-after-always`}),e.content&&(0,o.jsx)(i.SchemaRenderer,{schema:e.content})]},t)),!r.sections&&l&&l.length>0&&(0,o.jsx)(`div`,{className:`border rounded-lg overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-sm min-w-[600px]`,children:[(0,o.jsx)(`thead`,{className:`bg-muted`,children:(0,o.jsx)(`tr`,{children:r.fields?.map((e,t)=>(0,o.jsx)(`th`,{className:`px-4 py-2 font-medium ${e.type===`number`?`text-right`:`text-left`}`,children:e.label||e.name},t))})}),(0,o.jsx)(`tbody`,{children:l.map((e,t)=>(0,o.jsx)(`tr`,{className:`border-t hover:bg-muted/50 even:bg-muted/20`,children:r.fields?.map((t,n)=>(0,o.jsx)(`td`,{className:`px-4 py-2 ${t.type===`number`?`text-right tabular-nums`:``}`,style:v(t.name,e[t.name]),children:y(e[t.name],t)},n))},t))})]})})]})]})]}):(0,o.jsx)(a.Card,{children:(0,o.jsx)(a.CardContent,{className:`p-8 text-center text-muted-foreground`,children:`No report to display`})})};function P(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.dataset==`string`&&t.dataset.length>0||t.type===`joined`&&Array.isArray(t.blocks)&&t.blocks.some(e=>typeof e?.dataset==`string`)}function F(e,t){return e?typeof e==`string`?e:typeof e==`object`&&typeof e.default==`string`?e.default:t:t}function I(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&!!e):[]}function L(e){if(!Array.isArray(e))return;let t={};for(let n of e){let e=n&&typeof n==`object`?n.by:void 0;typeof e!=`string`||!e||(t[e]=n.direction===`desc`?`desc`:`asc`)}return Object.keys(t).length>0?t:void 0}function R(e,t,n){if(!e)return;let r=new Set([...t,...n]),i={};for(let[t,n]of Object.entries(e))r.has(t)&&(i[t]=n);return Object.keys(i).length>0?i:void 0}function z(e,t,r,i,a,o,s){let[c,l]=n.useState({status:`idle`,rows:[]}),u=R(s,t,r),d=JSON.stringify(i??null),f=JSON.stringify(o??null),p=JSON.stringify(u??null),m=`${e}|${t.join(`,`)}|${r.join(`,`)}|${d}|${f}|${p}`;return n.useEffect(()=>{let n=a;if(!n||typeof n.queryDataset!=`function`){l({status:`error`,rows:[],error:`This data source does not support dataset queries.`});return}if(!e||r.length===0){l({status:`idle`,rows:[]});return}let s=!1;return l({status:`loading`,rows:[]}),n.queryDataset(e,{dimensions:t,measures:r,...i&&Object.keys(i).length>0?{runtimeFilter:i}:{},...o?{totals:{groupings:o}}:{},...u?{order:u}:{}}).then(e=>{s||l({status:`ok`,rows:Array.isArray(e?.rows)?e.rows:[],fields:Array.isArray(e?.fields)?e.fields:[],object:e?.object,dimensionFields:e?.dimensionFields,drillRawRows:Array.isArray(e?.drillRawRows)?e.drillRawRows:void 0,drillRanges:Array.isArray(e?.drillRanges)?e.drillRanges:void 0,totals:Array.isArray(e?.totals)?e.totals:void 0})}).catch(e=>{s||l({status:`error`,rows:[],error:String(e?.message??e)})}),()=>{s=!0}},[m]),c}function B({dataset:e}){return(0,o.jsxs)(`div`,{className:`flex items-center justify-center rounded-md border border-dashed bg-muted/20 p-4 text-xs text-muted-foreground`,children:[`This report binds the “`,e,`” dataset — choose at least one measure (values) to render.`]})}function V({status:e,error:t}){return e===`error`?(0,o.jsxs)(`div`,{role:`alert`,className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive`,children:[(0,o.jsx)(s.AlertTriangle,{className:`h-3.5 w-3.5 mt-0.5 shrink-0`}),(0,o.jsx)(`span`,{className:`break-words`,children:t})]}):(0,o.jsxs)(`div`,{className:`flex items-center gap-2 p-4 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Loader2,{className:`h-4 w-4 animate-spin`}),` Running report…`]})}function H(){return(0,o.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 rounded-md border border-dashed bg-muted/20 p-6 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Table2,{className:`h-6 w-6`}),` The dataset returned no rows for this report’s scope.`]})}var U=`cursor-pointer hover:bg-accent/40`;function W({dataset:e,rows:n,values:r,runtimeFilter:i,dataSource:a,onDrill:s,order:c,withTotals:u}){let d=z(e,n,r,i,a,u&&n.length>0?[[]]:void 0,c),{fieldLabel:f}=(0,l.useSafeFieldLabel)(),p=(0,l.useSafeTranslate)();if(r.length===0)return(0,o.jsx)(B,{dataset:e});if(d.status===`loading`||d.status===`idle`)return(0,o.jsx)(V,{status:d.status});if(d.status===`error`)return(0,o.jsx)(V,{status:`error`,error:d.error});if(d.rows.length===0)return(0,o.jsx)(H,{});let m=!!s&&n.length>0,h=d.dimensionFields?n.filter(e=>e in d.dimensionFields):[],g=(r,a)=>{let o={};for(let e of n)o[e]=r[e];let c=d.drillRanges?.[a],l=!!c&&Object.keys(c).length>0,u=d.object&&(h.length>0||l)?(0,t.buildDatasetDrillFilter)(d.drillRawRows?.[a],h,d.dimensionFields??{},i,c):void 0;s({dataset:e,groupKey:o,runtimeFilter:i,object:d.object,objectFilter:u})},{measureField:_,headerLabel:v}=(0,t.buildDatasetFieldHelpers)(d.fields,d.object,f),y=[...n,...r],b=u?d.totals?.find(e=>Array.isArray(e.dimensions)&&e.dimensions.length===0)?.rows?.[0]:void 0,x=p(`report.total`,`Total`);return(0,o.jsx)(`div`,{className:`overflow-auto max-h-[70vh] rounded-md border`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{className:`bg-muted/40`,children:(0,o.jsx)(`tr`,{children:y.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium whitespace-nowrap`,children:v(e)},e))})}),(0,o.jsxs)(`tbody`,{children:[d.rows.map((e,n)=>(0,o.jsx)(`tr`,{className:`border-t${m?` ${U}`:``}`,"data-testid":m?`dataset-drill-row`:void 0,onClick:m?()=>g(e,n):void 0,children:y.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 tabular-nums whitespace-nowrap`,children:r.includes(n)?(0,t.formatMeasure)(e[n],_(n)?.format,_(n)?.currency):(0,t.formatDimensionValue)(e[n])},n))},n)),b&&(0,o.jsxs)(`tr`,{className:`border-t bg-muted/30 font-medium`,"data-testid":`dataset-report-total-row`,children:[n.length>0&&(0,o.jsx)(`td`,{colSpan:n.length,className:`px-2 py-1 whitespace-nowrap`,children:x}),r.map(e=>(0,o.jsx)(`td`,{className:`px-2 py-1 tabular-nums whitespace-nowrap`,children:(0,t.formatMeasure)(b[e],_(e)?.format,_(e)?.currency)},e))]})]})]})})}function G(e){switch(e){case`summary`:return`summary`;case`matrix`:return`matrix`;case`joined`:return`joined`;default:return`tabular`}}function te(e){switch(e){case`bar`:case`column`:case`horizontal-bar`:case`line`:case`area`:case`pie`:case`donut`:case`funnel`:case`scatter`:case`treemap`:case`sankey`:case`radar`:return{kind:`series`,chartType:e};case`gauge`:case`solid-gauge`:case`metric`:case`kpi`:case`bullet`:return{kind:`single_value`};case`table`:case`pivot`:return{kind:`tabular`};default:return{kind:`unsupported`,type:String(e)}}}function ne(e){let[,r]=n.useReducer(e=>e+1,0);return n.useEffect(()=>{if(t.ComponentRegistry.get(e))return;let n=typeof t.ComponentRegistry.subscribe==`function`?t.ComponentRegistry.subscribe(()=>{t.ComponentRegistry.get(e)&&r()}):void 0,i=t.ComponentRegistry.loadLazy?.(e);return i&&typeof i.then==`function`&&i.then(()=>r()).catch(()=>{}),n},[e]),t.ComponentRegistry.get(e)}function K({dataset:e,chart:n,runtimeFilter:r,dataSource:i,order:a}){let c=typeof n.xAxis==`string`?n.xAxis:``,u=typeof n.yAxis==`string`?n.yAxis:``,d=te(n.type),f=d.kind===`series`||d.kind===`single_value`,p=z(e,d.kind===`series`&&c?[c]:[],f&&u?[u]:[],r,i,void 0,a),m=ne(`chart`),{fieldLabel:h}=(0,l.useSafeFieldLabel)(),g=typeof n.title==`string`?n.title:void 0;if(d.kind===`tabular`)return null;if(d.kind===`unsupported`)return(0,o.jsxs)(`div`,{className:`rounded-md border border-dashed bg-muted/20 px-3 py-2 text-xs text-muted-foreground`,"data-testid":`dataset-report-chart-unsupported`,children:[`Chart type “`,d.type,`” is not a spec chart type — the grouped table below carries this report’s numbers.`]});if(d.kind===`series`&&!c||!u)return null;if(p.status===`loading`||p.status===`idle`)return(0,o.jsxs)(`div`,{className:`flex items-center gap-2 p-4 text-xs text-muted-foreground`,children:[(0,o.jsx)(s.Loader2,{className:`h-4 w-4 animate-spin`}),` Loading chart…`]});if(p.status===`error`||p.rows.length===0)return null;if(d.kind===`single_value`){let{measureField:e,headerLabel:n}=(0,t.buildDatasetFieldHelpers)(p.fields,p.object,h),r=e(u);return(0,o.jsxs)(`div`,{className:`rounded-md border bg-card p-3`,"data-testid":`dataset-report-metric`,children:[g?(0,o.jsx)(`h3`,{className:`mb-2 text-sm font-semibold`,children:g}):null,(0,o.jsxs)(`div`,{className:`flex flex-col gap-0.5 py-2`,children:[(0,o.jsx)(`span`,{className:`text-2xl font-semibold tabular-nums`,children:(0,t.formatMeasure)(p.rows[0]?.[u],r?.format,r?.currency)}),(0,o.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:n(u)})]})]})}return m?(0,o.jsxs)(`div`,{className:`rounded-md border bg-card p-3`,"data-testid":`dataset-report-chart`,children:[g?(0,o.jsx)(`h3`,{className:`mb-2 text-sm font-semibold`,children:g}):null,(0,o.jsx)(m,{schema:{chartType:d.chartType,data:p.rows,xAxisKey:c,series:[{dataKey:u}],height:typeof n.height==`number`?n.height:280,isAnimationActive:!1}})]}):null}function q(e,t){return e.map(e=>String(t[e]??`∅`)).join(``)}function J(e,n){return e.map(e=>(0,t.formatDimensionValue)(n[e])).join(` / `)}function Y({dataset:e,rows:r,columnsAcross:i,values:a,runtimeFilter:s,dataSource:c,onDrill:u,order:d}){let f=z(e,[...r,...i],a,s,c,[r,i,[]],d),p=(0,l.useSafeTranslate)(),{fieldLabel:m}=(0,l.useSafeFieldLabel)(),h=n.useMemo(()=>{if(f.status!==`ok`)return null;let e=[],t=[],n=new Set,a=new Set,o=new Map;return f.rows.forEach((s,c)=>{let l=q(r,s),u=q(i,s);if(!n.has(l)){n.add(l);let t={};for(let e of r)t[e]=s[e];e.push({id:l,label:J(r,s),key:t})}if(!a.has(u)){a.add(u);let e={};for(let t of i)e[t]=s[t];t.push({id:u,label:J(i,s),key:e})}o.set(`${l} ${u}`,{row:s,index:c})}),{rowHeaders:e,colHeaders:t,cells:o}},[f,r,i]);if(a.length===0)return(0,o.jsx)(B,{dataset:e});if(f.status===`loading`||f.status===`idle`)return(0,o.jsx)(V,{status:f.status});if(f.status===`error`)return(0,o.jsx)(V,{status:`error`,error:f.error});if(!h||h.rowHeaders.length===0)return(0,o.jsx)(H,{});let{measureField:g,headerLabel:_}=(0,t.buildDatasetFieldHelpers)(f.fields,f.object,m),v=p(`report.total`,`Total`),y=!!u,b=f.dimensionFields?[...r,...i].filter(e=>e in f.dimensionFields):[],x=(n,r,i)=>{let a=f.drillRanges?.[i],o=!!a&&Object.keys(a).length>0,c=f.object&&(b.length>0||o)?(0,t.buildDatasetDrillFilter)(f.drillRawRows?.[i],b,f.dimensionFields??{},s,a):void 0;u({dataset:e,groupKey:{...n,...r},runtimeFilter:s,object:f.object,objectFilter:c})},S=h.colHeaders.flatMap(e=>a.map(t=>({col:e,measure:t,header:a.length===1?e.label:`${e.label} · ${_(t)}`}))),C=e=>f.totals?.find(t=>Array.isArray(t.dimensions)&&t.dimensions.join(`,`)===e.join(`,`))?.rows,w=new Map;for(let e of C(r)??[])w.set(q(r,e),e);let T=new Map;for(let e of C(i)??[])T.set(q(i,e),e);let E=C([])?.[0],D=w.size>0,O=T.size>0;return(0,o.jsx)(`div`,{className:`overflow-auto max-h-[70vh] rounded-md border`,"data-testid":`dataset-matrix`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{className:`bg-muted/40`,children:(0,o.jsxs)(`tr`,{children:[r.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium whitespace-nowrap`,children:_(e)},e)),S.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-right font-medium whitespace-nowrap`,children:e.header},`${e.col.id}-${e.measure}`)),D&&a.map(e=>(0,o.jsx)(`th`,{className:`px-2 py-1.5 text-right font-medium whitespace-nowrap`,"data-testid":`matrix-total-col-header`,children:a.length===1?v:`${v} · ${_(e)}`},`total-${e}`))]})}),(0,o.jsxs)(`tbody`,{children:[h.rowHeaders.map(e=>(0,o.jsxs)(`tr`,{className:`border-t`,children:[r.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 whitespace-nowrap font-medium`,children:(0,t.formatDimensionValue)(e.key[n])},n)),S.map(n=>{let r=h.cells.get(`${e.id} ${n.col.id}`),i=r?.row[n.measure],a=y&&r!=null;return(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap${a?` ${U}`:``}`,"data-testid":a?`dataset-drill-cell`:void 0,onClick:a?()=>x(e.key,n.col.key,r.index):void 0,children:(0,t.formatMeasure)(i,g(n.measure)?.format,g(n.measure)?.currency)},`${n.col.id}-${n.measure}`)}),D&&a.map(n=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap font-medium`,"data-testid":`matrix-row-total`,children:(0,t.formatMeasure)(w.get(e.id)?.[n],g(n)?.format,g(n)?.currency)},`total-${n}`))]},e.id)),O&&(0,o.jsxs)(`tr`,{className:`border-t bg-muted/30 font-medium`,"data-testid":`matrix-total-row`,children:[r.length>0&&(0,o.jsx)(`td`,{colSpan:r.length,className:`px-2 py-1 whitespace-nowrap`,children:v}),S.map(e=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap`,children:(0,t.formatMeasure)(T.get(e.col.id)?.[e.measure],g(e.measure)?.format,g(e.measure)?.currency)},`${e.col.id}-${e.measure}`)),D&&a.map(e=>(0,o.jsx)(`td`,{className:`px-2 py-1 text-right tabular-nums whitespace-nowrap`,"data-testid":`matrix-grand-total`,children:(0,t.formatMeasure)(E?.[e],g(e)?.format,g(e)?.currency)},`grand-${e}`))]})]})]})})}var X=({report:e,dataSource:n,runtimeFilter:r,onDrill:i,className:a})=>{let s=(0,t.mergeFilters)(e.runtimeFilter??e.filter,r),c=e.drilldown===!1?void 0:i,l=G(e.type);if(l===`joined`&&Array.isArray(e.blocks))return(0,o.jsx)(`div`,{className:a,"data-testid":`dataset-joined-report`,"data-report-name":e.name,style:{display:`flex`,flexDirection:`column`,gap:24},children:e.blocks.map((e,r)=>{let i=(0,t.mergeFilters)(s,e.runtimeFilter??e.filter),a=I(e.columns),l=L(e.order),u=G(e.type),d=u===`matrix`&&a.length>0?(0,o.jsx)(Y,{dataset:String(e.dataset??``),rows:I(e.rows),columnsAcross:a,values:I(e.values),runtimeFilter:i,dataSource:n,onDrill:c,order:l}):(0,o.jsx)(W,{dataset:String(e.dataset??``),rows:I(e.rows),values:I(e.values),runtimeFilter:i,dataSource:n,onDrill:c,order:l,withTotals:u===`summary`||u===`matrix`});return(0,o.jsxs)(`section`,{"data-testid":`dataset-report-block`,"data-block-id":e.name??`block-${r}`,className:`flex flex-col gap-2 rounded-lg border bg-card p-4`,children:[(0,o.jsxs)(`header`,{className:`flex flex-col gap-0.5`,children:[(0,o.jsx)(`h3`,{className:`text-sm font-semibold`,children:F(e.label,e.name??`Block ${r+1}`)}),e.description?(0,o.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:F(e.description,``)}):null]}),d]},e.name??`block-${r}`)})});let u=I(e.columns),d=L(e.order);if(l===`matrix`&&u.length>0)return(0,o.jsx)(`div`,{className:a,"data-testid":`dataset-report`,"data-report-name":e.name,children:(0,o.jsx)(Y,{dataset:String(e.dataset??``),rows:I(e.rows),columnsAcross:u,values:I(e.values),runtimeFilter:s,dataSource:n,onDrill:c,order:d})});let f=e.chart&&typeof e.chart==`object`&&e.chart.type?e.chart:null;return(0,o.jsxs)(`div`,{className:`${a??``} flex flex-col gap-3`,"data-testid":`dataset-report`,"data-report-name":e.name,"data-report-presentation":l,children:[f?(0,o.jsx)(K,{dataset:String(e.dataset??``),chart:f,runtimeFilter:s,dataSource:n,order:d}):null,(0,o.jsx)(W,{dataset:String(e.dataset??``),rows:I(e.rows),values:I(e.values),runtimeFilter:s,dataSource:n,onDrill:c,order:d,withTotals:l===`summary`||l===`matrix`})]})},Z=e=>{let{dataSource:t,rows:a,runtimeFilter:s,onDrill:c,className:l}=e,u=n.useContext(i.SchemaRendererContext),d=t??u?.dataSource,f=e.schema;return f&&typeof f==`object`&&f.type===`spec-report`&&f.report&&typeof f.report==`object`&&(f=f.report),P(f)?(0,o.jsx)(X,{report:f,dataSource:d,runtimeFilter:s,onDrill:c,className:l}):(0,r.isSpecReport)(f)?(0,o.jsx)(`div`,{className:l,"data-testid":`report-presentation-bridge`,children:(0,o.jsx)(N,{schema:{type:`report-viewer`,report:(0,r.specReportToPresentation)(f),data:a??[],showToolbar:!1}})}):(0,o.jsx)(_,{schema:f})};async function Q(e,t){let{dataSource:n,resource:r,queryParams:i,format:a,exportConfig:o}=t,s=a||e.defaultExportFormat||`pdf`;try{let t=(await n.find(r,i)).data||[];return C(s,e,t,{format:s,...e.exportConfigs?.[s],...o}),{success:!0,recordCount:t.length,format:s}}catch(e){return{success:!1,recordCount:0,format:s,error:e.message}}}function re(e,t,n={}){let{columns:r,filename:i,includeAggregationRow:a=!1}=n,o=r||(e.fields||[]).map(ae),s=o.map(e=>e.header),c=t.map((e,t)=>o.map(n=>{if(n.formula)return n.formula.replace(/\{ROW\}/g,String(t+2));let r=e[n.name];return oe(r,n.numberFormat)}));if(a&&t.length>0){let n=o.map((n,r)=>{let i=(e.fields||[]).find(e=>e.name===n.name);if(i?.aggregation){let e=se(r),n=t.length+1;switch(i.aggregation){case`sum`:return`=SUM(${e}2:${e}${n})`;case`avg`:return`=AVERAGE(${e}2:${e}${n})`;case`count`:return`=COUNTA(${e}2:${e}${n})`;case`min`:return`=MIN(${e}2:${e}${n})`;case`max`:return`=MAX(${e}2:${e}${n})`;default:return``}}return``});c.push(n)}le(``+[s.join(` `),...c.map(e=>e.join(` `))].join(`
59
+ `),i||`${e.title||`report`}.tsv`,`text/tab-separated-values`)}function ie(e,t,n,r){return async()=>{let i=e.schedule;if(!i?.enabled)return[];let a=i.formats||[e.defaultExportFormat||`pdf`],o=[];for(let r of a){let i=await Q(e,{dataSource:t,resource:n,format:r});o.push(i)}return r(e,i),o}}function ae(e){return{name:e.name,header:e.label||e.name}}function oe(e,t){return e==null?``:typeof e==`number`&&t?e.toLocaleString(`en-US`,$(t)):ce(String(e))}function $(e){if(e.includes(`%`))return{style:`percent`,minimumFractionDigits:0};let t=(e.match(/0/g)||[]).length;return{minimumFractionDigits:Math.max(0,t-1),maximumFractionDigits:Math.max(0,t-1)}}function se(e){let t=``,n=e;for(;n>=0;)t=String.fromCharCode(n%26+65)+t,n=Math.floor(n/26)-1;return t}function ce(e){if(e.length>0){let t=e.charAt(0);if(t===`=`||t===`+`||t===`-`||t===`@`||t===`|`)return`'${e}`}return e}function le(e,t,n){let r=new Blob([e],{type:`${n};charset=utf-8`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}t.ComponentRegistry.register(`report`,Z,{namespace:`report`,label:`Report`,category:`Report`,inputs:[{name:`title`,type:`string`,label:`Title`},{name:`description`,type:`string`,label:`Description`},{name:`chart`,type:`code`,label:`Chart Configuration`}]}),t.ComponentRegistry.register(`spec-report`,Z,{namespace:`report`,label:`Spec Report`,category:`Report`,inputs:[{name:`dataset`,type:`string`,label:`Dataset`},{name:`type`,type:`string`,label:`Report Type`}]}),t.ComponentRegistry.register(`report-viewer`,N,{namespace:`report`,label:`Report Viewer`,category:`Report`,inputs:[{name:`report`,type:`code`,label:`Report Definition`},{name:`showToolbar`,type:`boolean`,label:`Show Toolbar`}]}),e.DatasetReportRenderer=X,e.LegacyReportRenderer=_,e.ReportRenderer=Z,e.ReportViewer=N,e.createScheduleTrigger=ie,e.exportAsCSV=v,e.exportAsExcel=S,e.exportAsHTML=b,e.exportAsJSON=y,e.exportAsPDF=x,e.exportExcelWithFormulas=re,e.exportReport=C,e.exportWithLiveData=Q,e.formatValue=k,e.isDatasetReport=P,Object.defineProperty(e,"mergeFilters",{enumerable:!0,get:function(){return t.mergeFilters}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-report",
3
- "version": "16.1.0",
3
+ "version": "17.1.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.umd.cjs",
6
6
  "module": "dist/index.js",
@@ -21,25 +21,26 @@
21
21
  "dependencies": {
22
22
  "clsx": "^2.1.1",
23
23
  "lucide-react": "^1.25.0",
24
- "react-i18next": "^17.0.10",
24
+ "react-i18next": "^17.0.11",
25
25
  "tailwind-merge": "^3.6.0",
26
- "@object-ui/components": "16.1.0",
27
- "@object-ui/core": "16.1.0",
28
- "@object-ui/fields": "16.1.0",
29
- "@object-ui/i18n": "16.1.0",
30
- "@object-ui/plugin-grid": "16.1.0",
31
- "@object-ui/react": "16.1.0",
32
- "@object-ui/types": "16.1.0"
26
+ "@object-ui/components": "17.1.0",
27
+ "@object-ui/core": "17.1.0",
28
+ "@object-ui/fields": "17.1.0",
29
+ "@object-ui/i18n": "17.1.0",
30
+ "@object-ui/plugin-grid": "17.1.0",
31
+ "@object-ui/react": "17.1.0",
32
+ "@object-ui/types": "17.1.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0",
36
36
  "react-dom": "^18.0.0"
37
37
  },
38
38
  "devDependencies": {
39
+ "@objectstack/spec": "^17.0.0-rc.0",
39
40
  "@types/node": "^26.1.1",
40
41
  "@types/react": "19.2.17",
41
42
  "@types/react-dom": "19.2.3",
42
- "@vitejs/plugin-react": "^6.0.3",
43
+ "@vitejs/plugin-react": "^6.0.4",
43
44
  "vite": "^8.1.5",
44
45
  "vite-plugin-dts": "^5.0.3",
45
46
  "vitest": "^4.1.10"
@@ -74,6 +75,7 @@
74
75
  },
75
76
  "scripts": {
76
77
  "build": "vite build",
78
+ "type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
77
79
  "clean": "rm -rf dist",
78
80
  "test": "vitest run",
79
81
  "lint": "eslint ."