web-mojo 2.1.824 → 2.1.827

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.cjs.js.map +1 -1
  3. package/dist/admin.es.js +25 -12
  4. package/dist/admin.es.js.map +1 -1
  5. package/dist/auth.cjs.js +1 -1
  6. package/dist/auth.cjs.js.map +1 -1
  7. package/dist/auth.es.js +3 -3
  8. package/dist/auth.es.js.map +1 -1
  9. package/dist/charts.cjs.js +1 -1
  10. package/dist/charts.es.js +2 -2
  11. package/dist/chunks/{ChatView-Dm-1ojKc.js → ChatView-CM0ATZID.js} +2 -2
  12. package/dist/chunks/{ChatView-Dm-1ojKc.js.map → ChatView-CM0ATZID.js.map} +1 -1
  13. package/dist/chunks/{ChatView-DsdSe1A5.js → ChatView-DJK49g8O.js} +6 -6
  14. package/dist/chunks/{ChatView-DsdSe1A5.js.map → ChatView-DJK49g8O.js.map} +1 -1
  15. package/dist/chunks/{ContextMenu-6zcMDDiv.js → ContextMenu-CRwv6-gc.js} +2 -2
  16. package/dist/chunks/{ContextMenu-6zcMDDiv.js.map → ContextMenu-CRwv6-gc.js.map} +1 -1
  17. package/dist/chunks/{ContextMenu-C7wfFMyp.js → ContextMenu-K8sVV2Sf.js} +2 -2
  18. package/dist/chunks/{ContextMenu-C7wfFMyp.js.map → ContextMenu-K8sVV2Sf.js.map} +1 -1
  19. package/dist/chunks/{DataView-BJCAbOpx.js → DataView-3iqbZ_4y.js} +2 -2
  20. package/dist/chunks/{DataView-BJCAbOpx.js.map → DataView-3iqbZ_4y.js.map} +1 -1
  21. package/dist/chunks/{DataView-BDxfTYf0.js → DataView-DoKRJHii.js} +2 -2
  22. package/dist/chunks/{DataView-BDxfTYf0.js.map → DataView-DoKRJHii.js.map} +1 -1
  23. package/dist/chunks/{Dialog-CCnOsBBK.js → Dialog-Bup1WdQn.js} +5 -5
  24. package/dist/chunks/{Dialog-CCnOsBBK.js.map → Dialog-Bup1WdQn.js.map} +1 -1
  25. package/dist/chunks/{Dialog-B8_iNgDO.js → Dialog-CEEzQOVl.js} +2 -2
  26. package/dist/chunks/{Dialog-B8_iNgDO.js.map → Dialog-CEEzQOVl.js.map} +1 -1
  27. package/dist/chunks/{FormView-NYVaTwDE.js → FormView-BEIw_LH9.js} +2 -2
  28. package/dist/chunks/{FormView-NYVaTwDE.js.map → FormView-BEIw_LH9.js.map} +1 -1
  29. package/dist/chunks/{FormView-CHyzkf7A.js → FormView-C4Po3Q3z.js} +2 -2
  30. package/dist/chunks/{FormView-CHyzkf7A.js.map → FormView-C4Po3Q3z.js.map} +1 -1
  31. package/dist/chunks/{MetricsMiniChartWidget-DkroX-HM.js → MetricsMiniChartWidget-CK6K9Kh6.js} +3 -3
  32. package/dist/chunks/{MetricsMiniChartWidget-DkroX-HM.js.map → MetricsMiniChartWidget-CK6K9Kh6.js.map} +1 -1
  33. package/dist/chunks/{MetricsMiniChartWidget-Co_cyqd4.js → MetricsMiniChartWidget-CxTnMgp6.js} +2 -2
  34. package/dist/chunks/{MetricsMiniChartWidget-Co_cyqd4.js.map → MetricsMiniChartWidget-CxTnMgp6.js.map} +1 -1
  35. package/dist/chunks/{PDFViewer-CFbFrBdS.js → PDFViewer-BvBw9BNk.js} +2 -2
  36. package/dist/chunks/{PDFViewer-CFbFrBdS.js.map → PDFViewer-BvBw9BNk.js.map} +1 -1
  37. package/dist/chunks/{PDFViewer-DLYyetM9.js → PDFViewer-DgXB4rR9.js} +3 -3
  38. package/dist/chunks/{PDFViewer-DLYyetM9.js.map → PDFViewer-DgXB4rR9.js.map} +1 -1
  39. package/dist/chunks/{Page-C1nY4u_3.js → Page-BJxsE5Os.js} +2 -2
  40. package/dist/chunks/{Page-C1nY4u_3.js.map → Page-BJxsE5Os.js.map} +1 -1
  41. package/dist/chunks/{Page-kuadj0PG.js → Page-DaptCfWp.js} +2 -2
  42. package/dist/chunks/{Page-kuadj0PG.js.map → Page-DaptCfWp.js.map} +1 -1
  43. package/dist/chunks/{TopNav-CkJNTimo.js → TopNav-BjJojcF7.js} +5 -5
  44. package/dist/chunks/{TopNav-CkJNTimo.js.map → TopNav-BjJojcF7.js.map} +1 -1
  45. package/dist/chunks/{TopNav-B40XDQjS.js → TopNav-BkpUjJB2.js} +2 -2
  46. package/dist/chunks/{TopNav-B40XDQjS.js.map → TopNav-BkpUjJB2.js.map} +1 -1
  47. package/dist/chunks/{WebApp-D0vBp8ks.js → WebApp-9L0mkLAO.js} +2 -2
  48. package/dist/chunks/{WebApp-D0vBp8ks.js.map → WebApp-9L0mkLAO.js.map} +1 -1
  49. package/dist/chunks/{WebApp-DT6XLijH.js → WebApp-Cd21W4Hv.js} +13 -13
  50. package/dist/chunks/{WebApp-DT6XLijH.js.map → WebApp-Cd21W4Hv.js.map} +1 -1
  51. package/dist/docit.cjs.js +1 -1
  52. package/dist/docit.es.js +5 -5
  53. package/dist/index.cjs.js +1 -1
  54. package/dist/index.es.js +11 -11
  55. package/dist/lightbox.cjs.js +1 -1
  56. package/dist/lightbox.es.js +4 -4
  57. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
- "use strict";const e=require("./WebApp-D0vBp8ks.js");class Model{constructor(t={},s={}){this.endpoint=s.endpoint||this.constructor.endpoint||"",this.id=t.id||null,this.attributes={...t},this._=this.attributes,this.originalAttributes={...t},this.errors={},this.loading=!1,this.rest=e.rest,this.options={idAttribute:"id",timestamps:!0,...s}}getContextValue(e){return this.get(e)}get(t){return t.includes(".")||t.includes("|")||void 0===this[t]?e.MOJOUtils.getContextData(this.attributes,t):"function"==typeof this[t]?this[t]():this[t]}set(e,t,s={}){const i=JSON.parse(JSON.stringify(this.attributes));let a=!1;if("object"==typeof e){for(const[t,s]of Object.entries(e))a=this._setNestedAttribute(t,s)||a;void 0!==e.id&&(this.id=e.id)}else"id"===e?(this.id=t,a=!0):a=this._setNestedAttribute(e,t);if(a&&!s.silent)if(this.emit("change",this),"string"==typeof e)this.emit(`change:${e}`,t,this);else for(const[r,o]of Object.entries(e)){const e=this._getNestedValue(r);JSON.stringify(this._getNestedValue(r,i))!==JSON.stringify(e)&&this.emit(`change:${r}`,e,this)}}_setNestedAttribute(e,t){if(!e.includes(".")){const s=this.attributes[e];return this.attributes[e]=t,this[e]=t,s!==t}const s=e.split("."),i=s[0];this.attributes[i]&&"object"==typeof this.attributes[i]||(this.attributes[i]={}),this[i]&&"object"==typeof this[i]||(this[i]={});const a=this._getNestedValue(e);let r=this.attributes[i],o=this[i];for(let l=1;l<s.length-1;l++){const e=s[l];r[e]&&"object"==typeof r[e]||(r[e]={}),o[e]&&"object"==typeof o[e]||(o[e]={}),r=r[e],o=o[e]}const n=s[s.length-1];return r[n]=t,o[n]=t,JSON.stringify(a)!==JSON.stringify(t)}_getNestedValue(e,t=this.attributes){if(!e.includes("."))return t[e];const s=e.split(".");let i=t;for(const a of s){if(null==i||"object"!=typeof i)return;i=i[a]}return i}getData(){return this.attributes}getId(){return this.id}async fetch(e={}){let t=e.url;if(!t){const s=e.id||this.getId();if(!s&&!1!==this.options.requiresId)throw new Error("Model: ID is required for fetching");t=this.buildUrl(s)}const s=JSON.stringify({url:t,params:e.params});if(e.debounceMs&&e.debounceMs>0)return this._debouncedFetch(s,e);if(this.currentRequest&&this.currentRequestKey!==s&&(this.abortController?.abort(),this.currentRequest=null),this.currentRequest&&this.currentRequestKey===s)return this.currentRequest;const i=Date.now();if(this.lastFetchTime&&i-this.lastFetchTime<100)return this;this.loading=!0,this.errors={},this.lastFetchTime=i,this.currentRequestKey=s,this.abortController=new AbortController,this.currentRequest=this._performFetch(t,e,this.abortController);try{return await this.currentRequest}catch(a){if("AbortError"===a.name)return this;throw a}finally{this.currentRequest=null,this.currentRequestKey=null,this.abortController=null}}async _debouncedFetch(e,t){return this.debouncedFetchTimeout&&clearTimeout(this.debouncedFetchTimeout),this.cancel(),new Promise((e,s)=>{this.debouncedFetchTimeout=setTimeout(async()=>{try{const s=await this.fetch({...t,debounceMs:0});e(s)}catch(i){s(i)}},t.debounceMs)})}async _performFetch(e,t,s){try{!t.graph||t.params&&t.params.graph||(t.params||(t.params={}),t.params.graph=t.graph);const i=await this.rest.GET(e,t.params,{signal:s.signal});return i.success?i.data.status?(this.originalAttributes={...this.attributes},this.set(i.data.data),this.errors={}):this.errors=i.data:this.errors=i.errors||{},i}catch(i){if("AbortError"===i.name)throw i;return this.errors={fetch:i.message},{success:!1,error:i.message,status:i.status||500}}finally{this.loading=!1}}async save(e,t={}){const s=!this.id,i=s?"POST":"PUT",a=s?this.buildUrl():this.buildUrl(this.id);this.loading=!0,this.errors={};try{const s=await this.rest[i](a,e,t.params);return s.success?s.data.status?(this.originalAttributes={...this.attributes},this.set(s.data.data),this.errors={}):this.errors=s.data:this.errors=s.errors||{},s}catch(r){return{success:!1,error:r.message,status:r.status||500}}finally{this.loading=!1}}async destroy(e={}){if(!this.id)return this.errors={destroy:"Cannot destroy model without ID"},{success:!1,error:"Cannot destroy model without ID",status:400};const t=this.buildUrl(this.id);this.loading=!0,this.errors={};try{const s=await this.rest.DELETE(t,e.params);return s.success?(this.attributes={},this.originalAttributes={},this.id=null,this.errors={}):this.errors=s.errors||{},s}catch(s){return this.errors={destroy:s.message},{success:!1,error:s.message,status:s.status||500}}finally{this.loading=!1}}isDirty(){return JSON.stringify(this.attributes)!==JSON.stringify(this.originalAttributes)}getChangedAttributes(){const e={};for(const[t,s]of Object.entries(this.attributes))this.originalAttributes[t]!==s&&(e[t]=s);return e}reset(){this.attributes={...this.originalAttributes},this._=this.attributes,this.errors={}}buildUrl(e=null){let t=this.endpoint;return e&&(t=t.endsWith("/")?`${t}${e}`:`${t}/${e}`),t}toJSON(){return{id:this.id,...this.attributes}}validate(){if(this.errors={},this.constructor.validations)for(const[e,t]of Object.entries(this.constructor.validations))this.validateField(e,t);return 0===Object.keys(this.errors).length}validateField(e,t){const s=this.get(e),i=Array.isArray(t)?t:[t];for(const a of i)if("function"==typeof a){const t=a(s,this);if(!0!==t){this.errors[e]=t||`${e} is invalid`;break}}else if("object"==typeof a){if(a.required&&(null==s||""===s)){this.errors[e]=a.message||`${e} is required`;break}if(a.minLength&&s&&s.length<a.minLength){this.errors[e]=a.message||`${e} must be at least ${a.minLength} characters`;break}if(a.maxLength&&s&&s.length>a.maxLength){this.errors[e]=a.message||`${e} must be no more than ${a.maxLength} characters`;break}if(a.pattern&&s&&!a.pattern.test(s)){this.errors[e]=a.message||`${e} format is invalid`;break}}}static async find(e,t={}){const s=new this({},t);return await s.fetch({id:e,...t}),s}static create(e={},t={}){return new this(e,t)}cancel(){return this.currentRequest&&this.abortController?(this.abortController.abort(),!0):!!this.debouncedFetchTimeout&&(clearTimeout(this.debouncedFetchTimeout),this.debouncedFetchTimeout=null,!0)}isFetching(){return!!this.currentRequest}async showError(e){await Dialog.alert(e,"Error",{size:"md",class:"text-danger"})}}Object.assign(Model.prototype,e.EventEmitter);class Collection{constructor(t={},s=null){if(Array.isArray(t)?t=(s=t)||{}:s=s||t.data||[],this.ModelClass=t.ModelClass||Model,this.models=[],this.loading=!1,this.errors={},this.meta={},this.rest=e.rest,s&&this.add(s),this.params={start:0,size:t.size||10,...t.params},this.endpoint=t.endpoint||this.ModelClass.endpoint||"",!this.endpoint){let e=new this.ModelClass;this.endpoint=e.endpoint}this.restEnabled=!!this.endpoint,void 0!==t.restEnabled&&(this.restEnabled=t.restEnabled),this.options={parse:!0,reset:!0,preloaded:!1,...t}}getModelName(){return this.ModelClass.name}async fetch(e={}){const t=JSON.stringify({...this.params,...e});if(this.currentRequest&&this.currentRequestKey!==t&&(this.abortController?.abort(),this.currentRequest=null),this.currentRequest&&this.currentRequestKey===t)return this.currentRequest;const s=Date.now();if(this.options.rateLimiting&&this.lastFetchTime&&s-this.lastFetchTime<100)return{success:!0,message:"Rate limited, skipping fetch",data:{data:this.toJSON()}};if(!this.restEnabled)return{success:!0,message:"REST disabled, skipping fetch",data:{data:this.toJSON()}};if(this.options.preloaded&&this.models.length>0)return{success:!0,message:"Using preloaded data, skipping fetch",data:{data:this.toJSON()}};const i=this.buildUrl();this.loading=!0,this.errors={},this.lastFetchTime=s,this.currentRequestKey=t,this.abortController=new AbortController,this.currentRequest=this._performFetch(i,e,this.abortController);try{return await this.currentRequest}catch(a){return"AbortError"===a.name?{success:!1,error:"Request cancelled",status:0}:{success:!1,error:a.message,status:a.status||500}}finally{this.currentRequest=null,this.currentRequestKey=null,this.abortController=null}}async _performFetch(e,t,s){const i={...this.params,...t};try{this.emit("fetch:start");const a=await this.rest.GET(e,i,{signal:s.signal});if(a.success&&a.data.status){const e=this.options.parse?this.parse(a):a.data;(this.options.reset||!1!==t.reset)&&this.reset(),this.add(e,{silent:t.silent}),this.errors={},this.emit("fetch:success")}else a.data&&a.data.error?(this.errors=a.data,this.emit("fetch:error",{message:a.data.error,error:a.data})):(this.errors=a.errors||{},this.emit("fetch:error",{error:a.errors}));return a}catch(a){return"AbortError"===a.name?{success:!1,error:"Request cancelled",status:0}:(this.errors={fetch:a.message},this.emit("fetch:error",{message:a.message,error:a}),{success:!1,error:a.message,status:a.status||500})}finally{this.loading=!1,this.emit("fetch:end")}}async updateParams(e,t=!1,s=0){return await this.setParams({...this.params,...e},t,s)}async setParams(e,t=!1,s=0){return this.params=e,t&&this.restEnabled?s>0?(this.debouncedFetchTimeout&&clearTimeout(this.debouncedFetchTimeout),this.cancel(),new Promise((e,t)=>{this.debouncedFetchTimeout=setTimeout(async()=>{try{const t=await this.fetch();e(t)}catch(s){t(s)}},s)})):this.fetch():Promise.resolve(this)}async fetchOne(e,t={}){if(!e)return console.warn("Collection: fetchOne requires an ID"),null;if(!this.restEnabled)return null;try{const s=new this.ModelClass({id:e},{endpoint:this.endpoint,collection:this}),i=await s.fetch(t);if(i.success){if(!0===t.addToCollection){const e=this.get(s.id);e?!1!==t.merge&&e.set(s.attributes):this.add(s,{silent:t.silent})}return s}return console.warn("Collection: fetchOne failed -",i.error||"Unknown error"),null}catch(s){return console.error("Collection: fetchOne error -",s.message),null}}async download(e="json",t={}){if(!this.restEnabled)return console.warn("Collection: REST is not enabled, cannot download from remote."),{success:!1,message:"Remote downloads are not enabled for this collection."};const s=this.buildUrl(),i={...this.params};delete i.start,delete i.size,i.download_format=e;const a=`export-${this.getModelName().toLowerCase()}.${e}`,r={json:"application/json",csv:"text/csv"}[e]||"*/*";return this.rest.download(s,i,{...t,filename:a,headers:{Accept:r}})}parse(e){return e.data&&Array.isArray(e.data.data)?(this.meta={size:e.data.size||10,start:e.data.start||0,count:e.data.count||0,status:e.data.status,graph:e.data.graph,...e.meta},e.data.data):Array.isArray(e.data)?e.data:Array.isArray(e)?e:[e]}add(e,t={}){const s=Array.isArray(e)?e:[e],i=[];for(const a of s){let e;e=a instanceof this.ModelClass?a:new this.ModelClass(a,{endpoint:this.endpoint,collection:this});const s=this.models.findIndex(t=>t.id===e.id);-1!==s?!1!==t.merge&&this.models[s].set(e.attributes):(this.models.push(e),i.push(e))}return!t.silent&&i.length>0&&(this.emit("add",{models:i,collection:this}),this.emit("update",{collection:this})),i}remove(e,t={}){const s=Array.isArray(e)?e:[e],i=[];for(const a of s){let e=-1;if(e="string"==typeof a||"number"==typeof a?this.models.findIndex(e=>e.id==a):this.models.indexOf(a),-1!==e){const t=this.models.splice(e,1)[0];i.push(t)}}return!t.silent&&i.length>0&&(this.emit("remove",{models:i,collection:this}),this.emit("update",{collection:this})),i}reset(e=null,t={}){const s=[...this.models];return this.models=[],e&&this.add(e,{silent:!0,...t}),t.silent||this.emit("reset",{collection:this,previousModels:s}),this}get(e){return this.models.find(t=>t.id==e)}at(e){return this.models[e]}length(){return this.models.length}isEmpty(){return 0===this.models.length}where(e){return"function"==typeof e?this.models.filter(e):"object"==typeof e?this.models.filter(t=>Object.entries(e).every(([e,s])=>t.get(e)===s)):[]}findWhere(e){const t=this.where(e);return t.length>0?t[0]:void 0}forEach(e,t){if("function"!=typeof e)throw new TypeError("Callback must be a function");return this.models.forEach((s,i)=>{e.call(t,s,i,this)}),this}sort(e,t={}){if("string"==typeof e){const t=e;e=(e,s)=>{const i=e.get(t),a=s.get(t);return i<a?-1:i>a?1:0}}return this.models.sort(e),t.silent||this.trigger("sort",{collection:this}),this}toJSON(){return this.models.map(e=>e.toJSON())}cancel(){return!(!this.currentRequest||!this.abortController||(this.abortController.abort(),0))}isFetching(){return!!this.currentRequest}buildUrl(){return this.endpoint}*[Symbol.iterator](){for(const e of this.models)yield e}static fromArray(e,t=[],s={}){const i=new this(e,s);return i.add(t,{silent:!0}),i}}Object.assign(Collection.prototype,e.EventEmitter);class Group extends Model{constructor(e={}){super(e,{endpoint:"/api/group"})}}class GroupList extends Collection{constructor(e={}){super({ModelClass:Group,endpoint:"/api/group",size:10,...e})}}const t={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"},s=Object.entries(t).map(([e,t])=>({value:e,label:t})),i={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:s},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,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:s},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,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}]},detailed:{title:"Group Details",fields:[{type:"header",text:"Profile Information",level:4,class:"text-primary mb-3"},{type:"group",columns:{xs:12,md:4},fields:[{type:"image",name:"avatar",size:"lg",imageSize:{width:200,height:200},placeholder:"Upload your avatar",help:"Square images work best",columns:12},{name:"is_active",type:"switch",label:"Is Active",columns:12}]},{type:"group",columns:{xs:12,md:8},title:"Details",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name",columns:12},{name:"kind",type:"select",label:"Group Kind",required:!0,columns:12,options:[{value:"org",label:"Organization"},{value:"team",label:"Team"},{value:"department",label:"Department"},{value:"merchant",label:"Merchant"},{value:"iso",label:"ISO"},{value:"group",label:"Group"}]},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300,columns:12}]},{type:"group",columns:12,title:"Account Settings",class:"pt-3",fields:[{type:"select",name:"metadata.timezone",label:"Timezone",columns:6,options:[{value:"America/New_York",text:"Eastern Time"},{value:"America/Chicago",text:"Central Time"},{value:"America/Denver",text:"Mountain Time"},{value:"America/Los_Angeles",text:"Pacific Time"},{value:"UTC",text:"UTC"}]},{type:"select",name:"metadata.language",label:"Language",columns:6,options:[{value:"en",text:"English"},{value:"es",text:"Spanish"},{value:"fr",text:"French"},{value:"de",text:"German"}]},{type:"switch",name:"metadata.notify.email",label:"Email Notifications",columns:4},{type:"switch",name:"metadata.profile_public",label:"Public Profile",columns:4}]}]}};Group.EDIT_FORM=i.edit,Group.CREATE_FORM=i.create,Group.GroupKindOptions=s,Group.GroupKinds=t;const a=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Group:Group,GroupForms:i,GroupList:GroupList},Symbol.toStringTag,{value:"Module"}));class User extends Model{constructor(e={}){super(e,{endpoint:"/api/user"})}hasPermission(e){if(Array.isArray(e))return e.some(e=>this.hasPermission(e));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&&1==t[e]}hasPerm(e){return this.hasPermission(e)}}User.PERMISSIONS=[{name:"manage_users",label:"Manage 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"}],User.PERMISSION_FIELDS=[...User.PERMISSIONS.map(e=>({name:`permissions.${e.name}`,type:"switch",label:e.label,columns:4}))];const r={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:GroupList,labelField:"name",valueField:"id",columns:12}]},permissions:{title:"Edit Permissions",fields:User.PERMISSIONS_FIELDS}},o={profile:{title:"User Profile",columns:2,fields:[{name:"id",label:"User ID",type:"number",columns:4},{name:"username",label:"Username",type:"text",format:"lowercase",columns:4},{name:"last_login",label:"Last Login",type:"datetime",format:"relative",columns:4},{name:"email",label:"Email",type:"email",columns:4},{name:"display_name",label:"Display Name",type:"text",columns:4},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",columns:4},{name:"org.name",label:"Organization",type:"text",columns:4},{name:"phone_number",label:"Phone Number",type:"text",columns:4}]},activity:{title:"User Activity",columns:2,fields:[{name:"last_login",label:"Last Login",type:"datetime",format:"relative",colSize:6},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",colSize:6}]},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}]},permissions:{title:"User Permissions",columns:1,fields:[{name:"display_name",label:"User",type:"text",format:"capitalize",columns:12},{name:"permissions",label:"Assigned Permissions",type:"dataview",dataViewColumns:3,showEmptyValues:!1,colSize:12}]},summary:{title:"User Summary",columns:3,fields:[{name:"display_name",label:"Name",type:"text",format:"capitalize|truncate(30)"},{name:"email",label:"Email",type:"email"},{name:"is_active",label:"Status",type:"boolean"},{name:"last_activity",label:"Last Seen",type:"datetime",format:"relative",colSize:12}]}};User.DATA_VIEW=o.detailed,User.EDIT_FORM=r.edit,User.ADD_FORM=r.create;class UserDevice extends Model{constructor(e={}){super(e,{endpoint:"/api/user/device"})}static async getByDuid(e){const t=new UserDevice,s=await t.rest.GET("/api/user/device/lookup",{duid:e});return s.success&&s.data&&s.data.data?new UserDevice(s.data.data):null}}class UserDeviceLocation extends Model{constructor(e={}){super(e,{endpoint:"/api/user/device/location"})}}class ContextMenu extends e.View{constructor(e={}){super({tagName:"div",className:"context-menu-view dropdown",...e}),this.config=e.contextMenu||e.config||{},this.context=e.context||{}}async renderTemplate(){const e=this.config.items||[];if(0===e.length)return"";const t=this.config.icon||"bi-three-dots-horizontal",s=this.config.buttonClass||"btn btn-link text-secondary ps-3 pe-0 pt-0 pb-1",i=`context-menu-${this.id}`;return`\n <button class="${s}" type="button" id="${i}" data-bs-toggle="dropdown" aria-expanded="false">\n <i class="${t}"></i>\n </button>\n <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="${i}">\n ${e.map(e=>this.buildMenuItemHTML(e)).join("")}\n </ul>\n `}buildMenuItemHTML(e){if("divider"===e.type||e.separator)return'<li><hr class="dropdown-divider"></li>';const t=e.icon?`<i class="${e.icon} me-2"></i>`:"",s=e.label||"",i=`dropdown-item ${e.danger?"text-danger":""} ${e.disabled?"disabled":""}`,a=e.action||"";return e.href?`<li><a class="${i}" href="${e.href}" target="${e.target||"_self"}">${t}${s}</a></li>`:`<li><a class="${i}" href="#" data-action="menu-item-click" data-item-action="${a}">${t}${s}</a></li>`}async onActionMenuItemClick(e,t){e.preventDefault();const s=t.getAttribute("data-item-action");if(!s)return;const i=this.config.items.find(e=>e.action===s);i&&!i.disabled&&("function"==typeof i.handler?i.handler(this.context,e,t):this.parent.events.dispatch(s,e,t),this.closeDropdown())}closeDropdown(){const e=this.element.querySelector('[data-bs-toggle="dropdown"]');if(e){const t=window.bootstrap?.Dropdown.getInstance(e);t?.hide()}}}exports.Collection=Collection,exports.ContextMenu=ContextMenu,exports.Group=Group,exports.Group$1=a,exports.GroupForms=i,exports.GroupList=GroupList,exports.Model=Model,exports.ToastService=class{constructor(e={}){this.options={containerId:"toast-container",position:"top-end",autohide:!0,defaultDelay:5e3,maxToasts:5,...e},this.toasts=/* @__PURE__ */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:!1,...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),"undefined"==typeof bootstrap)throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const o=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});return this.toasts.set(i,{element:r,bootstrap:o,type:t,message:e}),r.addEventListener("hidden.bs.toast",()=>{this.cleanup(i)}),o.show(),{id:i,hide:()=>{try{o.hide()}catch(e){console.warn("Error hiding toast:",e)}},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),"undefined"==typeof bootstrap)throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const o=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});this.toasts.set(i,{element:r,bootstrap:o,type:t,view:e,message:"View toast"}),r.addEventListener("hidden.bs.toast",()=>{this.cleanupView(i)});const n=r.querySelector(".toast-view-body");return n&&e&&e.render(!0,n),o.show(),{id:i,view:e,hide:()=>{try{o.hide()}catch(e){console.warn("Error hiding view toast:",e)}},dispose:()=>this.cleanupView(i),updateProgress:t=>{e&&"function"==typeof e.updateProgress&&e.updateProgress(t)}}}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):"",o=this.createToastBody(t,i.icon&&!i.title);return a.innerHTML=`\n ${r}\n ${o}\n `,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):"",o=this.createViewToastBody();return a.innerHTML=`\n ${r}\n ${o}\n `,a}createViewToastBody(){return'\n <div class="toast-body p-0">\n <div class="toast-view-body p-3"></div>\n </div>\n '}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?`\n <div class="toast-header">\n ${i}\n ${a}\n ${r}\n </div>\n `:""}createToastBody(e,t=!1){return`\n <div class="toast-body d-flex align-items-center">\n ${t?`<i class="${this.getDefaultIcon("info")} toast-service-icon me-2"></i>`:""}\n <span>${this.escapeHtml(e)}</span>\n </div>\n `}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 e=this.toasts.keys().next().value,t=this.toasts.get(e);t&&t.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&&"function"==typeof t.view.dispose)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(){/* @__PURE__ */
1
+ "use strict";const e=require("./WebApp-9L0mkLAO.js");class Model{constructor(t={},s={}){this.endpoint=s.endpoint||this.constructor.endpoint||"",this.id=t.id||null,this.attributes={...t},this._=this.attributes,this.originalAttributes={...t},this.errors={},this.loading=!1,this.rest=e.rest,this.options={idAttribute:"id",timestamps:!0,...s}}getContextValue(e){return this.get(e)}get(t){return t.includes(".")||t.includes("|")||void 0===this[t]?e.MOJOUtils.getContextData(this.attributes,t):"function"==typeof this[t]?this[t]():this[t]}set(e,t,s={}){const i=JSON.parse(JSON.stringify(this.attributes));let a=!1;if("object"==typeof e){for(const[t,s]of Object.entries(e))a=this._setNestedAttribute(t,s)||a;void 0!==e.id&&(this.id=e.id)}else"id"===e?(this.id=t,a=!0):a=this._setNestedAttribute(e,t);if(a&&!s.silent)if(this.emit("change",this),"string"==typeof e)this.emit(`change:${e}`,t,this);else for(const[r,o]of Object.entries(e)){const e=this._getNestedValue(r);JSON.stringify(this._getNestedValue(r,i))!==JSON.stringify(e)&&this.emit(`change:${r}`,e,this)}}_setNestedAttribute(e,t){if(!e.includes(".")){const s=this.attributes[e];return this.attributes[e]=t,this[e]=t,s!==t}const s=e.split("."),i=s[0];this.attributes[i]&&"object"==typeof this.attributes[i]||(this.attributes[i]={}),this[i]&&"object"==typeof this[i]||(this[i]={});const a=this._getNestedValue(e);let r=this.attributes[i],o=this[i];for(let l=1;l<s.length-1;l++){const e=s[l];r[e]&&"object"==typeof r[e]||(r[e]={}),o[e]&&"object"==typeof o[e]||(o[e]={}),r=r[e],o=o[e]}const n=s[s.length-1];return r[n]=t,o[n]=t,JSON.stringify(a)!==JSON.stringify(t)}_getNestedValue(e,t=this.attributes){if(!e.includes("."))return t[e];const s=e.split(".");let i=t;for(const a of s){if(null==i||"object"!=typeof i)return;i=i[a]}return i}getData(){return this.attributes}getId(){return this.id}async fetch(e={}){let t=e.url;if(!t){const s=e.id||this.getId();if(!s&&!1!==this.options.requiresId)throw new Error("Model: ID is required for fetching");t=this.buildUrl(s)}const s=JSON.stringify({url:t,params:e.params});if(e.debounceMs&&e.debounceMs>0)return this._debouncedFetch(s,e);if(this.currentRequest&&this.currentRequestKey!==s&&(this.abortController?.abort(),this.currentRequest=null),this.currentRequest&&this.currentRequestKey===s)return this.currentRequest;const i=Date.now();if(this.lastFetchTime&&i-this.lastFetchTime<100)return this;this.loading=!0,this.errors={},this.lastFetchTime=i,this.currentRequestKey=s,this.abortController=new AbortController,this.currentRequest=this._performFetch(t,e,this.abortController);try{return await this.currentRequest}catch(a){if("AbortError"===a.name)return this;throw a}finally{this.currentRequest=null,this.currentRequestKey=null,this.abortController=null}}async _debouncedFetch(e,t){return this.debouncedFetchTimeout&&clearTimeout(this.debouncedFetchTimeout),this.cancel(),new Promise((e,s)=>{this.debouncedFetchTimeout=setTimeout(async()=>{try{const s=await this.fetch({...t,debounceMs:0});e(s)}catch(i){s(i)}},t.debounceMs)})}async _performFetch(e,t,s){try{!t.graph||t.params&&t.params.graph||(t.params||(t.params={}),t.params.graph=t.graph);const i=await this.rest.GET(e,t.params,{signal:s.signal});return i.success?i.data.status?(this.originalAttributes={...this.attributes},this.set(i.data.data),this.errors={}):this.errors=i.data:this.errors=i.errors||{},i}catch(i){if("AbortError"===i.name)throw i;return this.errors={fetch:i.message},{success:!1,error:i.message,status:i.status||500}}finally{this.loading=!1}}async save(e,t={}){const s=!this.id,i=s?"POST":"PUT",a=s?this.buildUrl():this.buildUrl(this.id);this.loading=!0,this.errors={};try{const s=await this.rest[i](a,e,t.params);return s.success?s.data.status?(this.originalAttributes={...this.attributes},this.set(s.data.data),this.errors={}):this.errors=s.data:this.errors=s.errors||{},s}catch(r){return{success:!1,error:r.message,status:r.status||500}}finally{this.loading=!1}}async destroy(e={}){if(!this.id)return this.errors={destroy:"Cannot destroy model without ID"},{success:!1,error:"Cannot destroy model without ID",status:400};const t=this.buildUrl(this.id);this.loading=!0,this.errors={};try{const s=await this.rest.DELETE(t,e.params);return s.success?(this.attributes={},this.originalAttributes={},this.id=null,this.errors={}):this.errors=s.errors||{},s}catch(s){return this.errors={destroy:s.message},{success:!1,error:s.message,status:s.status||500}}finally{this.loading=!1}}isDirty(){return JSON.stringify(this.attributes)!==JSON.stringify(this.originalAttributes)}getChangedAttributes(){const e={};for(const[t,s]of Object.entries(this.attributes))this.originalAttributes[t]!==s&&(e[t]=s);return e}reset(){this.attributes={...this.originalAttributes},this._=this.attributes,this.errors={}}buildUrl(e=null){let t=this.endpoint;return e&&(t=t.endsWith("/")?`${t}${e}`:`${t}/${e}`),t}toJSON(){return{id:this.id,...this.attributes}}validate(){if(this.errors={},this.constructor.validations)for(const[e,t]of Object.entries(this.constructor.validations))this.validateField(e,t);return 0===Object.keys(this.errors).length}validateField(e,t){const s=this.get(e),i=Array.isArray(t)?t:[t];for(const a of i)if("function"==typeof a){const t=a(s,this);if(!0!==t){this.errors[e]=t||`${e} is invalid`;break}}else if("object"==typeof a){if(a.required&&(null==s||""===s)){this.errors[e]=a.message||`${e} is required`;break}if(a.minLength&&s&&s.length<a.minLength){this.errors[e]=a.message||`${e} must be at least ${a.minLength} characters`;break}if(a.maxLength&&s&&s.length>a.maxLength){this.errors[e]=a.message||`${e} must be no more than ${a.maxLength} characters`;break}if(a.pattern&&s&&!a.pattern.test(s)){this.errors[e]=a.message||`${e} format is invalid`;break}}}static async find(e,t={}){const s=new this({},t);return await s.fetch({id:e,...t}),s}static create(e={},t={}){return new this(e,t)}cancel(){return this.currentRequest&&this.abortController?(this.abortController.abort(),!0):!!this.debouncedFetchTimeout&&(clearTimeout(this.debouncedFetchTimeout),this.debouncedFetchTimeout=null,!0)}isFetching(){return!!this.currentRequest}async showError(e){await Dialog.alert(e,"Error",{size:"md",class:"text-danger"})}}Object.assign(Model.prototype,e.EventEmitter);class Collection{constructor(t={},s=null){if(Array.isArray(t)?t=(s=t)||{}:s=s||t.data||[],this.ModelClass=t.ModelClass||Model,this.models=[],this.loading=!1,this.errors={},this.meta={},this.rest=e.rest,s&&this.add(s),this.params={start:0,size:t.size||10,...t.params},this.endpoint=t.endpoint||this.ModelClass.endpoint||"",!this.endpoint){let e=new this.ModelClass;this.endpoint=e.endpoint}this.restEnabled=!!this.endpoint,void 0!==t.restEnabled&&(this.restEnabled=t.restEnabled),this.options={parse:!0,reset:!0,preloaded:!1,...t}}getModelName(){return this.ModelClass.name}async fetch(e={}){const t=JSON.stringify({...this.params,...e});if(this.currentRequest&&this.currentRequestKey!==t&&(this.abortController?.abort(),this.currentRequest=null),this.currentRequest&&this.currentRequestKey===t)return this.currentRequest;const s=Date.now();if(this.options.rateLimiting&&this.lastFetchTime&&s-this.lastFetchTime<100)return{success:!0,message:"Rate limited, skipping fetch",data:{data:this.toJSON()}};if(!this.restEnabled)return{success:!0,message:"REST disabled, skipping fetch",data:{data:this.toJSON()}};if(this.options.preloaded&&this.models.length>0)return{success:!0,message:"Using preloaded data, skipping fetch",data:{data:this.toJSON()}};const i=this.buildUrl();this.loading=!0,this.errors={},this.lastFetchTime=s,this.currentRequestKey=t,this.abortController=new AbortController,this.currentRequest=this._performFetch(i,e,this.abortController);try{return await this.currentRequest}catch(a){return"AbortError"===a.name?{success:!1,error:"Request cancelled",status:0}:{success:!1,error:a.message,status:a.status||500}}finally{this.currentRequest=null,this.currentRequestKey=null,this.abortController=null}}async _performFetch(e,t,s){const i={...this.params,...t};try{this.emit("fetch:start");const a=await this.rest.GET(e,i,{signal:s.signal});if(a.success&&a.data.status){const e=this.options.parse?this.parse(a):a.data;(this.options.reset||!1!==t.reset)&&this.reset(),this.add(e,{silent:t.silent}),this.errors={},this.emit("fetch:success")}else a.data&&a.data.error?(this.errors=a.data,this.emit("fetch:error",{message:a.data.error,error:a.data})):(this.errors=a.errors||{},this.emit("fetch:error",{error:a.errors}));return a}catch(a){return"AbortError"===a.name?{success:!1,error:"Request cancelled",status:0}:(this.errors={fetch:a.message},this.emit("fetch:error",{message:a.message,error:a}),{success:!1,error:a.message,status:a.status||500})}finally{this.loading=!1,this.emit("fetch:end")}}async updateParams(e,t=!1,s=0){return await this.setParams({...this.params,...e},t,s)}async setParams(e,t=!1,s=0){return this.params=e,t&&this.restEnabled?s>0?(this.debouncedFetchTimeout&&clearTimeout(this.debouncedFetchTimeout),this.cancel(),new Promise((e,t)=>{this.debouncedFetchTimeout=setTimeout(async()=>{try{const t=await this.fetch();e(t)}catch(s){t(s)}},s)})):this.fetch():Promise.resolve(this)}async fetchOne(e,t={}){if(!e)return console.warn("Collection: fetchOne requires an ID"),null;if(!this.restEnabled)return null;try{const s=new this.ModelClass({id:e},{endpoint:this.endpoint,collection:this}),i=await s.fetch(t);if(i.success){if(!0===t.addToCollection){const e=this.get(s.id);e?!1!==t.merge&&e.set(s.attributes):this.add(s,{silent:t.silent})}return s}return console.warn("Collection: fetchOne failed -",i.error||"Unknown error"),null}catch(s){return console.error("Collection: fetchOne error -",s.message),null}}async download(e="json",t={}){if(!this.restEnabled)return console.warn("Collection: REST is not enabled, cannot download from remote."),{success:!1,message:"Remote downloads are not enabled for this collection."};const s=this.buildUrl(),i={...this.params};delete i.start,delete i.size,i.download_format=e;const a=`export-${this.getModelName().toLowerCase()}.${e}`,r={json:"application/json",csv:"text/csv"}[e]||"*/*";return this.rest.download(s,i,{...t,filename:a,headers:{Accept:r}})}parse(e){return e.data&&Array.isArray(e.data.data)?(this.meta={size:e.data.size||10,start:e.data.start||0,count:e.data.count||0,status:e.data.status,graph:e.data.graph,...e.meta},e.data.data):Array.isArray(e.data)?e.data:Array.isArray(e)?e:[e]}add(e,t={}){const s=Array.isArray(e)?e:[e],i=[];for(const a of s){let e;e=a instanceof this.ModelClass?a:new this.ModelClass(a,{endpoint:this.endpoint,collection:this});const s=this.models.findIndex(t=>t.id===e.id);-1!==s?!1!==t.merge&&this.models[s].set(e.attributes):(this.models.push(e),i.push(e))}return!t.silent&&i.length>0&&(this.emit("add",{models:i,collection:this}),this.emit("update",{collection:this})),i}remove(e,t={}){const s=Array.isArray(e)?e:[e],i=[];for(const a of s){let e=-1;if(e="string"==typeof a||"number"==typeof a?this.models.findIndex(e=>e.id==a):this.models.indexOf(a),-1!==e){const t=this.models.splice(e,1)[0];i.push(t)}}return!t.silent&&i.length>0&&(this.emit("remove",{models:i,collection:this}),this.emit("update",{collection:this})),i}reset(e=null,t={}){const s=[...this.models];return this.models=[],e&&this.add(e,{silent:!0,...t}),t.silent||this.emit("reset",{collection:this,previousModels:s}),this}get(e){return this.models.find(t=>t.id==e)}at(e){return this.models[e]}length(){return this.models.length}isEmpty(){return 0===this.models.length}where(e){return"function"==typeof e?this.models.filter(e):"object"==typeof e?this.models.filter(t=>Object.entries(e).every(([e,s])=>t.get(e)===s)):[]}findWhere(e){const t=this.where(e);return t.length>0?t[0]:void 0}forEach(e,t){if("function"!=typeof e)throw new TypeError("Callback must be a function");return this.models.forEach((s,i)=>{e.call(t,s,i,this)}),this}sort(e,t={}){if("string"==typeof e){const t=e;e=(e,s)=>{const i=e.get(t),a=s.get(t);return i<a?-1:i>a?1:0}}return this.models.sort(e),t.silent||this.trigger("sort",{collection:this}),this}toJSON(){return this.models.map(e=>e.toJSON())}cancel(){return!(!this.currentRequest||!this.abortController||(this.abortController.abort(),0))}isFetching(){return!!this.currentRequest}buildUrl(){return this.endpoint}*[Symbol.iterator](){for(const e of this.models)yield e}static fromArray(e,t=[],s={}){const i=new this(e,s);return i.add(t,{silent:!0}),i}}Object.assign(Collection.prototype,e.EventEmitter);class Group extends Model{constructor(e={}){super(e,{endpoint:"/api/group"})}}class GroupList extends Collection{constructor(e={}){super({ModelClass:Group,endpoint:"/api/group",size:10,...e})}}const t={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"},s=Object.entries(t).map(([e,t])=>({value:e,label:t})),i={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:s},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,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:s},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,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}]},detailed:{title:"Group Details",fields:[{type:"header",text:"Profile Information",level:4,class:"text-primary mb-3"},{type:"group",columns:{xs:12,md:4},fields:[{type:"image",name:"avatar",size:"lg",imageSize:{width:200,height:200},placeholder:"Upload your avatar",help:"Square images work best",columns:12},{name:"is_active",type:"switch",label:"Is Active",columns:12}]},{type:"group",columns:{xs:12,md:8},title:"Details",fields:[{name:"name",type:"text",label:"Group Name",required:!0,placeholder:"Enter group name",columns:12},{name:"kind",type:"select",label:"Group Kind",required:!0,columns:12,options:[{value:"org",label:"Organization"},{value:"team",label:"Team"},{value:"department",label:"Department"},{value:"merchant",label:"Merchant"},{value:"iso",label:"ISO"},{value:"group",label:"Group"}]},{type:"collection",name:"parent",label:"Parent Group",Collection:GroupList,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300,columns:12}]},{type:"group",columns:12,title:"Account Settings",class:"pt-3",fields:[{type:"select",name:"metadata.timezone",label:"Timezone",columns:6,options:[{value:"America/New_York",text:"Eastern Time"},{value:"America/Chicago",text:"Central Time"},{value:"America/Denver",text:"Mountain Time"},{value:"America/Los_Angeles",text:"Pacific Time"},{value:"UTC",text:"UTC"}]},{type:"select",name:"metadata.language",label:"Language",columns:6,options:[{value:"en",text:"English"},{value:"es",text:"Spanish"},{value:"fr",text:"French"},{value:"de",text:"German"}]},{type:"switch",name:"metadata.notify.email",label:"Email Notifications",columns:4},{type:"switch",name:"metadata.profile_public",label:"Public Profile",columns:4}]}]}};Group.EDIT_FORM=i.edit,Group.CREATE_FORM=i.create,Group.GroupKindOptions=s,Group.GroupKinds=t;const a=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Group:Group,GroupForms:i,GroupList:GroupList},Symbol.toStringTag,{value:"Module"}));class User extends Model{constructor(e={}){super(e,{endpoint:"/api/user"})}hasPermission(e){if(Array.isArray(e))return e.some(e=>this.hasPermission(e));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&&1==t[e]}hasPerm(e){return this.hasPermission(e)}}User.PERMISSIONS=[{name:"manage_users",label:"Manage 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"}],User.PERMISSION_FIELDS=[...User.PERMISSIONS.map(e=>({name:`permissions.${e.name}`,type:"switch",label:e.label,columns:4}))];const r={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:GroupList,labelField:"name",valueField:"id",columns:12}]},permissions:{title:"Edit Permissions",fields:User.PERMISSIONS_FIELDS}},o={profile:{title:"User Profile",columns:2,fields:[{name:"id",label:"User ID",type:"number",columns:4},{name:"username",label:"Username",type:"text",format:"lowercase",columns:4},{name:"last_login",label:"Last Login",type:"datetime",format:"relative",columns:4},{name:"email",label:"Email",type:"email",columns:4},{name:"display_name",label:"Display Name",type:"text",columns:4},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",columns:4},{name:"org.name",label:"Organization",type:"text",columns:4},{name:"phone_number",label:"Phone Number",type:"text",columns:4}]},activity:{title:"User Activity",columns:2,fields:[{name:"last_login",label:"Last Login",type:"datetime",format:"relative",colSize:6},{name:"last_activity",label:"Last Activity",type:"datetime",format:"relative",colSize:6}]},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}]},permissions:{title:"User Permissions",columns:1,fields:[{name:"display_name",label:"User",type:"text",format:"capitalize",columns:12},{name:"permissions",label:"Assigned Permissions",type:"dataview",dataViewColumns:3,showEmptyValues:!1,colSize:12}]},summary:{title:"User Summary",columns:3,fields:[{name:"display_name",label:"Name",type:"text",format:"capitalize|truncate(30)"},{name:"email",label:"Email",type:"email"},{name:"is_active",label:"Status",type:"boolean"},{name:"last_activity",label:"Last Seen",type:"datetime",format:"relative",colSize:12}]}};User.DATA_VIEW=o.detailed,User.EDIT_FORM=r.edit,User.ADD_FORM=r.create;class UserDevice extends Model{constructor(e={}){super(e,{endpoint:"/api/user/device"})}static async getByDuid(e){const t=new UserDevice,s=await t.rest.GET("/api/user/device/lookup",{duid:e});return s.success&&s.data&&s.data.data?new UserDevice(s.data.data):null}}class UserDeviceLocation extends Model{constructor(e={}){super(e,{endpoint:"/api/user/device/location"})}}class ContextMenu extends e.View{constructor(e={}){super({tagName:"div",className:"context-menu-view dropdown",...e}),this.config=e.contextMenu||e.config||{},this.context=e.context||{}}async renderTemplate(){const e=this.config.items||[];if(0===e.length)return"";const t=this.config.icon||"bi-three-dots-horizontal",s=this.config.buttonClass||"btn btn-link text-secondary ps-3 pe-0 pt-0 pb-1",i=`context-menu-${this.id}`;return`\n <button class="${s}" type="button" id="${i}" data-bs-toggle="dropdown" aria-expanded="false">\n <i class="${t}"></i>\n </button>\n <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="${i}">\n ${e.map(e=>this.buildMenuItemHTML(e)).join("")}\n </ul>\n `}buildMenuItemHTML(e){if("divider"===e.type||e.separator)return'<li><hr class="dropdown-divider"></li>';const t=e.icon?`<i class="${e.icon} me-2"></i>`:"",s=e.label||"",i=`dropdown-item ${e.danger?"text-danger":""} ${e.disabled?"disabled":""}`,a=e.action||"";return e.href?`<li><a class="${i}" href="${e.href}" target="${e.target||"_self"}">${t}${s}</a></li>`:`<li><a class="${i}" href="#" data-action="menu-item-click" data-item-action="${a}">${t}${s}</a></li>`}async onActionMenuItemClick(e,t){e.preventDefault();const s=t.getAttribute("data-item-action");if(!s)return;const i=this.config.items.find(e=>e.action===s);i&&!i.disabled&&("function"==typeof i.handler?i.handler(this.context,e,t):this.parent.events.dispatch(s,e,t),this.closeDropdown())}closeDropdown(){const e=this.element.querySelector('[data-bs-toggle="dropdown"]');if(e){const t=window.bootstrap?.Dropdown.getInstance(e);t?.hide()}}}exports.Collection=Collection,exports.ContextMenu=ContextMenu,exports.Group=Group,exports.Group$1=a,exports.GroupForms=i,exports.GroupList=GroupList,exports.Model=Model,exports.ToastService=class{constructor(e={}){this.options={containerId:"toast-container",position:"top-end",autohide:!0,defaultDelay:5e3,maxToasts:5,...e},this.toasts=/* @__PURE__ */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:!1,...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),"undefined"==typeof bootstrap)throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const o=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});return this.toasts.set(i,{element:r,bootstrap:o,type:t,message:e}),r.addEventListener("hidden.bs.toast",()=>{this.cleanup(i)}),o.show(),{id:i,hide:()=>{try{o.hide()}catch(e){console.warn("Error hiding toast:",e)}},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),"undefined"==typeof bootstrap)throw new Error("Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.");const o=new bootstrap.Toast(r,{autohide:a.autohide,delay:a.delay});this.toasts.set(i,{element:r,bootstrap:o,type:t,view:e,message:"View toast"}),r.addEventListener("hidden.bs.toast",()=>{this.cleanupView(i)});const n=r.querySelector(".toast-view-body");return n&&e&&e.render(!0,n),o.show(),{id:i,view:e,hide:()=>{try{o.hide()}catch(e){console.warn("Error hiding view toast:",e)}},dispose:()=>this.cleanupView(i),updateProgress:t=>{e&&"function"==typeof e.updateProgress&&e.updateProgress(t)}}}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):"",o=this.createToastBody(t,i.icon&&!i.title);return a.innerHTML=`\n ${r}\n ${o}\n `,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):"",o=this.createViewToastBody();return a.innerHTML=`\n ${r}\n ${o}\n `,a}createViewToastBody(){return'\n <div class="toast-body p-0">\n <div class="toast-view-body p-3"></div>\n </div>\n '}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?`\n <div class="toast-header">\n ${i}\n ${a}\n ${r}\n </div>\n `:""}createToastBody(e,t=!1){return`\n <div class="toast-body d-flex align-items-center">\n ${t?`<i class="${this.getDefaultIcon("info")} toast-service-icon me-2"></i>`:""}\n <span>${this.escapeHtml(e)}</span>\n </div>\n `}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 e=this.toasts.keys().next().value,t=this.toasts.get(e);t&&t.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&&"function"==typeof t.view.dispose)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(){/* @__PURE__ */
2
2
  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()}`)}},exports.User=User,exports.UserDataView=o,exports.UserDevice=UserDevice,exports.UserDeviceList=class extends Collection{constructor(e={}){super({ModelClass:UserDevice,endpoint:"/api/user/device",...e})}},exports.UserDeviceLocation=UserDeviceLocation,exports.UserDeviceLocationList=class extends Collection{constructor(e={}){super({ModelClass:UserDeviceLocation,endpoint:"/api/user/device/location",...e})}},exports.UserForms=r,exports.UserList=class extends Collection{constructor(e={}){super({ModelClass:User,endpoint:"/api/user",...e})}};
3
- //# sourceMappingURL=ContextMenu-C7wfFMyp.js.map
3
+ //# sourceMappingURL=ContextMenu-K8sVV2Sf.js.map