@bygd/nc-report-ui 0.1.18 → 0.1.20
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.
- package/dist/default/cjs/index.cjs +1 -1
- package/dist/default/esm/index.js +272 -107
- package/dist/default/iife/index.js +30 -30
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("@material-ui/core/Paper"),a=require("@material-ui/core/styles"),r=require("@material-ui/core/LinearProgress"),n=require("react-google-charts"),l=require("numeral"),i=require("axios"),o=require("@material-ui/core/Typography"),s=require("nunjucks"),u=require("@material-ui/core/FormControl"),d=require("@material-ui/core/Select"),c=require("@material-ui/core/MenuItem"),f=require("react-intersection-observer"),m=require("@mui/material"),p=require("@mui/icons-material/CheckBoxOutlineBlank"),h=require("@mui/icons-material/CheckBox"),y=require("@mui/material/Box"),g=require("@mui/material/InputLabel"),b=require("@mui/material/MenuItem"),v=require("@mui/material/FormControl"),E=require("@mui/material/Select"),w=require("eventemitter3"),x=require("@material-ui/core/Grid"),S=require("@material-ui/core/Box"),C=require("@material-ui/core/Container");function k(e){return e&&e.__esModule?e:{default:e}}function q(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(a){if("default"!==a){var r=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(t,a,r.get?r:{enumerable:!0,get:function(){return e[a]}})}}),t.default=e,Object.freeze(t)}var M=q(e),R=k(t),I=k(r),T=k(l),A=k(i),D=k(o),O=k(s),_=k(u),F=k(d),z=k(c),Y=k(p),P=k(h),j=k(y),$=k(g),B=k(b),W=k(v),G=k(E),L=k(w),U=k(x),V=k(S),H=k(C);function K(){return K=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var r in a)({}).hasOwnProperty.call(a,r)&&(e[r]=a[r])}return e},K.apply(null,arguments)}const N=a.makeStyles(e=>({root:{width:"100%","& > * + *":{marginTop:e.spacing(2)}}}));function J(e){const t=N();return M.default.createElement("div",K({className:t.root},e),M.default.createElement(I.default,null))}function Q(e,t,a="array"){const r=e.columns,n=[...t.doc.metrics,...t.doc.dimensions].reduce((e,t)=>(e[t.name]=t,e),{});return e=>{const t="array"===a?[]:{};return r.reduce((t,r)=>{const l=e[r.name],i=n[r.name];let o=l;return o="timestamp"===i.type?new Date(l):i.format?i.format&&i.prefix?{v:+l,f:i.prefix+" "+T.default(l).format(i.format)}:i.format?{v:+l,f:T.default(l).format(i.format)}:l:l,"array"===a?t.push(o):t[r.name]=o?.f||o,t},t)}}const X="https://report-api.netcapital.pro",Z=A.default.create({baseURL:X,headers:{"Content-Type":"application/json"}}),ee={},te=()=>{const e=Object.keys(ee);return e.length>0?e[0]:null},ae={setBaseUrl(e){Z.defaults.baseURL=e||X},setToken(e){e&&(Z.defaults.headers.common.Authorization=`Bearer ${e}`)},loadDashboardMeta:async({dashboardId:e})=>{const{data:t}=await Z.get(`/dashboard-meta/${e}`);return ee[e]={dashboards:t.dashboards||{},charts:t.charts||{},reports:t.reports||{},reportMetadata:t.reportMetadata||{},dateRanges:t.dateRanges||[]},ee[e]},getDashboard:async({id:e,dashboardId:t})=>{const a=t||te();if(a&&ee[a]?.dashboards?.[e])return ee[a].dashboards[e];const{data:r}=await Z.get(`/entity/dashboards/${e}`);return r},getChart:async({id:e,dashboardId:t})=>{const a=t||te();if(a&&ee[a]?.charts?.[e])return ee[a].charts[e];const{data:r}=await Z.get(`/entity/charts/${e}`);return r},getReport:async({id:e,dashboardId:t})=>{const a=t||te();if(a&&ee[a]?.reports?.[e])return ee[a].reports[e];const{data:r}=await Z.get(`/entity/reports/${e}`);return r},getProviders:async()=>{const{data:e}=await Z.get("/entity/providers");return e},getReportSchema:async({id:e,dashboardId:t,query:a={}})=>{const r=t||te();if(r&&ee[r]?.reportMetadata?.[e])return ee[r].reportMetadata[e];const{data:n}=await Z.post(`/reports/${e}/metadata`,a);return n},runReport:async({id:e,query:t={}})=>{const{data:a}=await Z.post(`/reports/${e}/run`,t);return a},runAdHocReport:async({report:e})=>{const{data:t}=await Z.post("/report-build/run",e);return t},getDateRanges:async({dashboardId:e}={})=>{const t=e||te();if(t&&ee[t]?.dateRanges)return ee[t].dateRanges;const{data:a}=await Z.get("/globals/date-ranges");return a},getReportDefinitions:async()=>{const{data:e}=await Z.get("/report-definitions");return e},getReportDefinition:async({id:e})=>{const{data:t}=await Z.get(`/report-definitions/${e}`);return t},createReportDefinition:async({reportDefinition:e})=>{const{data:t}=await Z.post("/report-definitions",e);return t},updateReportDefinition:async({id:e,reportDefinition:t})=>{const{data:a}=await Z.put(`/report-definitions/${e}`,t);return a},deleteReportDefinition:async({id:e})=>{const{data:t}=await Z.delete(`/report-definitions/${e}`);return t}},re=a.makeStyles(e=>({headerRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},tableRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},oddTableRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},headerCell:{backgroundColor:"white",padding:"4px !important"}})),ne={none:"YYYY-MM-dd",day:"MMM dd",week:"MMM dd",month:"YYYY MMM",year:"YYYY"};const le={GoogleChart:function({chart:t,source:a,view:r,report:l,schema:i,dashboard:o,query:s}){const[u,d]=M.default.useState([]),c=re(),[f,m]=M.default.useState([]);e.useEffect(()=>{(async()=>{const e=await ae.getDateRanges();m(e)})()},[]);const p=e.useMemo(()=>{const e="YYYY-MM-dd",t=s?.date_range?.name,a=f.find(e=>e.name===t);if(!a)return e;return ne[a?.granularity]||e},[f,s]);return M.default.useEffect(()=>{if(!(t&&r&&a&&l&&i))return;let e=[];e.push(function(e,t){const a=[...t.doc.metrics,...t.doc.dimensions];return e.columns.reduce((e,t)=>{const r=a.find(e=>e.name===t.name)||t;return e.push(r.title||r.name),e},[])}(r,i));const n=Q(r,i);a?.forEach(t=>{const a=n(t);e.push(a)}),a?.length?d(e):d()},[t,a,r,l,i]),u?M.default.createElement("div",{style:{}},M.default.createElement(n.Chart,K({width:t?.doc.size?.width||"100%",chartType:t?.doc.chart?.type,data:u,options:(e=>{if("Table"===t?.doc.chart?.type)return{...t?.doc.chart?.options,cssClassNames:c};if("AreaChart"===t?.doc.chart?.type){const a=t?.doc.chart?.options?.hAxis||{},r={...{ticks:e.slice(1).map(e=>e[0]),format:p},...a};return{...t?.doc.chart?.options,hAxis:r,focusTarget:"category"}}return t?.doc.chart?.options})(u)},t?.doc.chart?.props))):M.default.createElement("div",null)},LabelChart:function({chart:e,source:t,view:a,report:r,schema:n}){const[l,i]=M.default.useState([]),[o,s]=M.default.useState(),[u,d]=M.default.useState();return M.default.useEffect(()=>{if(!(e&&a&&t&&r&&n))return;let l=[];const o=Q(a,n);t.forEach(e=>l.push(o(e))),i(l);const u=e?.doc?.chart?.options||{},c=u?.index||0;if(l.length>0&&s(l[0][c]),u.subText?.format){O.default.configure({autoescape:!1});const e=Q(a,n,"object")(t[0]),r=O.default.renderString(u.subText?.format,e);d(r)}},[e,t,a,r,n]),M.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignContent:"center",height:"100%",flexDirection:"column"}},M.default.createElement(D.default,{variant:"h6"},o?.f||o),M.default.createElement(D.default,{variant:"caption"},u))}};function ie(e,t){return void 0!==le[e]?M.default.createElement(le[e],t):M.default.createElement(J,t)}const oe=M.createElement(Y.default,{fontSize:"small"}),se=M.createElement(P.default,{fontSize:"small"});function ue({items:t,selectedKeys:a,defaultSelectedKeys:r,onChange:n,inputValue:l,defaultInputValue:i,onInputChange:o,debounceMs:s=300,label:u,placeholder:d,loading:c,disabled:f,size:p="small",error:h,helperText:y,limitTags:g=3,disableClearable:b,id:v,textFieldProps:E}){const w=e.useMemo(()=>Array.isArray(t)?t:[],[t]),x=Array.isArray(a),[S,C]=e.useState(Array.isArray(r)?r:[]),k=x?a:S,q=e.useMemo(()=>{const e=new Map;for(const t of w)e.set(t&&t.key,t);return e},[w]),R=e.useMemo(()=>(Array.isArray(k)?k:[]).map(e=>q.get(e)).filter(Boolean),[k,q]),I="string"==typeof l,[T,A]=e.useState("string"==typeof i?i:""),D=I?l:T,O=function(t,a=300){const r=e.useRef(t),n=e.useRef(null);return r.current=t,e.useEffect(()=>()=>{n.current&&window.clearTimeout(n.current)},[]),M.useCallback((...e)=>{r.current&&(n.current&&window.clearTimeout(n.current),n.current=window.setTimeout(()=>{r.current&&r.current(...e)},a))},[a])}(e=>{o&&o(e)},s),_=R;return M.createElement(m.FormControl,{fullWidth:!0,error:h,disabled:f},M.createElement(m.Autocomplete,{openOnFocus:!0,forcePopupIcon:!0,id:v,multiple:!0,disableCloseOnSelect:!0,options:w,value:_,inputValue:D,getOptionLabel:e=>e&&"object"==typeof e?e.value??"":"",isOptionEqualToValue:(e,t)=>e&&t&&e.key===t.key,loading:c,limitTags:g,disableClearable:b,onChange:(e,t)=>{const a=Array.isArray(t)?t.map(e=>e&&e.key):[];x||C(a),n&&n(a,Array.isArray(t)?t:[])},onInputChange:(e,t,a)=>{I||A(t??""),"input"===a?O(t??""):"clear"===a&&O("")},renderOption:(e,t,{selected:a})=>M.createElement("li",K({},e,{key:t&&t.key||Math.random().toString(36)}),M.createElement(m.Checkbox,{icon:oe,checkedIcon:se,style:{marginRight:8},checked:!!a}),t&&t.value),renderTags:(e,t)=>(Array.isArray(e)?e:[]).map((e,a)=>M.createElement(m.Chip,K({},t({index:a}),{key:e&&e.key||a,label:e&&e.value||""}))),renderInput:e=>M.createElement(m.TextField,K({},e,{label:u,placeholder:d,InputProps:{...e.InputProps,endAdornment:M.createElement(M.Fragment,null,c?M.createElement(m.CircularProgress,{size:18}):null,e.InputProps.endAdornment)},size:p},E))}),y?M.createElement(m.FormHelperText,null,y):null)}const de=({filter:t,channel:a,query:r})=>{const[n,l]=e.useState([]),[i,o]=e.useState([]),[s,u]=e.useState(!1),[d,c]=e.useState("");return e.useEffect(()=>{o(r?.filter?.[t?.filter]||[])},[r]),e.useEffect(()=>{(async()=>{u(!0);const e=await async function(e,t){return t?.source?(await ae.runReport({id:t.source})).map(e=>({key:e[t.field],value:e[t.field]})):[]}(0,t);l(e),u(!1)})()},[d]),M.default.createElement("div",{style:{display:"flex"}},M.default.createElement("div",{style:{maxWidth:640,minWidth:200}},M.default.createElement(ue,{id:t?.title,label:t?.title,placeholder:"Type to search…",items:n,selectedKeys:i,onChange:(e,r)=>{o(e),a.emit("filterChanged",t,{[t.filter]:e})},onInputChange:e=>{c(e)},loading:s,debounceMs:300,helperText:i.length?`${i.length} selected`:""})))};function ce({items:e,value:t,label:a,onChange:r,sx:n={width:"100%"}}){const l=e.some(e=>e.key===t)?t:"";return M.default.createElement(j.default,{sx:n},M.default.createElement(W.default,{fullWidth:!0},M.default.createElement($.default,{id:"demo-simple-select-label"},a),M.default.createElement(G.default,{labelId:"demo-simple-select-label",id:"demo-simple-select",value:l,label:a,onChange:r,MenuProps:{style:{maxHeight:"300px"}},size:"small"},e.map(e=>{const{key:t,value:a,disabled:r}=e;return M.default.createElement(B.default,{key:t,value:t,disabled:r},a)}))))}const fe=({filter:t,channel:a,query:r})=>{const[n,l]=e.useState([]),[i,o]=e.useState("");return e.useEffect(()=>{o(r?.date_range?.name)},[r]),e.useEffect(()=>{(async()=>{const e=(await ae.getDateRanges()).filter(e=>!(t.allowedOptions.length>0)||t.allowedOptions.some(t=>t===e.name)).map(e=>({key:e.name,value:e.title}));l(e)})()},[]),M.default.createElement("div",{style:{minWidth:"200px",maxWidth:"640px"}},M.default.createElement(ce,{items:n,value:i,label:t?.title,onChange:(e,r)=>{const n=e.target.value;o(n),a.emit("filterChanged",t,{date_range:{name:n}})}}))},me=({filters:e=[],channel:t,query:a})=>M.default.createElement("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px"}},e.map(e=>"multi-select"===e.type?M.default.createElement(de,{key:e.title,channel:t,filter:e,query:a}):"date-range"===e.type?M.default.createElement(fe,{key:e.title,channel:t,filter:e,query:a}):null));var pe=e=>M.default.useRef(e||new L.default).current,he=e=>{const t=M.default.useState({}),a=M.default.useCallback((a,r)=>{let n={...t.current,...r};for(var l in t.current=n,n)"date_range"===l||n[l].length||delete n[l];e?.emit("mergedFilterChanged",{value:n})},[e]);M.default.useEffect(()=>(e?.on("filterChanged",a),()=>{e?.off("filterChanged",a)}),[e])},ye=({id:e,cache:t,dashboard:a,channel:r,...n})=>{const[l,i]=M.default.useState(),[o,s]=M.default.useState(),[u,d]=M.default.useState(),[c,m]=M.default.useState(),[p,h]=M.default.useState(ie()),[y,g]=M.default.useState(),[b,v]=M.default.useState(0),[E,w]=M.default.useState(!1),[x,S]=M.default.useState(),[C,k]=M.default.useState(!1),q=M.default.useRef({value:n?.filter}),[I,T]=M.default.useState({}),{ref:A,inView:O,entry:Y}=f.useInView({threshold:.1,delay:1e3}),P=pe(r);he(P);const j=M.default.useCallback(e=>{const t=e.target.value;v(t),g(l.doc.view[t])},[l]);M.default.useEffect(()=>{e&&(async()=>{const a=e,r=t?.[a]||await ae.getChart({id:a}),l=r.doc.source?.id,o=l?t?.[l]||await ae.getReport({id:l}):void 0,u=t?.[`schema_${l}`]||n?.schema||await ae.getReportSchema({id:l}),c=r.doc?.view?.[0];v(0),s(o),i(r),g(c),d(u),k(!0)})().catch(e=>{console.error(e.message)})},[e]),M.default.useEffect(()=>{l&&c&&(!l?.doc?.source?.id||o)&&u&&(async()=>{h(ie(l.doc.chart?.component,{view:y,source:c,chart:l,report:o,schema:u,dashboard:a,query:I}))})().catch(e=>{console.error(e.message)})},[l,c,y,o,u]);const $=e=>{const t={...o?.doc.query.filter||{},...n?.filter,...e?.value},a=t.date_range||o?.doc.query.date_range;if(delete t.date_range,k(!1),S(),w(!0),"context"===l?.doc?.source?.type)return m({filter:t}),void w(!1);const r={filter:t,date_range:a,parameters:n?.params};T(r),ae.runReport({id:o.id,query:r}).then(e=>{m(l.doc.source.reverse?e.reverse():e)}).catch(e=>{m([])}).finally(()=>{w(!1)})},B=e=>{q.current=e,O?$(e):(S(e),k(!0))};return M.default.useEffect(()=>(P?.on("mergedFilterChanged",B),()=>{P?.off("mergedFilterChanged",B)}),[P,o,l,O]),M.default.useEffect(()=>{O&&C&&$(x)},[O,C]),M.default.useEffect(()=>{k(!0)},[n.params]),M.default.createElement(R.default,{ref:A,style:{padding:"16px",paddingTop:0,flexGrow:1,borderRadius:12,display:"flex",flexDirection:"column",gap:"16px"},elevation:2},M.default.createElement(J,{style:{visibility:E?"visible":"hidden"}}),M.default.createElement("div",{style:{display:"flex"}},M.default.createElement("div",null,l&&M.default.createElement("div",{style:{display:"flex",alignItems:"center",lineHeight:0}},M.default.createElement(D.default,{noWrap:!0,variant:"caption"},n?.title||l.doc.name," "))),M.default.createElement("div",{style:{flexGrow:1}}),M.default.createElement("div",null,l?.doc?.view?.length>1&&M.default.createElement(_.default,null,M.default.createElement(F.default,{labelId:"date-range-select-label",id:"date-range-select",value:b,onChange:j,style:{fontSize:"12px"},disableUnderline:!0},l.doc.view.map((e,t)=>M.default.createElement(z.default,{key:t,value:t},e.title)))))),M.default.createElement("div",{style:{position:"relative",flexGrow:a?void 0:1,display:"flex",flexDirection:"column"}},M.default.createElement(me,{filters:l?.doc?.filters,channel:P,query:I}),p))};var ge={Chart:ye,Dashboard:function({id:t="sample_dashboard",api:a,params:r}){const[n,l]=M.default.useState(),[i]=M.default.useState(),[o,s]=M.default.useState([]),u=M.default.useRef({}),d=pe();he(d),e.useEffect(()=>{ae.setBaseUrl(a.base_url),ae.setToken(a.token)},[a]);const c=async e=>{const t=e?.doc?.rows||[],a=[];for(let e=0;e<t.length;e++){const r=t[e];r.columns?.forEach(e=>{if(e.override?.filter?.length){const t={};e.override.filter.forEach(e=>{e.hasOwnProperty("value")&&(t[e.field]=[e.value])}),e.filter=t}}),a.push(r)}s(a)};return M.default.useEffect(()=>{t&&(async()=>{ae.setBaseUrl(a.base_url),ae.setToken(a.token),await ae.loadDashboardMeta({dashboardId:t});const e=await ae.getDashboard({id:t});u.current[e?.id]=e,l(e),await c(e)})().catch(e=>console.error(e.message))},[t]),M.default.createElement(H.default,{maxWidth:!1,disableGutters:!0,style:{height:"100vh",padding:0,margin:0,overflow:"hidden"}},M.default.createElement(U.default,{container:!0,spacing:2,style:{height:"100%",width:"100%"}},o?.map((e,t)=>M.default.createElement(U.default,{key:t,container:!0,item:!0,alignItems:"stretch",spacing:2},e?.columns?.map((e,t)=>M.default.createElement(U.default,{key:t,item:!0,xs:!0,style:{display:"flex"}},M.default.createElement(V.default,{style:{flex:1,display:"flex",flexDirection:"column"}},M.default.createElement(ye,{api:a,cache:u.current,id:e.id,dashboard:n,schema:i,channel:null,title:e.title,filter:e.filter,params:r}))))))))}};exports.default=ge;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("@material-ui/core/Paper"),a=require("@material-ui/core/styles"),r=require("@material-ui/core"),n=require("react-google-charts"),l=require("numeral"),o=require("axios"),i=require("@material-ui/core/Typography"),s=require("nunjucks"),u=require("@material-ui/core/FormControl"),d=require("@material-ui/core/Select"),c=require("@material-ui/core/MenuItem"),f=require("react-intersection-observer"),m=require("@mui/material"),p=require("@mui/icons-material/CheckBoxOutlineBlank"),h=require("@mui/icons-material/CheckBox"),y=require("@mui/material/Box"),g=require("@mui/material/InputLabel"),b=require("@mui/material/MenuItem"),v=require("@mui/material/FormControl"),E=require("@mui/material/Select"),w=require("eventemitter3"),x=require("@material-ui/core/Grid"),C=require("@material-ui/core/Container");function S(e){return e&&e.__esModule?e:{default:e}}function k(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(a){if("default"!==a){var r=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(t,a,r.get?r:{enumerable:!0,get:function(){return e[a]}})}}),t.default=e,Object.freeze(t)}var R=k(e),q=S(t),M=S(l),A=S(o),I=S(i),T=S(s),O=S(u),D=S(d),F=S(c),P=S(p),_=S(h),j=S(y),z=S(g),Y=S(b),$=S(v),B=S(E),U=S(w),L=S(x),W=S(C);function V(){return V=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var r in a)({}).hasOwnProperty.call(a,r)&&(e[r]=a[r])}return e},V.apply(null,arguments)}const G=a.makeStyles(e=>({root:{width:"100%","& > * + *":{marginTop:e.spacing(2)}}}));function H(e){const t=G();return R.default.createElement("div",V({className:t.root},e),R.default.createElement(r.CircularProgress,{style:{color:"rgb(70, 134, 128)"},size:25}))}function K(e,t,a="array"){const r=e.columns,n=[...t.doc.metrics,...t.doc.dimensions].reduce((e,t)=>(e[t.name]=t,e),{});return e=>{const t="array"===a?[]:{};return r.reduce((t,r)=>{const l=e[r.name],o=n[r.name];let i=l;return i="timestamp"===o.type?new Date(l):o.format?o.format&&o.prefix?{v:+l,f:o.prefix+" "+M.default(l).format(o.format)}:o.format?{v:+l,f:M.default(l).format(o.format)}:l:l,"array"===a?t.push(i):t[r.name]=i?.f||i,t},t)}}const N="https://report-api.netcapital.pro",J=A.default.create({baseURL:N,headers:{"Content-Type":"application/json"}}),Q={},X=()=>{const e=Object.keys(Q);return e.length>0?e[0]:null},Z={setBaseUrl(e){J.defaults.baseURL=e||N},setToken(e){e&&(J.defaults.headers.common.Authorization=`Bearer ${e}`)},loadDashboardMeta:async({dashboardId:e})=>{const{data:t}=await J.get(`/dashboard-meta/${e}`);return Q[e]={dashboards:t.dashboards||{},charts:t.charts||{},reports:t.reports||{},reportMetadata:t.reportMetadata||{},dateRanges:t.dateRanges||[]},Q[e]},getDashboard:async({id:e,dashboardId:t})=>{const a=t||X();if(a&&Q[a]?.dashboards?.[e])return Q[a].dashboards[e];const{data:r}=await J.get(`/entity/dashboards/${e}`);return r},getChart:async({id:e,dashboardId:t})=>{const a=t||X();if(a&&Q[a]?.charts?.[e])return Q[a].charts[e];const{data:r}=await J.get(`/entity/charts/${e}`);return r},getReport:async({id:e,dashboardId:t})=>{const a=t||X();if(a&&Q[a]?.reports?.[e])return Q[a].reports[e];const{data:r}=await J.get(`/entity/reports/${e}`);return r},getProviders:async()=>{const{data:e}=await J.get("/entity/providers");return e},getReportSchema:async({id:e,dashboardId:t,query:a={}})=>{const r=t||X();if(r&&Q[r]?.reportMetadata?.[e])return Q[r].reportMetadata[e];const{data:n}=await J.post(`/reports/${e}/metadata`,a);return n},runReport:async({id:e,query:t={}})=>{const{data:a}=await J.post(`/reports/${e}/run`,t);return a},runAdHocReport:async({report:e})=>{const{data:t}=await J.post("/report-build/run",e);return t},downloadAdHocReport:async({report:e,filename:t})=>{const a=await J.post("/report-build/run?download=csv",e,{responseType:"blob"}),r=window.URL.createObjectURL(new Blob([a.data])),n=document.createElement("a");n.href=r;let l=t||"report.csv";if(!t){const e=a.headers["content-disposition"];if(e){const t=e.match(/filename="?(.+)"?/i);t&&t[1]&&(l=t[1])}}n.setAttribute("download",l),document.body.appendChild(n),n.click(),n.remove(),window.URL.revokeObjectURL(r)},getDateRanges:async({dashboardId:e}={})=>{const t=e||X();if(t&&Q[t]?.dateRanges)return Q[t].dateRanges;const{data:a}=await J.get("/globals/date-ranges");return a},getReportDefinitions:async()=>{const{data:e}=await J.get("/report-definitions");return e},getReportDefinition:async({id:e})=>{const{data:t}=await J.get(`/report-definitions/${e}`);return t},createReportDefinition:async({reportDefinition:e})=>{const{data:t}=await J.post("/report-definitions",e);return t},updateReportDefinition:async({id:e,reportDefinition:t})=>{const{data:a}=await J.put(`/report-definitions/${e}`,t);return a},deleteReportDefinition:async({id:e})=>{const{data:t}=await J.delete(`/report-definitions/${e}`);return t}},ee=a.makeStyles(e=>({headerRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},tableRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},oddTableRow:{fontFamily:e.typography.fontFamily,fontSize:e.typography.fontSize},headerCell:{backgroundColor:"white",padding:"4px !important"}})),te={none:"YYYY-MM-dd",day:"MMM dd",week:"MMM dd",month:"YYYY MMM",year:"YYYY"};const ae={GoogleChart:function({chart:t,source:a,view:r,report:l,schema:o,dashboard:i,query:s}){const[u,d]=R.default.useState([]),c=ee(),[f,m]=R.default.useState([]);e.useEffect(()=>{(async()=>{const e=await Z.getDateRanges();m(e)})()},[]);const p=e.useMemo(()=>{const e="YYYY-MM-dd",t=s?.date_range?.name,a=f.find(e=>e.name===t);if(!a)return e;return te[a?.granularity]||e},[f,s]);return R.default.useEffect(()=>{if(!(t&&r&&a&&l&&o))return;let e=[];e.push(function(e,t){const a=[...t.doc.metrics,...t.doc.dimensions];return e.columns.reduce((e,t)=>{const r=a.find(e=>e.name===t.name)||t;return e.push(r.title||r.name),e},[])}(r,o));const n=K(r,o);a?.forEach(t=>{const a=n(t);e.push(a)}),a?.length?d(e):d()},[t,a,r,l,o]),u?R.default.createElement("div",{style:{}},R.default.createElement(n.Chart,V({width:t?.doc.size?.width||"100%",chartType:t?.doc.chart?.type,data:u,options:(e=>{const a=["#468682","#ff686b","#6c757d","#FFD700","#073b4c"];if("Table"===t?.doc.chart?.type)return{...t?.doc.chart?.options,cssClassNames:c};if("AreaChart"===t?.doc.chart?.type){const r=t?.doc.chart?.options?.hAxis||{},n={...{ticks:e.slice(1).map(e=>e[0]),format:p},...r};return{...t?.doc.chart?.options,hAxis:n,focusTarget:"category",colors:a}}return{...t?.doc.chart?.options,colors:a}})(u)},t?.doc.chart?.props))):R.default.createElement("div",null)},LabelChart:function({chart:e,source:t,view:a,report:r,schema:n}){const[l,o]=R.default.useState([]),[i,s]=R.default.useState(),[u,d]=R.default.useState();return R.default.useEffect(()=>{if(!(e&&a&&t&&r&&n))return;let l=[];const i=K(a,n);t.forEach(e=>l.push(i(e))),o(l);const u=e?.doc?.chart?.options||{},c=u?.index||0;if(l.length>0&&s(l[0][c]),u.subText?.format){T.default.configure({autoescape:!1});const e=K(a,n,"object")(t[0]),r=T.default.renderString(u.subText?.format,e);d(r)}},[e,t,a,r,n]),R.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignContent:"center",height:"100%",flexDirection:"column"}},R.default.createElement(I.default,{variant:"h6"},i?.f||i),R.default.createElement(I.default,{variant:"caption"},u))}};function re(e,t){return void 0!==ae[e]?R.default.createElement(ae[e],t):R.default.createElement(H,t)}const ne=R.createElement(P.default,{fontSize:"small"}),le=R.createElement(_.default,{fontSize:"small"});function oe({items:t,selectedKeys:a,defaultSelectedKeys:r,onChange:n,inputValue:l,defaultInputValue:o,onInputChange:i,debounceMs:s=300,label:u,placeholder:d,loading:c,disabled:f,size:p="small",error:h,helperText:y,limitTags:g=3,disableClearable:b,id:v,textFieldProps:E}){const w=e.useMemo(()=>Array.isArray(t)?t:[],[t]),x=Array.isArray(a),[C,S]=e.useState(Array.isArray(r)?r:[]),k=x?a:C,q=e.useMemo(()=>{const e=new Map;for(const t of w)e.set(t&&t.key,t);return e},[w]),M=e.useMemo(()=>(Array.isArray(k)?k:[]).map(e=>q.get(e)).filter(Boolean),[k,q]),A="string"==typeof l,[I,T]=e.useState("string"==typeof o?o:""),O=A?l:I,D=function(t,a=300){const r=e.useRef(t),n=e.useRef(null);return r.current=t,e.useEffect(()=>()=>{n.current&&window.clearTimeout(n.current)},[]),R.useCallback((...e)=>{r.current&&(n.current&&window.clearTimeout(n.current),n.current=window.setTimeout(()=>{r.current&&r.current(...e)},a))},[a])}(e=>{i&&i(e)},s),F=M;return R.createElement(m.FormControl,{fullWidth:!0,error:h,disabled:f},R.createElement(m.Autocomplete,{openOnFocus:!0,forcePopupIcon:!0,id:v,multiple:!0,disableCloseOnSelect:!0,options:w,value:F,inputValue:O,getOptionLabel:e=>e&&"object"==typeof e?e.value??"":"",isOptionEqualToValue:(e,t)=>e&&t&&e.key===t.key,loading:c,limitTags:g,disableClearable:b,onChange:(e,t)=>{const a=Array.isArray(t)?t.map(e=>e&&e.key):[];x||S(a),n&&n(a,Array.isArray(t)?t:[])},onInputChange:(e,t,a)=>{A||T(t??""),"input"===a?D(t??""):"clear"===a&&D("")},renderOption:(e,t,{selected:a})=>R.createElement("li",V({},e,{key:t&&t.key||Math.random().toString(36)}),R.createElement(m.Checkbox,{icon:ne,checkedIcon:le,style:{marginRight:8},checked:!!a}),t&&t.value),renderTags:(e,t)=>(Array.isArray(e)?e:[]).map((e,a)=>R.createElement(m.Chip,V({},t({index:a}),{key:e&&e.key||a,label:e&&e.value||""}))),renderInput:e=>R.createElement(m.TextField,V({},e,{label:u,placeholder:d,InputProps:{...e.InputProps,endAdornment:R.createElement(R.Fragment,null,c?R.createElement(m.CircularProgress,{size:18}):null,e.InputProps.endAdornment)},size:p},E))}),y?R.createElement(m.FormHelperText,null,y):null)}const ie=({filter:t,channel:a,query:r})=>{const[n,l]=e.useState([]),[o,i]=e.useState([]),[s,u]=e.useState(!1),[d,c]=e.useState("");return e.useEffect(()=>{i(r?.filter?.[t?.filter]||[])},[r]),e.useEffect(()=>{(async()=>{u(!0);const e=await async function(e,t){return t?.source?(await Z.runReport({id:t.source})).map(e=>({key:e[t.field],value:e[t.field]})):[]}(0,t);l(e),u(!1)})()},[d]),R.default.createElement("div",{style:{display:"flex"}},R.default.createElement("div",{style:{maxWidth:640,minWidth:200}},R.default.createElement(oe,{id:t?.title,label:t?.title,placeholder:"Type to search…",items:n,selectedKeys:o,onChange:(e,r)=>{i(e),a.emit("filterChanged",t,{[t.filter]:e})},onInputChange:e=>{c(e)},loading:s,debounceMs:300,helperText:o.length?`${o.length} selected`:""})))};function se({items:e,value:t,label:a,onChange:r,sx:n={width:"100%"},disabled:l=!1}){const o=e.some(e=>e.key===t)?t:"";return R.default.createElement(j.default,{sx:n},R.default.createElement($.default,{fullWidth:!0},R.default.createElement(z.default,{id:"demo-simple-select-label"},a),R.default.createElement(B.default,{labelId:"demo-simple-select-label",id:"demo-simple-select",value:o,label:a,onChange:r,disabled:l,MenuProps:{style:{maxHeight:"300px"}},size:"small"},e.map(e=>{const{key:t,value:a,disabled:r}=e;return R.default.createElement(Y.default,{key:t,value:t,disabled:r},a)}))))}const ue=({filter:t,channel:a,query:r})=>{const[n,l]=e.useState([]),[o,i]=e.useState("");return e.useEffect(()=>{i(r?.date_range?.name)},[r]),e.useEffect(()=>{(async()=>{const e=(await Z.getDateRanges()).filter(e=>!(t.allowedOptions.length>0)||t.allowedOptions.some(t=>t===e.name)).map(e=>({key:e.name,value:e.title}));l(e)})()},[]),R.default.createElement("div",{style:{minWidth:"200px",maxWidth:"640px"}},R.default.createElement(se,{items:n,value:o,label:t?.title,onChange:(e,r)=>{const n=e.target.value;i(n),a.emit("filterChanged",t,{date_range:{name:n}})}}))},de=({filters:e=[],channel:t,query:a})=>R.default.createElement("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px"}},e.map(e=>"multi-select"===e.type?R.default.createElement(ie,{key:e.title,channel:t,filter:e,query:a}):"date-range"===e.type?R.default.createElement(ue,{key:e.title,channel:t,filter:e,query:a}):null));var ce=e=>R.default.useRef(e||new U.default).current,fe=e=>{const t=R.default.useState({}),a=R.default.useCallback((a,r)=>{let n={...t.current,...r};for(var l in t.current=n,n)"date_range"===l||n[l].length||delete n[l];e?.emit("mergedFilterChanged",{value:n})},[e]);R.default.useEffect(()=>(e?.on("filterChanged",a),()=>{e?.off("filterChanged",a)}),[e])},me=({id:e,cache:t,dashboard:a,channel:r,...n})=>{const[l,o]=R.default.useState(),[i,s]=R.default.useState(),[u,d]=R.default.useState(),[c,m]=R.default.useState(),[p,h]=R.default.useState(re()),[y,g]=R.default.useState(),[b,v]=R.default.useState(0),[E,w]=R.default.useState(!1),[x,C]=R.default.useState(),[S,k]=R.default.useState(!1),M=R.default.useRef({value:n?.filter}),[A,T]=R.default.useState({}),{ref:P,inView:_,entry:j}=f.useInView({threshold:.1,delay:1e3}),z=ce(r);fe(z);const Y=R.default.useCallback(e=>{const t=e.target.value;v(t),g(l.doc.view[t])},[l]);R.default.useEffect(()=>{e&&(async()=>{const a=e,r=t?.[a]||await Z.getChart({id:a}),l=r.doc.source?.id,i=l?t?.[l]||await Z.getReport({id:l}):void 0,u=t?.[`schema_${l}`]||n?.schema||await Z.getReportSchema({id:l}),c=r.doc?.view?.[0];v(0),s(i),o(r),g(c),d(u),k(!0)})().catch(e=>{console.error(e.message)})},[e]),R.default.useEffect(()=>{l&&c&&(!l?.doc?.source?.id||i)&&u&&(async()=>{h(re(l.doc.chart?.component,{view:y,source:c,chart:l,report:i,schema:u,dashboard:a,query:A}))})().catch(e=>{console.error(e.message)})},[l,c,y,i,u]);const $=e=>{const t={...i?.doc.query.filter||{},...n?.filter,...e?.value},a=t.date_range||i?.doc.query.date_range;if(delete t.date_range,k(!1),C(),w(!0),"context"===l?.doc?.source?.type)return m({filter:t}),void w(!1);const r={filter:t,date_range:a,parameters:n?.params};T(r),Z.runReport({id:i.id,query:r}).then(e=>{m(l.doc.source.reverse?e.reverse():e)}).catch(e=>{m([])}).finally(()=>{w(!1)})},B=e=>{M.current=e,_?$(e):(C(e),k(!0))};return R.default.useEffect(()=>(z?.on("mergedFilterChanged",B),()=>{z?.off("mergedFilterChanged",B)}),[z,i,l,_]),R.default.useEffect(()=>{_&&S&&$(x)},[_,S]),R.default.useEffect(()=>{k(!0)},[n.params]),R.default.createElement(q.default,{ref:P,elevation:0,style:{borderRadius:12,padding:20,border:"1px solid #e5e5e5",background:"#fff",display:"flex",flexDirection:"column",gap:"12px",height:"100%"}},l&&R.default.createElement("div",{style:{display:"flex",alignItems:"center",lineHeight:0}},R.default.createElement(I.default,{variant:"subtitle2",style:{fontWeight:600,color:"#252525"}},n?.title||l.doc.name," ")),E?R.default.createElement(H,{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100%",width:"100%"}}):R.default.createElement(R.default.Fragment,null,R.default.createElement("div",{style:{display:"flex"}},R.default.createElement("div",{style:{flexGrow:1}}),R.default.createElement("div",null,l?.doc?.view?.length>1&&R.default.createElement(O.default,null,R.default.createElement(D.default,{labelId:"date-range-select-label",id:"date-range-select",value:b,onChange:Y,style:{fontSize:"12px"},disableUnderline:!0},l.doc.view.map((e,t)=>R.default.createElement(F.default,{key:t,value:t},e.title)))))),R.default.createElement("div",{style:{position:"relative",flexGrow:a?void 0:1,display:"flex",flexDirection:"column"}},R.default.createElement(de,{filters:l?.doc?.filters,channel:z,query:A}),p)))};const pe=e.createContext(void 0),he=()=>e.useContext(pe);var ye={Chart:me,Dashboard:function({id:t="sample_dashboard",api:a,params:r}){const n=he(),l=a||n?.api||{},o=r||n?.parameters||{},[i,s]=R.default.useState(),[u]=R.default.useState(),[d,c]=R.default.useState([]),f=R.default.useRef({}),m=ce();fe(m),console.log({rows:d},{dashboard:i},{schema:u},{params:o}),e.useEffect(()=>{Z.setBaseUrl(l.base_url),Z.setToken(l.token)},[l]);const p=async e=>{const t=e?.doc?.rows||[],a=[];for(let e=0;e<t.length;e++){const r=t[e];r.columns?.forEach(e=>{if(e.override?.filter?.length){const t={};e.override.filter.forEach(e=>{e.hasOwnProperty("value")&&(t[e.field]=[e.value])}),e.filter=t}}),a.push(r)}c(a)};return R.default.useEffect(()=>{t&&(async()=>{Z.setBaseUrl(l.base_url),Z.setToken(l.token),await Z.loadDashboardMeta({dashboardId:t});const e=await Z.getDashboard({id:t});f.current[e?.id]=e,s(e),await p(e)})().catch(e=>console.error(e.message))},[t]),R.default.createElement(W.default,{maxWidth:!1,disableGutters:!0},R.default.createElement(L.default,{container:!0,spacing:3},d?.map((e,t)=>{const a=(e=>0===e?12:12/e)(e.columns.length);return R.default.createElement(R.default.Fragment,{key:t},1===t?R.default.createElement(L.default,{item:!0,xs:12},R.default.createElement(L.default,{container:!0,spacing:3},e.columns.map((e,t)=>R.default.createElement(L.default,{key:t,item:!0,xs:12,md:a},R.default.createElement(me,{api:l,cache:f.current,id:e.id,dashboard:i,schema:u,title:e.title,filter:e.filter,params:o}))))):e.columns.map((e,t)=>R.default.createElement(L.default,{key:t,item:!0,xs:12,md:a},R.default.createElement(me,{api:l,cache:f.current,id:e.id,dashboard:i,schema:u,title:e.title,filter:e.filter,params:o}))))})))},ReportingProvider:({defaultParameters:t={},defaultApi:a={},children:r})=>{const[n,l]=e.useState(t),[o,i]=e.useState(a),s={parameters:n,setParameters:l,api:o,setApi:i,setReportingContext:({parameters:e,api:t})=>{void 0!==e&&l(e),void 0!==t&&i(t)}};return R.default.createElement(pe.Provider,{value:s},r)},useReportingContext:()=>{const t=e.useContext(pe);if(void 0===t)throw new Error("useReportingContext must be used within a ReportingProvider");return t},useReportingContextOptional:he};exports.default=ye;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import React__default, { useEffect, useMemo, useState, useRef } from 'react';
|
|
2
|
+
import React__default, { useEffect, useMemo, useState, useRef, useContext, createContext } from 'react';
|
|
3
3
|
import Paper from '@material-ui/core/Paper';
|
|
4
4
|
import { makeStyles } from '@material-ui/core/styles';
|
|
5
|
-
import
|
|
5
|
+
import { CircularProgress } from '@material-ui/core';
|
|
6
6
|
import { Chart as Chart$1 } from 'react-google-charts';
|
|
7
7
|
import numeral from 'numeral';
|
|
8
8
|
import axios from 'axios';
|
|
@@ -12,7 +12,7 @@ import FormControl$2 from '@material-ui/core/FormControl';
|
|
|
12
12
|
import Select$1 from '@material-ui/core/Select';
|
|
13
13
|
import MenuItem$1 from '@material-ui/core/MenuItem';
|
|
14
14
|
import { useInView } from 'react-intersection-observer';
|
|
15
|
-
import { FormControl, Autocomplete, TextField, CircularProgress, Chip, Checkbox, FormHelperText } from '@mui/material';
|
|
15
|
+
import { FormControl, Autocomplete, TextField, CircularProgress as CircularProgress$1, Chip, Checkbox, FormHelperText } from '@mui/material';
|
|
16
16
|
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
|
|
17
17
|
import CheckBoxIcon from '@mui/icons-material/CheckBox';
|
|
18
18
|
import Box from '@mui/material/Box';
|
|
@@ -22,7 +22,6 @@ import FormControl$1 from '@mui/material/FormControl';
|
|
|
22
22
|
import Select from '@mui/material/Select';
|
|
23
23
|
import EventEmitter from 'eventemitter3';
|
|
24
24
|
import Grid from '@material-ui/core/Grid';
|
|
25
|
-
import Box$1 from '@material-ui/core/Box';
|
|
26
25
|
import Container from '@material-ui/core/Container';
|
|
27
26
|
|
|
28
27
|
function _extends() {
|
|
@@ -37,8 +36,8 @@ function _extends() {
|
|
|
37
36
|
|
|
38
37
|
const useStyles$1 = makeStyles(theme => ({
|
|
39
38
|
root: {
|
|
40
|
-
width:
|
|
41
|
-
|
|
39
|
+
width: "100%",
|
|
40
|
+
"& > * + *": {
|
|
42
41
|
marginTop: theme.spacing(2)
|
|
43
42
|
}
|
|
44
43
|
}
|
|
@@ -47,7 +46,13 @@ function LinearIndeterminate(props) {
|
|
|
47
46
|
const classes = useStyles$1();
|
|
48
47
|
return /*#__PURE__*/React__default.createElement("div", _extends({
|
|
49
48
|
className: classes.root
|
|
50
|
-
}, props), /*#__PURE__*/React__default.createElement(
|
|
49
|
+
}, props), /*#__PURE__*/React__default.createElement(CircularProgress, {
|
|
50
|
+
style: {
|
|
51
|
+
color: "rgb(70, 134, 128)"
|
|
52
|
+
} // custom color
|
|
53
|
+
,
|
|
54
|
+
size: 25
|
|
55
|
+
}));
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
function ValuePicker(view, schema, outputFormat = 'array') {
|
|
@@ -275,6 +280,43 @@ const Api = {
|
|
|
275
280
|
} = await apiClient.post(`/report-build/run`, report);
|
|
276
281
|
return data;
|
|
277
282
|
},
|
|
283
|
+
/**
|
|
284
|
+
* Download ad-hoc report as CSV
|
|
285
|
+
* @param {Object} params - Parameters object
|
|
286
|
+
* @param {Object} params.report - Report definition object containing dimensions, metrics, etc.
|
|
287
|
+
* @param {string} [params.filename] - Optional filename for the downloaded file
|
|
288
|
+
* @returns {Promise} Downloads CSV file
|
|
289
|
+
*/
|
|
290
|
+
downloadAdHocReport: async ({
|
|
291
|
+
report,
|
|
292
|
+
filename
|
|
293
|
+
}) => {
|
|
294
|
+
const response = await apiClient.post(`/report-build/run?download=csv`, report, {
|
|
295
|
+
responseType: 'blob'
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Create a download link and trigger download
|
|
299
|
+
const url = window.URL.createObjectURL(new Blob([response.data]));
|
|
300
|
+
const link = document.createElement('a');
|
|
301
|
+
link.href = url;
|
|
302
|
+
|
|
303
|
+
// Use provided filename, or extract from Content-Disposition header, or use default
|
|
304
|
+
let finalFilename = filename || 'report.csv';
|
|
305
|
+
if (!filename) {
|
|
306
|
+
const contentDisposition = response.headers['content-disposition'];
|
|
307
|
+
if (contentDisposition) {
|
|
308
|
+
const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i);
|
|
309
|
+
if (filenameMatch && filenameMatch[1]) {
|
|
310
|
+
finalFilename = filenameMatch[1];
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
link.setAttribute('download', finalFilename);
|
|
315
|
+
document.body.appendChild(link);
|
|
316
|
+
link.click();
|
|
317
|
+
link.remove();
|
|
318
|
+
window.URL.revokeObjectURL(url);
|
|
319
|
+
},
|
|
278
320
|
getDateRanges: async ({
|
|
279
321
|
dashboardId
|
|
280
322
|
} = {}) => {
|
|
@@ -384,11 +426,11 @@ const useStyles = makeStyles(theme => ({
|
|
|
384
426
|
// },
|
|
385
427
|
}));
|
|
386
428
|
const dateRangeFormats = {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
429
|
+
none: "YYYY-MM-dd",
|
|
430
|
+
day: "MMM dd",
|
|
431
|
+
week: "MMM dd",
|
|
432
|
+
month: "YYYY MMM",
|
|
433
|
+
year: "YYYY"
|
|
392
434
|
};
|
|
393
435
|
function GoogleChart({
|
|
394
436
|
chart,
|
|
@@ -409,7 +451,7 @@ function GoogleChart({
|
|
|
409
451
|
})();
|
|
410
452
|
}, []);
|
|
411
453
|
const dateRangeFormat = useMemo(() => {
|
|
412
|
-
const defaultFormat =
|
|
454
|
+
const defaultFormat = "YYYY-MM-dd";
|
|
413
455
|
const name = query?.date_range?.name;
|
|
414
456
|
const dateRange = dateRanges.find(f => f.name === name);
|
|
415
457
|
if (!dateRange) return defaultFormat;
|
|
@@ -417,12 +459,14 @@ function GoogleChart({
|
|
|
417
459
|
return format;
|
|
418
460
|
}, [dateRanges, query]);
|
|
419
461
|
const getOptions = data => {
|
|
420
|
-
|
|
462
|
+
const customColors = ["#468682", "#ff686b", "#6c757d", "#FFD700", "#073b4c"]; // your custom colors
|
|
463
|
+
|
|
464
|
+
if (chart?.doc.chart?.type === "Table") {
|
|
421
465
|
return {
|
|
422
466
|
...chart?.doc.chart?.options,
|
|
423
467
|
cssClassNames: classes
|
|
424
468
|
};
|
|
425
|
-
} else if (chart?.doc.chart?.type ===
|
|
469
|
+
} else if (chart?.doc.chart?.type === "AreaChart") {
|
|
426
470
|
const hAxisFromChart = chart?.doc.chart?.options?.hAxis || {};
|
|
427
471
|
const hAxisDefaults = {
|
|
428
472
|
ticks: data.slice(1).map(row => row[0]),
|
|
@@ -432,17 +476,18 @@ function GoogleChart({
|
|
|
432
476
|
...hAxisDefaults,
|
|
433
477
|
...hAxisFromChart
|
|
434
478
|
};
|
|
435
|
-
|
|
436
|
-
// console.log({GoogleChart:{chart,source,view,report,schema,query,dateRanges,dateRangeFormat,ticks:hAxis.ticks}})
|
|
437
|
-
|
|
438
479
|
return {
|
|
439
480
|
...chart?.doc.chart?.options,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
481
|
+
hAxis,
|
|
482
|
+
focusTarget: "category",
|
|
483
|
+
colors: customColors // <-- add this line
|
|
444
484
|
};
|
|
445
|
-
} else
|
|
485
|
+
} else {
|
|
486
|
+
return {
|
|
487
|
+
...chart?.doc.chart?.options,
|
|
488
|
+
colors: customColors // add for other chart types too
|
|
489
|
+
};
|
|
490
|
+
}
|
|
446
491
|
};
|
|
447
492
|
React__default.useEffect(() => {
|
|
448
493
|
if (!chart || !view || !source || !report || !schema) return;
|
|
@@ -458,7 +503,7 @@ function GoogleChart({
|
|
|
458
503
|
return data ? /*#__PURE__*/React__default.createElement("div", {
|
|
459
504
|
style: {}
|
|
460
505
|
}, /*#__PURE__*/React__default.createElement(Chart$1, _extends({
|
|
461
|
-
width: chart?.doc.size?.width ||
|
|
506
|
+
width: chart?.doc.size?.width || "100%"
|
|
462
507
|
//height={dashboard ? (chart?.doc.size?.height || '300px') : '100%'}
|
|
463
508
|
,
|
|
464
509
|
chartType: chart?.doc.chart?.type,
|
|
@@ -660,7 +705,7 @@ function CheckboxMultiAutocomplete({
|
|
|
660
705
|
placeholder: placeholder,
|
|
661
706
|
InputProps: {
|
|
662
707
|
...params.InputProps,
|
|
663
|
-
endAdornment: /*#__PURE__*/React.createElement(React.Fragment, null, loading ? /*#__PURE__*/React.createElement(CircularProgress, {
|
|
708
|
+
endAdornment: /*#__PURE__*/React.createElement(React.Fragment, null, loading ? /*#__PURE__*/React.createElement(CircularProgress$1, {
|
|
664
709
|
size: 18
|
|
665
710
|
}) : null, params.InputProps.endAdornment)
|
|
666
711
|
},
|
|
@@ -739,7 +784,8 @@ function SingleSelect({
|
|
|
739
784
|
onChange,
|
|
740
785
|
sx = {
|
|
741
786
|
width: '100%'
|
|
742
|
-
}
|
|
787
|
+
},
|
|
788
|
+
disabled = false
|
|
743
789
|
}) {
|
|
744
790
|
// Check if the current value exists in items, otherwise use empty string
|
|
745
791
|
const validValue = items.some(itm => itm.key === value) ? value : '';
|
|
@@ -755,6 +801,7 @@ function SingleSelect({
|
|
|
755
801
|
value: validValue,
|
|
756
802
|
label: label,
|
|
757
803
|
onChange: onChange,
|
|
804
|
+
disabled: disabled,
|
|
758
805
|
MenuProps: {
|
|
759
806
|
style: {
|
|
760
807
|
maxHeight: '300px'
|
|
@@ -909,7 +956,7 @@ var Chart = ({
|
|
|
909
956
|
entry
|
|
910
957
|
} = useInView({
|
|
911
958
|
/* Optional options */
|
|
912
|
-
threshold: 0.
|
|
959
|
+
threshold: 0.1,
|
|
913
960
|
delay: 1000
|
|
914
961
|
});
|
|
915
962
|
const channelUsed = useChannel(channel);
|
|
@@ -1002,7 +1049,7 @@ var Chart = ({
|
|
|
1002
1049
|
setDirty(false);
|
|
1003
1050
|
setFilter();
|
|
1004
1051
|
setLoading(true);
|
|
1005
|
-
if (chart?.doc?.source?.type ===
|
|
1052
|
+
if (chart?.doc?.source?.type === "context") {
|
|
1006
1053
|
setSource({
|
|
1007
1054
|
filter: finalFilter
|
|
1008
1055
|
});
|
|
@@ -1038,9 +1085,9 @@ var Chart = ({
|
|
|
1038
1085
|
}
|
|
1039
1086
|
};
|
|
1040
1087
|
React__default.useEffect(() => {
|
|
1041
|
-
channelUsed?.on(
|
|
1088
|
+
channelUsed?.on("mergedFilterChanged", onMergedFilterChanged);
|
|
1042
1089
|
return () => {
|
|
1043
|
-
channelUsed?.off(
|
|
1090
|
+
channelUsed?.off("mergedFilterChanged", onMergedFilterChanged);
|
|
1044
1091
|
};
|
|
1045
1092
|
}, [channelUsed, report, chart, inView]);
|
|
1046
1093
|
React__default.useEffect(() => {
|
|
@@ -1052,37 +1099,42 @@ var Chart = ({
|
|
|
1052
1099
|
}, [props.params]);
|
|
1053
1100
|
return /*#__PURE__*/React__default.createElement(Paper, {
|
|
1054
1101
|
ref: ref,
|
|
1102
|
+
elevation: 0,
|
|
1055
1103
|
style: {
|
|
1056
|
-
//margin: "4px",
|
|
1057
|
-
padding: "16px",
|
|
1058
|
-
paddingTop: 0,
|
|
1059
|
-
//flexGrow: dashboard ? undefined : 1, display: "flex", flexDirection: "column",
|
|
1060
|
-
flexGrow: 1,
|
|
1061
|
-
// gap:'16px',
|
|
1062
1104
|
borderRadius: 12,
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1105
|
+
padding: 20,
|
|
1106
|
+
border: "1px solid #e5e5e5",
|
|
1107
|
+
background: "#fff",
|
|
1108
|
+
display: "flex",
|
|
1109
|
+
flexDirection: "column",
|
|
1110
|
+
gap: "12px",
|
|
1111
|
+
height: "100%"
|
|
1112
|
+
}
|
|
1113
|
+
}, chart && /*#__PURE__*/React__default.createElement("div", {
|
|
1069
1114
|
style: {
|
|
1070
|
-
|
|
1115
|
+
display: "flex",
|
|
1116
|
+
alignItems: "center",
|
|
1117
|
+
lineHeight: 0
|
|
1071
1118
|
}
|
|
1072
|
-
}
|
|
1119
|
+
}, /*#__PURE__*/React__default.createElement(Typography, {
|
|
1120
|
+
variant: "subtitle2",
|
|
1073
1121
|
style: {
|
|
1074
|
-
|
|
1122
|
+
fontWeight: 600,
|
|
1123
|
+
color: "#252525"
|
|
1075
1124
|
}
|
|
1076
|
-
},
|
|
1125
|
+
}, props?.title || chart.doc.name, " ")), loading ? /*#__PURE__*/React__default.createElement(LinearIndeterminate, {
|
|
1077
1126
|
style: {
|
|
1078
1127
|
display: "flex",
|
|
1128
|
+
justifyContent: "center",
|
|
1079
1129
|
alignItems: "center",
|
|
1080
|
-
|
|
1130
|
+
height: "100%",
|
|
1131
|
+
width: "100%"
|
|
1081
1132
|
}
|
|
1082
|
-
}, /*#__PURE__*/React__default.createElement(
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1133
|
+
}) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
|
|
1134
|
+
style: {
|
|
1135
|
+
display: "flex"
|
|
1136
|
+
}
|
|
1137
|
+
}, /*#__PURE__*/React__default.createElement("div", {
|
|
1086
1138
|
style: {
|
|
1087
1139
|
flexGrow: 1
|
|
1088
1140
|
}
|
|
@@ -1105,15 +1157,99 @@ var Chart = ({
|
|
|
1105
1157
|
// paddingTop: chart?.doc?.size?.vpad,
|
|
1106
1158
|
// paddingBottom: chart?.doc?.size?.vpad,
|
|
1107
1159
|
flexGrow: dashboard ? undefined : 1,
|
|
1108
|
-
display:
|
|
1109
|
-
flexDirection:
|
|
1160
|
+
display: "flex",
|
|
1161
|
+
flexDirection: "column"
|
|
1110
1162
|
// gap:'16px'
|
|
1111
1163
|
}
|
|
1112
1164
|
}, /*#__PURE__*/React__default.createElement(ChartFilters, {
|
|
1113
1165
|
filters: chart?.doc?.filters,
|
|
1114
1166
|
channel: channelUsed,
|
|
1115
1167
|
query: currentQuery
|
|
1116
|
-
}), chartType));
|
|
1168
|
+
}), chartType)));
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
// Create the context
|
|
1172
|
+
const ReportingContext = /*#__PURE__*/createContext(undefined);
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* ReportingProvider - Provides reporting configuration context to child components
|
|
1176
|
+
*
|
|
1177
|
+
* @param {Object} props
|
|
1178
|
+
* @param {Object} [props.defaultParameters] - Default parameters for reports (base_currency, merchants, client, etc.)
|
|
1179
|
+
* @param {Object} [props.defaultApi] - Default API configuration (token, base_url)
|
|
1180
|
+
* @param {React.ReactNode} props.children - Child components
|
|
1181
|
+
*/
|
|
1182
|
+
const ReportingProvider = ({
|
|
1183
|
+
defaultParameters = {},
|
|
1184
|
+
defaultApi = {},
|
|
1185
|
+
children
|
|
1186
|
+
}) => {
|
|
1187
|
+
const [parameters, setParameters] = useState(defaultParameters);
|
|
1188
|
+
const [api, setApi] = useState(defaultApi);
|
|
1189
|
+
const value = {
|
|
1190
|
+
parameters,
|
|
1191
|
+
setParameters,
|
|
1192
|
+
api,
|
|
1193
|
+
setApi,
|
|
1194
|
+
// Convenience method to update both at once
|
|
1195
|
+
setReportingContext: ({
|
|
1196
|
+
parameters: newParams,
|
|
1197
|
+
api: newApi
|
|
1198
|
+
}) => {
|
|
1199
|
+
if (newParams !== undefined) {
|
|
1200
|
+
setParameters(newParams);
|
|
1201
|
+
}
|
|
1202
|
+
if (newApi !== undefined) {
|
|
1203
|
+
setApi(newApi);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
return /*#__PURE__*/React__default.createElement(ReportingContext.Provider, {
|
|
1208
|
+
value: value
|
|
1209
|
+
}, children);
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* useReportingContext - Hook to access reporting context
|
|
1214
|
+
*
|
|
1215
|
+
* @returns {Object} Context value with parameters, api, and setter functions
|
|
1216
|
+
* @returns {Object} return.parameters - Current parameters object
|
|
1217
|
+
* @returns {Function} return.setParameters - Function to update parameters
|
|
1218
|
+
* @returns {Object} return.api - Current API configuration
|
|
1219
|
+
* @returns {Function} return.setApi - Function to update API configuration
|
|
1220
|
+
* @returns {Function} return.setReportingContext - Function to update both parameters and api
|
|
1221
|
+
*
|
|
1222
|
+
* @example
|
|
1223
|
+
* const { parameters, setParameters, api, setApi, setReportingContext } = useReportingContext();
|
|
1224
|
+
*
|
|
1225
|
+
* // Update parameters only
|
|
1226
|
+
* setParameters({ base_currency: 'USD', merchants: [...] });
|
|
1227
|
+
*
|
|
1228
|
+
* // Update API only
|
|
1229
|
+
* setApi({ token: 'new-token', base_url: 'https://api.example.com' });
|
|
1230
|
+
*
|
|
1231
|
+
* // Update both at once
|
|
1232
|
+
* setReportingContext({
|
|
1233
|
+
* parameters: { base_currency: 'EUR' },
|
|
1234
|
+
* api: { token: 'token', base_url: 'https://api.example.com' }
|
|
1235
|
+
* });
|
|
1236
|
+
*/
|
|
1237
|
+
const useReportingContext = () => {
|
|
1238
|
+
const context = useContext(ReportingContext);
|
|
1239
|
+
if (context === undefined) {
|
|
1240
|
+
throw new Error('useReportingContext must be used within a ReportingProvider');
|
|
1241
|
+
}
|
|
1242
|
+
return context;
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* useReportingContextOptional - Hook to optionally access reporting context
|
|
1247
|
+
* Returns null if used outside of ReportingProvider (useful for optional fallback)
|
|
1248
|
+
*
|
|
1249
|
+
* @returns {Object|null} Context value or null if not within provider
|
|
1250
|
+
*/
|
|
1251
|
+
const useReportingContextOptional = () => {
|
|
1252
|
+
return useContext(ReportingContext);
|
|
1117
1253
|
};
|
|
1118
1254
|
|
|
1119
1255
|
function Dashboard({
|
|
@@ -1121,6 +1257,11 @@ function Dashboard({
|
|
|
1121
1257
|
api,
|
|
1122
1258
|
params
|
|
1123
1259
|
}) {
|
|
1260
|
+
const reportingContext = useReportingContextOptional();
|
|
1261
|
+
|
|
1262
|
+
// Use props if provided, otherwise fall back to context
|
|
1263
|
+
const finalApi = api || reportingContext?.api || {};
|
|
1264
|
+
const finalParams = params || reportingContext?.parameters || {};
|
|
1124
1265
|
const [dashboard, setDashboard] = React__default.useState();
|
|
1125
1266
|
//const [schema, setSchema] = React.useState();
|
|
1126
1267
|
const [schema] = React__default.useState();
|
|
@@ -1128,15 +1269,24 @@ function Dashboard({
|
|
|
1128
1269
|
const cache = React__default.useRef({});
|
|
1129
1270
|
const channel = useChannel();
|
|
1130
1271
|
useFilterManager(channel);
|
|
1272
|
+
console.log({
|
|
1273
|
+
rows
|
|
1274
|
+
}, {
|
|
1275
|
+
dashboard
|
|
1276
|
+
}, {
|
|
1277
|
+
schema
|
|
1278
|
+
}, {
|
|
1279
|
+
params: finalParams
|
|
1280
|
+
});
|
|
1131
1281
|
useEffect(() => {
|
|
1132
|
-
// console.log('token changed',
|
|
1282
|
+
// console.log('token changed',finalApi);
|
|
1133
1283
|
|
|
1134
|
-
Api.setBaseUrl(
|
|
1135
|
-
Api.setToken(
|
|
1136
|
-
}, [
|
|
1284
|
+
Api.setBaseUrl(finalApi.base_url);
|
|
1285
|
+
Api.setToken(finalApi.token);
|
|
1286
|
+
}, [finalApi]);
|
|
1137
1287
|
const init = async () => {
|
|
1138
|
-
Api.setBaseUrl(
|
|
1139
|
-
Api.setToken(
|
|
1288
|
+
Api.setBaseUrl(finalApi.base_url);
|
|
1289
|
+
Api.setToken(finalApi.token);
|
|
1140
1290
|
await Api.loadDashboardMeta({
|
|
1141
1291
|
dashboardId: id
|
|
1142
1292
|
});
|
|
@@ -1161,7 +1311,7 @@ function Dashboard({
|
|
|
1161
1311
|
if (column.override?.filter?.length) {
|
|
1162
1312
|
const filter = {};
|
|
1163
1313
|
column.override.filter.forEach(item => {
|
|
1164
|
-
if (item.hasOwnProperty(
|
|
1314
|
+
if (item.hasOwnProperty("value")) filter[item.field] = [item.value];
|
|
1165
1315
|
// else filter[item.field] = [sourceDataRow[item.field]];
|
|
1166
1316
|
});
|
|
1167
1317
|
column.filter = filter;
|
|
@@ -1175,6 +1325,10 @@ function Dashboard({
|
|
|
1175
1325
|
if (!id) return;
|
|
1176
1326
|
init().catch(error => console.error(error.message));
|
|
1177
1327
|
}, [id]);
|
|
1328
|
+
const getMd = count => {
|
|
1329
|
+
if (count === 0) return 12;
|
|
1330
|
+
return 12 / count;
|
|
1331
|
+
};
|
|
1178
1332
|
return (
|
|
1179
1333
|
/*#__PURE__*/
|
|
1180
1334
|
// <Container>
|
|
@@ -1203,59 +1357,70 @@ function Dashboard({
|
|
|
1203
1357
|
// </Container>
|
|
1204
1358
|
React__default.createElement(Container, {
|
|
1205
1359
|
maxWidth: false,
|
|
1206
|
-
disableGutters: true
|
|
1207
|
-
style
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
overflow: 'hidden'
|
|
1213
|
-
}
|
|
1360
|
+
disableGutters: true
|
|
1361
|
+
// style={{
|
|
1362
|
+
// padding: "24px",
|
|
1363
|
+
// background: "#f7f8fa",
|
|
1364
|
+
// borderRadius: "10px",
|
|
1365
|
+
// }}
|
|
1214
1366
|
}, /*#__PURE__*/React__default.createElement(Grid, {
|
|
1215
1367
|
container: true,
|
|
1216
|
-
spacing:
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1368
|
+
spacing: 3
|
|
1369
|
+
}, rows?.map((row, rowIndex) => {
|
|
1370
|
+
const count = row.columns.length;
|
|
1371
|
+
const md = getMd(count);
|
|
1372
|
+
return /*#__PURE__*/React__default.createElement(React__default.Fragment, {
|
|
1373
|
+
key: rowIndex
|
|
1374
|
+
}, rowIndex === 1 ?
|
|
1375
|
+
/*#__PURE__*/
|
|
1376
|
+
// Row 2 is special: nested grid inside a full-width container
|
|
1377
|
+
React__default.createElement(Grid, {
|
|
1378
|
+
item: true,
|
|
1379
|
+
xs: 12
|
|
1380
|
+
}, /*#__PURE__*/React__default.createElement(Grid, {
|
|
1381
|
+
container: true,
|
|
1382
|
+
spacing: 3
|
|
1383
|
+
}, row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(Grid, {
|
|
1384
|
+
key: i,
|
|
1385
|
+
item: true,
|
|
1386
|
+
xs: 12,
|
|
1387
|
+
md: md
|
|
1388
|
+
}, /*#__PURE__*/React__default.createElement(Chart, {
|
|
1389
|
+
api: finalApi,
|
|
1390
|
+
cache: cache.current,
|
|
1391
|
+
id: column.id,
|
|
1392
|
+
dashboard: dashboard,
|
|
1393
|
+
schema: schema,
|
|
1394
|
+
title: column.title,
|
|
1395
|
+
filter: column.filter,
|
|
1396
|
+
params: finalParams
|
|
1397
|
+
}))))) :
|
|
1398
|
+
// All other rows behave normally
|
|
1399
|
+
row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(Grid, {
|
|
1400
|
+
key: i,
|
|
1401
|
+
item: true,
|
|
1402
|
+
xs: 12,
|
|
1403
|
+
md: md
|
|
1404
|
+
}, /*#__PURE__*/React__default.createElement(Chart, {
|
|
1405
|
+
api: finalApi,
|
|
1406
|
+
cache: cache.current,
|
|
1407
|
+
id: column.id,
|
|
1408
|
+
dashboard: dashboard,
|
|
1409
|
+
schema: schema,
|
|
1410
|
+
title: column.title,
|
|
1411
|
+
filter: column.filter,
|
|
1412
|
+
params: finalParams
|
|
1413
|
+
}))));
|
|
1414
|
+
})))
|
|
1253
1415
|
);
|
|
1254
1416
|
}
|
|
1255
1417
|
|
|
1256
1418
|
var index = {
|
|
1257
1419
|
Chart,
|
|
1258
|
-
Dashboard
|
|
1420
|
+
Dashboard,
|
|
1421
|
+
ReportingProvider,
|
|
1422
|
+
useReportingContext,
|
|
1423
|
+
useReportingContextOptional
|
|
1259
1424
|
};
|
|
1260
1425
|
|
|
1261
1426
|
export { index as default };
|