web-mojo 2.2.84 → 2.2.85
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.css +212 -0
- 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.es.js +1 -1
- package/dist/chunks/{ChatView-BkS8Ek80.js → ChatView-BC4vHjIO.js} +2 -2
- package/dist/chunks/{ChatView-BGRSX9Sq.js.map → ChatView-BC4vHjIO.js.map} +1 -1
- package/dist/chunks/{ChatView-BGRSX9Sq.js → ChatView-DZBmWPu-.js} +2 -2
- package/dist/chunks/{ChatView-BkS8Ek80.js.map → ChatView-DZBmWPu-.js.map} +1 -1
- package/dist/chunks/Dialog-2gXM2UcO.js +3 -0
- package/dist/chunks/Dialog-2gXM2UcO.js.map +1 -0
- package/dist/chunks/Dialog-EZ9XD2AO.js +3 -0
- package/dist/chunks/Dialog-EZ9XD2AO.js.map +1 -0
- package/dist/chunks/{FormView-CrXCpM9j.js → FormView-BqqtbPVb.js} +2 -2
- package/dist/chunks/{FormView-CrXCpM9j.js.map → FormView-BqqtbPVb.js.map} +1 -1
- package/dist/chunks/{FormView-BcRIRWcN.js → FormView-CRPeN8tp.js} +2 -2
- package/dist/chunks/{FormView-BcRIRWcN.js.map → FormView-CRPeN8tp.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-Bj9mbQbd.js → MetricsMiniChartWidget-B4CcNlv-.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-Bj9mbQbd.js.map → MetricsMiniChartWidget-B4CcNlv-.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-nmEb8fxQ.js → MetricsMiniChartWidget-y-KklF3c.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-nmEb8fxQ.js.map → MetricsMiniChartWidget-y-KklF3c.js.map} +1 -1
- package/dist/chunks/{Modal-BOnZ3jlz.js → Modal-DoIYUAKi.js} +2 -2
- package/dist/chunks/{Modal-BOnZ3jlz.js.map → Modal-DoIYUAKi.js.map} +1 -1
- package/dist/chunks/{Modal-AFggmQ5t.js → Modal-Y1PW_Fmf.js} +2 -2
- package/dist/chunks/{Modal-AFggmQ5t.js.map → Modal-Y1PW_Fmf.js.map} +1 -1
- package/dist/chunks/{PDFViewer-DTWJyqLN.js → PDFViewer-Cg_tbqb7.js} +2 -2
- package/dist/chunks/{PDFViewer-DTWJyqLN.js.map → PDFViewer-Cg_tbqb7.js.map} +1 -1
- package/dist/chunks/{PDFViewer-C6jQRd1i.js → PDFViewer-DYAJqRAV.js} +2 -2
- package/dist/chunks/{PDFViewer-C6jQRd1i.js.map → PDFViewer-DYAJqRAV.js.map} +1 -1
- package/dist/chunks/{Passkeys-BnfMtc_e.js → Passkeys-DNpner4L.js} +2 -2
- package/dist/chunks/{Passkeys-BnfMtc_e.js.map → Passkeys-DNpner4L.js.map} +1 -1
- package/dist/chunks/{Passkeys-Df_sesCg.js → Passkeys-DapTiqNW.js} +2 -2
- package/dist/chunks/{Passkeys-Df_sesCg.js.map → Passkeys-DapTiqNW.js.map} +1 -1
- package/dist/chunks/{TokenManager-CpQiouEe.js → TokenManager-BAyuM351.js} +2 -2
- package/dist/chunks/{TokenManager-CpQiouEe.js.map → TokenManager-BAyuM351.js.map} +1 -1
- package/dist/chunks/{TokenManager-dPm2wXim.js → TokenManager-BLd64x-1.js} +2 -2
- package/dist/chunks/{TokenManager-dPm2wXim.js.map → TokenManager-BLd64x-1.js.map} +1 -1
- package/dist/chunks/{UserProfileView-C51avAXU.js → UserProfileView-BDD3WOjd.js} +2 -2
- package/dist/chunks/{UserProfileView-C51avAXU.js.map → UserProfileView-BDD3WOjd.js.map} +1 -1
- package/dist/chunks/{UserProfileView-DDLFDrSq.js → UserProfileView-q29bxm0T.js} +2 -2
- package/dist/chunks/{UserProfileView-DDLFDrSq.js.map → UserProfileView-q29bxm0T.js.map} +1 -1
- package/dist/chunks/{WebApp-6X5Na7jP.js → WebApp-C98dm94j.js} +2 -2
- package/dist/chunks/{WebApp-6X5Na7jP.js.map → WebApp-C98dm94j.js.map} +1 -1
- package/dist/chunks/{WebApp-CPMiCjY7.js → WebApp-DgmB8vpR.js} +2 -2
- package/dist/chunks/{WebApp-CPMiCjY7.js.map → WebApp-DgmB8vpR.js.map} +1 -1
- package/dist/chunks/{index-CsVVg7HM.js → index-DXlIy6bc.js} +2 -2
- package/dist/chunks/{index-CsVVg7HM.js.map → index-DXlIy6bc.js.map} +1 -1
- package/dist/chunks/{index-B8MmVPsw.js → index-iPINfbSy.js} +2 -2
- package/dist/chunks/{index-B8MmVPsw.js.map → index-iPINfbSy.js.map} +1 -1
- package/dist/chunks/{version-C9BOiwG3.js → version-Bps8Ct3l.js} +2 -2
- package/dist/chunks/{version-C9BOiwG3.js.map → version-Bps8Ct3l.js.map} +1 -1
- package/dist/chunks/{version-gygZr-Ew.js → version-iFGy9HZj.js} +2 -2
- package/dist/chunks/{version-gygZr-Ew.js.map → version-iFGy9HZj.js.map} +1 -1
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +1 -1
- package/dist/map.cjs.js +1 -1
- package/dist/map.es.js +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 +2 -1
- package/dist/web-mojo.lite.iife.js.map +1 -1
- package/dist/web-mojo.lite.iife.min.js +1 -1
- package/dist/web-mojo.lite.iife.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/Dialog-DB9A3lyf.js +0 -3
- package/dist/chunks/Dialog-DB9A3lyf.js.map +0 -1
- package/dist/chunks/Dialog-v6R0OESu.js +0 -3
- package/dist/chunks/Dialog-v6R0OESu.js.map +0 -1
|
@@ -72,7 +72,7 @@ var MOJO=(function(A){"use strict";class re{constructor(e={}){this.defaultRoute=
|
|
|
72
72
|
</small>
|
|
73
73
|
</div>
|
|
74
74
|
</div>
|
|
75
|
-
`}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=L.pipe(this.loaded,"filesize"),this.totalFormatted=L.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=L.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 Be{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 ze),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 he({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 G extends Y{constructor(e={}){super(e,{endpoint:"/api/group"})}}class ue extends J{constructor(e={}){super({ModelClass:G,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"},me=Object.entries(Ie).map(([u,e])=>({value:u,label:e})),pe={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:me},{type:"collection",name:"parent",label:"Parent Group",Collection:ue,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:me},{type:"collection",name:"parent",label:"Parent Group",Collection:ue,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}]}};G.EDIT_FORM=pe.edit,G.ADD_FORM=pe.create,G.CREATE_FORM=pe.create,G.GroupKindOptions=me,G.GroupKinds=Ie;class $ extends Y{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");if(!t)return!1;if(t[e]==!0)return!0;const s=$.GRANULAR_TO_CATEGORY[e];return!!(s&&t[s]==!0)}hasPerm(e){return this.hasPermission(e)}}$.CATEGORY_PERMISSIONS=[{name:"view_admin",label:"Admin Panel",tooltip:"Access the admin panel, assistant, and system tools"},{name:"security",label:"Security",tooltip:"Incidents, events, rules, tickets, firewall, bouncer, GeoIP, system logs"},{name:"users",label:"Users",tooltip:"User records, passkeys, TOTP, API keys, OAuth, devices, locations"},{name:"groups",label:"Groups",tooltip:"Groups, members, group API keys, settings"},{name:"comms",label:"Communications",tooltip:"Email, phone, SMS, push notifications, chat, notifications"},{name:"jobs",label:"Jobs",tooltip:"Jobs, job events, job logs, runners, queue control, system stats"},{name:"metrics",label:"Metrics",tooltip:"Metrics recording, fetching, categories, values, permissions"},{name:"files",label:"Files",tooltip:"File managers, files, renditions, vault files, vault data, S3 buckets"},{name:"assistant",label:"AI Assistant",tooltip:"Access to the AI Assistant"}],$.GRANULAR_PERMISSION_TABS=[{label:"Account",permissions:[{name:"view_users",label:"View Users"},{name:"manage_users",label:"Manage Users"},{name:"view_groups",label:"View Groups"},{name:"manage_groups",label:"Manage Groups"},{name:"manage_group",label:"Manage Own Group"},{name:"view_members",label:"View Members"},{name:"manage_settings",label:"Manage Settings"}]},{label:"Communication",permissions:[{name:"manage_chat",label:"Manage Chat"},{name:"manage_aws",label:"Manage Email (AWS)"},{name:"view_notifications",label:"View Notifications"},{name:"manage_notifications",label:"Manage Notifications"},{name:"send_notifications",label:"Send Notifications"},{name:"view_devices",label:"View Push Devices"},{name:"manage_devices",label:"Manage Push Devices"},{name:"manage_push_config",label:"Push Config"},{name:"view_phone_numbers",label:"View Phone Numbers"},{name:"manage_phone_numbers",label:"Manage Phone Numbers"},{name:"manage_phone_config",label:"Phone Config"},{name:"view_sms",label:"View SMS"},{name:"manage_sms",label:"Manage SMS"},{name:"send_sms",label:"Send SMS"}]},{label:"Platform",permissions:[{name:"view_security",label:"View Security"},{name:"manage_security",label:"Manage Security"},{name:"admin",label:"Log Admin"},{name:"view_logs",label:"View Logs"},{name:"manage_logs",label:"Manage Logs"},{name:"view_jobs",label:"View Jobs"},{name:"manage_jobs",label:"Manage Jobs"},{name:"view_metrics",label:"View Metrics"},{name:"manage_metrics",label:"Manage Metrics"},{name:"write_metrics",label:"Write Metrics"},{name:"view_fileman",label:"View File Managers"},{name:"manage_files",label:"Manage Files"},{name:"view_vault",label:"View Vault"},{name:"manage_vault",label:"Manage Vault"},{name:"manage_docit",label:"Manage Docs"},{name:"manage_shortlinks",label:"Manage Shortlinks"}]}],$.CATEGORY_GRANULAR_MAP={security:["view_security","manage_security"],users:["view_users","manage_users","view_members"],groups:["view_groups","manage_groups","manage_group"],comms:["manage_chat","manage_aws","view_notifications","manage_notifications","send_notifications","view_devices","manage_devices","manage_push_config","view_phone_numbers","manage_phone_numbers","manage_phone_config","view_sms","manage_sms","send_sms"],jobs:["view_jobs","manage_jobs"],metrics:["view_metrics","manage_metrics","write_metrics"],files:["view_fileman","manage_files","view_vault","manage_vault"]},$.GRANULAR_TO_CATEGORY={};for(const[u,e]of Object.entries($.CATEGORY_GRANULAR_MAP))for(const t of e)$.GRANULAR_TO_CATEGORY[t]=u;$.APP_CATEGORY_PERMISSIONS=[],$.APP_GRANULAR_PERMISSIONS=[],$.PERMISSIONS=[...$.CATEGORY_PERMISSIONS,...$.GRANULAR_PERMISSION_TABS.flatMap(u=>u.permissions),...$.APP_CATEGORY_PERMISSIONS,...$.APP_GRANULAR_PERMISSIONS],$.PERMISSION_FIELDS=[...$.PERMISSIONS.map(u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:6}))];const se=u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:6,...u.tooltip?{tooltip:u.tooltip}:{}});$.CATEGORY_PERMISSION_FIELDS=(()=>{const u=[{label:"System",fields:$.CATEGORY_PERMISSIONS.map(se)}];return $.APP_CATEGORY_PERMISSIONS.length>0&&u.push({label:"App",fields:$.APP_CATEGORY_PERMISSIONS.map(se)}),[{type:"tabset",tabs:u}]})(),$.GRANULAR_PERMISSION_FIELDS=(()=>{const u=$.GRANULAR_PERMISSION_TABS.map(e=>({label:e.label,fields:e.permissions.map(se)}));return $.APP_GRANULAR_PERMISSIONS.length>0&&u.push({label:"App",fields:$.APP_GRANULAR_PERMISSIONS.map(se)}),[{type:"tabset",tabs:u}]})();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:ue,labelField:"name",valueField:"id",columns:12}]},permissions:{fields:$.PERMISSION_FIELDS}},Ue={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}]}};$.DATA_VIEW=Ue.detailed,$.EDIT_FORM=ke.edit,$.ADD_FORM=ke.create;let Ye=class extends Y{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return this.get("category")==="image"}upload(e={}){return new Be(this,e)}},_=class E extends C{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=E._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(){E.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=`
|
|
75
|
+
`}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=L.pipe(this.loaded,"filesize"),this.totalFormatted=L.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=L.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 Be{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 ze),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 he({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 G extends Y{constructor(e={}){super(e,{endpoint:"/api/group"})}}class ue extends J{constructor(e={}){super({ModelClass:G,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"},me=Object.entries(Ie).map(([u,e])=>({value:u,label:e})),pe={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:me},{type:"collection",name:"parent",label:"Parent Group",Collection:ue,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:me},{type:"collection",name:"parent",label:"Parent Group",Collection:ue,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}]}};G.EDIT_FORM=pe.edit,G.ADD_FORM=pe.create,G.CREATE_FORM=pe.create,G.GroupKindOptions=me,G.GroupKinds=Ie;class $ extends Y{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");if(!t)return!1;if(t[e]==!0)return!0;const s=$.GRANULAR_TO_CATEGORY[e];return!!(s&&t[s]==!0)}hasPerm(e){return this.hasPermission(e)}}$.CATEGORY_PERMISSIONS=[{name:"view_admin",label:"Admin Panel",tooltip:"Access the admin panel, assistant, and system tools"},{name:"security",label:"Security",tooltip:"Incidents, events, rules, tickets, firewall, bouncer, GeoIP, system logs"},{name:"users",label:"Users",tooltip:"User records, passkeys, TOTP, API keys, OAuth, devices, locations"},{name:"groups",label:"Groups",tooltip:"Groups, members, group API keys, settings"},{name:"comms",label:"Communications",tooltip:"Email, phone, SMS, push notifications, chat, notifications"},{name:"jobs",label:"Jobs",tooltip:"Jobs, job events, job logs, runners, queue control, system stats"},{name:"metrics",label:"Metrics",tooltip:"Metrics recording, fetching, categories, values, permissions"},{name:"files",label:"Files",tooltip:"File managers, files, renditions, vault files, vault data, S3 buckets"},{name:"assistant",label:"AI Assistant",tooltip:"Access to the AI Assistant"},{name:"comms",label:"Communication",tooltip:"Ability to notify users"}],$.GRANULAR_PERMISSION_TABS=[{label:"Account",permissions:[{name:"view_users",label:"View Users"},{name:"manage_users",label:"Manage Users"},{name:"view_groups",label:"View Groups"},{name:"manage_groups",label:"Manage Groups"},{name:"manage_group",label:"Manage Own Group"},{name:"view_members",label:"View Members"},{name:"manage_settings",label:"Manage Settings"}]},{label:"Communication",permissions:[{name:"manage_chat",label:"Manage Chat"},{name:"manage_aws",label:"Manage Email (AWS)"},{name:"view_notifications",label:"View Notifications"},{name:"manage_notifications",label:"Manage Notifications"},{name:"send_notifications",label:"Send Notifications"},{name:"view_devices",label:"View Push Devices"},{name:"manage_devices",label:"Manage Push Devices"},{name:"manage_push_config",label:"Push Config"},{name:"view_phone_numbers",label:"View Phone Numbers"},{name:"manage_phone_numbers",label:"Manage Phone Numbers"},{name:"manage_phone_config",label:"Phone Config"},{name:"view_sms",label:"View SMS"},{name:"manage_sms",label:"Manage SMS"},{name:"send_sms",label:"Send SMS"}]},{label:"Platform",permissions:[{name:"view_security",label:"View Security"},{name:"manage_security",label:"Manage Security"},{name:"admin",label:"Log Admin"},{name:"view_logs",label:"View Logs"},{name:"manage_logs",label:"Manage Logs"},{name:"view_jobs",label:"View Jobs"},{name:"manage_jobs",label:"Manage Jobs"},{name:"view_metrics",label:"View Metrics"},{name:"manage_metrics",label:"Manage Metrics"},{name:"write_metrics",label:"Write Metrics"},{name:"view_fileman",label:"View File Managers"},{name:"manage_files",label:"Manage Files"},{name:"view_vault",label:"View Vault"},{name:"manage_vault",label:"Manage Vault"},{name:"manage_docit",label:"Manage Docs"},{name:"manage_shortlinks",label:"Manage Shortlinks"}]}],$.CATEGORY_GRANULAR_MAP={security:["view_security","manage_security"],users:["view_users","manage_users","view_members"],groups:["view_groups","manage_groups","manage_group"],comms:["manage_chat","manage_aws","view_notifications","manage_notifications","send_notifications","view_devices","manage_devices","manage_push_config","view_phone_numbers","manage_phone_numbers","manage_phone_config","view_sms","manage_sms","send_sms"],jobs:["view_jobs","manage_jobs"],metrics:["view_metrics","manage_metrics","write_metrics"],files:["view_fileman","manage_files","view_vault","manage_vault"]},$.GRANULAR_TO_CATEGORY={};for(const[u,e]of Object.entries($.CATEGORY_GRANULAR_MAP))for(const t of e)$.GRANULAR_TO_CATEGORY[t]=u;$.APP_CATEGORY_PERMISSIONS=[],$.APP_GRANULAR_PERMISSIONS=[],$.PERMISSIONS=[...$.CATEGORY_PERMISSIONS,...$.GRANULAR_PERMISSION_TABS.flatMap(u=>u.permissions),...$.APP_CATEGORY_PERMISSIONS,...$.APP_GRANULAR_PERMISSIONS],$.PERMISSION_FIELDS=[...$.PERMISSIONS.map(u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:6}))];const se=u=>({name:`permissions.${u.name}`,type:"switch",label:u.label,columns:6,...u.tooltip?{tooltip:u.tooltip}:{}});$.CATEGORY_PERMISSION_FIELDS=(()=>{const u=[{label:"System",fields:$.CATEGORY_PERMISSIONS.map(se)}];return $.APP_CATEGORY_PERMISSIONS.length>0&&u.push({label:"App",fields:$.APP_CATEGORY_PERMISSIONS.map(se)}),[{type:"tabset",tabs:u}]})(),$.GRANULAR_PERMISSION_FIELDS=(()=>{const u=$.GRANULAR_PERMISSION_TABS.map(e=>({label:e.label,fields:e.permissions.map(se)}));return $.APP_GRANULAR_PERMISSIONS.length>0&&u.push({label:"App",fields:$.APP_GRANULAR_PERMISSIONS.map(se)}),[{type:"tabset",tabs:u}]})();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:ue,labelField:"name",valueField:"id",columns:12}]},permissions:{fields:$.PERMISSION_FIELDS}},Ue={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}]}};$.DATA_VIEW=Ue.detailed,$.EDIT_FORM=ke.edit,$.ADD_FORM=ke.create;let Ye=class extends Y{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return this.get("category")==="image"}upload(e={}){return new Be(this,e)}},_=class E extends C{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=E._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(){E.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=`
|
|
76
76
|
<div class="mojo-busy-spinner">
|
|
77
77
|
<div class="spinner-border text-light" role="status">
|
|
78
78
|
<span class="visually-hidden">Loading...</span>
|