web-mojo 2.2.69 → 2.2.70
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/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +1 -1
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.cjs.js.map +1 -1
- package/dist/charts.es.js +1 -1
- package/dist/charts.es.js.map +1 -1
- package/dist/chunks/ChatView-DH42WXgV.js +2 -0
- package/dist/chunks/{ChatView-Dw-iVmht.js.map → ChatView-DH42WXgV.js.map} +1 -1
- package/dist/chunks/ChatView-_8eQTETQ.js +2 -0
- package/dist/chunks/{ChatView-CZ3Key2k.js.map → ChatView-_8eQTETQ.js.map} +1 -1
- package/dist/chunks/Collection-BUv4E9op.js +2 -0
- package/dist/chunks/Collection-BUv4E9op.js.map +1 -0
- package/dist/chunks/Collection-r1ACzUeh.js +2 -0
- package/dist/chunks/Collection-r1ACzUeh.js.map +1 -0
- package/dist/chunks/ContextMenu-BFxliZ03.js +2 -0
- package/dist/chunks/{ContextMenu-8vTiZZQV.js.map → ContextMenu-BFxliZ03.js.map} +1 -1
- package/dist/chunks/ContextMenu-BwJJ4QJE.js +2 -0
- package/dist/chunks/{ContextMenu-DBw0WMTO.js.map → ContextMenu-BwJJ4QJE.js.map} +1 -1
- package/dist/chunks/DataView-DMpNXerv.js +2 -0
- package/dist/chunks/{DataView-DyJKgOn3.js.map → DataView-DMpNXerv.js.map} +1 -1
- package/dist/chunks/DataView-_CACqzRt.js +2 -0
- package/dist/chunks/{DataView-BEovBggn.js.map → DataView-_CACqzRt.js.map} +1 -1
- package/dist/chunks/Dialog-BVCCpLPw.js +3 -0
- package/dist/chunks/Dialog-BVCCpLPw.js.map +1 -0
- package/dist/chunks/Dialog-BYiynSW-.js +3 -0
- package/dist/chunks/Dialog-BYiynSW-.js.map +1 -0
- package/dist/chunks/FormView-Dw7HDwzy.js +3 -0
- package/dist/chunks/{FormView-BRHAIawp.js.map → FormView-Dw7HDwzy.js.map} +1 -1
- package/dist/chunks/FormView-OgrZ7x0z.js +3 -0
- package/dist/chunks/{FormView-B1CXO2t8.js.map → FormView-OgrZ7x0z.js.map} +1 -1
- package/dist/chunks/ListView-2M4I8KHF.js +2 -0
- package/dist/chunks/{ListView-CMZpwyyC.js.map → ListView-2M4I8KHF.js.map} +1 -1
- package/dist/chunks/ListView-B0QbqSPv.js +2 -0
- package/dist/chunks/{ListView-BLFFK_Ir.js.map → ListView-B0QbqSPv.js.map} +1 -1
- package/dist/chunks/MetricsCountryMapView-DDdDJQFA.js +2 -0
- package/dist/chunks/{MetricsCountryMapView-B0kWK-Js.js.map → MetricsCountryMapView-DDdDJQFA.js.map} +1 -1
- package/dist/chunks/MetricsCountryMapView-DIlezla0.js +2 -0
- package/dist/chunks/{MetricsCountryMapView-DuBKO7gz.js.map → MetricsCountryMapView-DIlezla0.js.map} +1 -1
- package/dist/chunks/MetricsMiniChartWidget-Dt2V0eXP.js +2 -0
- package/dist/chunks/{MetricsMiniChartWidget-Dg1e6EQJ.js.map → MetricsMiniChartWidget-Dt2V0eXP.js.map} +1 -1
- package/dist/chunks/MetricsMiniChartWidget-_N4kzNY_.js +2 -0
- package/dist/chunks/{MetricsMiniChartWidget-D1w608Jy.js.map → MetricsMiniChartWidget-_N4kzNY_.js.map} +1 -1
- package/dist/chunks/PDFViewer-BruR1RFn.js +2 -0
- package/dist/chunks/{PDFViewer-D_3V8QJe.js.map → PDFViewer-BruR1RFn.js.map} +1 -1
- package/dist/chunks/PDFViewer-CyGFVcvX.js +2 -0
- package/dist/chunks/{PDFViewer-CDeV9OBs.js.map → PDFViewer-CyGFVcvX.js.map} +1 -1
- package/dist/chunks/TableView-CxYpxZvr.js +2 -0
- package/dist/chunks/{TableView-CI_7a-kD.js.map → TableView-CxYpxZvr.js.map} +1 -1
- package/dist/chunks/TableView-DemRVhnX.js +2 -0
- package/dist/chunks/{TableView-CWk5k4LQ.js.map → TableView-DemRVhnX.js.map} +1 -1
- package/dist/chunks/TokenManager-BFaxNsXO.js +2 -0
- package/dist/chunks/{TokenManager-sZgt--C9.js.map → TokenManager-BFaxNsXO.js.map} +1 -1
- package/dist/chunks/TokenManager-IlBEFXqZ.js +2 -0
- package/dist/chunks/{TokenManager-ien2XzwO.js.map → TokenManager-IlBEFXqZ.js.map} +1 -1
- package/dist/chunks/UserProfileView-9vkfCPsp.js +2 -0
- package/dist/chunks/{UserProfileView-kupeq2rN.js.map → UserProfileView-9vkfCPsp.js.map} +1 -1
- package/dist/chunks/UserProfileView-tcBT6XcE.js +2 -0
- package/dist/chunks/{UserProfileView-DnVMHcLH.js.map → UserProfileView-tcBT6XcE.js.map} +1 -1
- package/dist/chunks/WebApp-BFR1zozS.js +2 -0
- package/dist/chunks/{WebApp-CcVF73yg.js.map → WebApp-BFR1zozS.js.map} +1 -1
- package/dist/chunks/WebApp-C82womPC.js +2 -0
- package/dist/chunks/{WebApp-Bti0Gqqo.js.map → WebApp-C82womPC.js.map} +1 -1
- package/dist/chunks/WebSocketClient-Ibi7mLQu.js +2 -0
- package/dist/chunks/{WebSocketClient-Bh0Mmtje.js.map → WebSocketClient-Ibi7mLQu.js.map} +1 -1
- package/dist/chunks/WebSocketClient-QaCUN3EQ.js +2 -0
- package/dist/chunks/{WebSocketClient-CLgYPxWX.js.map → WebSocketClient-QaCUN3EQ.js.map} +1 -1
- package/dist/chunks/index-BaPQHxbL.js +2 -0
- package/dist/chunks/{index-Da9sT-tE.js.map → index-BaPQHxbL.js.map} +1 -1
- package/dist/chunks/index-BdfwxVMZ.js +2 -0
- package/dist/chunks/{index-Aq9ke4vg.js.map → index-BdfwxVMZ.js.map} +1 -1
- package/dist/chunks/{version-XmirKYWA.js → version-C2yYRyPn.js} +2 -2
- package/dist/chunks/{version-XmirKYWA.js.map → version-C2yYRyPn.js.map} +1 -1
- package/dist/chunks/{version-D8JjsPW0.js → version-CaiqhdME.js} +2 -2
- package/dist/chunks/{version-D8JjsPW0.js.map → version-CaiqhdME.js.map} +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.cjs.js.map +1 -1
- package/dist/docit.es.js +1 -1
- package/dist/docit.es.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.cjs.js.map +1 -1
- package/dist/lightbox.es.js +1 -1
- package/dist/lightbox.es.js.map +1 -1
- package/dist/map.cjs.js +1 -1
- package/dist/map.cjs.js.map +1 -1
- package/dist/map.es.js +1 -1
- package/dist/map.es.js.map +1 -1
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.cjs.js.map +1 -1
- package/dist/timeline.es.js +1 -1
- package/dist/timeline.es.js.map +1 -1
- package/dist/user-profile.cjs.js +1 -1
- package/dist/user-profile.es.js +1 -1
- package/dist/web-mojo.lite.iife.js +5435 -5435
- package/dist/web-mojo.lite.iife.js.map +1 -1
- package/dist/web-mojo.lite.iife.min.js +68 -68
- package/dist/web-mojo.lite.iife.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/ChatView-CZ3Key2k.js +0 -2
- package/dist/chunks/ChatView-Dw-iVmht.js +0 -2
- package/dist/chunks/Collection-BWKmydl5.js +0 -2
- package/dist/chunks/Collection-BWKmydl5.js.map +0 -1
- package/dist/chunks/Collection-CmjTsmrP.js +0 -2
- package/dist/chunks/Collection-CmjTsmrP.js.map +0 -1
- package/dist/chunks/ContextMenu-8vTiZZQV.js +0 -2
- package/dist/chunks/ContextMenu-DBw0WMTO.js +0 -2
- package/dist/chunks/DataView-BEovBggn.js +0 -2
- package/dist/chunks/DataView-DyJKgOn3.js +0 -2
- package/dist/chunks/Dialog-Dhqtd9Yz.js +0 -2
- package/dist/chunks/Dialog-Dhqtd9Yz.js.map +0 -1
- package/dist/chunks/Dialog-t_9l2Mou.js +0 -2
- package/dist/chunks/Dialog-t_9l2Mou.js.map +0 -1
- package/dist/chunks/Files-6eRT5k3r.js +0 -2
- package/dist/chunks/Files-6eRT5k3r.js.map +0 -1
- package/dist/chunks/Files-Dh_5PFBn.js +0 -2
- package/dist/chunks/Files-Dh_5PFBn.js.map +0 -1
- package/dist/chunks/FormView-B1CXO2t8.js +0 -3
- package/dist/chunks/FormView-BRHAIawp.js +0 -3
- package/dist/chunks/ListView-BLFFK_Ir.js +0 -2
- package/dist/chunks/ListView-CMZpwyyC.js +0 -2
- package/dist/chunks/MetricsCountryMapView-B0kWK-Js.js +0 -2
- package/dist/chunks/MetricsCountryMapView-DuBKO7gz.js +0 -2
- package/dist/chunks/MetricsMiniChartWidget-D1w608Jy.js +0 -2
- package/dist/chunks/MetricsMiniChartWidget-Dg1e6EQJ.js +0 -2
- package/dist/chunks/PDFViewer-CDeV9OBs.js +0 -2
- package/dist/chunks/PDFViewer-D_3V8QJe.js +0 -2
- package/dist/chunks/Rest-B1eUyLX5.js +0 -2
- package/dist/chunks/Rest-B1eUyLX5.js.map +0 -1
- package/dist/chunks/Rest-BJ3Mvx1L.js +0 -2
- package/dist/chunks/Rest-BJ3Mvx1L.js.map +0 -1
- package/dist/chunks/TableView-CI_7a-kD.js +0 -2
- package/dist/chunks/TableView-CWk5k4LQ.js +0 -2
- package/dist/chunks/ToastService-C2tTooFn.js +0 -3
- package/dist/chunks/ToastService-C2tTooFn.js.map +0 -1
- package/dist/chunks/ToastService-nUaGVpSl.js +0 -3
- package/dist/chunks/ToastService-nUaGVpSl.js.map +0 -1
- package/dist/chunks/TokenManager-ien2XzwO.js +0 -2
- package/dist/chunks/TokenManager-sZgt--C9.js +0 -2
- package/dist/chunks/User-BL9M_PWB.js +0 -2
- package/dist/chunks/User-BL9M_PWB.js.map +0 -1
- package/dist/chunks/User-DqHG5Gr1.js +0 -2
- package/dist/chunks/User-DqHG5Gr1.js.map +0 -1
- package/dist/chunks/UserProfileView-DnVMHcLH.js +0 -2
- package/dist/chunks/UserProfileView-kupeq2rN.js +0 -2
- package/dist/chunks/WebApp-Bti0Gqqo.js +0 -2
- package/dist/chunks/WebApp-CcVF73yg.js +0 -2
- package/dist/chunks/WebSocketClient-Bh0Mmtje.js +0 -2
- package/dist/chunks/WebSocketClient-CLgYPxWX.js +0 -2
- package/dist/chunks/index-Aq9ke4vg.js +0 -2
- package/dist/chunks/index-Da9sT-tE.js +0 -2
|
@@ -1087,7 +1087,67 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1087
1087
|
</div>
|
|
1088
1088
|
<i class="bi bi-check-circle text-success d-none" data-status="saved"></i>
|
|
1089
1089
|
<i class="bi bi-exclamation-circle text-danger d-none" data-status="error"></i>
|
|
1090
|
-
`}showStatus(e,t={}){this.clearTimeout(e),this.showStandardStatus(e,t)}showStandardStatus(e,t={}){this.hideAllStatuses();const s=this.statusContainer.querySelector(`[data-status="${e}"]`);s&&(s.classList.remove("d-none"),s.classList.add("d-inline-block","show"),e==="saved"?this.setTimeout(e,()=>this.hideStatus(e),2500):e==="error"&&(t.message&&(s.title=t.message),this.setTimeout(e,()=>this.hideStatus(e),6e3)))}showFullOverlayStatus(e,t={}){this.statusContainer.querySelectorAll(".saving-indicator, .success-indicator, .error-indicator").forEach(a=>a.classList.add("d-none")),this.statusContainer.classList.remove("d-none");let i;switch(e){case"saving":i=".saving-indicator";break;case"saved":i=".success-indicator",this.setTimeout(e,()=>this.hideStatus(e),2500);break;case"error":if(i=".error-indicator",t.message){const a=this.statusContainer.querySelector(".error-indicator span");a&&(a.textContent=t.message)}this.setTimeout(e,()=>this.hideStatus(e),6e3);break}if(i){const a=this.statusContainer.querySelector(i);a&&a.classList.remove("d-none")}}hideStatus(e){const t=this.statusContainer.querySelector(`[data-status="${e}"]`);t&&(t.classList.remove("show"),t.classList.add("hide"),setTimeout(()=>{t.classList.add("d-none"),t.classList.remove("d-inline-block","hide"),t.title=""},300))}hideAllStatuses(){this.statusContainer.querySelectorAll("[data-status]").forEach(t=>{t.classList.add("d-none"),t.classList.remove("d-inline-block","show","hide"),t.title=""})}setTimeout(e,t,s){const i=setTimeout(t,s);this.timeouts.set(e,i)}clearTimeout(e){this.timeouts.has(e)&&(clearTimeout(this.timeouts.get(e)),this.timeouts.delete(e))}destroy(){this.timeouts.forEach(e=>clearTimeout(e)),this.timeouts.clear()}}Re(H);const Te=Object.freeze(Object.defineProperty({__proto__:null,FormView:H,default:H},Symbol.toStringTag,{value:"Module"}));class Qe extends K{constructor(e={}){super({title:"Form Page",description:"A page for submitting forms",icon:"form",fields:[],template:'<div data-container="form-view-container"></div>',className:"form-page container-sm",...e})}async onInit(){await super.onInit(),await this.recreateFormView()}async onEnter(){await super.onEnter(),this.formView&&await this.recreateFormView()}async onGroupChange(e){this.formView&&await this.recreateFormView()}async getModel(){return this.model?this.model:this.getApp().activeGroup?this.getApp().activeGroup:null}async recreateFormView(){this.formView&&(await this.formView.destroy(),this.removeChild(this.formView)),this.formView=new H({containerId:"form-view-container",fields:this.options.fields,autosaveModelField:!0}),this.addChild(this.formView);const e=await this.getModel();e&&this.formView.setModel(e)}}
|
|
1090
|
+
`}showStatus(e,t={}){this.clearTimeout(e),this.showStandardStatus(e,t)}showStandardStatus(e,t={}){this.hideAllStatuses();const s=this.statusContainer.querySelector(`[data-status="${e}"]`);s&&(s.classList.remove("d-none"),s.classList.add("d-inline-block","show"),e==="saved"?this.setTimeout(e,()=>this.hideStatus(e),2500):e==="error"&&(t.message&&(s.title=t.message),this.setTimeout(e,()=>this.hideStatus(e),6e3)))}showFullOverlayStatus(e,t={}){this.statusContainer.querySelectorAll(".saving-indicator, .success-indicator, .error-indicator").forEach(a=>a.classList.add("d-none")),this.statusContainer.classList.remove("d-none");let i;switch(e){case"saving":i=".saving-indicator";break;case"saved":i=".success-indicator",this.setTimeout(e,()=>this.hideStatus(e),2500);break;case"error":if(i=".error-indicator",t.message){const a=this.statusContainer.querySelector(".error-indicator span");a&&(a.textContent=t.message)}this.setTimeout(e,()=>this.hideStatus(e),6e3);break}if(i){const a=this.statusContainer.querySelector(i);a&&a.classList.remove("d-none")}}hideStatus(e){const t=this.statusContainer.querySelector(`[data-status="${e}"]`);t&&(t.classList.remove("show"),t.classList.add("hide"),setTimeout(()=>{t.classList.add("d-none"),t.classList.remove("d-inline-block","hide"),t.title=""},300))}hideAllStatuses(){this.statusContainer.querySelectorAll("[data-status]").forEach(t=>{t.classList.add("d-none"),t.classList.remove("d-inline-block","show","hide"),t.title=""})}setTimeout(e,t,s){const i=setTimeout(t,s);this.timeouts.set(e,i)}clearTimeout(e){this.timeouts.has(e)&&(clearTimeout(this.timeouts.get(e)),this.timeouts.delete(e))}destroy(){this.timeouts.forEach(e=>clearTimeout(e)),this.timeouts.clear()}}Re(H);const Te=Object.freeze(Object.defineProperty({__proto__:null,FormView:H,default:H},Symbol.toStringTag,{value:"Module"}));class Qe extends K{constructor(e={}){super({title:"Form Page",description:"A page for submitting forms",icon:"form",fields:[],template:'<div data-container="form-view-container"></div>',className:"form-page container-sm",...e})}async onInit(){await super.onInit(),await this.recreateFormView()}async onEnter(){await super.onEnter(),this.formView&&await this.recreateFormView()}async onGroupChange(e){this.formView&&await this.recreateFormView()}async getModel(){return this.model?this.model:this.getApp().activeGroup?this.getApp().activeGroup:null}async recreateFormView(){this.formView&&(await this.formView.destroy(),this.removeChild(this.formView)),this.formView=new H({containerId:"form-view-container",fields:this.options.fields,autosaveModelField:!0}),this.addChild(this.formView);const e=await this.getModel();e&&this.formView.setModel(e)}}class Xe{constructor(e={}){this.options={containerId:"toast-container",position:"top-end",autohide:!0,defaultDelay:5e3,maxToasts:5,...e},this.toasts=new Map,this.toastCounter=0,this.init()}init(){this.createContainer()}createContainer(){let e=document.getElementById(this.options.containerId);e||(e=document.createElement("div"),e.id=this.options.containerId,e.className=`toast-container position-fixed ${this.getPositionClasses()}`,e.style.zIndex="1070",e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),document.body.appendChild(e)),this.container=e}getPositionClasses(){const e={"top-start":"top-0 start-0 p-3","top-center":"top-0 start-50 translate-middle-x p-3","top-end":"top-0 end-0 p-3","middle-start":"top-50 start-0 translate-middle-y p-3","middle-center":"top-50 start-50 translate-middle p-3","middle-end":"top-50 end-0 translate-middle-y p-3","bottom-start":"bottom-0 start-0 p-3","bottom-center":"bottom-0 start-50 translate-middle-x p-3","bottom-end":"bottom-0 end-0 p-3"};return e[this.options.position]||e["top-end"]}success(e,t={}){return this.show(e,"success",{icon:"bi-check-circle-fill",...t})}error(e,t={}){return this.show(e,"error",{icon:"bi-exclamation-triangle-fill",autohide:!0,...t})}info(e,t={}){return this.show(e,"info",{icon:"bi-info-circle-fill",...t})}warning(e,t={}){return this.show(e,"warning",{icon:"bi-exclamation-triangle-fill",...t})}plain(e,t={}){return this.show(e,"plain",{...t})}show(e,t="info",s={}){this.enforceMaxToasts();const i=`toast-${++this.toastCounter}`,a={title:this.getDefaultTitle(t),icon:this.getDefaultIcon(t),autohide:this.options.autohide,delay:this.options.defaultDelay,dismissible:!0,...s},r=this.createToastElement(i,e,t,a);if(this.container.appendChild(r),typeof bootstrap>"u")throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const n=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});return this.toasts.set(i,{element:r,bootstrap:n,type:t,message:e}),r.addEventListener("hidden.bs.toast",()=>{this.cleanup(i)}),n.show(),{id:i,hide:()=>{try{n.hide()}catch(o){console.warn("Error hiding toast:",o)}},dispose:()=>this.cleanup(i),updateProgress:s.updateProgress||null}}showView(e,t="info",s={}){this.enforceMaxToasts();const i=`toast-${++this.toastCounter}`,a={title:s.title||this.getDefaultTitle(t),icon:s.icon||this.getDefaultIcon(t),autohide:this.options.autohide,delay:this.options.defaultDelay,dismissible:!0,...s},r=this.createViewToastElement(i,e,t,a);if(this.container.appendChild(r),typeof bootstrap>"u")throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const n=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});this.toasts.set(i,{element:r,bootstrap:n,type:t,view:e,message:"View toast"}),r.addEventListener("hidden.bs.toast",()=>{this.cleanupView(i)});const o=r.querySelector(".toast-view-body");return o&&e&&e.render(!0,o),n.show(),{id:i,view:e,hide:()=>{try{n.hide()}catch(l){console.warn("Error hiding view toast:",l)}},dispose:()=>this.cleanupView(i),updateProgress:l=>{e&&typeof e.updateProgress=="function"&&e.updateProgress(l)}}}createToastElement(e,t,s,i){const a=document.createElement("div");a.id=e,a.className=`toast toast-service-${s}`,a.setAttribute("role","alert"),a.setAttribute("aria-live","assertive"),a.setAttribute("aria-atomic","true");const r=i.title||i.icon?this.createToastHeader(i,s):"",n=this.createToastBody(t,i.icon&&!i.title);return a.innerHTML=`
|
|
1091
|
+
${r}
|
|
1092
|
+
${n}
|
|
1093
|
+
`,a}createViewToastElement(e,t,s,i){const a=document.createElement("div");a.id=e,a.className=`toast toast-service-${s}`,a.setAttribute("role","alert"),a.setAttribute("aria-live","assertive"),a.setAttribute("aria-atomic","true");const r=i.title||i.icon?this.createToastHeader(i,s):"",n=this.createViewToastBody();return a.innerHTML=`
|
|
1094
|
+
${r}
|
|
1095
|
+
${n}
|
|
1096
|
+
`,a}createViewToastBody(){return`
|
|
1097
|
+
<div class="toast-body p-0">
|
|
1098
|
+
<div class="toast-view-body p-3"></div>
|
|
1099
|
+
</div>
|
|
1100
|
+
`}createToastHeader(e,t){const s=e.icon?`<i class="${e.icon} toast-service-icon me-2"></i>`:"",i=e.title?`<strong class="me-auto">${s}${this.escapeHtml(e.title)}</strong>`:"",a=e.showTime?`<small class="text-muted">${this.getTimeString()}</small>`:"",r=e.dismissible?'<button type="button" class="btn-close toast-service-close" data-bs-dismiss="toast" aria-label="Close"></button>':"";return!i&&!a&&!r?"":`
|
|
1101
|
+
<div class="toast-header">
|
|
1102
|
+
${i}
|
|
1103
|
+
${a}
|
|
1104
|
+
${r}
|
|
1105
|
+
</div>
|
|
1106
|
+
`}createToastBody(e,t=!1){return`
|
|
1107
|
+
<div class="toast-body d-flex align-items-center">
|
|
1108
|
+
${t?`<i class="${this.getDefaultIcon("info")} toast-service-icon me-2"></i>`:""}
|
|
1109
|
+
<span>${this.escapeHtml(e)}</span>
|
|
1110
|
+
</div>
|
|
1111
|
+
`}getDefaultTitle(e){return{success:"Success",error:"Error",warning:"Warning",info:"Information",plain:""}[e]||"Notification"}getDefaultIcon(e){return{success:"bi-check-circle-fill",error:"bi-exclamation-triangle-fill",warning:"bi-exclamation-triangle-fill",info:"bi-info-circle-fill",plain:""}[e]||"bi-info-circle-fill"}enforceMaxToasts(){if(Array.from(this.toasts.values()).length>=this.options.maxToasts){const t=this.toasts.keys().next().value,s=this.toasts.get(t);s&&s.bootstrap.hide()}}cleanup(e){const t=this.toasts.get(e);if(t){try{t.bootstrap.dispose()}catch(s){console.warn("Error disposing toast:",s)}t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element),this.toasts.delete(e)}}cleanupView(e){const t=this.toasts.get(e);if(t){if(t.view&&typeof t.view.dispose=="function")try{t.view.dispose()}catch(s){console.warn("Error disposing view in toast:",s)}try{t.bootstrap.dispose()}catch(s){console.warn("Error disposing toast:",s)}t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element),this.toasts.delete(e)}}hideAll(){this.toasts.forEach((e,t)=>{e.bootstrap.hide()})}clearAll(){this.toasts.forEach((e,t)=>{this.cleanup(t)})}getTimeString(){return new Date().toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}dispose(){this.clearAll(),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container)}getStats(){const e={total:this.toasts.size,byType:{}};return this.toasts.forEach(t=>{e.byType[t.type]=(e.byType[t.type]||0)+1}),e}setOptions(e){this.options={...this.options,...e},e.position&&this.container&&(this.container.className=`toast-container position-fixed ${this.getPositionClasses()}`)}}class me extends v{constructor(e={}){super({template:"progress-view-template",...e}),this.filename=e.filename||"Unknown file",this.filesize=e.filesize||0,this.filesizeFormatted=V.pipe(this.filesize,"filesize"),this.progress=0,this.percentage=0,this.loaded=0,this.total=this.filesize,this.loadedFormatted="0 B",this.totalFormatted=this.filesizeFormatted,this.status="Starting upload...",this.showCancel=e.showCancel!==!1,this.onCancel=e.onCancel||null,this.cancelled=!1,this.completed=!1}getTemplate(){return`
|
|
1112
|
+
<div class="progress-view">
|
|
1113
|
+
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
1114
|
+
<div class="flex-grow-1 min-width-0">
|
|
1115
|
+
<div class="fw-medium text-truncate" title="{{filename}}">
|
|
1116
|
+
<i class="bi bi-file-earmark me-1"></i>
|
|
1117
|
+
{{filename}}
|
|
1118
|
+
</div>
|
|
1119
|
+
<small class="text-muted">{{status}}</small>
|
|
1120
|
+
</div>
|
|
1121
|
+
{{#showCancel}}
|
|
1122
|
+
<button type="button"
|
|
1123
|
+
class="btn btn-sm btn-outline-secondary ms-2"
|
|
1124
|
+
data-action="cancel"
|
|
1125
|
+
{{#cancelled}}disabled{{/cancelled}}>
|
|
1126
|
+
<i class="bi bi-x"></i>
|
|
1127
|
+
</button>
|
|
1128
|
+
{{/showCancel}}
|
|
1129
|
+
</div>
|
|
1130
|
+
|
|
1131
|
+
<div class="progress mb-2" style="height: 8px;">
|
|
1132
|
+
<div class="progress-bar"
|
|
1133
|
+
role="progressbar"
|
|
1134
|
+
style="width: {{percentage}}%"
|
|
1135
|
+
aria-valuenow="{{percentage}}"
|
|
1136
|
+
aria-valuemin="0"
|
|
1137
|
+
aria-valuemax="100">
|
|
1138
|
+
</div>
|
|
1139
|
+
</div>
|
|
1140
|
+
|
|
1141
|
+
<div class="d-flex justify-content-between">
|
|
1142
|
+
<small class="text-muted">
|
|
1143
|
+
{{loadedFormatted}} / {{totalFormatted}}
|
|
1144
|
+
</small>
|
|
1145
|
+
<small class="text-muted">
|
|
1146
|
+
{{percentage}}%
|
|
1147
|
+
</small>
|
|
1148
|
+
</div>
|
|
1149
|
+
</div>
|
|
1150
|
+
`}updateProgress(e){this.cancelled||this.completed||(this.progress=e.progress,this.percentage=e.percentage,this.loaded=e.loaded,this.total=e.total||this.filesize,this.loadedFormatted=V.pipe(this.loaded,"filesize"),this.totalFormatted=V.pipe(this.total,"filesize"),this.percentage<100?this.status=`Uploading... ${this.percentage}%`:this.status="Finalizing upload...",this.render())}markCompleted(e="Upload completed!"){this.completed=!0,this.progress=1,this.percentage=100,this.status=e,this.render()}markFailed(e="Upload failed"){this.status=e,this.render()}markCancelled(){this.cancelled=!0,this.status="Upload cancelled",this.render()}async onActionCancel(e,t,s){if(!(this.cancelled||this.completed)&&(s.disabled=!0,this.markCancelled(),this.emit("cancel"),typeof this.onCancel=="function"))try{await this.onCancel()}catch(i){console.error("Error in cancel callback:",i)}}setFilename(e){this.filename=e,this.render()}setFilesize(e){this.filesize=e,this.filesizeFormatted=V.pipe(e,"filesize"),this.total=e,this.totalFormatted=this.filesizeFormatted,this.render()}getPercentage(){return this.percentage}isCompleted(){return this.completed}isCancelled(){return this.cancelled}getStats(){return{filename:this.filename,filesize:this.filesize,progress:this.progress,percentage:this.percentage,loaded:this.loaded,total:this.total,cancelled:this.cancelled,completed:this.completed,status:this.status}}}class et{constructor(e,t={}){if(this.fileModel=e,this.options={file:null,name:null,group:null,description:null,onProgress:null,onComplete:null,onError:null,showToast:!0,...t},!this.options.file||!(this.options.file instanceof File))throw new Error("FileUpload requires a valid File object");this.cancelled=!1,this.uploadRequest=null,this.progressToast=null,this.progressView=null,this.toastService=null,this.options.showToast&&(this.toastService=new Xe),this.promise=this._startUpload()}async _startUpload(){try{this.options.showToast&&this._showProgressToast();let e;try{e=await this._initiateUpload()}catch(i){throw new Error(`Failed to initiate upload: ${i.message}`)}if(this.cancelled)throw new Error("Upload cancelled");if(!e||!e.upload_url)throw new Error("Invalid upload response: missing upload URL");let t;if(typeof e.upload_url=="string")t={url:e.upload_url,method:"PUT",fields:null,headers:{}};else if(e.upload_url&&typeof e.upload_url=="object"&&e.upload_url.upload_url)t={url:e.upload_url.upload_url,method:e.upload_url.method||"POST",fields:e.upload_url.fields||null,headers:e.upload_url.headers||{}};else throw new Error(`Invalid upload response: unrecognised upload_url format. Server returned: ${JSON.stringify(e.upload_url)}`);let s;try{s=await this._performUpload(t)}catch(i){throw new Error(`File upload failed: ${i.message}`)}if(this.cancelled)throw new Error("Upload cancelled");try{await this._completeUpload()}catch(i){console.warn("Failed to mark upload as completed:",i)}return this._onComplete(this.fileModel),this.fileModel}catch(e){throw e.message!=="Upload cancelled"&&this._onError(e),e}}async _initiateUpload(){try{const e={filename:this.options.name||this.options.file.name,file_size:this.options.file.size,content_type:this.options.file.type};this.options.group&&(e.group=this.options.group),this.options.description&&(e.description=this.options.description);const t=await this.fileModel.rest.POST("/api/fileman/upload/initiate",e);if(!t)throw new Error("No response from upload initiation API");if(!t.data)throw new Error("Upload initiation response missing data");if(!t.data.status){const s=t.data.error||"Upload initiation failed";throw new Error(s)}if(!t.data.data)throw new Error("Upload initiation response missing data payload");return t.data.data.id&&this.fileModel.set("id",t.data.data.id),t.data.data}catch(e){throw e.message==="Network Error"||e.name==="TypeError"?new Error("Network error during upload initiation. Please check your connection."):e}}async _performUpload(e){return new Promise((t,s)=>{if(!(this.options.file instanceof File)){s(new Error("Only single File objects are supported"));return}const{url:i,method:a,fields:r,headers:n}=e,o=a==="POST"&&r!==null,l=new XMLHttpRequest;this.uploadRequest=l,l.upload.onprogress=h=>{this.cancelled||this._onProgress({progress:h.loaded/h.total,loaded:h.loaded,total:h.total,percentage:Math.round(h.loaded/h.total*100)})},l.onload=()=>{l.status>=200&&l.status<300?t({data:l.response,status:l.status,statusText:l.statusText,xhr:l}):s(new Error(`Upload failed: ${l.status} ${l.statusText}`))},l.onerror=()=>s(new Error("Upload failed: Network error")),l.ontimeout=()=>s(new Error("Upload timed out — file may be too large or connection too slow")),l.onabort=()=>s(new Error("Upload cancelled"));let c=i;i.startsWith("/")&&!i.startsWith("/api/")&&(c="/api"+i);const d=this.fileModel.rest.buildUrl(c);if(l.open(a,d),l.timeout=3e4,o){for(const[m,p]of Object.entries(n||{}))m.toLowerCase()!=="content-type"&&l.setRequestHeader(m,p);const h=new FormData;for(const[m,p]of Object.entries(r))h.append(m,p);h.append("file",this.options.file),l.send(h)}else{l.setRequestHeader("Content-Type",this.options.file.type);for(const[h,m]of Object.entries(n||{}))h.toLowerCase()!=="content-type"&&l.setRequestHeader(h,m);l.send(this.options.file)}})}async _completeUpload(){try{const e=await this.fileModel.save({action:"mark_as_completed"});if(!e)throw new Error("No response from upload completion API");if(e.data&&!e.data.status){const t=e.data.error||"Failed to mark upload as completed";throw new Error(t)}return e}catch(e){throw e.message==="Network Error"||e.name==="TypeError"?new Error("Network error during upload completion. The file may have uploaded successfully."):e}}_onProgress(e){this.progressToast&&this.progressToast.updateProgress&&this.progressToast.updateProgress(e),typeof this.options.onProgress=="function"&&this.options.onProgress(e)}_onComplete(e){this.progressView&&this.progressView.markCompleted("Upload completed successfully!"),this.progressToast&&setTimeout(()=>{try{this.progressToast&&typeof this.progressToast.hide=="function"&&this.progressToast.hide()}catch(t){console.warn("Error hiding progress toast:",t)}},2e3),typeof this.options.onComplete=="function"&&this.options.onComplete(e)}_onError(e){if(this.progressToast)try{this.progressToast.hide()}catch(t){console.warn("Error hiding progress toast on error:",t)}this.toastService&&this.toastService.error(`Upload failed: ${e.message}`),typeof this.options.onError=="function"&&this.options.onError(e)}_showProgressToast(){this.progressView=new me({filename:this.options.name||this.options.file.name,filesize:this.options.file.size,showCancel:!0,onCancel:()=>this.cancel()}),this.progressToast=this.toastService.showView(this.progressView,"info",{title:"File Upload",autohide:!1,dismissible:!1})}cancel(){return this.cancelled?!1:(this.cancelled=!0,this.uploadRequest&&typeof this.uploadRequest.abort=="function"&&this.uploadRequest.abort(),this.progressView&&this.progressView.markCancelled(),this.progressToast&&setTimeout(()=>{try{this.progressToast&&typeof this.progressToast.hide=="function"&&this.progressToast.hide()}catch(e){console.warn("Error hiding progress toast on cancel:",e)}},1500),!0)}isCancelled(){return this.cancelled}then(e,t){return this.promise.then(e,t)}catch(e){return this.promise.catch(e)}finally(e){return this.promise.finally(e)}getStats(){return{filename:this.options.file.name,size:this.options.file.size,type:this.options.file.type,cancelled:this.cancelled,group:this.options.group,description:this.options.description}}}class J extends B{constructor(e={}){super(e,{endpoint:"/api/group"})}}class pe extends W{constructor(e={}){super({ModelClass:J,endpoint:"/api/group",size:10,...e})}}const Ae={org:"Organization",division:"Division",department:"Department",team:"Team",merchant:"Merchant",partner:"Partner",client:"Client",iso:"ISO",sales:"Sales",reseller:"Reseller",location:"Location",region:"Region",route:"Route",project:"Project",inventory:"Inventory",test:"Testing",misc:"Miscellaneous",qa:"Quality Assurance"},fe=Object.entries(Ae).map(([u,e])=>({value:u,label:e})),ge={create:{title:"Create Group",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name"},{name:"kind",type:"select",label:"Group Kind",required:!0,options:fe},{type:"collection",name:"parent",label:"Parent Group",Collection:pe,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300}]},edit:{title:"Edit Group",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name"},{name:"kind",type:"select",label:"Group Kind",required:!0,options:fe},{type:"collection",name:"parent",label:"Parent Group",Collection:pe,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300},{name:"metadata.domain",type:"text",label:"Default Domain",placeholder:"Enter Domain"},{name:"metadata.portal",type:"text",label:"Default Portal",placeholder:"Enter Portal URL"},{name:"is_active",type:"switch",label:"Is Active",cols:4}]}};J.EDIT_FORM=ge.edit,J.ADD_FORM=ge.create,J.CREATE_FORM=ge.create,J.GroupKindOptions=fe,J.GroupKinds=Ae;class U extends B{constructor(e={}){super(e,{endpoint:"/api/user"})}hasPermission(e){if(this.get("is_superuser"))return!0;if(Array.isArray(e))return e.some(i=>this.hasPermission(i));const t=e.startsWith("sys."),s=t?e.substring(4):e;return!!(this._hasPermission(s)||!t&&this.member&&this.member.hasPermission(e))}_hasPermission(e){const t=this.get("permissions");return t?t[e]==!0:!1}hasPerm(e){return this.hasPermission(e)}}U.PERMISSIONS=[{name:"manage_users",label:"Manage Users"},{name:"view_users",label:"View Users"},{name:"view_groups",label:"View Groups"},{name:"manage_groups",label:"Manage Groups"},{name:"view_metrics",label:"View System Metrics"},{name:"manage_metrics",label:"Manage System Metrics"},{name:"view_logs",label:"View Logs"},{name:"view_incidents",label:"View Incidents"},{name:"manage_incidents",label:"Manage Incidents"},{name:"view_tickets",label:"View Tickets"},{name:"manage_tickets",label:"Manage Tickets"},{name:"view_admin",label:"View Admin"},{name:"view_jobs",label:"View Jobs"},{name:"manage_jobs",label:"Manage Jobs"},{name:"view_global",label:"View Global"},{name:"manage_notifications",label:"Manage Notifications"},{name:"manage_files",label:"Manage Files"},{name:"force_single_session",label:"Force Single Session"},{name:"file_vault",label:"Access File Vault"},{name:"manage_aws",label:"Manage AWS"},{name:"manage_docit",label:"Manage DocIt"}],U.PERMISSION_FIELDS=[...U.PERMISSIONS.map(u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:4}))];const ke={create:{title:"Create User",fields:[{name:"email",type:"text",label:"Email",required:!0},{name:"phone_number",type:"text",label:"Phone number",columns:12},{name:"display_name",type:"text",label:"Display Name"}]},edit:{title:"Edit User",fields:[{name:"email",type:"email",label:"Email",columns:12},{name:"display_name",type:"text",label:"Display Name",columns:12},{name:"phone_number",type:"text",label:"Phone number",columns:12},{type:"collection",name:"org",label:"Organization",Collection:pe,labelField:"name",valueField:"id",columns:12}]},permissions:{fields:U.PERMISSION_FIELDS}},tt={detailed:{title:"Detailed User Information",columns:2,showEmptyValues:!0,emptyValueText:"Not set",fields:[{name:"id",label:"User ID",type:"number",colSize:3},{name:"display_name",label:"Display Name",type:"text",format:'capitalize|default("Unnamed User")',colSize:9},{name:"username",label:"Username",type:"text",format:"lowercase",colSize:6},{name:"email",label:"Email Address",type:"email",colSize:6},{name:"phone_number",label:"Phone Number",type:"phone",format:'phone|default("Not provided")',colSize:6},{name:"is_active",label:"Account Status",type:"boolean",colSize:6},{name:"last_login",label:"Last Login",type:"datetime",format:"relative",colSize:6},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",colSize:6},{name:"avatar.url",label:"Avatar",type:"url",colSize:12},{name:"permissions",label:"User Permissions",type:"dataview",dataViewColumns:2,showEmptyValues:!1},{name:"metadata",label:"User Metadata",type:"dataview",dataViewColumns:1},{name:"avatar",label:"Avatar Details",type:"dataview",dataViewColumns:1}]}};U.DATA_VIEW=tt.detailed,U.EDIT_FORM=ke.edit,U.ADD_FORM=ke.create;let st=class extends B{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return this.get("category")==="image"}upload(e={}){return new et(this,e)}},T=class F extends v{static _openDialogs=[];static _baseZIndex={backdrop:1050,modal:1055};static getFullscreenAwareZIndex(){return document.querySelector(".table-fullscreen")?{backdrop:10040,modal:10050}:this._baseZIndex}static _busyIndicator=null;static _busyCounter=0;static _busyTimeout=null;static fixAllBackdropStacking(){const e=document.querySelectorAll(".modal-backdrop"),t=F._openDialogs;if(e.length===0||t.length===0)return;const s=[...t].sort((i,a)=>(i._dialogZIndex||0)-(a._dialogZIndex||0));e.forEach((i,a)=>{if(a<s.length){const n=s[a]._dialogZIndex-5;i.style.zIndex=n;const l=document.querySelector(".table-fullscreen")||document.body;i.parentNode!==l&&l.appendChild(i)}})}static updateAllBackdropStacking(){F.fixAllBackdropStacking()}static showBusy(e={}){const{timeout:t=3e4,message:s="Loading..."}=e;if(this._busyCounter++,this._busyCounter===1){if(this._busyTimeout&&clearTimeout(this._busyTimeout),!this._busyIndicator){const r=this.getFullscreenAwareZIndex().modal+1e3;this._busyIndicator=document.createElement("div"),this._busyIndicator.className="mojo-busy-indicator",this._busyIndicator.innerHTML=`
|
|
1091
1151
|
<div class="mojo-busy-spinner">
|
|
1092
1152
|
<div class="spinner-border text-light" role="status">
|
|
1093
1153
|
<span class="visually-hidden">Loading...</span>
|
|
@@ -1210,46 +1270,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1210
1270
|
id="${i}"
|
|
1211
1271
|
value="${a}"
|
|
1212
1272
|
placeholder="${n}">
|
|
1213
|
-
`,size:s.size||"sm",centered:!0,backdrop:"static",buttons:[{text:"Cancel",class:"btn-secondary",dismiss:!0},{text:"OK",class:"btn-primary",action:"ok"}],...s}),c=document.querySelector(".table-fullscreen")||document.body;return await o.render(!0,c),o.show(),o.on("shown",()=>{const d=o.element.querySelector(`#${i}`);d&&(d.focus(),d.select())}),new Promise(d=>{let h=null;o.on("action:ok",()=>{const m=o.element.querySelector(`#${i}`);h=m?m.value:null,o.hide()}),o.on("hidden",()=>{o.destroy(),o.element.remove(),d(h)})})}getModal(){return this.modal}isShown(){return this.element?.classList.contains("show")||!1}static async showForm(e={}){const{title:t="Form",formConfig:s={},size:i="md",centered:a=!0,submitText:r="Submit",cancelText:n="Cancel",...o}=e,l=(await Promise.resolve().then(()=>Te)).default,c=new l({fileHandling:e.fileHandling||"base64",data:e.data,defaults:e.defaults,model:e.model,formConfig:{fields:s.fields||e.fields,...s,submitButton:!1,resetButton:!1}}),d=new F({title:t,body:c,size:i,centered:a,buttons:[{text:n,class:"btn-secondary",action:"cancel"},{text:r,class:"btn-primary",action:"submit"}],...o}),m=document.querySelector(".table-fullscreen")||document.body;return await d.render(!0,m),d.show(),new Promise(p=>{let f=!1;d.on("action:submit",async()=>{if(!f){if(!c.validate()){c.focusFirstError();return}if(e.autoSave&&e.model){d.setLoading(!0);const g=await c.saveModel();if(!g.success){d.setLoading(!1),d.render(),d.getApp().toast.error(g.message);return}f=!0,d.hide(),p(g)}try{const g=await c.getFormData();f=!0,d.hide(),p(g)}catch(g){console.error("Error collecting form data:",g),c.showError("Error collecting form data")}}}),d.on("action:cancel",()=>{f||(f=!0,d.hide(),p(null))}),d.on("hidden",()=>{f||(f=!0,p(null)),setTimeout(()=>{c.destroy(),d.destroy()},100)})})}static async updateModelImage(e={},t={}){const s=e.upload||!1,i=t.name||e.field||"image",a={title:"Upload Your Avatar",model:null,autoSave:!s,size:"sm",fields:[{type:"image",name:i,size:"lg",imageSize:{width:200,height:200},placeholder:"Upload your image",...t}],...e},r=await F.showForm(a);if(!s||!r||!e.model)return r;const n=r[i];if(!n||!n.startsWith("data:"))return r;const o=n.split(","),
|
|
1214
|
-
<div class="progress-view">
|
|
1215
|
-
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
1216
|
-
<div class="flex-grow-1 min-width-0">
|
|
1217
|
-
<div class="fw-medium text-truncate" title="{{filename}}">
|
|
1218
|
-
<i class="bi bi-file-earmark me-1"></i>
|
|
1219
|
-
{{filename}}
|
|
1220
|
-
</div>
|
|
1221
|
-
<small class="text-muted">{{status}}</small>
|
|
1222
|
-
</div>
|
|
1223
|
-
{{#showCancel}}
|
|
1224
|
-
<button type="button"
|
|
1225
|
-
class="btn btn-sm btn-outline-secondary ms-2"
|
|
1226
|
-
data-action="cancel"
|
|
1227
|
-
{{#cancelled}}disabled{{/cancelled}}>
|
|
1228
|
-
<i class="bi bi-x"></i>
|
|
1229
|
-
</button>
|
|
1230
|
-
{{/showCancel}}
|
|
1231
|
-
</div>
|
|
1232
|
-
|
|
1233
|
-
<div class="progress mb-2" style="height: 8px;">
|
|
1234
|
-
<div class="progress-bar"
|
|
1235
|
-
role="progressbar"
|
|
1236
|
-
style="width: {{percentage}}%"
|
|
1237
|
-
aria-valuenow="{{percentage}}"
|
|
1238
|
-
aria-valuemin="0"
|
|
1239
|
-
aria-valuemax="100">
|
|
1240
|
-
</div>
|
|
1241
|
-
</div>
|
|
1242
|
-
|
|
1243
|
-
<div class="d-flex justify-content-between">
|
|
1244
|
-
<small class="text-muted">
|
|
1245
|
-
{{loadedFormatted}} / {{totalFormatted}}
|
|
1246
|
-
</small>
|
|
1247
|
-
<small class="text-muted">
|
|
1248
|
-
{{percentage}}%
|
|
1249
|
-
</small>
|
|
1250
|
-
</div>
|
|
1251
|
-
</div>
|
|
1252
|
-
`}updateProgress(e){this.cancelled||this.completed||(this.progress=e.progress,this.percentage=e.percentage,this.loaded=e.loaded,this.total=e.total||this.filesize,this.loadedFormatted=V.pipe(this.loaded,"filesize"),this.totalFormatted=V.pipe(this.total,"filesize"),this.percentage<100?this.status=`Uploading... ${this.percentage}%`:this.status="Finalizing upload...",this.render())}markCompleted(e="Upload completed!"){this.completed=!0,this.progress=1,this.percentage=100,this.status=e,this.render()}markFailed(e="Upload failed"){this.status=e,this.render()}markCancelled(){this.cancelled=!0,this.status="Upload cancelled",this.render()}async onActionCancel(e,t,s){if(!(this.cancelled||this.completed)&&(s.disabled=!0,this.markCancelled(),this.emit("cancel"),typeof this.onCancel=="function"))try{await this.onCancel()}catch(i){console.error("Error in cancel callback:",i)}}setFilename(e){this.filename=e,this.render()}setFilesize(e){this.filesize=e,this.filesizeFormatted=V.pipe(e,"filesize"),this.total=e,this.totalFormatted=this.filesizeFormatted,this.render()}getPercentage(){return this.percentage}isCompleted(){return this.completed}isCancelled(){return this.cancelled}getStats(){return{filename:this.filename,filesize:this.filesize,progress:this.progress,percentage:this.percentage,loaded:this.loaded,total:this.total,cancelled:this.cancelled,completed:this.completed,status:this.status}}}class se extends v{constructor(e={}){super({className:"list-view-item",...e}),this.selected=!1,this.index=e.index??0,this.listView=e.listView??null,this.template||(this.template=`
|
|
1273
|
+
`,size:s.size||"sm",centered:!0,backdrop:"static",buttons:[{text:"Cancel",class:"btn-secondary",dismiss:!0},{text:"OK",class:"btn-primary",action:"ok"}],...s}),c=document.querySelector(".table-fullscreen")||document.body;return await o.render(!0,c),o.show(),o.on("shown",()=>{const d=o.element.querySelector(`#${i}`);d&&(d.focus(),d.select())}),new Promise(d=>{let h=null;o.on("action:ok",()=>{const m=o.element.querySelector(`#${i}`);h=m?m.value:null,o.hide()}),o.on("hidden",()=>{o.destroy(),o.element.remove(),d(h)})})}getModal(){return this.modal}isShown(){return this.element?.classList.contains("show")||!1}static async showForm(e={}){const{title:t="Form",formConfig:s={},size:i="md",centered:a=!0,submitText:r="Submit",cancelText:n="Cancel",...o}=e,l=(await Promise.resolve().then(()=>Te)).default,c=new l({fileHandling:e.fileHandling||"base64",data:e.data,defaults:e.defaults,model:e.model,formConfig:{fields:s.fields||e.fields,...s,submitButton:!1,resetButton:!1}}),d=new F({title:t,body:c,size:i,centered:a,buttons:[{text:n,class:"btn-secondary",action:"cancel"},{text:r,class:"btn-primary",action:"submit"}],...o}),m=document.querySelector(".table-fullscreen")||document.body;return await d.render(!0,m),d.show(),new Promise(p=>{let f=!1;d.on("action:submit",async()=>{if(!f){if(!c.validate()){c.focusFirstError();return}if(e.autoSave&&e.model){d.setLoading(!0);const g=await c.saveModel();if(!g.success){d.setLoading(!1),d.render(),d.getApp().toast.error(g.message);return}f=!0,d.hide(),p(g)}try{const g=await c.getFormData();f=!0,d.hide(),p(g)}catch(g){console.error("Error collecting form data:",g),c.showError("Error collecting form data")}}}),d.on("action:cancel",()=>{f||(f=!0,d.hide(),p(null))}),d.on("hidden",()=>{f||(f=!0,p(null)),setTimeout(()=>{c.destroy(),d.destroy()},100)})})}static async updateModelImage(e={},t={}){const s=e.upload||!1,i=t.name||e.field||"image",a={title:"Upload Your Avatar",model:null,autoSave:!s,size:"sm",fields:[{type:"image",name:i,size:"lg",imageSize:{width:200,height:200},placeholder:"Upload your image",...t}],...e},r=await F.showForm(a);if(!s||!r||!e.model)return r;const n=r[i];if(!n||!n.startsWith("data:"))return r;const o=n.split(","),c=o[0]?.match(/:(.*?);/)?.[1]||"image/png",d=atob(o[1]);let h=d.length;const m=new Uint8Array(h);for(;h--;)m[h]=d.charCodeAt(h);const p=c.split("/")[1]||"png",f=typeof window<"u"&&window.File||globalThis.File;if(!f)throw new Error("File API is not available in this environment");const g=new f([m],`${i}.${p}`,{type:c}),y=new st;return await y.upload({file:g,name:`${i}.${p}`,description:e.uploadDescription||`${i} upload`,showToast:!0}),await e.model.save({[i]:y.id})}static async showModelView(e,t){const i=e.constructor.VIEW_CLASS,a=new i({model:e});return t=t||{},await F.showDialog({header:!1,body:a,size:"lg",centered:!1,...t})}static async showModelForm(e={}){const{title:t="Edit",formConfig:s={},size:i="md",centered:a=!0,submitText:r="Save",cancelText:n="Cancel",model:o,fields:l,...c}=e;if(!o)throw new Error("showModelForm requires a model");const d=(await Promise.resolve().then(()=>Te)).default,h=new d({fileHandling:e.fileHandling||"base64",model:o,data:e.data,defaults:e.defaults,formConfig:{fields:l||s.fields||[],...s,submitButton:!1,resetButton:!1}}),m=new F({title:t,body:h,size:i,centered:a,buttons:[{text:n,class:"btn-secondary",action:"cancel"},{text:r,class:"btn-primary",action:"submit"}],...c}),f=document.querySelector(".table-fullscreen")||document.body;return await m.render(!0,f),m.show(),new Promise(g=>{let y=!1;m.on("action:submit",async()=>{if(!y){m.setLoading(!0,"Saving...");try{const b=await h.handleSubmit();if(b.success)y=!0,m.hide(),g(b);else{m.setLoading(!1);let w=b.error;b.data&&b.data.error&&(w=b.data.error),m.getApp().toast.error(w)}}catch(b){console.error("Error saving form:",b),await m.setContent(h),h.showError(b.message||"An error occurred while saving")}}}),m.on("action:cancel",()=>{y||(y=!0,m.hide(),g(null))}),m.on("hidden",()=>{y||(y=!0,g(null)),setTimeout(()=>{h.destroy(),m.destroy()},100)})})}static async showData(e={}){const{title:t="Data View",data:s={},model:i=null,fields:a=[],columns:r=2,responsive:n=!0,showEmptyValues:o=!1,emptyValueText:l="—",size:c="lg",centered:d=!0,closeText:h="Close",...m}=e,p=(await Promise.resolve().then(()=>nt)).default,f=new p({data:s,model:i,fields:a,columns:r,responsive:n,showEmptyValues:o,emptyValueText:l}),g=new F({title:t,body:f,size:c,centered:d,buttons:[{text:h,class:"btn-secondary",value:"close"}],...m}),b=document.querySelector(".table-fullscreen")||document.body;return await g.render(!0,b),g.show(),new Promise(w=>{let C=!1;const $=g.element.querySelector(".modal-footer button"),S=()=>{C||(C=!0,g.hide(),w(!0))};$?.addEventListener("click",S),g.on("hidden",()=>{C||(C=!0,w(!0)),setTimeout(()=>{f.destroy(),g.destroy(),g.element.remove()},100)}),f.on("field:click",M=>{g.emit("dataview:field:click",M)}),f.on("error",M=>{g.emit("dataview:error",M)})})}};T.showConfirm=T.confirm,T.showError=T.alert;const L=Object.freeze(Object.defineProperty({__proto__:null,default:T},Symbol.toStringTag,{value:"Module"}));class se extends v{constructor(e={}){super({className:"list-view-item",...e}),this.selected=!1,this.index=e.index??0,this.listView=e.listView??null,this.template||(this.template=`
|
|
1253
1274
|
<div class="list-item-content" data-action="select">
|
|
1254
1275
|
{{#model}}
|
|
1255
1276
|
{{#id}}<span class="item-id">{{id}}</span>{{/id}}
|
|
@@ -1262,7 +1283,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1262
1283
|
<span class="item-empty">No data</span>
|
|
1263
1284
|
{{/model}}
|
|
1264
1285
|
</div>
|
|
1265
|
-
`)}async onActionSelect(e,t){e.stopPropagation(),this.selected?this.deselect():this.select()}select(){this.selected||(this.selected=!0,this.addClass("selected"),this.emit("item:select",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:select",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}))}deselect(){this.selected&&(this.selected=!1,this.removeClass("selected"),this.emit("item:deselect",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:deselect",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}))}async onActionDefault(e,t,s){this.emit("item:click",{item:this,model:this.model,index:this.index,action:e,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:click",{item:this,model:this.model,index:this.index,action:e,data:this.model?.toJSON?this.model.toJSON():this.model})}setIndex(e){return this.index=e,this.element.setAttribute("data-index",e),this}setSelected(e){return e?this.select():this.deselect(),this}async destroy(){this.listView=null,await super.destroy()}}class
|
|
1286
|
+
`)}async onActionSelect(e,t){e.stopPropagation(),this.selected?this.deselect():this.select()}select(){this.selected||(this.selected=!0,this.addClass("selected"),this.emit("item:select",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:select",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}))}deselect(){this.selected&&(this.selected=!1,this.removeClass("selected"),this.emit("item:deselect",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:deselect",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}))}async onActionDefault(e,t,s){this.emit("item:click",{item:this,model:this.model,index:this.index,action:e,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:click",{item:this,model:this.model,index:this.index,action:e,data:this.model?.toJSON?this.model.toJSON():this.model})}setIndex(e){return this.index=e,this.element.setAttribute("data-index",e),this}setSelected(e){return e?this.select():this.deselect(),this}async destroy(){this.listView=null,await super.destroy()}}class be extends v{constructor(e={}){super({className:"list-view",template:`
|
|
1266
1287
|
<div class="list-view-container">
|
|
1267
1288
|
{{#loading}}
|
|
1268
1289
|
<div class="list-loading">
|
|
@@ -1283,7 +1304,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1283
1304
|
{{/isEmpty}}
|
|
1284
1305
|
{{/loading}}
|
|
1285
1306
|
</div>
|
|
1286
|
-
`,...e}),this.collection=null,this.itemViews=new Map,this.selectedItems=new Set,this.itemTemplate=e.itemTemplate||null,this.itemClass=e.itemClass||se,this.selectionMode=e.selectionMode||"none",this.emptyMessage=e.emptyMessage||"No items to display",this.loading=!1,this.isEmpty=!0}async onInit(){this._initCollection(this.options.collection||this.options.Collection)}_initCollection(e){if(!e){console.log("Collection not provided");return}if(e instanceof W)this.setCollection(e);else if(typeof e=="function"){const t=new e;this.setCollection(t)}else if(Array.isArray(e)){const t=new W(null,{},e);this.setCollection(t)}}setCollection(e){return this.collection===e?this:(this.collection&&(this.collection.off("add",this._onModelsAdded,this),this.collection.off("remove",this._onModelsRemoved,this),this.collection.off("reset",this._onCollectionReset,this),this.collection.off("fetch:start",this._onFetchStart,this),this.collection.off("fetch:end",this._onFetchEnd,this)),this.collection=e,this.options.defaultQuery&&!this.options.collectionParams&&(this.collection.params={...this.collection.params,...this.options.defaultQuery}),this.options.collectionParams&&(this.collection.params={...this.collection.params,...this.options.collectionParams}),this.collection&&(this.collection.on("add",this._onModelsAdded,this),this.collection.on("remove",this._onModelsRemoved,this),this.collection.on("reset",this._onCollectionReset,this),this.collection.on("fetch:start",this._onFetchStart,this),this.collection.on("fetch:end",this._onFetchEnd,this),this._buildItems()),this)}async _renderChildren(){await super._renderChildren();const e=this.getChildElement("items");e&&this.forEachItem((t,s)=>{e.appendChild(t.element),t.render(!1)})}_buildItems(){if(this._clearItems(),!this.collection||this.collection.isEmpty()){this.isEmpty=!0,this.emit("list:empty");return}this.isEmpty=!1,this.collection.forEach((e,t)=>{this._createItemView(e,t)}),this.emit("list:loaded",{count:this.collection.length()}),this.isMounted()&&this.render()}_createItemView(e,t){if(this.itemViews.has(e.id))return;const s=new this.itemClass({model:e,index:t,listView:this,template:this.itemTemplate});return this.itemViews.set(e.id,s),s.on("item:select",this._onItemSelect.bind(this)),s.on("item:deselect",this._onItemDeselect.bind(this)),s}_clearItems(){this.forEachItem(e=>{this.removeChild(e.id)}),this.itemViews.clear(),this.selectedItems.clear()}_onModelsAdded(e){const{models:t}=e;t.forEach(s=>{const i=this.collection.models.indexOf(s);this._createItemView(s,i)}),this.isEmpty=this.collection.isEmpty(),!this.loading&&this.isMounted()&&this.render()}_onModelsRemoved(e){const{models:t}=e;t.forEach(s=>{const i=this.itemViews.get(s.id);i&&(this.removeChild(i.id),this.itemViews.delete(s.id),this.selectedItems.delete(s.id))}),this.isEmpty=this.collection.isEmpty(),!this.loading&&this.isMounted()&&this.render(),this.isEmpty&&this.emit("list:empty")}_onCollectionReset(e){this._buildItems()}_onFetchStart(){this.loading=!0,this.isMounted()&&this.render()}_onFetchEnd(){this.loading=!1,this.isMounted()&&this.render()}_onItemSelect(e){const{model:t,item:s}=e;if(this.selectionMode==="none"){s.deselect();return}this.selectionMode==="single"&&(this.itemViews.forEach((i,a)=>{a!==t.id&&i.selected&&i.deselect()}),this.selectedItems.clear()),this.selectedItems.add(t.id),this.emit("selection:change",{selected:Array.from(this.selectedItems),item:s,model:t})}_onItemDeselect(e){const{model:t}=e;this.selectedItems.delete(t.id),this.emit("selection:change",{selected:Array.from(this.selectedItems),item:e.item,model:t})}getSelectedItems(){const e=[];return this.selectedItems.forEach(t=>{const s=this.itemViews.get(t);s&&e.push({view:s,model:s.model,data:s.model?.toJSON?s.model.toJSON():s.model})}),e}forEachItem(e,t){if(typeof e!="function")throw new TypeError("Callback must be a function");let s=0;return this.itemViews.forEach((i,a)=>{e.call(t,i,i.model,s++)}),this}clearSelection(){this.forEachItem(e=>{e.selected&&e.deselect()}),this.selectedItems.clear(),this.emit("selection:change",{selected:[]})}selectItem(e){const t=this.itemViews.get(e);return t&&t.select(),this}deselectItem(e){const t=this.itemViews.get(e);return t&&t.deselect(),this}setItemTemplate(e,t=!1){return this.itemTemplate=e,t&&this.itemViews.size>0&&this.forEachItem(s=>{s.setTemplate(e),s.isMounted()&&s.render()}),this}async onAfterMount(){await super.onAfterMount(),this.collection&&(this.options.fetchOnMount||!this.collection.lastFetchTime)&&this.collection.fetch()}async refresh(){if(this.collection&&this.collection.restEnabled)return await this.collection.fetch();this._buildItems()}async destroy(){this.collection&&(this.collection.off("add",this._onModelsAdded,this),this.collection.off("remove",this._onModelsRemoved,this),this.collection.off("reset",this._onCollectionReset,this),this.collection.off("fetch:start",this._onFetchStart,this),this.collection.off("fetch:end",this._onFetchEnd,this)),this._clearItems(),await super.destroy()}}class
|
|
1307
|
+
`,...e}),this.collection=null,this.itemViews=new Map,this.selectedItems=new Set,this.itemTemplate=e.itemTemplate||null,this.itemClass=e.itemClass||se,this.selectionMode=e.selectionMode||"none",this.emptyMessage=e.emptyMessage||"No items to display",this.loading=!1,this.isEmpty=!0}async onInit(){this._initCollection(this.options.collection||this.options.Collection)}_initCollection(e){if(!e){console.log("Collection not provided");return}if(e instanceof W)this.setCollection(e);else if(typeof e=="function"){const t=new e;this.setCollection(t)}else if(Array.isArray(e)){const t=new W(null,{},e);this.setCollection(t)}}setCollection(e){return this.collection===e?this:(this.collection&&(this.collection.off("add",this._onModelsAdded,this),this.collection.off("remove",this._onModelsRemoved,this),this.collection.off("reset",this._onCollectionReset,this),this.collection.off("fetch:start",this._onFetchStart,this),this.collection.off("fetch:end",this._onFetchEnd,this)),this.collection=e,this.options.defaultQuery&&!this.options.collectionParams&&(this.collection.params={...this.collection.params,...this.options.defaultQuery}),this.options.collectionParams&&(this.collection.params={...this.collection.params,...this.options.collectionParams}),this.collection&&(this.collection.on("add",this._onModelsAdded,this),this.collection.on("remove",this._onModelsRemoved,this),this.collection.on("reset",this._onCollectionReset,this),this.collection.on("fetch:start",this._onFetchStart,this),this.collection.on("fetch:end",this._onFetchEnd,this),this._buildItems()),this)}async _renderChildren(){await super._renderChildren();const e=this.getChildElement("items");e&&this.forEachItem((t,s)=>{e.appendChild(t.element),t.render(!1)})}_buildItems(){if(this._clearItems(),!this.collection||this.collection.isEmpty()){this.isEmpty=!0,this.emit("list:empty");return}this.isEmpty=!1,this.collection.forEach((e,t)=>{this._createItemView(e,t)}),this.emit("list:loaded",{count:this.collection.length()}),this.isMounted()&&this.render()}_createItemView(e,t){if(this.itemViews.has(e.id))return;const s=new this.itemClass({model:e,index:t,listView:this,template:this.itemTemplate});return this.itemViews.set(e.id,s),s.on("item:select",this._onItemSelect.bind(this)),s.on("item:deselect",this._onItemDeselect.bind(this)),s}_clearItems(){this.forEachItem(e=>{this.removeChild(e.id)}),this.itemViews.clear(),this.selectedItems.clear()}_onModelsAdded(e){const{models:t}=e;t.forEach(s=>{const i=this.collection.models.indexOf(s);this._createItemView(s,i)}),this.isEmpty=this.collection.isEmpty(),!this.loading&&this.isMounted()&&this.render()}_onModelsRemoved(e){const{models:t}=e;t.forEach(s=>{const i=this.itemViews.get(s.id);i&&(this.removeChild(i.id),this.itemViews.delete(s.id),this.selectedItems.delete(s.id))}),this.isEmpty=this.collection.isEmpty(),!this.loading&&this.isMounted()&&this.render(),this.isEmpty&&this.emit("list:empty")}_onCollectionReset(e){this._buildItems()}_onFetchStart(){this.loading=!0,this.isMounted()&&this.render()}_onFetchEnd(){this.loading=!1,this.isMounted()&&this.render()}_onItemSelect(e){const{model:t,item:s}=e;if(this.selectionMode==="none"){s.deselect();return}this.selectionMode==="single"&&(this.itemViews.forEach((i,a)=>{a!==t.id&&i.selected&&i.deselect()}),this.selectedItems.clear()),this.selectedItems.add(t.id),this.emit("selection:change",{selected:Array.from(this.selectedItems),item:s,model:t})}_onItemDeselect(e){const{model:t}=e;this.selectedItems.delete(t.id),this.emit("selection:change",{selected:Array.from(this.selectedItems),item:e.item,model:t})}getSelectedItems(){const e=[];return this.selectedItems.forEach(t=>{const s=this.itemViews.get(t);s&&e.push({view:s,model:s.model,data:s.model?.toJSON?s.model.toJSON():s.model})}),e}forEachItem(e,t){if(typeof e!="function")throw new TypeError("Callback must be a function");let s=0;return this.itemViews.forEach((i,a)=>{e.call(t,i,i.model,s++)}),this}clearSelection(){this.forEachItem(e=>{e.selected&&e.deselect()}),this.selectedItems.clear(),this.emit("selection:change",{selected:[]})}selectItem(e){const t=this.itemViews.get(e);return t&&t.select(),this}deselectItem(e){const t=this.itemViews.get(e);return t&&t.deselect(),this}setItemTemplate(e,t=!1){return this.itemTemplate=e,t&&this.itemViews.size>0&&this.forEachItem(s=>{s.setTemplate(e),s.isMounted()&&s.render()}),this}async onAfterMount(){await super.onAfterMount(),this.collection&&(this.options.fetchOnMount||!this.collection.lastFetchTime)&&this.collection.fetch()}async refresh(){if(this.collection&&this.collection.restEnabled)return await this.collection.fetch();this._buildItems()}async destroy(){this.collection&&(this.collection.off("add",this._onModelsAdded,this),this.collection.off("remove",this._onModelsRemoved,this),this.collection.off("reset",this._onCollectionReset,this),this.collection.off("fetch:start",this._onFetchStart,this),this.collection.off("fetch:end",this._onFetchEnd,this)),this._clearItems(),await super.destroy()}}class ye extends se{constructor(e={}){super({tagName:"tr",className:"table-row",enableTooltips:!0,...e}),this.columns=e.columns||[],this.actions=e.actions||null,this.contextMenu=e.contextMenu||null,this.batchActions=e.batchActions||null,this.tableView=e.tableView||e.listView||null,this.editingCells=new Set,this.template=this.buildRowTemplate()}getResponsiveClasses(e){if(!e)return"";const t=["sm","md","lg","xl","xxl"];if(typeof e=="string")return t.includes(e)?`d-none d-${e}-table-cell`:(console.warn(`Invalid visibility breakpoint: ${e}. Valid options are: ${t.join(", ")}`),"");if(typeof e=="object"){const s=[];if(e.hide){if(!t.includes(e.hide))return console.warn(`Invalid hide breakpoint: ${e.hide}. Valid options are: ${t.join(", ")}`),"";s.push(`d-table-cell d-${e.hide}-none`)}if(e.show){if(!t.includes(e.show))return console.warn(`Invalid show breakpoint: ${e.show}. Valid options are: ${t.join(", ")}`),"";e.hide?s.push(`d-${e.show}-table-cell`):s.push(`d-none d-${e.show}-table-cell`)}return s.join(" ")}return""}buildRowTemplate(){let e="";return this.tableView&&this.tableView.isSelectable()&&(e+=`
|
|
1287
1308
|
<td style="padding: 0;">
|
|
1288
1309
|
<div class="mojo-select-cell {{#selected}}selected{{/selected}}"
|
|
1289
1310
|
data-action="select">
|
|
@@ -1396,7 +1417,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1396
1417
|
</button>
|
|
1397
1418
|
</div>
|
|
1398
1419
|
</div>
|
|
1399
|
-
`}setupEditorEvents(e,t,s){const i=e.querySelector(".cell-input"),a=e.querySelector(".cell-save"),r=e.querySelector(".cell-cancel");i&&(i.type==="text"||i.type==="email"||i.type==="number")&&i.addEventListener("keydown",n=>{n.key==="Enter"?(n.preventDefault(),this.saveCellEdit(e,t,s)):n.key==="Escape"&&(n.preventDefault(),this.cancelCellEdit(e,t))}),i&&(i.type==="checkbox"||i.tagName==="SELECT")&&s.autoSave!==!1&&i.addEventListener("change",()=>{this.saveCellEdit(e,t,s)}),a?.addEventListener("click",()=>{this.saveCellEdit(e,t,s)}),r?.addEventListener("click",()=>{this.cancelCellEdit(e,t)})}async saveCellEdit(e,t,s){const i=e.querySelector(".cell-input");if(!i)return;let a;i.type==="checkbox"?a=i.checked:(i.tagName,a=i.value);const r=this.model.get?this.model.get(t):this.model[t];try{this.model.save?await this.model.save({[t]:a}):this.model[t]=a,this.exitEditMode(e,t,a),this.emit("cell:save",{row:this,model:this.model,column:t,oldValue:r,newValue:a})}catch(n){console.error("Failed to save cell edit:",n),this.emit("cell:save:error",{row:this,model:this.model,column:t,oldValue:r,newValue:a,error:n}),e.classList.add("saving-error"),setTimeout(()=>e.classList.remove("saving-error"),3e3)}}cancelCellEdit(e,t){const s=e.dataset.originalContent;this.exitEditMode(e,t,null,s),this.emit("cell:cancel",{row:this,model:this.model,column:t})}exitEditMode(e,t,s=null,i=null){const r=e.closest("td").querySelector(".cell-content");if(r){if(s!==null){const n=this.columns.find(l=>l.key===t);let o=s;n&&n.formatter&&typeof n.formatter=="string"&&(o=V.pipe(s,n.formatter)),r.innerHTML=this.escapeHtml(o)}else i&&(r.innerHTML=i);r.style.display=""}e.remove(),this.editingCells.delete(t)}escapeHtml(e){if(e==null)return"";const t=document.createElement("div");return t.textContent=e,t.innerHTML}select(){super.select(),this.addClass("selected");const e=this.element?.querySelector(".mojo-select-cell");e&&e.classList.add("selected")}deselect(){super.deselect(),this.removeClass("selected");const e=this.element?.querySelector(".mojo-select-cell");e&&e.classList.remove("selected")}}const
|
|
1420
|
+
`}setupEditorEvents(e,t,s){const i=e.querySelector(".cell-input"),a=e.querySelector(".cell-save"),r=e.querySelector(".cell-cancel");i&&(i.type==="text"||i.type==="email"||i.type==="number")&&i.addEventListener("keydown",n=>{n.key==="Enter"?(n.preventDefault(),this.saveCellEdit(e,t,s)):n.key==="Escape"&&(n.preventDefault(),this.cancelCellEdit(e,t))}),i&&(i.type==="checkbox"||i.tagName==="SELECT")&&s.autoSave!==!1&&i.addEventListener("change",()=>{this.saveCellEdit(e,t,s)}),a?.addEventListener("click",()=>{this.saveCellEdit(e,t,s)}),r?.addEventListener("click",()=>{this.cancelCellEdit(e,t)})}async saveCellEdit(e,t,s){const i=e.querySelector(".cell-input");if(!i)return;let a;i.type==="checkbox"?a=i.checked:(i.tagName,a=i.value);const r=this.model.get?this.model.get(t):this.model[t];try{this.model.save?await this.model.save({[t]:a}):this.model[t]=a,this.exitEditMode(e,t,a),this.emit("cell:save",{row:this,model:this.model,column:t,oldValue:r,newValue:a})}catch(n){console.error("Failed to save cell edit:",n),this.emit("cell:save:error",{row:this,model:this.model,column:t,oldValue:r,newValue:a,error:n}),e.classList.add("saving-error"),setTimeout(()=>e.classList.remove("saving-error"),3e3)}}cancelCellEdit(e,t){const s=e.dataset.originalContent;this.exitEditMode(e,t,null,s),this.emit("cell:cancel",{row:this,model:this.model,column:t})}exitEditMode(e,t,s=null,i=null){const r=e.closest("td").querySelector(".cell-content");if(r){if(s!==null){const n=this.columns.find(l=>l.key===t);let o=s;n&&n.formatter&&typeof n.formatter=="string"&&(o=V.pipe(s,n.formatter)),r.innerHTML=this.escapeHtml(o)}else i&&(r.innerHTML=i);r.style.display=""}e.remove(),this.editingCells.delete(t)}escapeHtml(e){if(e==null)return"";const t=document.createElement("div");return t.textContent=e,t.innerHTML}select(){super.select(),this.addClass("selected");const e=this.element?.querySelector(".mojo-select-cell");e&&e.classList.add("selected")}deselect(){super.deselect(),this.removeClass("selected");const e=this.element?.querySelector(".mojo-select-cell");e&&e.classList.remove("selected")}}const Ie={exact:{display:"is",description:"Exact match"},in:{display:"in",description:"Match any of the values (comma-separated)"},not:{display:"is not",description:"Does not match"},not_in:{display:"not in",description:"Does not match any of the values"},gt:{display:">",description:"Greater than"},gte:{display:">=",description:"Greater than or equal to"},lt:{display:"<",description:"Less than"},lte:{display:"<=",description:"Less than or equal to"},contains:{display:"contains",description:"Contains substring (case-sensitive)"},icontains:{display:"contains",description:"Contains substring (case-insensitive)"},startswith:{display:"starts with",description:"Starts with substring (case-sensitive)"},istartswith:{display:"starts with",description:"Starts with substring (case-insensitive)"},endswith:{display:"ends with",description:"Ends with substring (case-sensitive)"},iendswith:{display:"ends with",description:"Ends with substring (case-insensitive)"},isnull:{display:u=>u==="true"||u===!0?"is null":"is not null",description:"Check if value is null or not"},range:{display:"between",description:"Between two values (comma-separated)"}};function X(u){if(!u||typeof u!="string")return{field:u,lookup:null};const e=u.split("__");if(e.length===1)return{field:u,lookup:null};const t=e[e.length-1];return Ie[t]?{field:e.slice(0,-1).join("__"),lookup:t}:{field:u,lookup:null}}function it(u,e,t){if(!u||e===null||e===void 0)return"";const{field:s,lookup:i}=X(u),a=Ie[i];if(e&&typeof e=="object"&&!Array.isArray(e)){const n=e.start!==void 0&&e.start!==null&&e.start!=="",o=e.end!==void 0&&e.end!==null&&e.end!=="";return n||o?n&&o?`${t} between '${e.start}' and '${e.end}'`:n?`${t} from '${e.start}'`:`${t} until '${e.end}'`:`${t} is '${JSON.stringify(e)}'`}const r=Array.isArray(e)?e.join(","):String(e);if(!i||i==="exact")return`${t} is '${r}'`;if(i==="in"||i==="not_in"){const n=r.split(",").map(l=>l.trim()).filter(l=>l);if(n.length===0)return`${t} ${a.display}`;const o=n.map(l=>`'${l}'`).join(", ");return`${t} ${a.display} ${o}`}if(i==="range"){const n=r.split(",").map(o=>o.trim()).filter(o=>o);return n.length===2?`${t} between '${n[0]}' and '${n[1]}'`:`${t} ${a.display} '${r}'`}if(i==="isnull"){const n=typeof a.display=="function"?a.display(r):a.display;return`${t} ${n}`}return a?`${t} ${a.display} '${r}'`:`${t} is '${r}'`}class Me extends be{constructor(e={}){const t={className:"table-view-component",itemClass:e.itemClass||ye,selectionMode:e.selectable?"multiple":"none",emptyMessage:e.emptyMessage||"No data available",addButtonIcon:e.addButtonIcon||"bi bi-plus-circle",...e};super(t),this.isFullscreen=!1,this.columns=e.columns||[],this.actions=e.actions||null,this.contextMenu=e.contextMenu||null,this.batchActions=e.batchActions||null,this.searchable=e.searchable!==!1,this.sortable=e.sortable!==!1,this.filterable=e.filterable!==!1,this.paginated=e.paginated!==!1,this.clickAction=e.clickAction||"view",this.itemView=e.itemView,this.addForm=e.addForm,this.editForm=e.editForm,this.deleteTemplate=e.deleteTemplate,this.formDialogConfig=e.formDialogConfig||{},this.viewDialogOptions=e.viewDialogOptions||{},this.exportOptions=e.exportOptions||null,this.options.showExport&&!this.exportOptions&&(this.exportOptions=[{format:"csv",label:"Export as CSV",icon:"bi bi-file-earmark-spreadsheet"},{format:"json",label:"Export as JSON",icon:"bi bi-file-earmark-code"}]),this.exportSource=e.exportSource||"remote",this.filters={},this.additionalFilters=e.filters||[],this.hideActivePills=e.hideActivePills||!1,this.hideActivePillNames=e.hideActivePillNames||[],this.rowAction=e.rowAction||"row-click",this.batchBarLocation=e.batchBarLocation||"bottom",this.options.addButtonLabel=e.addButtonLabel||"Add",this.toolbarButtons=e.toolbarButtons||[],this.tableOptions={striped:!0,bordered:!1,hover:!0,responsive:!1,size:null,...e.tableOptions},this.searchPlacement=e.searchPlacement||"toolbar",this.searchPlaceholder=e.searchPlaceholder||"Search...",this.initializeColumns(),this.extractColumnFilters(),this.footerTotalColumns=this.columns.filter(s=>s.footer_total===!0),this.hasFooterTotals=this.footerTotalColumns.length>0,this.template=this.buildTableTemplate(),this.setupCollectionListeners()}setupCollectionListeners(){this.hasFooterTotals&&this.collection&&this.collection.on("reset add remove change",()=>{this.updateFooterTotals()})}initializeColumns(){this.columns.forEach(e=>{!e.key&&e.name&&(e.key=e.name),!e.label&&!e.title&&(e.label=e.key.charAt(0).toUpperCase()+e.key.slice(1))})}getResponsiveClasses(e){if(!e)return"";const t=["sm","md","lg","xl","xxl"];if(typeof e=="string")return t.includes(e)?`d-none d-${e}-table-cell`:(console.warn(`Invalid visibility breakpoint: ${e}. Valid options are: ${t.join(", ")}`),"");if(typeof e=="object"){const s=[];if(e.hide){if(!t.includes(e.hide))return console.warn(`Invalid hide breakpoint: ${e.hide}. Valid options are: ${t.join(", ")}`),"";s.push(`d-table-cell d-${e.hide}-none`)}if(e.show){if(!t.includes(e.show))return console.warn(`Invalid show breakpoint: ${e.show}. Valid options are: ${t.join(", ")}`),"";e.hide?s.push(`d-${e.show}-table-cell`):s.push(`d-none d-${e.show}-table-cell`)}return s.join(" ")}return""}parseColumnKey(e){const t=e.split("|");return{fieldKey:t[0],formatter:t[1]||null}}updateFooterTotals(){if(!this.hasFooterTotals||!this.element)return;const e=this.calculateFooterTotals();console.log("Updating footer totals in DOM:",e);let t=0;this.columns.forEach(s=>{if(s.footer_total){const i=`col_${t}`,a=this.element.querySelector(`[data-total-column="${i}"]`);if(a&&e[i]){const r=this.parseColumnKey(s.key).formatter||s.formatter;let n;r&&typeof r=="string"?n=this.formatValue(e[i].value,r):n=e[i].value,a.textContent=n}t++}})}formatValue(e,t){try{return V.pipe(e,t)}catch(s){return console.warn("Error formatting value:",s),e}}calculateFooterTotals(){if(!this.hasFooterTotals||!this.collection||this.collection.length===0)return{};const e={};return this.footerTotalColumns.forEach((t,s)=>{const{fieldKey:i,formatter:a}=this.parseColumnKey(t.key);let r=0;this.collection.forEach(o=>{const l=o.get?o.get(i):o[i],c=parseFloat(l)||0;r+=c}),console.log(`Footer total for ${t.key}: ${r} (from ${this.collection.length} items)`);const n=`col_${s}`;e[n]={value:r,formatter:a||t.formatter,fieldKey:i,originalKey:t.key}}),e}extractColumnFilters(){this.filters={},this.columns.forEach(e=>{if(e.filter){const{fieldKey:t}=this.parseColumnKey(e.key);this.filters[t]=e.filter}})}isSelectable(){return this.batchActions&&this.batchActions.length>0&&this.selectionMode=="multiple"}buildTableTemplate(){const e=this.batchBarLocation==="top"?this.buildBatchActionsPanel():"",t=this.batchBarLocation==="bottom"?this.buildBatchActionsPanel():"";return`
|
|
1400
1421
|
<div class="mojo-table-wrapper">
|
|
1401
1422
|
${this.buildToolbarTemplate()}
|
|
1402
1423
|
${e}
|
|
@@ -1536,7 +1557,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1536
1557
|
<i class="bi bi-x-circle me-2"></i>Clear All Filters
|
|
1537
1558
|
</button>
|
|
1538
1559
|
`:""}
|
|
1539
|
-
`}updateFilterPills(){const e=this.element?.querySelector('[data-container="filter-pills"]');if(!e)return;this.getActiveFilters();const t=this.buildActivePills();e.innerHTML=t}updateSearchInputs(e){const t=this.element?.querySelectorAll('[data-filter="search"]');t&&t.forEach(s=>{s.value=e||""})}buildActivePills(){if(this.hideActivePills)return"";const e=this.getActiveFilters(),t=e.search&&e.search.toString().trim()!=="";let s=Object.entries(e).filter(([n,o])=>o&&o.toString().trim()!==""&&n!=="search");if(this.hideActivePillNames&&this.hideActivePillNames.length>0&&(s=s.filter(([n])=>!this.hideActivePillNames.includes(n))),s.length===0&&!t)return"";const i=s.map(([n,o])=>{const{field:l}=X(n),c=this.getFilterLabel(l),d=
|
|
1560
|
+
`}updateFilterPills(){const e=this.element?.querySelector('[data-container="filter-pills"]');if(!e)return;this.getActiveFilters();const t=this.buildActivePills();e.innerHTML=t}updateSearchInputs(e){const t=this.element?.querySelectorAll('[data-filter="search"]');t&&t.forEach(s=>{s.value=e||""})}buildActivePills(){if(this.hideActivePills)return"";const e=this.getActiveFilters(),t=e.search&&e.search.toString().trim()!=="";let s=Object.entries(e).filter(([n,o])=>o&&o.toString().trim()!==""&&n!=="search");if(this.hideActivePillNames&&this.hideActivePillNames.length>0&&(s=s.filter(([n])=>!this.hideActivePillNames.includes(n))),s.length===0&&!t)return"";const i=s.map(([n,o])=>{const{field:l}=X(n),c=this.getFilterLabel(l),d=it(n,o,c);return`
|
|
1540
1561
|
<span class="badge bg-primary me-1 mb-1 py-1 px-2 position-relative" style="font-size: 0.75rem;">
|
|
1541
1562
|
<i class="bi bi-filter me-1" style="font-size: 0.65rem;"></i>
|
|
1542
1563
|
|
|
@@ -1712,28 +1733,7 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1712
1733
|
<i class="bi bi-chevron-right"></i>
|
|
1713
1734
|
</a>
|
|
1714
1735
|
</li>
|
|
1715
|
-
`),e.innerHTML=l.join("")}async onActionPage(e,t){e.preventDefault();const s=parseInt(t.getAttribute("data-page"),10),i=this.collection.params?.size||10,a=this.collection.meta?.count||this.collection.length(),r=Math.max(1,Math.ceil(a/i));let n=isNaN(s)?1:s;n<1&&(n=r),n>r&&(n=1),this.collection.setParams({...this.collection.params,start:(n-1)*i}),this.collection.restEnabled?await this.collection.fetch():this.render(),this.emit("table:page",{page:n,event:e}),this.emit("params-changed")}async onChangePageSize(e,t){const s=parseInt(t.value);this.collection&&(this.collection.setParams({...this.collection.params,start:0,size:s}),this.collection.restEnabled&&await this.collection.fetch(),this.render()),this.emit("table:pagesize",{size:s,event:e}),this.emit("params-changed")}getActiveFilters(){if(!this.collection?.params)return{};const{start:e,size:t,sort:s,...i}=this.collection.params,a={},r=new Set;return this.getAllAvailableFilters().forEach(o=>{if(o.config.type==="daterange"){const l=o.key,c=o.config.startName||"dr_start",d=o.config.endName||"dr_end",h=o.config.fieldName||"dr_field";i[h]===l&&(i[c]||i[d])&&(a[l]={start:i[c]||"",end:i[d]||""},r.add(c),r.add(d),r.add(h))}}),Object.keys(i).forEach(o=>{r.has(o)||(a[o]=i[o])}),Object.keys(a).forEach(o=>{if(a.hasOwnProperty(o)){const l=`${o}__in`;a.hasOwnProperty(l)&&(delete a[o],a[l]=a[l])}}),a}setFilter(e,t){if(!this.collection)return;const s=this.getFilterConfig(e);if(s&&s.type==="daterange"){const i=s.startName||"dr_start",a=s.endName||"dr_end",r=s.fieldName||"dr_field";delete this.collection.params[i],delete this.collection.params[a],delete this.collection.params[r],t&&typeof t=="object"&&(t.start||t.end)&&(t.start&&(this.collection.params[i]=t.start),t.end&&(this.collection.params[a]=t.end),this.collection.params[r]=e)}else{const{field:i,lookup:a}=X(e);if(delete this.collection.params[e],delete this.collection.params[i],delete this.collection.params[`${i}__in`],!t||Array.isArray(t)&&t.length===0)return;Array.isArray(t)?t.length===1?this.collection.params[i]=t[0]:this.collection.params[`${i}__in`]=t.join(","):this.collection.params[e]=t}}getAllAvailableFilters(){const e=[];return this.columns.forEach(t=>{if(t.filter){const{fieldKey:s}=this.parseColumnKey(t.key);e.push({key:s,label:t.filter.label||t.label||s,type:t.filter.type,config:t.filter})}}),this.additionalFilters&&Array.isArray(this.additionalFilters)&&this.additionalFilters.forEach(t=>{e.push({key:t.name||t.key,label:t.label,type:t.type,config:t})}),e}getFilterConfig(e){const t=this.columns.find(s=>{const{fieldKey:i}=this.parseColumnKey(s.key);return i===e});if(t&&t.filter)return t.filter;if(this.additionalFilters&&Array.isArray(this.additionalFilters)){const s=this.additionalFilters.find(i=>(i.name||i.key)===e);if(s)return s}return null}getFilterLabel(e){if(e==="search")return"Search";const t=this.filters[e];if(t&&t.label)return t.label;const s=this.additionalFilters.find(i=>(i.name||i.key)===e);return s&&s.label?s.label:e.charAt(0).toUpperCase()+e.slice(1)}getFilterDisplayValue(e,t){if(e==="search")return`"${t}"`;const s=this.filters[e]||this.additionalFilters.find(i=>(i.name||i.key)===e);if(s&&s.type==="daterange"&&typeof t=="object"){const i=t.start||"",a=t.end||"";return`${i} to ${a}`}if(s&&s.type==="select"&&s.options){if(typeof s.options[0]=="object"){const i=s.options.find(a=>a.value===t);return i?i.label:t}return t}return t}getFilterIcon(e){return{text:"search",select:"funnel",date:"calendar",daterange:"calendar-range",number:"123",boolean:"toggle-on"}[e]||"filter"}async onActionAddFilter(e,t){const s=t.getAttribute("data-filter-key"),i=this.getFilterConfig(s),a=this.getActiveFilters()[s];if(!i){console.warn("No filter config found for key:",s);return}const r=await T.showForm({title:`${a!==void 0&&a!==""?"Edit":"Add"} ${this.getFilterLabel(s)} Filter`,size:"md",fields:[this.buildFilterDialogField(i,a,s)]});if(r){const n=this.extractFilterValue(i,r);this.setFilter(s,n),await this.applyFilters()}}buildFilterDialogField(e,t,s){const i={name:"filter_value",label:e.label,value:t,...e,placeholder:e.placeholder||e.placeHolder};if(e.type==="daterange"){if(i.startName=i.startName||"dr_start",i.endName=i.endName||"dr_end",i.fieldName=i.fieldName||"dr_field",i.format=i.format||"YYYY-MM-DD",i.displayFormat=i.displayFormat||"MMM DD, YYYY",i.separator=i.separator||" to ",i.label=i.label||"Date Range",t&&typeof t=="object"){const a=r=>{if(!r&&r!==0)return"";if(r instanceof Date&&!isNaN(r))return r.toISOString().slice(0,10);const n=String(r).trim();if(!n)return"";if(/^-?\d+$/.test(n)){const l=Number(n),c=n.length<=10?l*1e3:l,d=new Date(c);if(!isNaN(d))return d.toISOString().slice(0,10)}const o=new Date(n);return isNaN(o)?n:o.toISOString().slice(0,10)};i.startDate=a(t.start||t.from||t.begin||""),i.endDate=a(t.end||t.to||t.finish||"")}}else if(e.type==="multiselect"){let a=[];t&&(Array.isArray(t)?a=t:typeof t=="string"&&(a=t.split(",").map(r=>r.trim()).filter(r=>r))),i.value=a,!i.placeholder&&!i.placeHolder&&(e.placeholder||e.placeHolder?i.placeholder=e.placeholder||e.placeHolder:e.label&&(i.placeholder=`Select ${e.label}...`))}return i}extractFilterValue(e,t){if(e.type==="daterange"){const s=e.startName||"dr_start",i=e.endName||"dr_end";return{start:t[s],end:t[i]}}return e.type==="multiselect",t.filter_value}async applyFilters(){if(this.collection&&(this.collection.params.start=0),this.collection?.restEnabled)try{await this.collection.fetch(),this.render()}catch(e){console.error("Failed to fetch filtered data:",e),this.render()}else this.render();this.updateFilterPills(),this.emit("params-changed")}async onActionEditFilter(e,t){const s=t.getAttribute("data-filter"),{field:i}=X(s);let a=this.getFilterConfig(i)||this.getFilterConfig(s);const r=this.getActiveFilters(),n=r[s]||r[i];if(!a){console.warn("No filter config found for key:",s,"or field:",i);return}const o={filter_value:n};if(a.type==="daterange"&&n&&typeof n=="object"){const c=a.startName||"dr_start",d=a.endName||"dr_end";o[c]=n.start||"",o[d]=n.end||""}const l=await T.showForm({title:`Edit ${this.getFilterLabel(i)} Filter`,size:"md",data:o,fields:[this.buildFilterDialogField(a,n,i)]});if(l){const c=this.extractFilterValue(a,l);this.setFilter(s,c),await this.applyFilters()}}async onActionRemoveFilter(e,t){const s=t.getAttribute("data-filter"),{field:i}=X(s);this.setFilter(s,null),s==="search"&&this.updateSearchInputs(""),this.collection.restEnabled&&await this.collection.fetch(),this.render(),this.updateFilterPills(),this.emit("filter:remove",{key:s,field:i}),this.emit("params-changed")}async onActionClearAllFilters(e,t){if(!this.collection)return;const{start:s,size:i,sort:a}=this.collection.params;this.collection.params={start:s,size:i},a&&(this.collection.params.sort=a),this.updateSearchInputs(""),this.collection.restEnabled&&await this.collection.fetch(),this.render(),this.updateFilterPills(),this.emit("filters:clear"),this.emit("params-changed")}updateBatchActionsPanel(){if(!this.batchActions||this.batchActions.length===0)return;const e=this.getSelectedItems().length;if(this.batchBarLocation==="top"){const s=this.element?.querySelector(".batch-actions-panel-top"),i=this.element?.querySelector(".batch-select-count");s&&i&&(i.textContent=e,e>0?s.classList.remove("d-none"):s.classList.add("d-none"))}else{const s=this.element?.querySelector(".batch-actions-panel"),i=this.element?.querySelector(".batch-select-count");s&&i&&(i.textContent=e,s.style.display=e>0?"block":"none")}const t=this.element?.querySelector(".mojo-select-all-cell");if(t){const s=this.itemViews.size>0&&Array.from(this.itemViews.values()).every(r=>r.selected),i=Array.from(this.itemViews.values()).some(r=>r.selected);t.classList.toggle("selected",s),t.classList.toggle("indeterminate",!s&&i);const a=t.querySelector("i");a&&(a.className=!s&&i?"bi bi-dash":"bi bi-check")}}async onActionBatch(e,t){const s=t.getAttribute("data-action").replace("batch-",""),i=this.getSelectedItems();this.emit("batch:action",{action:s,items:i,event:e})}async onActionClearSelection(e,t){this.clearSelection(),this.updateBatchActionsPanel()}async onActionCustomToolbarButton(e,t){const s=parseInt(t.getAttribute("data-button-index"),10),i=this.toolbarButtons[s];i&&typeof i.handler=="function"&&await i.handler.call(this,e,t)}}function et(){return typeof window>"u"?null:((!window.MOJO||typeof window.MOJO!="object")&&(window.MOJO={}),window.MOJO)}function tt(u){return u.__lite&&u.__lite.version||(u.WebApp=ee,u.View=v,u.Page=K,u.Router=ie,u.Model=B,u.Collection=W,u.Rest=z,u.FormBuilder=Q,u.FormView=H,u.Dialog=T,u.ProgressView=me,u.ListView=pe,u.ListViewItem=se,u.TableView=ke,u.TableRow=fe,u.DataFormatter=V,u.MOJOUtils=x,u.__lite={version:"dev",build:"web-mojo.lite"},u.mount=async function(t,s){if(!t)throw new Error("MOJO.mount(view, container) requires a view");const i=typeof s=="string"?document.querySelector(s):s;if(!i)throw new Error("MOJO.mount(view, container) container not found");if(typeof t.render!="function"||typeof t.mount!="function")throw new Error("MOJO.mount expects a View instance with render() and mount() methods");return await t.render(),await t.mount(i),t}),u}const ge=et();ge&&tt(ge);class st{constructor(e={}){this.options={containerId:"toast-container",position:"top-end",autohide:!0,defaultDelay:5e3,maxToasts:5,...e},this.toasts=new Map,this.toastCounter=0,this.init()}init(){this.createContainer()}createContainer(){let e=document.getElementById(this.options.containerId);e||(e=document.createElement("div"),e.id=this.options.containerId,e.className=`toast-container position-fixed ${this.getPositionClasses()}`,e.style.zIndex="1070",e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),document.body.appendChild(e)),this.container=e}getPositionClasses(){const e={"top-start":"top-0 start-0 p-3","top-center":"top-0 start-50 translate-middle-x p-3","top-end":"top-0 end-0 p-3","middle-start":"top-50 start-0 translate-middle-y p-3","middle-center":"top-50 start-50 translate-middle p-3","middle-end":"top-50 end-0 translate-middle-y p-3","bottom-start":"bottom-0 start-0 p-3","bottom-center":"bottom-0 start-50 translate-middle-x p-3","bottom-end":"bottom-0 end-0 p-3"};return e[this.options.position]||e["top-end"]}success(e,t={}){return this.show(e,"success",{icon:"bi-check-circle-fill",...t})}error(e,t={}){return this.show(e,"error",{icon:"bi-exclamation-triangle-fill",autohide:!0,...t})}info(e,t={}){return this.show(e,"info",{icon:"bi-info-circle-fill",...t})}warning(e,t={}){return this.show(e,"warning",{icon:"bi-exclamation-triangle-fill",...t})}plain(e,t={}){return this.show(e,"plain",{...t})}show(e,t="info",s={}){this.enforceMaxToasts();const i=`toast-${++this.toastCounter}`,a={title:this.getDefaultTitle(t),icon:this.getDefaultIcon(t),autohide:this.options.autohide,delay:this.options.defaultDelay,dismissible:!0,...s},r=this.createToastElement(i,e,t,a);if(this.container.appendChild(r),typeof bootstrap>"u")throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const n=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});return this.toasts.set(i,{element:r,bootstrap:n,type:t,message:e}),r.addEventListener("hidden.bs.toast",()=>{this.cleanup(i)}),n.show(),{id:i,hide:()=>{try{n.hide()}catch(o){console.warn("Error hiding toast:",o)}},dispose:()=>this.cleanup(i),updateProgress:s.updateProgress||null}}showView(e,t="info",s={}){this.enforceMaxToasts();const i=`toast-${++this.toastCounter}`,a={title:s.title||this.getDefaultTitle(t),icon:s.icon||this.getDefaultIcon(t),autohide:this.options.autohide,delay:this.options.defaultDelay,dismissible:!0,...s},r=this.createViewToastElement(i,e,t,a);if(this.container.appendChild(r),typeof bootstrap>"u")throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const n=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});this.toasts.set(i,{element:r,bootstrap:n,type:t,view:e,message:"View toast"}),r.addEventListener("hidden.bs.toast",()=>{this.cleanupView(i)});const o=r.querySelector(".toast-view-body");return o&&e&&e.render(!0,o),n.show(),{id:i,view:e,hide:()=>{try{n.hide()}catch(l){console.warn("Error hiding view toast:",l)}},dispose:()=>this.cleanupView(i),updateProgress:l=>{e&&typeof e.updateProgress=="function"&&e.updateProgress(l)}}}createToastElement(e,t,s,i){const a=document.createElement("div");a.id=e,a.className=`toast toast-service-${s}`,a.setAttribute("role","alert"),a.setAttribute("aria-live","assertive"),a.setAttribute("aria-atomic","true");const r=i.title||i.icon?this.createToastHeader(i,s):"",n=this.createToastBody(t,i.icon&&!i.title);return a.innerHTML=`
|
|
1716
|
-
${r}
|
|
1717
|
-
${n}
|
|
1718
|
-
`,a}createViewToastElement(e,t,s,i){const a=document.createElement("div");a.id=e,a.className=`toast toast-service-${s}`,a.setAttribute("role","alert"),a.setAttribute("aria-live","assertive"),a.setAttribute("aria-atomic","true");const r=i.title||i.icon?this.createToastHeader(i,s):"",n=this.createViewToastBody();return a.innerHTML=`
|
|
1719
|
-
${r}
|
|
1720
|
-
${n}
|
|
1721
|
-
`,a}createViewToastBody(){return`
|
|
1722
|
-
<div class="toast-body p-0">
|
|
1723
|
-
<div class="toast-view-body p-3"></div>
|
|
1724
|
-
</div>
|
|
1725
|
-
`}createToastHeader(e,t){const s=e.icon?`<i class="${e.icon} toast-service-icon me-2"></i>`:"",i=e.title?`<strong class="me-auto">${s}${this.escapeHtml(e.title)}</strong>`:"",a=e.showTime?`<small class="text-muted">${this.getTimeString()}</small>`:"",r=e.dismissible?'<button type="button" class="btn-close toast-service-close" data-bs-dismiss="toast" aria-label="Close"></button>':"";return!i&&!a&&!r?"":`
|
|
1726
|
-
<div class="toast-header">
|
|
1727
|
-
${i}
|
|
1728
|
-
${a}
|
|
1729
|
-
${r}
|
|
1730
|
-
</div>
|
|
1731
|
-
`}createToastBody(e,t=!1){return`
|
|
1732
|
-
<div class="toast-body d-flex align-items-center">
|
|
1733
|
-
${t?`<i class="${this.getDefaultIcon("info")} toast-service-icon me-2"></i>`:""}
|
|
1734
|
-
<span>${this.escapeHtml(e)}</span>
|
|
1735
|
-
</div>
|
|
1736
|
-
`}getDefaultTitle(e){return{success:"Success",error:"Error",warning:"Warning",info:"Information",plain:""}[e]||"Notification"}getDefaultIcon(e){return{success:"bi-check-circle-fill",error:"bi-exclamation-triangle-fill",warning:"bi-exclamation-triangle-fill",info:"bi-info-circle-fill",plain:""}[e]||"bi-info-circle-fill"}enforceMaxToasts(){if(Array.from(this.toasts.values()).length>=this.options.maxToasts){const t=this.toasts.keys().next().value,s=this.toasts.get(t);s&&s.bootstrap.hide()}}cleanup(e){const t=this.toasts.get(e);if(t){try{t.bootstrap.dispose()}catch(s){console.warn("Error disposing toast:",s)}t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element),this.toasts.delete(e)}}cleanupView(e){const t=this.toasts.get(e);if(t){if(t.view&&typeof t.view.dispose=="function")try{t.view.dispose()}catch(s){console.warn("Error disposing view in toast:",s)}try{t.bootstrap.dispose()}catch(s){console.warn("Error disposing toast:",s)}t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element),this.toasts.delete(e)}}hideAll(){this.toasts.forEach((e,t)=>{e.bootstrap.hide()})}clearAll(){this.toasts.forEach((e,t)=>{this.cleanup(t)})}getTimeString(){return new Date().toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}dispose(){this.clearAll(),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container)}getStats(){const e={total:this.toasts.size,byType:{}};return this.toasts.forEach(t=>{e.byType[t.type]=(e.byType[t.type]||0)+1}),e}setOptions(e){this.options={...this.options,...e},e.position&&this.container&&(this.container.className=`toast-container position-fixed ${this.getPositionClasses()}`)}}class it{constructor(e,t={}){if(this.fileModel=e,this.options={file:null,name:null,group:null,description:null,onProgress:null,onComplete:null,onError:null,showToast:!0,...t},!this.options.file||!(this.options.file instanceof File))throw new Error("FileUpload requires a valid File object");this.cancelled=!1,this.uploadRequest=null,this.progressToast=null,this.progressView=null,this.toastService=null,this.options.showToast&&(this.toastService=new st),this.promise=this._startUpload()}async _startUpload(){try{this.options.showToast&&this._showProgressToast();let e;try{e=await this._initiateUpload()}catch(i){throw new Error(`Failed to initiate upload: ${i.message}`)}if(this.cancelled)throw new Error("Upload cancelled");if(!e||!e.upload_url)throw new Error("Invalid upload response: missing upload URL");let t;if(typeof e.upload_url=="string")t={url:e.upload_url,method:"PUT",fields:null,headers:{}};else if(e.upload_url&&typeof e.upload_url=="object"&&e.upload_url.upload_url)t={url:e.upload_url.upload_url,method:e.upload_url.method||"POST",fields:e.upload_url.fields||null,headers:e.upload_url.headers||{}};else throw new Error(`Invalid upload response: unrecognised upload_url format. Server returned: ${JSON.stringify(e.upload_url)}`);let s;try{s=await this._performUpload(t)}catch(i){throw new Error(`File upload failed: ${i.message}`)}if(this.cancelled)throw new Error("Upload cancelled");try{await this._completeUpload()}catch(i){console.warn("Failed to mark upload as completed:",i)}return this._onComplete(this.fileModel),this.fileModel}catch(e){throw e.message!=="Upload cancelled"&&this._onError(e),e}}async _initiateUpload(){try{const e={filename:this.options.name||this.options.file.name,file_size:this.options.file.size,content_type:this.options.file.type};this.options.group&&(e.group=this.options.group),this.options.description&&(e.description=this.options.description);const t=await this.fileModel.rest.POST("/api/fileman/upload/initiate",e);if(!t)throw new Error("No response from upload initiation API");if(!t.data)throw new Error("Upload initiation response missing data");if(!t.data.status){const s=t.data.error||"Upload initiation failed";throw new Error(s)}if(!t.data.data)throw new Error("Upload initiation response missing data payload");return t.data.data.id&&this.fileModel.set("id",t.data.data.id),t.data.data}catch(e){throw e.message==="Network Error"||e.name==="TypeError"?new Error("Network error during upload initiation. Please check your connection."):e}}async _performUpload(e){return new Promise((t,s)=>{if(!(this.options.file instanceof File)){s(new Error("Only single File objects are supported"));return}const{url:i,method:a,fields:r,headers:n}=e,o=a==="POST"&&r!==null,l=new XMLHttpRequest;this.uploadRequest=l,l.upload.onprogress=h=>{this.cancelled||this._onProgress({progress:h.loaded/h.total,loaded:h.loaded,total:h.total,percentage:Math.round(h.loaded/h.total*100)})},l.onload=()=>{l.status>=200&&l.status<300?t({data:l.response,status:l.status,statusText:l.statusText,xhr:l}):s(new Error(`Upload failed: ${l.status} ${l.statusText}`))},l.onerror=()=>s(new Error("Upload failed: Network error")),l.ontimeout=()=>s(new Error("Upload timed out — file may be too large or connection too slow")),l.onabort=()=>s(new Error("Upload cancelled"));let c=i;i.startsWith("/")&&!i.startsWith("/api/")&&(c="/api"+i);const d=this.fileModel.rest.buildUrl(c);if(l.open(a,d),l.timeout=3e4,o){for(const[m,p]of Object.entries(n||{}))m.toLowerCase()!=="content-type"&&l.setRequestHeader(m,p);const h=new FormData;for(const[m,p]of Object.entries(r))h.append(m,p);h.append("file",this.options.file),l.send(h)}else{l.setRequestHeader("Content-Type",this.options.file.type);for(const[h,m]of Object.entries(n||{}))h.toLowerCase()!=="content-type"&&l.setRequestHeader(h,m);l.send(this.options.file)}})}async _completeUpload(){try{const e=await this.fileModel.save({action:"mark_as_completed"});if(!e)throw new Error("No response from upload completion API");if(e.data&&!e.data.status){const t=e.data.error||"Failed to mark upload as completed";throw new Error(t)}return e}catch(e){throw e.message==="Network Error"||e.name==="TypeError"?new Error("Network error during upload completion. The file may have uploaded successfully."):e}}_onProgress(e){this.progressToast&&this.progressToast.updateProgress&&this.progressToast.updateProgress(e),typeof this.options.onProgress=="function"&&this.options.onProgress(e)}_onComplete(e){this.progressView&&this.progressView.markCompleted("Upload completed successfully!"),this.progressToast&&setTimeout(()=>{try{this.progressToast&&typeof this.progressToast.hide=="function"&&this.progressToast.hide()}catch(t){console.warn("Error hiding progress toast:",t)}},2e3),typeof this.options.onComplete=="function"&&this.options.onComplete(e)}_onError(e){if(this.progressToast)try{this.progressToast.hide()}catch(t){console.warn("Error hiding progress toast on error:",t)}this.toastService&&this.toastService.error(`Upload failed: ${e.message}`),typeof this.options.onError=="function"&&this.options.onError(e)}_showProgressToast(){this.progressView=new me({filename:this.options.name||this.options.file.name,filesize:this.options.file.size,showCancel:!0,onCancel:()=>this.cancel()}),this.progressToast=this.toastService.showView(this.progressView,"info",{title:"File Upload",autohide:!1,dismissible:!1})}cancel(){return this.cancelled?!1:(this.cancelled=!0,this.uploadRequest&&typeof this.uploadRequest.abort=="function"&&this.uploadRequest.abort(),this.progressView&&this.progressView.markCancelled(),this.progressToast&&setTimeout(()=>{try{this.progressToast&&typeof this.progressToast.hide=="function"&&this.progressToast.hide()}catch(e){console.warn("Error hiding progress toast on cancel:",e)}},1500),!0)}isCancelled(){return this.cancelled}then(e,t){return this.promise.then(e,t)}catch(e){return this.promise.catch(e)}finally(e){return this.promise.finally(e)}getStats(){return{filename:this.options.file.name,size:this.options.file.size,type:this.options.file.type,cancelled:this.cancelled,group:this.options.group,description:this.options.description}}}class J extends B{constructor(e={}){super(e,{endpoint:"/api/group"})}}class be extends W{constructor(e={}){super({ModelClass:J,endpoint:"/api/group",size:10,...e})}}const Ie={org:"Organization",division:"Division",department:"Department",team:"Team",merchant:"Merchant",partner:"Partner",client:"Client",iso:"ISO",sales:"Sales",reseller:"Reseller",location:"Location",region:"Region",route:"Route",project:"Project",inventory:"Inventory",test:"Testing",misc:"Miscellaneous",qa:"Quality Assurance"},ye=Object.entries(Ie).map(([u,e])=>({value:u,label:e})),we={create:{title:"Create Group",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name"},{name:"kind",type:"select",label:"Group Kind",required:!0,options:ye},{type:"collection",name:"parent",label:"Parent Group",Collection:be,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300}]},edit:{title:"Edit Group",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name"},{name:"kind",type:"select",label:"Group Kind",required:!0,options:ye},{type:"collection",name:"parent",label:"Parent Group",Collection:be,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300},{name:"metadata.domain",type:"text",label:"Default Domain",placeholder:"Enter Domain"},{name:"metadata.portal",type:"text",label:"Default Portal",placeholder:"Enter Portal URL"},{name:"is_active",type:"switch",label:"Is Active",cols:4}]}};J.EDIT_FORM=we.edit,J.ADD_FORM=we.create,J.CREATE_FORM=we.create,J.GroupKindOptions=ye,J.GroupKinds=Ie;class U extends B{constructor(e={}){super(e,{endpoint:"/api/user"})}hasPermission(e){if(this.get("is_superuser"))return!0;if(Array.isArray(e))return e.some(i=>this.hasPermission(i));const t=e.startsWith("sys."),s=t?e.substring(4):e;return!!(this._hasPermission(s)||!t&&this.member&&this.member.hasPermission(e))}_hasPermission(e){const t=this.get("permissions");return t?t[e]==!0:!1}hasPerm(e){return this.hasPermission(e)}}U.PERMISSIONS=[{name:"manage_users",label:"Manage Users"},{name:"view_users",label:"View Users"},{name:"view_groups",label:"View Groups"},{name:"manage_groups",label:"Manage Groups"},{name:"view_metrics",label:"View System Metrics"},{name:"manage_metrics",label:"Manage System Metrics"},{name:"view_logs",label:"View Logs"},{name:"view_incidents",label:"View Incidents"},{name:"manage_incidents",label:"Manage Incidents"},{name:"view_tickets",label:"View Tickets"},{name:"manage_tickets",label:"Manage Tickets"},{name:"view_admin",label:"View Admin"},{name:"view_jobs",label:"View Jobs"},{name:"manage_jobs",label:"Manage Jobs"},{name:"view_global",label:"View Global"},{name:"manage_notifications",label:"Manage Notifications"},{name:"manage_files",label:"Manage Files"},{name:"force_single_session",label:"Force Single Session"},{name:"file_vault",label:"Access File Vault"},{name:"manage_aws",label:"Manage AWS"},{name:"manage_docit",label:"Manage DocIt"}],U.PERMISSION_FIELDS=[...U.PERMISSIONS.map(u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:4}))];const Me={create:{title:"Create User",fields:[{name:"email",type:"text",label:"Email",required:!0},{name:"phone_number",type:"text",label:"Phone number",columns:12},{name:"display_name",type:"text",label:"Display Name"}]},edit:{title:"Edit User",fields:[{name:"email",type:"email",label:"Email",columns:12},{name:"display_name",type:"text",label:"Display Name",columns:12},{name:"phone_number",type:"text",label:"Phone number",columns:12},{type:"collection",name:"org",label:"Organization",Collection:be,labelField:"name",valueField:"id",columns:12}]},permissions:{fields:U.PERMISSION_FIELDS}},at={detailed:{title:"Detailed User Information",columns:2,showEmptyValues:!0,emptyValueText:"Not set",fields:[{name:"id",label:"User ID",type:"number",colSize:3},{name:"display_name",label:"Display Name",type:"text",format:'capitalize|default("Unnamed User")',colSize:9},{name:"username",label:"Username",type:"text",format:"lowercase",colSize:6},{name:"email",label:"Email Address",type:"email",colSize:6},{name:"phone_number",label:"Phone Number",type:"phone",format:'phone|default("Not provided")',colSize:6},{name:"is_active",label:"Account Status",type:"boolean",colSize:6},{name:"last_login",label:"Last Login",type:"datetime",format:"relative",colSize:6},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",colSize:6},{name:"avatar.url",label:"Avatar",type:"url",colSize:12},{name:"permissions",label:"User Permissions",type:"dataview",dataViewColumns:2,showEmptyValues:!1},{name:"metadata",label:"User Metadata",type:"dataview",dataViewColumns:1},{name:"avatar",label:"Avatar Details",type:"dataview",dataViewColumns:1}]}};U.DATA_VIEW=at.detailed,U.EDIT_FORM=Me.edit,U.ADD_FORM=Me.create;const rt=Object.freeze(Object.defineProperty({__proto__:null,File:class extends B{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return this.get("category")==="image"}upload(e={}){return new it(this,e)}}},Symbol.toStringTag,{value:"Module"}));class ve extends v{constructor(e={}){const{data:t,model:s,fields:i,columns:a,responsive:r,showEmptyValues:n,emptyValueText:o,...l}=e;super({tagName:"div",className:"data-view",...l}),this.data=t||{},this.fields=i||[],this.model=s||null,this.model&&(this.data=this.model),this.dataViewOptions={columns:a||2,responsive:r!==!1,showEmptyValues:n||!1,emptyValueText:o||"—",rowClass:"row g-3",itemClass:"data-view-item",labelClass:"data-view-label fw-semibold text-muted small text-uppercase",valueClass:"data-view-value"}}async onBeforeRender(){this.fields.length===0&&this.getData()&&this.generateFieldsFromData()}async renderTemplate(){const e=this.buildItemsHTML();return`
|
|
1736
|
+
`),e.innerHTML=l.join("")}async onActionPage(e,t){e.preventDefault();const s=parseInt(t.getAttribute("data-page"),10),i=this.collection.params?.size||10,a=this.collection.meta?.count||this.collection.length(),r=Math.max(1,Math.ceil(a/i));let n=isNaN(s)?1:s;n<1&&(n=r),n>r&&(n=1),this.collection.setParams({...this.collection.params,start:(n-1)*i}),this.collection.restEnabled?await this.collection.fetch():this.render(),this.emit("table:page",{page:n,event:e}),this.emit("params-changed")}async onChangePageSize(e,t){const s=parseInt(t.value);this.collection&&(this.collection.setParams({...this.collection.params,start:0,size:s}),this.collection.restEnabled&&await this.collection.fetch(),this.render()),this.emit("table:pagesize",{size:s,event:e}),this.emit("params-changed")}getActiveFilters(){if(!this.collection?.params)return{};const{start:e,size:t,sort:s,...i}=this.collection.params,a={},r=new Set;return this.getAllAvailableFilters().forEach(o=>{if(o.config.type==="daterange"){const l=o.key,c=o.config.startName||"dr_start",d=o.config.endName||"dr_end",h=o.config.fieldName||"dr_field";i[h]===l&&(i[c]||i[d])&&(a[l]={start:i[c]||"",end:i[d]||""},r.add(c),r.add(d),r.add(h))}}),Object.keys(i).forEach(o=>{r.has(o)||(a[o]=i[o])}),Object.keys(a).forEach(o=>{if(a.hasOwnProperty(o)){const l=`${o}__in`;a.hasOwnProperty(l)&&(delete a[o],a[l]=a[l])}}),a}setFilter(e,t){if(!this.collection)return;const s=this.getFilterConfig(e);if(s&&s.type==="daterange"){const i=s.startName||"dr_start",a=s.endName||"dr_end",r=s.fieldName||"dr_field";delete this.collection.params[i],delete this.collection.params[a],delete this.collection.params[r],t&&typeof t=="object"&&(t.start||t.end)&&(t.start&&(this.collection.params[i]=t.start),t.end&&(this.collection.params[a]=t.end),this.collection.params[r]=e)}else{const{field:i,lookup:a}=X(e);if(delete this.collection.params[e],delete this.collection.params[i],delete this.collection.params[`${i}__in`],!t||Array.isArray(t)&&t.length===0)return;Array.isArray(t)?t.length===1?this.collection.params[i]=t[0]:this.collection.params[`${i}__in`]=t.join(","):this.collection.params[e]=t}}getAllAvailableFilters(){const e=[];return this.columns.forEach(t=>{if(t.filter){const{fieldKey:s}=this.parseColumnKey(t.key);e.push({key:s,label:t.filter.label||t.label||s,type:t.filter.type,config:t.filter})}}),this.additionalFilters&&Array.isArray(this.additionalFilters)&&this.additionalFilters.forEach(t=>{e.push({key:t.name||t.key,label:t.label,type:t.type,config:t})}),e}getFilterConfig(e){const t=this.columns.find(s=>{const{fieldKey:i}=this.parseColumnKey(s.key);return i===e});if(t&&t.filter)return t.filter;if(this.additionalFilters&&Array.isArray(this.additionalFilters)){const s=this.additionalFilters.find(i=>(i.name||i.key)===e);if(s)return s}return null}getFilterLabel(e){if(e==="search")return"Search";const t=this.filters[e];if(t&&t.label)return t.label;const s=this.additionalFilters.find(i=>(i.name||i.key)===e);return s&&s.label?s.label:e.charAt(0).toUpperCase()+e.slice(1)}getFilterDisplayValue(e,t){if(e==="search")return`"${t}"`;const s=this.filters[e]||this.additionalFilters.find(i=>(i.name||i.key)===e);if(s&&s.type==="daterange"&&typeof t=="object"){const i=t.start||"",a=t.end||"";return`${i} to ${a}`}if(s&&s.type==="select"&&s.options){if(typeof s.options[0]=="object"){const i=s.options.find(a=>a.value===t);return i?i.label:t}return t}return t}getFilterIcon(e){return{text:"search",select:"funnel",date:"calendar",daterange:"calendar-range",number:"123",boolean:"toggle-on"}[e]||"filter"}async onActionAddFilter(e,t){const s=t.getAttribute("data-filter-key"),i=this.getFilterConfig(s),a=this.getActiveFilters()[s];if(!i){console.warn("No filter config found for key:",s);return}const r=await T.showForm({title:`${a!==void 0&&a!==""?"Edit":"Add"} ${this.getFilterLabel(s)} Filter`,size:"md",fields:[this.buildFilterDialogField(i,a,s)]});if(r){const n=this.extractFilterValue(i,r);this.setFilter(s,n),await this.applyFilters()}}buildFilterDialogField(e,t,s){const i={name:"filter_value",label:e.label,value:t,...e,placeholder:e.placeholder||e.placeHolder};if(e.type==="daterange"){if(i.startName=i.startName||"dr_start",i.endName=i.endName||"dr_end",i.fieldName=i.fieldName||"dr_field",i.format=i.format||"YYYY-MM-DD",i.displayFormat=i.displayFormat||"MMM DD, YYYY",i.separator=i.separator||" to ",i.label=i.label||"Date Range",t&&typeof t=="object"){const a=r=>{if(!r&&r!==0)return"";if(r instanceof Date&&!isNaN(r))return r.toISOString().slice(0,10);const n=String(r).trim();if(!n)return"";if(/^-?\d+$/.test(n)){const l=Number(n),c=n.length<=10?l*1e3:l,d=new Date(c);if(!isNaN(d))return d.toISOString().slice(0,10)}const o=new Date(n);return isNaN(o)?n:o.toISOString().slice(0,10)};i.startDate=a(t.start||t.from||t.begin||""),i.endDate=a(t.end||t.to||t.finish||"")}}else if(e.type==="multiselect"){let a=[];t&&(Array.isArray(t)?a=t:typeof t=="string"&&(a=t.split(",").map(r=>r.trim()).filter(r=>r))),i.value=a,!i.placeholder&&!i.placeHolder&&(e.placeholder||e.placeHolder?i.placeholder=e.placeholder||e.placeHolder:e.label&&(i.placeholder=`Select ${e.label}...`))}return i}extractFilterValue(e,t){if(e.type==="daterange"){const s=e.startName||"dr_start",i=e.endName||"dr_end";return{start:t[s],end:t[i]}}return e.type==="multiselect",t.filter_value}async applyFilters(){if(this.collection&&(this.collection.params.start=0),this.collection?.restEnabled)try{await this.collection.fetch(),this.render()}catch(e){console.error("Failed to fetch filtered data:",e),this.render()}else this.render();this.updateFilterPills(),this.emit("params-changed")}async onActionEditFilter(e,t){const s=t.getAttribute("data-filter"),{field:i}=X(s);let a=this.getFilterConfig(i)||this.getFilterConfig(s);const r=this.getActiveFilters(),n=r[s]||r[i];if(!a){console.warn("No filter config found for key:",s,"or field:",i);return}const o={filter_value:n};if(a.type==="daterange"&&n&&typeof n=="object"){const c=a.startName||"dr_start",d=a.endName||"dr_end";o[c]=n.start||"",o[d]=n.end||""}const l=await T.showForm({title:`Edit ${this.getFilterLabel(i)} Filter`,size:"md",data:o,fields:[this.buildFilterDialogField(a,n,i)]});if(l){const c=this.extractFilterValue(a,l);this.setFilter(s,c),await this.applyFilters()}}async onActionRemoveFilter(e,t){const s=t.getAttribute("data-filter"),{field:i}=X(s);this.setFilter(s,null),s==="search"&&this.updateSearchInputs(""),this.collection.restEnabled&&await this.collection.fetch(),this.render(),this.updateFilterPills(),this.emit("filter:remove",{key:s,field:i}),this.emit("params-changed")}async onActionClearAllFilters(e,t){if(!this.collection)return;const{start:s,size:i,sort:a}=this.collection.params;this.collection.params={start:s,size:i},a&&(this.collection.params.sort=a),this.updateSearchInputs(""),this.collection.restEnabled&&await this.collection.fetch(),this.render(),this.updateFilterPills(),this.emit("filters:clear"),this.emit("params-changed")}updateBatchActionsPanel(){if(!this.batchActions||this.batchActions.length===0)return;const e=this.getSelectedItems().length;if(this.batchBarLocation==="top"){const s=this.element?.querySelector(".batch-actions-panel-top"),i=this.element?.querySelector(".batch-select-count");s&&i&&(i.textContent=e,e>0?s.classList.remove("d-none"):s.classList.add("d-none"))}else{const s=this.element?.querySelector(".batch-actions-panel"),i=this.element?.querySelector(".batch-select-count");s&&i&&(i.textContent=e,s.style.display=e>0?"block":"none")}const t=this.element?.querySelector(".mojo-select-all-cell");if(t){const s=this.itemViews.size>0&&Array.from(this.itemViews.values()).every(r=>r.selected),i=Array.from(this.itemViews.values()).some(r=>r.selected);t.classList.toggle("selected",s),t.classList.toggle("indeterminate",!s&&i);const a=t.querySelector("i");a&&(a.className=!s&&i?"bi bi-dash":"bi bi-check")}}async onActionBatch(e,t){const s=t.getAttribute("data-action").replace("batch-",""),i=this.getSelectedItems();this.emit("batch:action",{action:s,items:i,event:e})}async onActionClearSelection(e,t){this.clearSelection(),this.updateBatchActionsPanel()}async onActionCustomToolbarButton(e,t){const s=parseInt(t.getAttribute("data-button-index"),10),i=this.toolbarButtons[s];i&&typeof i.handler=="function"&&await i.handler.call(this,e,t)}}function at(){return typeof window>"u"?null:((!window.MOJO||typeof window.MOJO!="object")&&(window.MOJO={}),window.MOJO)}function rt(u){return u.__lite&&u.__lite.version||(u.WebApp=ee,u.View=v,u.Page=K,u.Router=ie,u.Model=B,u.Collection=W,u.Rest=z,u.FormBuilder=Q,u.FormView=H,u.Dialog=T,u.ProgressView=me,u.ListView=be,u.ListViewItem=se,u.TableView=Me,u.TableRow=ye,u.DataFormatter=V,u.MOJOUtils=x,u.__lite={version:"dev",build:"web-mojo.lite"},u.mount=async function(t,s){if(!t)throw new Error("MOJO.mount(view, container) requires a view");const i=typeof s=="string"?document.querySelector(s):s;if(!i)throw new Error("MOJO.mount(view, container) container not found");if(typeof t.render!="function"||typeof t.mount!="function")throw new Error("MOJO.mount expects a View instance with render() and mount() methods");return await t.render(),await t.mount(i),t}),u}const we=at();we&&rt(we);class ve extends v{constructor(e={}){const{data:t,model:s,fields:i,columns:a,responsive:r,showEmptyValues:n,emptyValueText:o,...l}=e;super({tagName:"div",className:"data-view",...l}),this.data=t||{},this.fields=i||[],this.model=s||null,this.model&&(this.data=this.model),this.dataViewOptions={columns:a||2,responsive:r!==!1,showEmptyValues:n||!1,emptyValueText:o||"—",rowClass:"row g-3",itemClass:"data-view-item",labelClass:"data-view-label fw-semibold text-muted small text-uppercase",valueClass:"data-view-value"}}async onBeforeRender(){this.fields.length===0&&this.getData()&&this.generateFieldsFromData()}async renderTemplate(){const e=this.buildItemsHTML();return`
|
|
1737
1737
|
<div class="${this.dataViewOptions.rowClass}">
|
|
1738
1738
|
${e}
|
|
1739
1739
|
</div>
|
|
@@ -1781,5 +1781,5 @@ var MOJO=(function(D){"use strict";class ie{constructor(e={}){this.defaultRoute=
|
|
|
1781
1781
|
${i}
|
|
1782
1782
|
</div>
|
|
1783
1783
|
</div>
|
|
1784
|
-
`}catch(s){return console.error("Error creating nested DataView:",s),'<span class="text-danger">Error displaying nested data</span>'}}async updateData(e){return this.data=e,this.model&&typeof this.model.set=="function"&&this.model.set(e),this.fields.length>0&&!this.options.fields&&(this.fields=[]),await this.render(),this.emit("data:updated",{data:e}),this}async updateFields(e){return this.fields=e,await this.render(),this.emit("fields:updated",{fields:e}),this}async updateConfig(e){return this.dataViewOptions={...this.dataViewOptions,...e},await this.render(),this.emit("config:updated",{options:this.dataViewOptions}),this}async refresh(){if(this.model&&typeof this.model.fetch=="function")try{await this.model.fetch(),this.emit("data:refreshed",{model:this.model})}catch(e){throw this.emit("error",{error:e,message:"Failed to refresh data"}),e}return this}getCurrentData(){return this.getData()}getField(e){return this.fields.find(t=>t.name===e)||null}setFieldFormat(e,t){const s=this.getField(e);return s?(s.format=t,s.formatter=t):this.fields.push({name:e,label:this.formatLabel(e),type:this.inferFieldType(this.getData()[e],e),format:t,formatter:t}),this}addFormatPipe(e,t){const s=this.getField(e);return s&&(s.format?(s.format+=`|${t}`,s.formatter=s.format):(s.format=t,s.formatter=t)),this}clearFieldFormat(e){const t=this.getField(e);if(t){const s=this.getData(),i=this.inferFormatter(s[e],e,t.type);t.format=i,t.formatter=i}return this}getFormattedValue(e,t=null){const s=this.getField(e);if(!s)return null;const i=t!==null?t:this.getData()[e],a=s.format||s.formatter;return a&&i!=null?V.pipe(i,a):i}setFieldFormats(e){return Object.entries(e).forEach(([t,s])=>{this.setFieldFormat(t,s)}),this}getFieldFormats(){const e={};return this.fields.forEach(t=>{const s=t.format||t.formatter;s&&(e[t.name]=s)}),e}onInit(){super.onInit(),this.model&&typeof this.model.on=="function"&&this.model.on("change",()=>{this.render()})}static create(e={}){return new ve(e)}}const nt=Object.freeze(Object.defineProperty({__proto__:null,default:ve},Symbol.toStringTag,{value:"Module"}));return D.Collection=W,D.DataFormatter=V,D.Dialog=T,D.FormBuilder=Q,D.FormPage=Qe,D.FormView=H,D.ListView=
|
|
1784
|
+
`}catch(s){return console.error("Error creating nested DataView:",s),'<span class="text-danger">Error displaying nested data</span>'}}async updateData(e){return this.data=e,this.model&&typeof this.model.set=="function"&&this.model.set(e),this.fields.length>0&&!this.options.fields&&(this.fields=[]),await this.render(),this.emit("data:updated",{data:e}),this}async updateFields(e){return this.fields=e,await this.render(),this.emit("fields:updated",{fields:e}),this}async updateConfig(e){return this.dataViewOptions={...this.dataViewOptions,...e},await this.render(),this.emit("config:updated",{options:this.dataViewOptions}),this}async refresh(){if(this.model&&typeof this.model.fetch=="function")try{await this.model.fetch(),this.emit("data:refreshed",{model:this.model})}catch(e){throw this.emit("error",{error:e,message:"Failed to refresh data"}),e}return this}getCurrentData(){return this.getData()}getField(e){return this.fields.find(t=>t.name===e)||null}setFieldFormat(e,t){const s=this.getField(e);return s?(s.format=t,s.formatter=t):this.fields.push({name:e,label:this.formatLabel(e),type:this.inferFieldType(this.getData()[e],e),format:t,formatter:t}),this}addFormatPipe(e,t){const s=this.getField(e);return s&&(s.format?(s.format+=`|${t}`,s.formatter=s.format):(s.format=t,s.formatter=t)),this}clearFieldFormat(e){const t=this.getField(e);if(t){const s=this.getData(),i=this.inferFormatter(s[e],e,t.type);t.format=i,t.formatter=i}return this}getFormattedValue(e,t=null){const s=this.getField(e);if(!s)return null;const i=t!==null?t:this.getData()[e],a=s.format||s.formatter;return a&&i!=null?V.pipe(i,a):i}setFieldFormats(e){return Object.entries(e).forEach(([t,s])=>{this.setFieldFormat(t,s)}),this}getFieldFormats(){const e={};return this.fields.forEach(t=>{const s=t.format||t.formatter;s&&(e[t.name]=s)}),e}onInit(){super.onInit(),this.model&&typeof this.model.on=="function"&&this.model.on("change",()=>{this.render()})}static create(e={}){return new ve(e)}}const nt=Object.freeze(Object.defineProperty({__proto__:null,default:ve},Symbol.toStringTag,{value:"Module"}));return D.Collection=W,D.DataFormatter=V,D.Dialog=T,D.FormBuilder=Q,D.FormPage=Qe,D.FormView=H,D.ListView=be,D.ListViewItem=se,D.MOJOUtils=x,D.Model=B,D.Page=K,D.ProgressView=me,D.Rest=z,D.Router=ie,D.TableRow=ye,D.TableView=Me,D.View=v,D.WebApp=ee,D.default=we,Object.defineProperties(D,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),D})({});
|
|
1785
1785
|
//# sourceMappingURL=web-mojo.lite.iife.min.js.map
|