directus-extension-sql-query-panel 1.2.0 → 1.2.1

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.
Files changed (2) hide show
  1. package/dist/app.js +1 -1
  2. package/package.json +1 -1
package/dist/app.js CHANGED
@@ -1 +1 @@
1
- import{useApi as e,useStores as t,definePanel as n}from"@directus/extensions-sdk";import{onMounted as a,nextTick as o,getCurrentScope as r,onScopeDispose as l,getCurrentInstance as i,computed as s,shallowRef as u,ref as c,watch as d,toValue as f,resolveComponent as v,resolveDirective as h,createElementBlock as p,openBlock as m,createElementVNode as b,normalizeProps as g,guardReactiveProps as y,unref as w,createCommentVNode as k,normalizeClass as x,createVNode as q,withCtx as S,Fragment as _,renderList as C,normalizeStyle as L,createTextVNode as T,createBlock as A,toDisplayString as j,mergeProps as R,renderSlot as $,withModifiers as E,withDirectives as O,defineComponent as z,toRefs as D,createSlots as B}from"vue";import{useRouter as N}from"vue-router";import{useI18n as W}from"vue-i18n";var H="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function I(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var P=/^\s+|\s+$/g,M=/^[-+]0x[0-9a-f]+$/i,U=/^0b[01]+$/i,V=/^0o[0-7]+$/i,G=parseInt,Q="object"==typeof H&&H&&H.Object===Object&&H,Y="object"==typeof self&&self&&self.Object===Object&&self,F=Q||Y||Function("return this")(),J=Object.prototype.toString,Z=Math.max,K=Math.min,X=function(){return F.Date.now()};function ee(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function te(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==J.call(e)}(e))return NaN;if(ee(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=ee(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(P,"");var n=U.test(e);return n||V.test(e)?G(e.slice(2),n?2:8):M.test(e)?NaN:+e}var ne=I((function(e,t,n){var a,o,r,l,i,s,u=0,c=!1,d=!1,f=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function v(t){var n=a,r=o;return a=o=void 0,u=t,l=e.apply(r,n)}function h(e){var n=e-s;return void 0===s||n>=t||n<0||d&&e-u>=r}function p(){var e=X();if(h(e))return m(e);i=setTimeout(p,function(e){var n=t-(e-s);return d?K(n,r-(e-u)):n}(e))}function m(e){return i=void 0,f&&a?v(e):(a=o=void 0,l)}function b(){var e=X(),n=h(e);if(a=arguments,o=this,s=e,n){if(void 0===i)return function(e){return u=e,i=setTimeout(p,t),c?v(e):l}(s);if(d)return i=setTimeout(p,t),v(s)}return void 0===i&&(i=setTimeout(p,t)),l}return t=te(t)||0,ee(n)&&(c=!!n.leading,r=(d="maxWait"in n)?Z(te(n.maxWait)||0,t):r,f="trailing"in n?!!n.trailing:f),b.cancel=function(){void 0!==i&&clearTimeout(i),u=0,a=s=o=i=void 0},b.flush=function(){return void 0===i?l:m(X())},b}));const ae="undefined"!=typeof window&&"undefined"!=typeof document;function oe(e,t=!0,n){i()?a(e,n):t?e():o(e)}"undefined"!=typeof WorkerGlobalScope&&(globalThis,WorkerGlobalScope);const re=ae?window:void 0;function le(e){var t;const n=f(e);return null!=(t=null==n?void 0:n.$el)?t:n}function ie(e){const t=function(){const e=u(!1),t=i();return t&&a((()=>{e.value=!0}),t),e}();return s((()=>(t.value,Boolean(e()))))}function se(e,t,n={}){const{window:a=re,...o}=n;let i;const u=ie((()=>a&&"ResizeObserver"in a)),c=()=>{i&&(i.disconnect(),i=void 0)},v=s((()=>{const t=f(e);return Array.isArray(t)?t.map((e=>le(e))):[le(t)]})),h=d(v,(e=>{if(c(),u.value&&a){i=new ResizeObserver(t);for(const t of e)t&&i.observe(t,o)}}),{immediate:!0,flush:"post"}),p=()=>{c(),h()};var m;return m=p,r()&&l(m),{isSupported:u,stop:p}}function ue(e,t={width:0,height:0},n={}){const{window:a=re,box:o="content-box"}=n,r=s((()=>{var t,n;return null==(n=null==(t=le(e))?void 0:t.namespaceURI)?void 0:n.includes("svg")})),l=u(t.width),i=u(t.height),{stop:c}=se(e,(([t])=>{const n="border-box"===o?t.borderBoxSize:"content-box"===o?t.contentBoxSize:t.devicePixelContentBoxSize;if(a&&r.value){const t=le(e);if(t){const e=t.getBoundingClientRect();l.value=e.width,i.value=e.height}}else if(n){const e=(s=n,Array.isArray(s)?s:[s]);l.value=e.reduce(((e,{inlineSize:t})=>e+t),0),i.value=e.reduce(((e,{blockSize:t})=>e+t),0)}else l.value=t.contentRect.width,i.value=t.contentRect.height;var s}),n);oe((()=>{const n=le(e);n&&(l.value="offsetWidth"in n?n.offsetWidth:t.width,i.value="offsetHeight"in n?n.offsetHeight:t.height)}));const f=d((()=>le(e)),(e=>{l.value=e?t.width:0,i.value=e?t.height:0}));return{width:l,height:i,stop:function(){c(),f()}}}function ce(e,t){const{containerStyle:n,wrapperProps:a,scrollTo:o,calculateRange:r,currentList:l,containerRef:i}="itemHeight"in t?function(e,t){const n=de(t),{state:a,source:o,currentList:r,size:l,containerRef:i}=n,u={overflowY:"auto"},{itemHeight:c,overscan:d=5}=e,f=fe(a,o,c),v=ve(o,c),h=he("vertical",d,v,f,n),p=pe(c,o),m=s((()=>p(a.value.start))),b=be(c,o);me(l,t,i,h);const g=ye("vertical",h,p,i),y=s((()=>({style:{width:"100%",height:b.value-m.value+"px",marginTop:`${m.value}px`}})));return{calculateRange:h,scrollTo:g,containerStyle:u,wrapperProps:y,currentList:r,containerRef:i}}(t,e):function(e,t){const n=de(t),{state:a,source:o,currentList:r,size:l,containerRef:i}=n,u={overflowX:"auto"},{itemWidth:c,overscan:d=5}=e,f=fe(a,o,c),v=ve(o,c),h=he("horizontal",d,v,f,n),p=pe(c,o),m=s((()=>p(a.value.start))),b=be(c,o);me(l,t,i,h);const g=ye("horizontal",h,p,i),y=s((()=>({style:{height:"100%",width:b.value-m.value+"px",marginLeft:`${m.value}px`,display:"flex"}})));return{scrollTo:g,calculateRange:h,wrapperProps:y,containerStyle:u,currentList:r,containerRef:i}}(t,e);return{list:l,scrollTo:o,containerProps:{ref:i,onScroll:()=>{r()},style:n},wrapperProps:a}}function de(e){const t=u(null),n=ue(t),a=c([]),o=u(e);return{state:c({start:0,end:10}),source:o,currentList:a,size:n,containerRef:t}}function fe(e,t,n){return a=>{if("number"==typeof n)return Math.ceil(a/n);const{start:o=0}=e.value;let r=0,l=0;for(let e=o;e<t.value.length;e++){if(r+=n(e),l=e,r>a)break}return l-o}}function ve(e,t){return n=>{if("number"==typeof t)return Math.floor(n/t)+1;let a=0,o=0;for(let r=0;r<e.value.length;r++){if(a+=t(r),a>=n){o=r;break}}return o+1}}function he(e,t,n,a,{containerRef:o,state:r,currentList:l,source:i}){return()=>{const s=o.value;if(s){const o=n("vertical"===e?s.scrollTop:s.scrollLeft),u=a("vertical"===e?s.clientHeight:s.clientWidth),c=o-t,d=o+u+t;r.value={start:c<0?0:c,end:d>i.value.length?i.value.length:d},l.value=i.value.slice(r.value.start,r.value.end).map(((e,t)=>({data:e,index:t+r.value.start})))}}}function pe(e,t){return n=>{if("number"==typeof e){return n*e}return t.value.slice(0,n).reduce(((t,n,a)=>t+e(a)),0)}}function me(e,t,n,a){d([e.width,e.height,t,n],(()=>{a()}))}function be(e,t){return s((()=>"number"==typeof e?t.value.length*e:t.value.reduce(((t,n,a)=>t+e(a)),0)))}const ge={horizontal:"scrollLeft",vertical:"scrollTop"};function ye(e,t,n,a){return o=>{a.value&&(a.value[ge[e]]=n(o),t())}}const we={sum:"Σ",avg:"μ",count:"#",count_unique:"#!"},ke={sum:(e,t)=>e.reduce(((e,n)=>e+Number.parseInt(n[t])),0),avg:(e,t)=>Math.round(ke.sum(e,t)/e.length),count:e=>e.length,count_unique:(e,t)=>new Set(e.map((e=>e[t]))).size,count_groups:(e,t)=>e.reduce(((e,n)=>{const a=n[t];return e[a]=(e[a]||0)+1,e}),{})};var xe=[],qe=[];function Se(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",o=!0===t.singleTag,r="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(o){var l=xe.indexOf(r);-1===l&&(l=xe.push(r)-1,qe[l]={}),n=qe[l]&&qe[l][a]?qe[l][a]:qe[l][a]=i()}else n=i();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function i(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),o=0;o<n.length;o++)e.setAttribute(n[o],t.attributes[n[o]]);var l="prepend"===a?"afterbegin":"beforeend";return r.insertAdjacentElement(l,e),e}}Se("\nbody {\n --v-table-color: var(--v-input-color);\n --v-table-background-color: var(--v-input-background-color);\n}\n.sql-query-table[data-v-d4f2aab7] {\n position: relative;\n height: var(--v-table-height);\n overflow-y: auto;\n\n --sqt-head--background: var(--background-normal, var(--theme--background));\n --sqt-head--color: color: var(--foreground-normal, var(--theme--foreground));\n\n --sqt-foot--background: var(--background-normal, var(--theme--background));\n --sqt-foot--color: color: var(--foreground-normal, var(--theme--foreground));\n}\ntable[data-v-d4f2aab7] {\n min-width: 100%;\n min-height: 100%;\n border-collapse: collapse;\n border-spacing: 0;\n background-color: var(--v-table-background-color);\n color: var(--v-table-color);\n}\ntable thead[data-v-d4f2aab7] {\n background-color: var(--sqt-head--background);\n color: var(--sqt-head--color);\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable thead.fixed[data-v-d4f2aab7] {\n position: sticky;\n top: 0;\n z-index: 3;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);\n}\ntable thead tr.headers th[data-v-d4f2aab7] {\n padding: 8px;\n font-weight: bold;\n min-width: 3rem;\n background-color: var(--sqt-head--background);\n color: var(--sqt-head--color);\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable tr.search th[data-v-d4f2aab7] {\n padding: 0;\n}\ntable tr.search th .search-input.v-input[data-v-d4f2aab7] {\n margin: 0;\n border: none;\n}\ntable th .sort-icon[data-v-d4f2aab7] {\n opacity: 0;\n}\ntable th:hover .sort-icon[data-v-d4f2aab7] {\n opacity: 0.5;\n}\ntable th .sort-icon.show[data-v-d4f2aab7] {\n opacity: 1;\n}\ntable th.select[data-v-d4f2aab7] {\n width: 2rem;\n}\ntable td[data-v-d4f2aab7] {\n padding: 8px;\n align: middle;\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable tr.clickable[data-v-d4f2aab7]:hover {\n background-color: var(--theme--background-subdued);\n cursor: pointer\n}\ntable tr.active[data-v-d4f2aab7] {\n background-color: var(--theme--background-accent);\n}\ntable tbody[data-v-d4f2aab7] {\n display: contents;\n}\ntable tfoot tr[data-v-d4f2aab7] {\n position: sticky;\n bottom: 0;\n background-color: var(--sqt-foot--background);\n color: var(--sqt-foot--color);\n box-shadow: var(--card-shadow);\n}\ntable tfoot tr td[data-v-d4f2aab7] {\n padding: 8px;\n height: 44px;\n font-weight: bold;\n background-color: var(--sqt-foot--background);\n color: var(--sqt-foot--color);\n}\n",{});var _e=(e,t)=>{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n};const Ce={class:"sql-query-table"},Le={key:0,class:"search"},Te={colspan:"80%"},Ae={class:"headers"},je=["onClick","align"],Re={key:0},$e={key:1},Ee=["colspan"],Oe={key:0},ze={colspan:"100%"},De=["onClick"],Be={key:2},Ne={key:0,class:"v-text-overflow"},We={__name:"FastTable",props:{loading:Boolean,headers:{type:Array,validator:e=>e.every((e=>e.value&&e.text)),required:!0},items:{type:Array,required:!0},sort:String,sortDesc:Boolean,fixedHeader:Boolean,rowClickable:Boolean},emits:["update:sort","update:sortDesc","click:row"],setup(e,{emit:t}){const{t:n}=W(),a=e,o=c(""),r=s((()=>a.headers.filter((e=>e.searchable)))),l=s((()=>{a.sort,a.sortDesc;const e=o.value?o.value.toLowerCase().trim():"";return e?a.items.filter((t=>r.value.some((n=>t[n.value]&&t[n.value].toLowerCase().includes(e))))):a.items})),{list:i,containerProps:u,wrapperProps:d}=ce(l,{itemHeight:40}),f=s((()=>{const e=function(e,t){if(!t.some((e=>!!e.summarise)))return null;const n={};for(const a of t){if(!a.summarise)continue;const t=ke[a.summarise];if(!t)throw new Error(`Summariser function for ${a.summarise} not found.`);const o=t(e,a.value);if("count_groups"===a.summarise){let e=JSON.stringify(o,null,1).replace("{\n","").replace("\n}","").replace(/[",]/g,"");n[a.value]=e}else n[a.value]=`${we[a.summarise]} ${o}`}return n}(l.value,a.headers);return e})),z=t,D=c(null);return(t,l)=>{const s=v("v-icon"),c=v("v-input"),B=v("v-progress-linear"),N=v("v-card-title"),W=v("v-card"),H=h("tooltip");return m(),p("div",Ce,[b("table",g(y(w(u))),[b("thead",{class:x(["table-header",{fixed:e.fixedHeader}])},[r.value.length&&e.items.length>10?(m(),p("tr",Le,[b("th",Te,[q(c,{modelValue:o.value,"onUpdate:modelValue":l[0]||(l[0]=e=>o.value=e),small:"",trim:"",class:"search-input",rounded:"",placeholder:"Search"},{prepend:S((()=>[q(s,{name:"search"})])),_:1},8,["modelValue"])])])):k("v-if",!0),b("tr",Ae,[(m(!0),p(_,null,C(e.headers,(n=>(m(),p("th",{style:L({minWidth:`${n.width||t.auto}ch`}),key:n.value,onClick:e=>function(e){e.sortable&&(z("update:sort",e.value),z("update:sortDesc",!a.sortDesc))}(n),align:n.align||"left"},[T(j(n.text)+" ",1),n.sortable?(m(),A(s,{key:0,name:"sort",small:"",class:x(["sort-icon",{show:e.sort===n.value}]),style:L(`transform: ${e.sortDesc?"rotateZ(0deg) rotateY(0deg)":"rotateZ(180deg) rotateY(180deg)"}; transition: .2s all ease`)},null,8,["class","style"])):k("v-if",!0)],12,je)))),128)),t.$slots["item-append"]?(m(),p("th",Re,"#")):k("v-if",!0)]),e.loading?(m(),p("tr",$e,[b("td",{colspan:e.headers.length+1},[q(B,{indeterminate:""})],8,Ee)])):k("v-if",!0)],2),e.loading||e.items.length?(m(),p("tbody",g(R({key:1},w(d))),[$(t.$slots,"default",{items:w(i)},(()=>[(m(!0),p(_,null,C(w(i),(({data:n})=>(m(),p("tr",{onClick:e=>{D.value=n,z("click:row",{item:n,event:e})},class:x({clickable:e.rowClickable,active:D.value===n})},[(m(!0),p(_,null,C(e.headers,(e=>(m(),p("td",{key:e.value,class:x(`align-${e.align}`)},j(n[e.value]),3)))),128)),t.$slots["item-append"]?(m(),p("td",{key:0,onClick:l[1]||(l[1]=E((()=>{}),["stop"]))},[$(t.$slots,"item-append",{item:n},void 0,!0)])):k("v-if",!0)],10,De)))),256))]),!0),k(" This is to fill up any remaining height in the table "),l[2]||(l[2]=b("tr",null,[b("td",{style:{height:"100%"}})],-1))],16)):(m(),p("tbody",Oe,[b("tr",null,[b("td",ze,[q(W,{style:{padding:"2rem","--v-card-max-width":"100%",margin:"2rem auto"}},{default:S((()=>[q(N,null,{default:S((()=>[q(s,{name:"info",style:{"margin-right":"2rem"}}),T(" "+j(w(n)("no_items")),1)])),_:1})])),_:1})])])])),f.value?(m(),p("tfoot",Be,[b("tr",null,[(m(!0),p(_,null,C(e.headers,(e=>O((m(),p("td",{key:e.value},[f.value[e.value]?(m(),p("code",Ne,j(f.value[e.value]),1)):k("v-if",!0)])),[[H,e.summarise]]))),128))])])):k("v-if",!0)],16)])}}};var He=_e(We,[["__scopeId","data-v-d4f2aab7"]]);const Ie={key:0,class:"center"},Pe={key:0};var Me=z({__name:"panel",props:{id:{},showHeader:{type:Boolean},sql:{},cache:{},columns:{},download:{type:Boolean,default:!0},is_static:{type:Boolean},actions:{}},setup(n){const a=N(),r=n,{id:l,showHeader:i,download:u,is_static:f}=D(r),b=c(!1),g=c(""),y=c(""),L=c(null),R=c(null),$=e(),{useInsightsStore:E}=t(),z=E(),W=c(new Set),H=s((()=>{const e=new Set(W.value),t=r.sql.match(/{{ \w+ }}/g);return t&&t.forEach((t=>e.add(t.replace(/{{ | }}/g,"")))),e})),I=s((()=>{const e={},t=[];return H.value.forEach((n=>{const a=z.getVariable(n);null==a?t.push(n):e[n]=a})),t.length?t:e}));if(f.value)o(Y);else{const e=ne(Y,1e3);d(I,(()=>{Array.isArray(I.value)?y.value=`Please specify: ${I.value.join(" & ")}`:(y.value="",R.value||(b.value=!0),e())}),{immediate:!0})}const P=s((()=>r.columns?.length>0?r.columns.map((e=>({...e,text:e.text||e.value}))):L.value)),M=c({by:null,desc:!1});d(M,(({by:e,desc:t})=>{e&&R.value&&(R.value=R.value.sort(((n,a)=>n[e]<a[e]?t?1:-1:n[e]>a[e]?t?-1:1:0)))}),{deep:!0});let U,V,G=!1,Q={};async function Y(){if(b.value=!1,Array.isArray(I.value))Q={};else{if(!G){let e=!H.value.size;for(const t in I.value)Q[t]!==I.value[t]&&(e=!0),Q[t]=I.value[t];if(!e)return;b.value=!0}g.value="";try{const e={};V=e;const{data:t}=await $.get(`insights/query/${l.value}`,{params:I.value});if(V!==e)return;t.error&&(g.value=t.error),G=!1,r.cache&&setTimeout((()=>{G=!0}),1e3*r.cache);const n=JSON.stringify(t);if(U===n)return void(b.value=!1);if(U=n,L.value=null,R.value=null,t.headers&&t.items){const e=t.items.length>2;L.value=t.headers.map((function(t,n){const a=t.replace(/_/g," ").replace(/(?:^|\s)\S/g,(function(e){return e.toUpperCase()}));return{text:a,value:t,width:a.length+1,sortable:e}}));const n=r.columns&&r.columns.filter((e=>e.isNumber));R.value=n?t.items.map((e=>(n.forEach((t=>{e[t.value]=""!==e[t.value]?1*e[t.value]:null})),e))):t.items}}catch(e){const t=e.response?.data?.error||e.message;t.includes("Missing query param")?(y.value=t.replace("Missing query param","Please specify"),t.split(": ")[1].split(", ").forEach((e=>W.value.add(e)))):g.value=t}b.value=!1}}const F=s((()=>r.actions?.find((e=>e.row))));function J(){const e=L.value||P.value;if(e&&R.value){let t=e.map((e=>e.text)).join(",");t+="\r\n",t+=function(){if(!R.value)return;let e="";return R.value.forEach((t=>{for(let n in t)/[, ]/.test(t[n])?e+=`"${t[n].replace(/"/g,'\\"')}",`:e+=t[n]+",";e+="\r\n"})),e}();const n=(new Date).toISOString()+".csv",a=new Blob([t],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob)navigator.msSaveBlob(a,n);else{const e=document.createElement("a");if(void 0!==e.download){const t=URL.createObjectURL(a);e.setAttribute("href",t),e.setAttribute("download",n),e.style.visibility="hidden",document.body.appendChild(e),e.click(),document.body.removeChild(e)}}}}function Z({item:e}){F.value&&K(F.value,e)}function K(e,t){e.filter&&e.filter.forEach((({variable:e,value:n})=>{z.setVariable(e,n.replace(/%(\w+)%/g,((e,n)=>t[n])))})),e.link&&a.push(function(e,t){let n=e;for(let e in t)n=n.replace(new RegExp(`%${e}%`,"g"),t[e]);return n}(e.link,t))}return(e,t)=>{const n=v("v-progress-circular"),a=v("v-notice"),o=v("v-icon"),r=v("v-button"),l=h("tooltip");return m(),p("div",{class:x(["sql-panel-container",{"has-header":w(i)}])},[b.value||g.value||y.value?(m(),p("div",Ie,[b.value?(m(),A(n,{key:0,indeterminate:""})):y.value?(m(),A(a,{key:1,type:"info",center:""},{default:S((()=>[T(j(y.value),1)])),_:1})):(m(),A(a,{key:2,type:"danger",center:""},{default:S((()=>[T(j(g.value),1)])),_:1}))])):P.value&&R.value?(m(),p(_,{key:1},[w(u)?(m(),A(r,{key:0,onClick:J,icon:"",secondary:"",class:"export-csv-button"},{default:S((()=>[q(o,{name:"download-file"})])),_:1})):k("v-if",!0),q(He,{headers:P.value,items:R.value,"onClick:row":Z,sort:M.value.by,"onUpdate:sort":t[0]||(t[0]=e=>M.value.by=e),sortDesc:M.value.desc,"onUpdate:sortDesc":t[1]||(t[1]=e=>M.value.desc=e),rowClickable:!!F.value,"fixed-header":""},B({_:2},[e.actions?.find((e=>!e.row))?{name:"item-append",fn:S((({item:t})=>[(m(!0),p(_,null,C(e.actions.filter((e=>!e.row)),(e=>O((m(),A(r,{outlined:"",onClick:n=>K(e,t),icon:!e.show_label,"x-small":""},{default:S((()=>[q(o,{name:e.icon},null,8,["name"]),e.show_label?(m(),p("span",Pe,j(e.label),1)):k("v-if",!0)])),_:2},1032,["onClick","icon"])),[[l,e.label]]))),256))])),key:"0"}:void 0]),1032,["headers","items","sort","sortDesc","rowClickable"])],64)):k("v-if",!0)],2)}}});Se("\n.sql-panel-container {\n width: 100%;\n height: 100%;\n --v-table-height: 100%;\n}\n.sql-panel-container .v-text-overflow {\n user-select: text;\n white-space: pre-wrap;\n}\n.sql-panel-container .center {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n.export-csv-button {\n position: absolute;\n right: 0;\n bottom: 0;\n z-index: 2;\n opacity: 0.8;\n}\n.export-csv-button .button {\n border-radius: var(--border-radius) 0 0 0 !important;\n}\n",{});const Ue=[],Ve=[],Ge=[],Qe=[],Ye=[n({id:"sql-query",name:"SQL Query panel",icon:"view_list",description:"Show result of a stored SQL query as a table",component:Me,skipUndefinedKeys:["sql"],options:[{field:"sql",name:"SQL query",type:"string",meta:{note:"Supports variables in the format of {{variable_name}}. Don't quote string variables. Example: SELECT * FROM tasks WHERE list = {{list}} AND status IN ({{status}})",interface:"input-code",width:"full",options:{language:"sql"}}},{field:"columns",name:"Columns",type:"json",special:"cast-json",meta:{width:"full",interface:"list",options:{addLabel:"Add column",label:"{{name}} - {{width}}",fields:[{field:"value",name:"Column Name",type:"string",note:"As returned by query",meta:{required:!0,width:"half",interface:"input",options:{trim:!0,softLength:100}}},{field:"text",name:"Label",type:"string",note:"What to display in the column header (Default is same as name)",meta:{width:"half",interface:"input",options:{trim:!0,softLength:100}}},{field:"width",name:"Width",type:"integer",meta:{required:!0,width:"half",interface:"input",options:{min:1,max:300},note:"Width of the column in ch (character width). Default is 10."},schema:{default_value:10}},{field:"isNumber",name:"Is Numberic",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"sortable",name:"Sortable",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"searchable",name:"Searchable",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"summarise",name:"Summarise",type:"string",meta:{width:"half",interface:"select-dropdown",options:{choices:[{text:"Sum",value:"sum"},{text:"Average",value:"avg"},{text:"Count",value:"count"},{text:"Count Unique",value:"count_unique"},{text:"Count Groups",value:"count_groups"}]}}}]}}},{field:"actions",name:"Actions",type:"json",special:"cast-json",meta:{width:"full",interface:"list",options:{addLabel:"Add action",label:"{{{label}}",fields:[{field:"label",name:"Label",type:"string",meta:{required:!0,width:"half",interface:"input",options:{trim:!0,softLength:50}}},{field:"row",name:"Activate on row click",type:"boolean",meta:{note:"If you don't want to show the action button, but want to activate the action on row click",width:"half",interface:"boolean"}},{field:"link",name:"Goto Link",type:"string",meta:{note:"Variables per row can be inserted as such %column_name%",width:"half",interface:"input",options:{trim:!0}}},{field:"filter",name:"Set Variables",type:"json",meta:{note:"Change dashboard variables based on the values of an item",width:"half",interface:"list",options:{fields:[{field:"variable",name:"variable",type:"string",meta:{type:"string",field:"variable",width:"half",display:"formatted-value",options:{trim:!0},required:!0,interface:"input"}},{field:"value",name:"value",type:"string",meta:{note:"A raw value or use %column_name% to use values from the row",type:"string",field:"value",width:"half",options:{trim:!0},required:!0,interface:"input"}}]}}},{field:"icon",name:"Icon",type:"string",meta:{note:"Leave blank to not show an icon",width:"half",interface:"select-icon"}},{field:"show_label",name:"Show label",type:"boolean",meta:{width:"half",interface:"boolean"}}]}}},{field:"download",name:"Download button",type:"boolean",meta:{width:"half",interface:"boolean",options:{label:"Show"}},schema:{default_value:!0}},{field:"is_static",name:"Is static",type:"boolean",meta:{width:"half",interface:"boolean",options:{label:"Yes"},note:"If the result will not be affect when variables are changed, you can check this box to improve performance."},schema:{default_value:!1}},{field:"cache",name:"Cache Response",type:"integer",meta:{width:"half",interface:"input",options:{min:10,max:3600},note:"Tells the browser how long to cache results for. Default is 30 seconds."},schema:{default_value:300}}],minWidth:10,minHeight:10})],Fe=[],Je=[];export{Ve as displays,Ue as interfaces,Ge as layouts,Qe as modules,Je as operations,Ye as panels,Fe as themes};
1
+ import{useApi as e,useStores as t,definePanel as n}from"@directus/extensions-sdk";import{onMounted as a,nextTick as o,getCurrentScope as r,onScopeDispose as l,getCurrentInstance as i,computed as s,shallowRef as u,ref as c,watch as d,toValue as f,resolveComponent as v,resolveDirective as h,createElementBlock as p,openBlock as m,createElementVNode as b,normalizeProps as g,guardReactiveProps as y,unref as w,createCommentVNode as k,normalizeClass as x,createVNode as q,withCtx as S,Fragment as _,renderList as C,normalizeStyle as L,createTextVNode as T,createBlock as A,toDisplayString as j,mergeProps as R,renderSlot as $,withModifiers as E,withDirectives as O,defineComponent as z,toRefs as D,createSlots as B}from"vue";import{useRouter as N}from"vue-router";import{useI18n as W}from"vue-i18n";var H="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function I(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var P=/^\s+|\s+$/g,M=/^[-+]0x[0-9a-f]+$/i,U=/^0b[01]+$/i,V=/^0o[0-7]+$/i,G=parseInt,Q="object"==typeof H&&H&&H.Object===Object&&H,Y="object"==typeof self&&self&&self.Object===Object&&self,F=Q||Y||Function("return this")(),J=Object.prototype.toString,Z=Math.max,K=Math.min,X=function(){return F.Date.now()};function ee(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function te(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==J.call(e)}(e))return NaN;if(ee(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=ee(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(P,"");var n=U.test(e);return n||V.test(e)?G(e.slice(2),n?2:8):M.test(e)?NaN:+e}var ne=I((function(e,t,n){var a,o,r,l,i,s,u=0,c=!1,d=!1,f=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function v(t){var n=a,r=o;return a=o=void 0,u=t,l=e.apply(r,n)}function h(e){var n=e-s;return void 0===s||n>=t||n<0||d&&e-u>=r}function p(){var e=X();if(h(e))return m(e);i=setTimeout(p,function(e){var n=t-(e-s);return d?K(n,r-(e-u)):n}(e))}function m(e){return i=void 0,f&&a?v(e):(a=o=void 0,l)}function b(){var e=X(),n=h(e);if(a=arguments,o=this,s=e,n){if(void 0===i)return function(e){return u=e,i=setTimeout(p,t),c?v(e):l}(s);if(d)return i=setTimeout(p,t),v(s)}return void 0===i&&(i=setTimeout(p,t)),l}return t=te(t)||0,ee(n)&&(c=!!n.leading,r=(d="maxWait"in n)?Z(te(n.maxWait)||0,t):r,f="trailing"in n?!!n.trailing:f),b.cancel=function(){void 0!==i&&clearTimeout(i),u=0,a=s=o=i=void 0},b.flush=function(){return void 0===i?l:m(X())},b}));const ae="undefined"!=typeof window&&"undefined"!=typeof document;function oe(e,t=!0,n){i()?a(e,n):t?e():o(e)}"undefined"!=typeof WorkerGlobalScope&&(globalThis,WorkerGlobalScope);const re=ae?window:void 0;function le(e){var t;const n=f(e);return null!=(t=null==n?void 0:n.$el)?t:n}function ie(e){const t=function(){const e=u(!1),t=i();return t&&a((()=>{e.value=!0}),t),e}();return s((()=>(t.value,Boolean(e()))))}function se(e,t,n={}){const{window:a=re,...o}=n;let i;const u=ie((()=>a&&"ResizeObserver"in a)),c=()=>{i&&(i.disconnect(),i=void 0)},v=s((()=>{const t=f(e);return Array.isArray(t)?t.map((e=>le(e))):[le(t)]})),h=d(v,(e=>{if(c(),u.value&&a){i=new ResizeObserver(t);for(const t of e)t&&i.observe(t,o)}}),{immediate:!0,flush:"post"}),p=()=>{c(),h()};var m;return m=p,r()&&l(m),{isSupported:u,stop:p}}function ue(e,t={width:0,height:0},n={}){const{window:a=re,box:o="content-box"}=n,r=s((()=>{var t,n;return null==(n=null==(t=le(e))?void 0:t.namespaceURI)?void 0:n.includes("svg")})),l=u(t.width),i=u(t.height),{stop:c}=se(e,(([t])=>{const n="border-box"===o?t.borderBoxSize:"content-box"===o?t.contentBoxSize:t.devicePixelContentBoxSize;if(a&&r.value){const t=le(e);if(t){const e=t.getBoundingClientRect();l.value=e.width,i.value=e.height}}else if(n){const e=(s=n,Array.isArray(s)?s:[s]);l.value=e.reduce(((e,{inlineSize:t})=>e+t),0),i.value=e.reduce(((e,{blockSize:t})=>e+t),0)}else l.value=t.contentRect.width,i.value=t.contentRect.height;var s}),n);oe((()=>{const n=le(e);n&&(l.value="offsetWidth"in n?n.offsetWidth:t.width,i.value="offsetHeight"in n?n.offsetHeight:t.height)}));const f=d((()=>le(e)),(e=>{l.value=e?t.width:0,i.value=e?t.height:0}));return{width:l,height:i,stop:function(){c(),f()}}}function ce(e,t){const{containerStyle:n,wrapperProps:a,scrollTo:o,calculateRange:r,currentList:l,containerRef:i}="itemHeight"in t?function(e,t){const n=de(t),{state:a,source:o,currentList:r,size:l,containerRef:i}=n,u={overflowY:"auto"},{itemHeight:c,overscan:d=5}=e,f=fe(a,o,c),v=ve(o,c),h=he("vertical",d,v,f,n),p=pe(c,o),m=s((()=>p(a.value.start))),b=be(c,o);me(l,t,i,h);const g=ye("vertical",h,p,i),y=s((()=>({style:{width:"100%",height:b.value-m.value+"px",marginTop:`${m.value}px`}})));return{calculateRange:h,scrollTo:g,containerStyle:u,wrapperProps:y,currentList:r,containerRef:i}}(t,e):function(e,t){const n=de(t),{state:a,source:o,currentList:r,size:l,containerRef:i}=n,u={overflowX:"auto"},{itemWidth:c,overscan:d=5}=e,f=fe(a,o,c),v=ve(o,c),h=he("horizontal",d,v,f,n),p=pe(c,o),m=s((()=>p(a.value.start))),b=be(c,o);me(l,t,i,h);const g=ye("horizontal",h,p,i),y=s((()=>({style:{height:"100%",width:b.value-m.value+"px",marginLeft:`${m.value}px`,display:"flex"}})));return{scrollTo:g,calculateRange:h,wrapperProps:y,containerStyle:u,currentList:r,containerRef:i}}(t,e);return{list:l,scrollTo:o,containerProps:{ref:i,onScroll:()=>{r()},style:n},wrapperProps:a}}function de(e){const t=u(null),n=ue(t),a=c([]),o=u(e);return{state:c({start:0,end:10}),source:o,currentList:a,size:n,containerRef:t}}function fe(e,t,n){return a=>{if("number"==typeof n)return Math.ceil(a/n);const{start:o=0}=e.value;let r=0,l=0;for(let e=o;e<t.value.length;e++){if(r+=n(e),l=e,r>a)break}return l-o}}function ve(e,t){return n=>{if("number"==typeof t)return Math.floor(n/t)+1;let a=0,o=0;for(let r=0;r<e.value.length;r++){if(a+=t(r),a>=n){o=r;break}}return o+1}}function he(e,t,n,a,{containerRef:o,state:r,currentList:l,source:i}){return()=>{const s=o.value;if(s){const o=n("vertical"===e?s.scrollTop:s.scrollLeft),u=a("vertical"===e?s.clientHeight:s.clientWidth),c=o-t,d=o+u+t;r.value={start:c<0?0:c,end:d>i.value.length?i.value.length:d},l.value=i.value.slice(r.value.start,r.value.end).map(((e,t)=>({data:e,index:t+r.value.start})))}}}function pe(e,t){return n=>{if("number"==typeof e){return n*e}return t.value.slice(0,n).reduce(((t,n,a)=>t+e(a)),0)}}function me(e,t,n,a){d([e.width,e.height,t,n],(()=>{a()}))}function be(e,t){return s((()=>"number"==typeof e?t.value.length*e:t.value.reduce(((t,n,a)=>t+e(a)),0)))}const ge={horizontal:"scrollLeft",vertical:"scrollTop"};function ye(e,t,n,a){return o=>{a.value&&(a.value[ge[e]]=n(o),t())}}const we={sum:"Σ",avg:"μ",count:"#",count_unique:"#!"},ke={sum:(e,t)=>e.reduce(((e,n)=>e+Number.parseInt(n[t])),0),avg:(e,t)=>Math.round(ke.sum(e,t)/e.length),count:e=>e.length,count_unique:(e,t)=>new Set(e.map((e=>e[t]))).size,count_groups:(e,t)=>e.reduce(((e,n)=>{const a=n[t];return e[a]=(e[a]||0)+1,e}),{})};var xe=[],qe=[];function Se(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",o=!0===t.singleTag,r="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(o){var l=xe.indexOf(r);-1===l&&(l=xe.push(r)-1,qe[l]={}),n=qe[l]&&qe[l][a]?qe[l][a]:qe[l][a]=i()}else n=i();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function i(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),o=0;o<n.length;o++)e.setAttribute(n[o],t.attributes[n[o]]);var l="prepend"===a?"afterbegin":"beforeend";return r.insertAdjacentElement(l,e),e}}Se("\nbody {\n --v-table-color: var(--v-input-color);\n --v-table-background-color: var(--v-input-background-color);\n}\n.sql-query-table[data-v-1fe562b8] {\n position: relative;\n height: var(--v-table-height);\n overflow-y: auto;\n\n --sqt-head--background: var(--background-normal, var(--theme--background));\n --sqt-head--color: color: var(--foreground-normal, var(--theme--foreground));\n\n --sqt-foot--background: var(--background-normal, var(--theme--background));\n --sqt-foot--color: color: var(--foreground-normal, var(--theme--foreground));\n}\ntable[data-v-1fe562b8] {\n min-width: 100%;\n min-height: 100%;\n border-collapse: collapse;\n border-spacing: 0;\n background-color: var(--v-table-background-color);\n color: var(--v-table-color);\n}\ntable thead[data-v-1fe562b8] {\n background-color: var(--sqt-head--background);\n color: var(--sqt-head--color);\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable thead.fixed[data-v-1fe562b8] {\n position: sticky;\n top: 0;\n z-index: 3;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);\n}\ntable thead tr.headers th[data-v-1fe562b8] {\n padding: 8px;\n font-weight: bold;\n min-width: 3rem;\n background-color: var(--sqt-head--background);\n color: var(--sqt-head--color);\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable tr.search th[data-v-1fe562b8] {\n padding: 0;\n}\ntable tr.search th .search-input.v-input[data-v-1fe562b8] {\n margin: 0;\n border: none;\n}\ntable th .sort-icon[data-v-1fe562b8] {\n opacity: 0;\n}\ntable th:hover .sort-icon[data-v-1fe562b8] {\n opacity: 0.5;\n}\ntable th .sort-icon.show[data-v-1fe562b8] {\n opacity: 1;\n}\ntable th.select[data-v-1fe562b8] {\n width: 2rem;\n}\ntable td[data-v-1fe562b8] {\n padding: 8px;\n align: middle;\n border-bottom: var(--border-width) solid var(--v-input-border-color);\n}\ntable tr.clickable[data-v-1fe562b8]:hover {\n background-color: var(--theme--background-subdued);\n cursor: pointer\n}\ntable tr.active[data-v-1fe562b8] {\n background-color: var(--theme--background-accent);\n}\ntable tbody[data-v-1fe562b8] {\n display: contents;\n}\ntable tfoot tr[data-v-1fe562b8] {\n position: sticky;\n bottom: 0;\n background-color: var(--sqt-foot--background);\n color: var(--sqt-foot--color);\n box-shadow: var(--card-shadow);\n}\ntable tfoot tr td[data-v-1fe562b8] {\n padding: 8px;\n height: 44px;\n font-weight: bold;\n background-color: var(--sqt-foot--background);\n color: var(--sqt-foot--color);\n}\n",{});var _e=(e,t)=>{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n};const Ce={class:"sql-query-table"},Le={key:0,class:"search"},Te={colspan:"80%"},Ae={class:"headers"},je=["onClick","align"],Re={key:0},$e={key:1},Ee=["colspan"],Oe={key:0},ze={colspan:"100%"},De=["onClick"],Be={key:2},Ne={key:0,class:"v-text-overflow"},We={__name:"FastTable",props:{loading:Boolean,headers:{type:Array,validator:e=>e.every((e=>e.value&&e.text)),required:!0},items:{type:Array,required:!0},sort:String,sortDesc:Boolean,fixedHeader:Boolean,rowClickable:Boolean},emits:["update:sort","update:sortDesc","click:row"],setup(e,{emit:t}){const{t:n}=W(),a=e,o=c(""),r=s((()=>a.headers.filter((e=>e.searchable)))),l=s((()=>{console.debug(a.sort,a.sortDesc);const e=o.value?o.value.toLowerCase().trim():"";return e?a.items.filter((t=>r.value.some((n=>t[n.value]&&t[n.value].toLowerCase().includes(e))))):[...a.items]})),{list:i,containerProps:u,wrapperProps:d}=ce(l,{itemHeight:40}),f=s((()=>{const e=function(e,t){if(!t.some((e=>!!e.summarise)))return null;const n={};for(const a of t){if(!a.summarise)continue;const t=ke[a.summarise];if(!t)throw new Error(`Summariser function for ${a.summarise} not found.`);const o=t(e,a.value);if("count_groups"===a.summarise){let e=JSON.stringify(o,null,1).replace("{\n","").replace("\n}","").replace(/[",]/g,"");n[a.value]=e}else n[a.value]=`${we[a.summarise]} ${o}`}return n}(l.value,a.headers);return e})),z=t,D=c(null);return(t,l)=>{const s=v("v-icon"),c=v("v-input"),B=v("v-progress-linear"),N=v("v-card-title"),W=v("v-card"),H=h("tooltip");return m(),p("div",Ce,[b("table",g(y(w(u))),[b("thead",{class:x(["table-header",{fixed:e.fixedHeader}])},[r.value.length&&e.items.length>10?(m(),p("tr",Le,[b("th",Te,[q(c,{modelValue:o.value,"onUpdate:modelValue":l[0]||(l[0]=e=>o.value=e),small:"",trim:"",class:"search-input",rounded:"",placeholder:"Search"},{prepend:S((()=>[q(s,{name:"search"})])),_:1},8,["modelValue"])])])):k("v-if",!0),b("tr",Ae,[(m(!0),p(_,null,C(e.headers,(n=>(m(),p("th",{style:L({minWidth:`${n.width||t.auto}ch`}),key:n.value,onClick:e=>function(e){e.sortable&&(z("update:sort",e.value),z("update:sortDesc",!a.sortDesc))}(n),align:n.align||"left"},[T(j(n.text)+" ",1),n.sortable?(m(),A(s,{key:0,name:"sort",small:"",class:x(["sort-icon",{show:e.sort===n.value}]),style:L(`transform: ${e.sortDesc?"rotateZ(0deg) rotateY(0deg)":"rotateZ(180deg) rotateY(180deg)"}; transition: .2s all ease`)},null,8,["class","style"])):k("v-if",!0)],12,je)))),128)),t.$slots["item-append"]?(m(),p("th",Re,"#")):k("v-if",!0)]),e.loading?(m(),p("tr",$e,[b("td",{colspan:e.headers.length+1},[q(B,{indeterminate:""})],8,Ee)])):k("v-if",!0)],2),e.loading||e.items.length?(m(),p("tbody",g(R({key:1},w(d))),[$(t.$slots,"default",{items:w(i)},(()=>[(m(!0),p(_,null,C(w(i),(({data:n})=>(m(),p("tr",{onClick:e=>{D.value=n,z("click:row",{item:n,event:e})},class:x({clickable:e.rowClickable,active:D.value===n})},[(m(!0),p(_,null,C(e.headers,(e=>(m(),p("td",{key:e.value,class:x(`align-${e.align}`)},j(n[e.value]),3)))),128)),t.$slots["item-append"]?(m(),p("td",{key:0,onClick:l[1]||(l[1]=E((()=>{}),["stop"]))},[$(t.$slots,"item-append",{item:n},void 0,!0)])):k("v-if",!0)],10,De)))),256))]),!0),k(" This is to fill up any remaining height in the table "),l[2]||(l[2]=b("tr",null,[b("td",{style:{height:"100%"}})],-1))],16)):(m(),p("tbody",Oe,[b("tr",null,[b("td",ze,[q(W,{style:{padding:"2rem","--v-card-max-width":"100%",margin:"2rem auto"}},{default:S((()=>[q(N,null,{default:S((()=>[q(s,{name:"info",style:{"margin-right":"2rem"}}),T(" "+j(w(n)("no_items")),1)])),_:1})])),_:1})])])])),f.value?(m(),p("tfoot",Be,[b("tr",null,[(m(!0),p(_,null,C(e.headers,(e=>O((m(),p("td",{key:e.value},[f.value[e.value]?(m(),p("code",Ne,j(f.value[e.value]),1)):k("v-if",!0)])),[[H,e.summarise]]))),128))])])):k("v-if",!0)],16)])}}};var He=_e(We,[["__scopeId","data-v-1fe562b8"]]);const Ie={key:0,class:"center"},Pe={key:0};var Me=z({__name:"panel",props:{id:{},showHeader:{type:Boolean},sql:{},cache:{},columns:{},download:{type:Boolean,default:!0},is_static:{type:Boolean},actions:{}},setup(n){const a=N(),r=n,{id:l,showHeader:i,download:u,is_static:f}=D(r),b=c(!1),g=c(""),y=c(""),L=c(null),R=c(null),$=e(),{useInsightsStore:E}=t(),z=E(),W=c(new Set),H=s((()=>{const e=new Set(W.value),t=r.sql.match(/{{ \w+ }}/g);return t&&t.forEach((t=>e.add(t.replace(/{{ | }}/g,"")))),e})),I=s((()=>{const e={},t=[];return H.value.forEach((n=>{const a=z.getVariable(n);null==a?t.push(n):e[n]=a})),t.length?t:e}));if(f.value)o(Y);else{const e=ne(Y,1e3);d(I,(()=>{Array.isArray(I.value)?y.value=`Please specify: ${I.value.join(" & ")}`:(y.value="",R.value||(b.value=!0),e())}),{immediate:!0})}const P=s((()=>r.columns?.length>0?r.columns.map((e=>({...e,text:e.text||e.value}))):L.value)),M=c({by:null,desc:!1});d(M,(({by:e,desc:t})=>{e&&R.value&&(R.value=R.value.sort(((n,a)=>n[e]<a[e]?t?1:-1:n[e]>a[e]?t?-1:1:0)))}),{deep:!0});let U,V,G=!1,Q={};async function Y(){if(b.value=!1,Array.isArray(I.value))Q={};else{if(!G){let e=!H.value.size;for(const t in I.value)Q[t]!==I.value[t]&&(e=!0),Q[t]=I.value[t];if(!e)return;b.value=!0}g.value="";try{const e={};V=e;const{data:t}=await $.get(`insights/query/${l.value}`,{params:I.value});if(V!==e)return;t.error&&(g.value=t.error),G=!1,r.cache&&setTimeout((()=>{G=!0}),1e3*r.cache);const n=JSON.stringify(t);if(U===n)return void(b.value=!1);if(U=n,L.value=null,R.value=null,t.headers&&t.items){const e=t.items.length>2;L.value=t.headers.map((function(t,n){const a=t.replace(/_/g," ").replace(/(?:^|\s)\S/g,(function(e){return e.toUpperCase()}));return{text:a,value:t,width:a.length+1,sortable:e}}));const n=r.columns&&r.columns.filter((e=>e.isNumber));R.value=n?t.items.map((e=>(n.forEach((t=>{e[t.value]=""!==e[t.value]?1*e[t.value]:null})),e))):t.items}}catch(e){const t=e.response?.data?.error||e.message;t.includes("Missing query param")?(y.value=t.replace("Missing query param","Please specify"),t.split(": ")[1].split(", ").forEach((e=>W.value.add(e)))):g.value=t}b.value=!1}}const F=s((()=>r.actions?.find((e=>e.row))));function J(){const e=L.value||P.value;if(e&&R.value){let t=e.map((e=>e.text)).join(",");t+="\r\n",t+=function(){if(!R.value)return;let e="";return R.value.forEach((t=>{for(let n in t)/[, ]/.test(t[n])?e+=`"${t[n].replace(/"/g,'\\"')}",`:e+=t[n]+",";e+="\r\n"})),e}();const n=(new Date).toISOString()+".csv",a=new Blob([t],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob)navigator.msSaveBlob(a,n);else{const e=document.createElement("a");if(void 0!==e.download){const t=URL.createObjectURL(a);e.setAttribute("href",t),e.setAttribute("download",n),e.style.visibility="hidden",document.body.appendChild(e),e.click(),document.body.removeChild(e)}}}}function Z({item:e}){F.value&&K(F.value,e)}function K(e,t){e.filter&&e.filter.forEach((({variable:e,value:n})=>{z.setVariable(e,n.replace(/%(\w+)%/g,((e,n)=>t[n])))})),e.link&&a.push(function(e,t){let n=e;for(let e in t)n=n.replace(new RegExp(`%${e}%`,"g"),t[e]);return n}(e.link,t))}return(e,t)=>{const n=v("v-progress-circular"),a=v("v-notice"),o=v("v-icon"),r=v("v-button"),l=h("tooltip");return m(),p("div",{class:x(["sql-panel-container",{"has-header":w(i)}])},[b.value||g.value||y.value?(m(),p("div",Ie,[b.value?(m(),A(n,{key:0,indeterminate:""})):y.value?(m(),A(a,{key:1,type:"info",center:""},{default:S((()=>[T(j(y.value),1)])),_:1})):(m(),A(a,{key:2,type:"danger",center:""},{default:S((()=>[T(j(g.value),1)])),_:1}))])):P.value&&R.value?(m(),p(_,{key:1},[w(u)?(m(),A(r,{key:0,onClick:J,icon:"",secondary:"",class:"export-csv-button"},{default:S((()=>[q(o,{name:"download-file"})])),_:1})):k("v-if",!0),q(He,{headers:P.value,items:R.value,"onClick:row":Z,sort:M.value.by,"onUpdate:sort":t[0]||(t[0]=e=>M.value.by=e),sortDesc:M.value.desc,"onUpdate:sortDesc":t[1]||(t[1]=e=>M.value.desc=e),rowClickable:!!F.value,"fixed-header":""},B({_:2},[e.actions?.find((e=>!e.row))?{name:"item-append",fn:S((({item:t})=>[(m(!0),p(_,null,C(e.actions.filter((e=>!e.row)),(e=>O((m(),A(r,{outlined:"",onClick:n=>K(e,t),icon:!e.show_label,"x-small":""},{default:S((()=>[q(o,{name:e.icon},null,8,["name"]),e.show_label?(m(),p("span",Pe,j(e.label),1)):k("v-if",!0)])),_:2},1032,["onClick","icon"])),[[l,e.label]]))),256))])),key:"0"}:void 0]),1032,["headers","items","sort","sortDesc","rowClickable"])],64)):k("v-if",!0)],2)}}});Se("\n.sql-panel-container {\n width: 100%;\n height: 100%;\n --v-table-height: 100%;\n}\n.sql-panel-container .v-text-overflow {\n user-select: text;\n white-space: pre-wrap;\n}\n.sql-panel-container .center {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n.export-csv-button {\n position: absolute;\n right: 0;\n bottom: 0;\n z-index: 2;\n opacity: 0.8;\n}\n.export-csv-button .button {\n border-radius: var(--border-radius) 0 0 0 !important;\n}\n",{});const Ue=[],Ve=[],Ge=[],Qe=[],Ye=[n({id:"sql-query",name:"SQL Query panel",icon:"view_list",description:"Show result of a stored SQL query as a table",component:Me,skipUndefinedKeys:["sql"],options:[{field:"sql",name:"SQL query",type:"string",meta:{note:"Supports variables in the format of {{variable_name}}. Don't quote string variables. Example: SELECT * FROM tasks WHERE list = {{list}} AND status IN ({{status}})",interface:"input-code",width:"full",options:{language:"sql"}}},{field:"columns",name:"Columns",type:"json",special:"cast-json",meta:{width:"full",interface:"list",options:{addLabel:"Add column",label:"{{name}} - {{width}}",fields:[{field:"value",name:"Column Name",type:"string",note:"As returned by query",meta:{required:!0,width:"half",interface:"input",options:{trim:!0,softLength:100}}},{field:"text",name:"Label",type:"string",note:"What to display in the column header (Default is same as name)",meta:{width:"half",interface:"input",options:{trim:!0,softLength:100}}},{field:"width",name:"Width",type:"integer",meta:{required:!0,width:"half",interface:"input",options:{min:1,max:300},note:"Width of the column in ch (character width). Default is 10."},schema:{default_value:10}},{field:"isNumber",name:"Is Numberic",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"sortable",name:"Sortable",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"searchable",name:"Searchable",type:"boolean",meta:{width:"half",interface:"boolean"}},{field:"summarise",name:"Summarise",type:"string",meta:{width:"half",interface:"select-dropdown",options:{choices:[{text:"Sum",value:"sum"},{text:"Average",value:"avg"},{text:"Count",value:"count"},{text:"Count Unique",value:"count_unique"},{text:"Count Groups",value:"count_groups"}]}}}]}}},{field:"actions",name:"Actions",type:"json",special:"cast-json",meta:{width:"full",interface:"list",options:{addLabel:"Add action",label:"{{{label}}",fields:[{field:"label",name:"Label",type:"string",meta:{required:!0,width:"half",interface:"input",options:{trim:!0,softLength:50}}},{field:"row",name:"Activate on row click",type:"boolean",meta:{note:"If you don't want to show the action button, but want to activate the action on row click",width:"half",interface:"boolean"}},{field:"link",name:"Goto Link",type:"string",meta:{note:"Variables per row can be inserted as such %column_name%",width:"half",interface:"input",options:{trim:!0}}},{field:"filter",name:"Set Variables",type:"json",meta:{note:"Change dashboard variables based on the values of an item",width:"half",interface:"list",options:{fields:[{field:"variable",name:"variable",type:"string",meta:{type:"string",field:"variable",width:"half",display:"formatted-value",options:{trim:!0},required:!0,interface:"input"}},{field:"value",name:"value",type:"string",meta:{note:"A raw value or use %column_name% to use values from the row",type:"string",field:"value",width:"half",options:{trim:!0},required:!0,interface:"input"}}]}}},{field:"icon",name:"Icon",type:"string",meta:{note:"Leave blank to not show an icon",width:"half",interface:"select-icon"}},{field:"show_label",name:"Show label",type:"boolean",meta:{width:"half",interface:"boolean"}}]}}},{field:"download",name:"Download button",type:"boolean",meta:{width:"half",interface:"boolean",options:{label:"Show"}},schema:{default_value:!0}},{field:"is_static",name:"Is static",type:"boolean",meta:{width:"half",interface:"boolean",options:{label:"Yes"},note:"If the result will not be affect when variables are changed, you can check this box to improve performance."},schema:{default_value:!1}},{field:"cache",name:"Cache Response",type:"integer",meta:{width:"half",interface:"input",options:{min:10,max:3600},note:"Tells the browser how long to cache results for. Default is 30 seconds."},schema:{default_value:300}}],minWidth:10,minHeight:10})],Fe=[],Je=[];export{Ve as displays,Ue as interfaces,Ge as layouts,Qe as modules,Je as operations,Ye as panels,Fe as themes};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "directus-extension-sql-query-panel",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "description": "Insights Panel for viewing results for dynamic sql queries",
6
6
  "icon": "extension",