web-mojo 2.2.67 → 2.2.69

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 (102) hide show
  1. package/CHANGELOG.md +25 -9
  2. package/dist/admin.cjs.js +1 -1
  3. package/dist/admin.cjs.js.map +1 -1
  4. package/dist/admin.es.js +1 -1
  5. package/dist/admin.es.js.map +1 -1
  6. package/dist/auth.cjs.js +1 -1
  7. package/dist/auth.es.js +1 -1
  8. package/dist/charts.cjs.js +1 -1
  9. package/dist/charts.es.js +1 -1
  10. package/dist/chunks/ChatView-CZ3Key2k.js +2 -0
  11. package/dist/chunks/ChatView-CZ3Key2k.js.map +1 -0
  12. package/dist/chunks/ChatView-Dw-iVmht.js +2 -0
  13. package/dist/chunks/ChatView-Dw-iVmht.js.map +1 -0
  14. package/dist/chunks/{Dialog-DW7PHzUc.js → Dialog-Dhqtd9Yz.js} +2 -2
  15. package/dist/chunks/{Dialog-DW7PHzUc.js.map → Dialog-Dhqtd9Yz.js.map} +1 -1
  16. package/dist/chunks/{Dialog-jfBsXy5X.js → Dialog-t_9l2Mou.js} +2 -2
  17. package/dist/chunks/{Dialog-jfBsXy5X.js.map → Dialog-t_9l2Mou.js.map} +1 -1
  18. package/dist/chunks/Files-6eRT5k3r.js +2 -0
  19. package/dist/chunks/{Files-C-ChBvr5.js.map → Files-6eRT5k3r.js.map} +1 -1
  20. package/dist/chunks/Files-Dh_5PFBn.js +2 -0
  21. package/dist/chunks/{Files-DNbHDy43.js.map → Files-Dh_5PFBn.js.map} +1 -1
  22. package/dist/chunks/{FormView-EoB_ZdIB.js → FormView-B1CXO2t8.js} +2 -2
  23. package/dist/chunks/{FormView-EoB_ZdIB.js.map → FormView-B1CXO2t8.js.map} +1 -1
  24. package/dist/chunks/{FormView-Q_lFA0nr.js → FormView-BRHAIawp.js} +2 -2
  25. package/dist/chunks/{FormView-Q_lFA0nr.js.map → FormView-BRHAIawp.js.map} +1 -1
  26. package/dist/chunks/{MetricsMiniChartWidget-ChC5GGm6.js → MetricsMiniChartWidget-D1w608Jy.js} +2 -2
  27. package/dist/chunks/MetricsMiniChartWidget-D1w608Jy.js.map +1 -0
  28. package/dist/chunks/{MetricsMiniChartWidget-BkMjI-gz.js → MetricsMiniChartWidget-Dg1e6EQJ.js} +2 -2
  29. package/dist/chunks/MetricsMiniChartWidget-Dg1e6EQJ.js.map +1 -0
  30. package/dist/chunks/{PDFViewer-iOqYpg-6.js → PDFViewer-CDeV9OBs.js} +2 -2
  31. package/dist/chunks/{PDFViewer-iOqYpg-6.js.map → PDFViewer-CDeV9OBs.js.map} +1 -1
  32. package/dist/chunks/{PDFViewer-sFoyopz3.js → PDFViewer-D_3V8QJe.js} +2 -2
  33. package/dist/chunks/{PDFViewer-sFoyopz3.js.map → PDFViewer-D_3V8QJe.js.map} +1 -1
  34. package/dist/chunks/TableView-CI_7a-kD.js +2 -0
  35. package/dist/chunks/TableView-CI_7a-kD.js.map +1 -0
  36. package/dist/chunks/TableView-CWk5k4LQ.js +2 -0
  37. package/dist/chunks/TableView-CWk5k4LQ.js.map +1 -0
  38. package/dist/chunks/ToastService-C2tTooFn.js +3 -0
  39. package/dist/chunks/ToastService-C2tTooFn.js.map +1 -0
  40. package/dist/chunks/ToastService-nUaGVpSl.js +3 -0
  41. package/dist/chunks/ToastService-nUaGVpSl.js.map +1 -0
  42. package/dist/chunks/TokenManager-ien2XzwO.js +2 -0
  43. package/dist/chunks/TokenManager-ien2XzwO.js.map +1 -0
  44. package/dist/chunks/TokenManager-sZgt--C9.js +2 -0
  45. package/dist/chunks/TokenManager-sZgt--C9.js.map +1 -0
  46. package/dist/chunks/User-BL9M_PWB.js +2 -0
  47. package/dist/chunks/User-BL9M_PWB.js.map +1 -0
  48. package/dist/chunks/{User-BnlvMG5J.js → User-DqHG5Gr1.js} +2 -3
  49. package/dist/chunks/User-DqHG5Gr1.js.map +1 -0
  50. package/dist/chunks/UserProfileView-DnVMHcLH.js +2 -0
  51. package/dist/chunks/UserProfileView-DnVMHcLH.js.map +1 -0
  52. package/dist/chunks/UserProfileView-kupeq2rN.js +2 -0
  53. package/dist/chunks/UserProfileView-kupeq2rN.js.map +1 -0
  54. package/dist/chunks/{WebApp-Bsic6FPo.js → WebApp-Bti0Gqqo.js} +2 -2
  55. package/dist/chunks/{WebApp-Bsic6FPo.js.map → WebApp-Bti0Gqqo.js.map} +1 -1
  56. package/dist/chunks/{WebApp-B0m6JCjO.js → WebApp-CcVF73yg.js} +2 -2
  57. package/dist/chunks/{WebApp-B0m6JCjO.js.map → WebApp-CcVF73yg.js.map} +1 -1
  58. package/dist/chunks/index-Aq9ke4vg.js +2 -0
  59. package/dist/chunks/index-Aq9ke4vg.js.map +1 -0
  60. package/dist/chunks/index-Da9sT-tE.js +2 -0
  61. package/dist/chunks/index-Da9sT-tE.js.map +1 -0
  62. package/dist/chunks/{version-BY7AsEkb.js → version-D8JjsPW0.js} +2 -2
  63. package/dist/chunks/{version-BY7AsEkb.js.map → version-D8JjsPW0.js.map} +1 -1
  64. package/dist/chunks/{version-BdfRyQDm.js → version-XmirKYWA.js} +2 -2
  65. package/dist/chunks/{version-BdfRyQDm.js.map → version-XmirKYWA.js.map} +1 -1
  66. package/dist/css/web-mojo.css +1 -1
  67. package/dist/docit.cjs.js +1 -1
  68. package/dist/docit.cjs.js.map +1 -1
  69. package/dist/docit.es.js +1 -1
  70. package/dist/docit.es.js.map +1 -1
  71. package/dist/index.cjs.js +1 -1
  72. package/dist/index.cjs.js.map +1 -1
  73. package/dist/index.es.js +1 -1
  74. package/dist/index.es.js.map +1 -1
  75. package/dist/lightbox.cjs.js +1 -1
  76. package/dist/lightbox.es.js +1 -1
  77. package/dist/map.cjs.js +1 -1
  78. package/dist/map.es.js +1 -1
  79. package/dist/user-profile.cjs.js +2 -0
  80. package/dist/user-profile.cjs.js.map +1 -0
  81. package/dist/user-profile.es.js +2 -0
  82. package/dist/user-profile.es.js.map +1 -0
  83. package/dist/web-mojo.lite.iife.js +9 -6
  84. package/dist/web-mojo.lite.iife.js.map +1 -1
  85. package/dist/web-mojo.lite.iife.min.js +11 -11
  86. package/dist/web-mojo.lite.iife.min.js.map +1 -1
  87. package/package.json +5 -1
  88. package/dist/chunks/ChatView-Cfe0ZGvr.js +0 -2
  89. package/dist/chunks/ChatView-Cfe0ZGvr.js.map +0 -1
  90. package/dist/chunks/ChatView-DuQVFrCY.js +0 -2
  91. package/dist/chunks/ChatView-DuQVFrCY.js.map +0 -1
  92. package/dist/chunks/Files-C-ChBvr5.js +0 -2
  93. package/dist/chunks/Files-DNbHDy43.js +0 -2
  94. package/dist/chunks/MetricsMiniChartWidget-BkMjI-gz.js.map +0 -1
  95. package/dist/chunks/MetricsMiniChartWidget-ChC5GGm6.js.map +0 -1
  96. package/dist/chunks/TokenManager-BYMKH_aW.js +0 -2
  97. package/dist/chunks/TokenManager-BYMKH_aW.js.map +0 -1
  98. package/dist/chunks/TokenManager-DhDUKmaw.js +0 -2
  99. package/dist/chunks/TokenManager-DhDUKmaw.js.map +0 -1
  100. package/dist/chunks/User-BnlvMG5J.js.map +0 -1
  101. package/dist/chunks/User-DSqcOwPL.js +0 -3
  102. package/dist/chunks/User-DSqcOwPL.js.map +0 -1
@@ -1,2 +0,0 @@
1
- import{M as e,C as t}from"./Collection-BWKmydl5.js";import{T as s,G as a,U as o}from"./User-DSqcOwPL.js";import{V as i,d as l}from"./Rest-BJ3Mvx1L.js";class ProgressView extends i{constructor(e={}){super({template:"progress-view-template",...e}),this.filename=e.filename||"Unknown file",this.filesize=e.filesize||0,this.filesizeFormatted=l.pipe(this.filesize,"filesize"),this.progress=0,this.percentage=0,this.loaded=0,this.total=this.filesize,this.loadedFormatted="0 B",this.totalFormatted=this.filesizeFormatted,this.status="Starting upload...",this.showCancel=!1!==e.showCancel,this.onCancel=e.onCancel||null,this.cancelled=!1,this.completed=!1}getTemplate(){return'\n <div class="progress-view">\n <div class="d-flex justify-content-between align-items-start mb-2">\n <div class="flex-grow-1 min-width-0">\n <div class="fw-medium text-truncate" title="{{filename}}">\n <i class="bi bi-file-earmark me-1"></i>\n {{filename}}\n </div>\n <small class="text-muted">{{status}}</small>\n </div>\n {{#showCancel}}\n <button type="button" \n class="btn btn-sm btn-outline-secondary ms-2" \n data-action="cancel"\n {{#cancelled}}disabled{{/cancelled}}>\n <i class="bi bi-x"></i>\n </button>\n {{/showCancel}}\n </div>\n \n <div class="progress mb-2" style="height: 8px;">\n <div class="progress-bar" \n role="progressbar" \n style="width: {{percentage}}%"\n aria-valuenow="{{percentage}}" \n aria-valuemin="0" \n aria-valuemax="100">\n </div>\n </div>\n \n <div class="d-flex justify-content-between">\n <small class="text-muted">\n {{loadedFormatted}} / {{totalFormatted}}\n </small>\n <small class="text-muted">\n {{percentage}}%\n </small>\n </div>\n </div>\n '}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"),"function"==typeof this.onCancel))try{await this.onCancel()}catch(a){console.error("Error in cancel callback:",a)}}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 FileUpload{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 s),this.promise=this._startUpload()}async _startUpload(){try{let t,s,a;this.options.showToast&&this._showProgressToast();try{t=await this._initiateUpload()}catch(e){throw new Error(`Failed to initiate upload: ${e.message}`)}if(this.cancelled)throw new Error("Upload cancelled");if(!t||!t.upload_url)throw new Error("Invalid upload response: missing upload URL");if("string"==typeof t.upload_url)s={url:t.upload_url,method:"PUT",fields:null,headers:{}};else{if(!t.upload_url||"object"!=typeof t.upload_url||!t.upload_url.upload_url)throw new Error(`Invalid upload response: unrecognised upload_url format. Server returned: ${JSON.stringify(t.upload_url)}`);s={url:t.upload_url.upload_url,method:t.upload_url.method||"POST",fields:t.upload_url.fields||null,headers:t.upload_url.headers||{}}}try{a=await this._performUpload(s)}catch(e){throw new Error(`File upload failed: ${e.message}`)}if(this.cancelled)throw new Error("Upload cancelled");try{await this._completeUpload()}catch(e){console.warn("Failed to mark upload as completed:",e)}return this._onComplete(this.fileModel),this.fileModel}catch(e){throw"Upload cancelled"!==e.message&&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 e=t.data.error||"Upload initiation failed";throw new Error(e)}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){if("Network Error"===e.message||"TypeError"===e.name)throw new Error("Network error during upload initiation. Please check your connection.");throw e}}async _performUpload(e){return new Promise((t,s)=>{if(!(this.options.file instanceof File))return void s(new Error("Only single File objects are supported"));const{url:a,method:o,fields:i,headers:l}=e,r="POST"===o&&null!==i,n=new XMLHttpRequest;this.uploadRequest=n,n.upload.onprogress=e=>{this.cancelled||this._onProgress({progress:e.loaded/e.total,loaded:e.loaded,total:e.total,percentage:Math.round(e.loaded/e.total*100)})},n.onload=()=>{n.status>=200&&n.status<300?t({data:n.response,status:n.status,statusText:n.statusText,xhr:n}):s(new Error(`Upload failed: ${n.status} ${n.statusText}`))},n.onerror=()=>s(new Error("Upload failed: Network error")),n.ontimeout=()=>s(new Error("Upload timed out — file may be too large or connection too slow")),n.onabort=()=>s(new Error("Upload cancelled"));let p=a;a.startsWith("/")&&!a.startsWith("/api/")&&(p="/api"+a);const d=this.fileModel.rest.buildUrl(p);if(n.open(o,d),n.timeout=3e4,r){for(const[t,s]of Object.entries(l||{}))"content-type"!==t.toLowerCase()&&n.setRequestHeader(t,s);const e=new FormData;for(const[t,s]of Object.entries(i))e.append(t,s);e.append("file",this.options.file),n.send(e)}else{n.setRequestHeader("Content-Type",this.options.file.type);for(const[e,t]of Object.entries(l||{}))"content-type"!==e.toLowerCase()&&n.setRequestHeader(e,t);n.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){if("Network Error"===e.message||"TypeError"===e.name)throw new Error("Network error during upload completion. The file may have uploaded successfully.");throw e}}_onProgress(e){this.progressToast&&this.progressToast.updateProgress&&this.progressToast.updateProgress(e),"function"==typeof this.options.onProgress&&this.options.onProgress(e)}_onComplete(e){this.progressView&&this.progressView.markCompleted("Upload completed successfully!"),this.progressToast&&setTimeout(()=>{try{this.progressToast&&"function"==typeof this.progressToast.hide&&this.progressToast.hide()}catch(e){console.warn("Error hiding progress toast:",e)}},2e3),"function"==typeof this.options.onComplete&&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}`),"function"==typeof this.options.onError&&this.options.onError(e)}_showProgressToast(){this.progressView=new ProgressView({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&&(this.cancelled=!0,this.uploadRequest&&"function"==typeof this.uploadRequest.abort&&this.uploadRequest.abort(),this.progressView&&this.progressView.markCancelled(),this.progressToast&&setTimeout(()=>{try{this.progressToast&&"function"==typeof this.progressToast.hide&&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 FileManager extends e{constructor(e={}){super(e,{endpoint:"/api/fileman/manager"})}}class FileManagerList extends t{constructor(e={}){super({ModelClass:FileManager,endpoint:"/api/fileman/manager",size:10,...e})}}const r={create:{title:"Add Storage Backend",fields:[{name:"name",type:"text",label:"Display Name",placeholder:"Enter Display Name",cols:12},{name:"use",type:"text",label:"Use",placeholder:"Enter User or Leave Blank",cols:12},{name:"backend_url",type:"text",label:"Backend URL",required:!0,value:"s3://BUCKET_NAME/OPTION_FOLDER",placeholder:"s3://bucket_name/optional folder",help:"Format: service://path. Valid services: s3",cols:12},{name:"aws_region",type:"select",label:"AWS Region (optional)",value:"us-east-1",options:[{value:"",text:"System Default"},{value:"us-east-1",text:"US East (N. Virginia)"},{value:"us-east-2",text:"US East (Ohio)"},{value:"us-west-1",text:"US West (N. California)"},{value:"us-west-2",text:"US West (Oregon)"},{value:"ca-central-1",text:"Canada (Central)"},{value:"eu-west-1",text:"Europe (Ireland)"},{value:"eu-west-2",text:"Europe (London)"},{value:"eu-west-3",text:"Europe (Paris)"},{value:"eu-central-1",text:"Europe (Frankfurt)"},{value:"eu-north-1",text:"Europe (Stockholm)"},{value:"eu-south-1",text:"Europe (Milan)"},{value:"ap-southeast-2",text:"Asia Pacific (Sydney)"}],columns:12,help:"Optional. Defaults to project AWS_REGION if omitted."},{name:"aws_key",type:"text",label:"AWS Key (optional)",placeholder:"enter your AWS Key with S3 permissions",columns:12,help:"Optional, AWS Key with S3 permissions"},{name:"aws_secret",type:"text",label:"AWS Secret (optional)",placeholder:"enter your AWS Secret with S3 permissions",columns:12,help:"Optional, AWS Secret with S3 permissions"},{name:"is_default",type:"switch",label:"Is Default",cols:6},{name:"is_active",type:"switch",label:"Is Active",default:!0,cols:6}]},edit:{title:"Edit Storage Backend",fields:[{name:"name",type:"text",label:"Display Name",placeholder:"Enter Display Name",cols:12},{name:"use",type:"text",label:"Use",placeholder:"Enter User or Leave Blank",cols:12},{name:"backend_url",type:"text",label:"Backend URL",required:!0,placeholder:"s3://bucket_name/optional folder",help:"Format: service://path. Valid services: s3",cols:12},{name:"allowed_origins",type:"text",label:"Domains Who Can Upload",cols:12},{name:"is_default",type:"switch",label:"Is Default",cols:6},{name:"is_active",type:"switch",label:"Is Active",default:!0,cols:6},{name:"is_public",type:"switch",label:"Is Public",default:!0,cols:6}]},owners:{fields:[{type:"collection",name:"group",label:"Group (Owner)",Collection:a,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300},{type:"collection",name:"user",label:"User (Owner)",Collection:o,labelField:"display_name",valueField:"id",maxItems:10,placeholder:"Search users...",emptyFetch:!1,debounceMs:300}]},credentials:{fields:[{name:"aws_region",type:"select",label:"AWS Region (optional)",value:"us-east-1",options:[{value:"",text:"System Default"},{value:"us-east-1",text:"US East (N. Virginia)"},{value:"us-east-2",text:"US East (Ohio)"},{value:"us-west-1",text:"US West (N. California)"},{value:"us-west-2",text:"US West (Oregon)"},{value:"ca-central-1",text:"Canada (Central)"},{value:"eu-west-1",text:"Europe (Ireland)"},{value:"eu-west-2",text:"Europe (London)"},{value:"eu-west-3",text:"Europe (Paris)"},{value:"eu-central-1",text:"Europe (Frankfurt)"},{value:"eu-north-1",text:"Europe (Stockholm)"},{value:"eu-south-1",text:"Europe (Milan)"},{value:"ap-southeast-2",text:"Asia Pacific (Sydney)"}],columns:12,help:"Optional. Defaults to project AWS_REGION if omitted."},{name:"aws_key",type:"text",label:"AWS Key (optional)",placeholder:"enter your AWS Key with S3 permissions",columns:12,help:"Optional, AWS Key with S3 permissions"},{name:"aws_secret",type:"text",label:"AWS Secret (optional)",placeholder:"enter your AWS Secret with S3 permissions",columns:12,help:"Optional, AWS Secret with S3 permissions"}]}};let n=class extends e{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return"image"===this.get("category")}upload(e={}){return new FileUpload(this,e)}};class FileList extends t{constructor(e={}){super({ModelClass:n,endpoint:"/api/fileman/file",size:10,...e})}}const p={create:{title:"Add File",fields:[]},edit:{title:"Edit File Backend",fields:[]}},d=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,File:n,FileForms:p,FileList:FileList,FileManager:FileManager,FileManagerForms:r,FileManagerList:FileManagerList},Symbol.toStringTag,{value:"Module"}));export{n as F,ProgressView as P,r as a,FileManagerList as b,p as c,FileList as d,FileManager as e,FileUpload as f,d as g};
2
- //# sourceMappingURL=Files-C-ChBvr5.js.map
@@ -1,2 +0,0 @@
1
- "use strict";const e=require("./Collection-CmjTsmrP.js"),t=require("./User-BnlvMG5J.js"),s=require("./Rest-B1eUyLX5.js");class ProgressView extends s.View{constructor(e={}){super({template:"progress-view-template",...e}),this.filename=e.filename||"Unknown file",this.filesize=e.filesize||0,this.filesizeFormatted=s.dataFormatter.pipe(this.filesize,"filesize"),this.progress=0,this.percentage=0,this.loaded=0,this.total=this.filesize,this.loadedFormatted="0 B",this.totalFormatted=this.filesizeFormatted,this.status="Starting upload...",this.showCancel=!1!==e.showCancel,this.onCancel=e.onCancel||null,this.cancelled=!1,this.completed=!1}getTemplate(){return'\n <div class="progress-view">\n <div class="d-flex justify-content-between align-items-start mb-2">\n <div class="flex-grow-1 min-width-0">\n <div class="fw-medium text-truncate" title="{{filename}}">\n <i class="bi bi-file-earmark me-1"></i>\n {{filename}}\n </div>\n <small class="text-muted">{{status}}</small>\n </div>\n {{#showCancel}}\n <button type="button" \n class="btn btn-sm btn-outline-secondary ms-2" \n data-action="cancel"\n {{#cancelled}}disabled{{/cancelled}}>\n <i class="bi bi-x"></i>\n </button>\n {{/showCancel}}\n </div>\n \n <div class="progress mb-2" style="height: 8px;">\n <div class="progress-bar" \n role="progressbar" \n style="width: {{percentage}}%"\n aria-valuenow="{{percentage}}" \n aria-valuemin="0" \n aria-valuemax="100">\n </div>\n </div>\n \n <div class="d-flex justify-content-between">\n <small class="text-muted">\n {{loadedFormatted}} / {{totalFormatted}}\n </small>\n <small class="text-muted">\n {{percentage}}%\n </small>\n </div>\n </div>\n '}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=s.dataFormatter.pipe(this.loaded,"filesize"),this.totalFormatted=s.dataFormatter.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"),"function"==typeof this.onCancel))try{await this.onCancel()}catch(o){console.error("Error in cancel callback:",o)}}setFilename(e){this.filename=e,this.render()}setFilesize(e){this.filesize=e,this.filesizeFormatted=s.dataFormatter.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 FileUpload{constructor(e,s={}){if(this.fileModel=e,this.options={file:null,name:null,group:null,description:null,onProgress:null,onComplete:null,onError:null,showToast:!0,...s},!(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 t.ToastService),this.promise=this._startUpload()}async _startUpload(){try{let t,s,o;this.options.showToast&&this._showProgressToast();try{t=await this._initiateUpload()}catch(e){throw new Error(`Failed to initiate upload: ${e.message}`)}if(this.cancelled)throw new Error("Upload cancelled");if(!t||!t.upload_url)throw new Error("Invalid upload response: missing upload URL");if("string"==typeof t.upload_url)s={url:t.upload_url,method:"PUT",fields:null,headers:{}};else{if(!t.upload_url||"object"!=typeof t.upload_url||!t.upload_url.upload_url)throw new Error(`Invalid upload response: unrecognised upload_url format. Server returned: ${JSON.stringify(t.upload_url)}`);s={url:t.upload_url.upload_url,method:t.upload_url.method||"POST",fields:t.upload_url.fields||null,headers:t.upload_url.headers||{}}}try{o=await this._performUpload(s)}catch(e){throw new Error(`File upload failed: ${e.message}`)}if(this.cancelled)throw new Error("Upload cancelled");try{await this._completeUpload()}catch(e){console.warn("Failed to mark upload as completed:",e)}return this._onComplete(this.fileModel),this.fileModel}catch(e){throw"Upload cancelled"!==e.message&&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 e=t.data.error||"Upload initiation failed";throw new Error(e)}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){if("Network Error"===e.message||"TypeError"===e.name)throw new Error("Network error during upload initiation. Please check your connection.");throw e}}async _performUpload(e){return new Promise((t,s)=>{if(!(this.options.file instanceof File))return void s(new Error("Only single File objects are supported"));const{url:o,method:a,fields:i,headers:l}=e,r="POST"===a&&null!==i,n=new XMLHttpRequest;this.uploadRequest=n,n.upload.onprogress=e=>{this.cancelled||this._onProgress({progress:e.loaded/e.total,loaded:e.loaded,total:e.total,percentage:Math.round(e.loaded/e.total*100)})},n.onload=()=>{n.status>=200&&n.status<300?t({data:n.response,status:n.status,statusText:n.statusText,xhr:n}):s(new Error(`Upload failed: ${n.status} ${n.statusText}`))},n.onerror=()=>s(new Error("Upload failed: Network error")),n.ontimeout=()=>s(new Error("Upload timed out — file may be too large or connection too slow")),n.onabort=()=>s(new Error("Upload cancelled"));let p=o;o.startsWith("/")&&!o.startsWith("/api/")&&(p="/api"+o);const d=this.fileModel.rest.buildUrl(p);if(n.open(a,d),n.timeout=3e4,r){for(const[t,s]of Object.entries(l||{}))"content-type"!==t.toLowerCase()&&n.setRequestHeader(t,s);const e=new FormData;for(const[t,s]of Object.entries(i))e.append(t,s);e.append("file",this.options.file),n.send(e)}else{n.setRequestHeader("Content-Type",this.options.file.type);for(const[e,t]of Object.entries(l||{}))"content-type"!==e.toLowerCase()&&n.setRequestHeader(e,t);n.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){if("Network Error"===e.message||"TypeError"===e.name)throw new Error("Network error during upload completion. The file may have uploaded successfully.");throw e}}_onProgress(e){this.progressToast&&this.progressToast.updateProgress&&this.progressToast.updateProgress(e),"function"==typeof this.options.onProgress&&this.options.onProgress(e)}_onComplete(e){this.progressView&&this.progressView.markCompleted("Upload completed successfully!"),this.progressToast&&setTimeout(()=>{try{this.progressToast&&"function"==typeof this.progressToast.hide&&this.progressToast.hide()}catch(e){console.warn("Error hiding progress toast:",e)}},2e3),"function"==typeof this.options.onComplete&&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}`),"function"==typeof this.options.onError&&this.options.onError(e)}_showProgressToast(){this.progressView=new ProgressView({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&&(this.cancelled=!0,this.uploadRequest&&"function"==typeof this.uploadRequest.abort&&this.uploadRequest.abort(),this.progressView&&this.progressView.markCancelled(),this.progressToast&&setTimeout(()=>{try{this.progressToast&&"function"==typeof this.progressToast.hide&&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 FileManager extends e.Model{constructor(e={}){super(e,{endpoint:"/api/fileman/manager"})}}class FileManagerList extends e.Collection{constructor(e={}){super({ModelClass:FileManager,endpoint:"/api/fileman/manager",size:10,...e})}}const o={create:{title:"Add Storage Backend",fields:[{name:"name",type:"text",label:"Display Name",placeholder:"Enter Display Name",cols:12},{name:"use",type:"text",label:"Use",placeholder:"Enter User or Leave Blank",cols:12},{name:"backend_url",type:"text",label:"Backend URL",required:!0,value:"s3://BUCKET_NAME/OPTION_FOLDER",placeholder:"s3://bucket_name/optional folder",help:"Format: service://path. Valid services: s3",cols:12},{name:"aws_region",type:"select",label:"AWS Region (optional)",value:"us-east-1",options:[{value:"",text:"System Default"},{value:"us-east-1",text:"US East (N. Virginia)"},{value:"us-east-2",text:"US East (Ohio)"},{value:"us-west-1",text:"US West (N. California)"},{value:"us-west-2",text:"US West (Oregon)"},{value:"ca-central-1",text:"Canada (Central)"},{value:"eu-west-1",text:"Europe (Ireland)"},{value:"eu-west-2",text:"Europe (London)"},{value:"eu-west-3",text:"Europe (Paris)"},{value:"eu-central-1",text:"Europe (Frankfurt)"},{value:"eu-north-1",text:"Europe (Stockholm)"},{value:"eu-south-1",text:"Europe (Milan)"},{value:"ap-southeast-2",text:"Asia Pacific (Sydney)"}],columns:12,help:"Optional. Defaults to project AWS_REGION if omitted."},{name:"aws_key",type:"text",label:"AWS Key (optional)",placeholder:"enter your AWS Key with S3 permissions",columns:12,help:"Optional, AWS Key with S3 permissions"},{name:"aws_secret",type:"text",label:"AWS Secret (optional)",placeholder:"enter your AWS Secret with S3 permissions",columns:12,help:"Optional, AWS Secret with S3 permissions"},{name:"is_default",type:"switch",label:"Is Default",cols:6},{name:"is_active",type:"switch",label:"Is Active",default:!0,cols:6}]},edit:{title:"Edit Storage Backend",fields:[{name:"name",type:"text",label:"Display Name",placeholder:"Enter Display Name",cols:12},{name:"use",type:"text",label:"Use",placeholder:"Enter User or Leave Blank",cols:12},{name:"backend_url",type:"text",label:"Backend URL",required:!0,placeholder:"s3://bucket_name/optional folder",help:"Format: service://path. Valid services: s3",cols:12},{name:"allowed_origins",type:"text",label:"Domains Who Can Upload",cols:12},{name:"is_default",type:"switch",label:"Is Default",cols:6},{name:"is_active",type:"switch",label:"Is Active",default:!0,cols:6},{name:"is_public",type:"switch",label:"Is Public",default:!0,cols:6}]},owners:{fields:[{type:"collection",name:"group",label:"Group (Owner)",Collection:t.GroupList,labelField:"name",valueField:"id",maxItems:10,placeholder:"Search groups...",emptyFetch:!1,debounceMs:300},{type:"collection",name:"user",label:"User (Owner)",Collection:t.UserList,labelField:"display_name",valueField:"id",maxItems:10,placeholder:"Search users...",emptyFetch:!1,debounceMs:300}]},credentials:{fields:[{name:"aws_region",type:"select",label:"AWS Region (optional)",value:"us-east-1",options:[{value:"",text:"System Default"},{value:"us-east-1",text:"US East (N. Virginia)"},{value:"us-east-2",text:"US East (Ohio)"},{value:"us-west-1",text:"US West (N. California)"},{value:"us-west-2",text:"US West (Oregon)"},{value:"ca-central-1",text:"Canada (Central)"},{value:"eu-west-1",text:"Europe (Ireland)"},{value:"eu-west-2",text:"Europe (London)"},{value:"eu-west-3",text:"Europe (Paris)"},{value:"eu-central-1",text:"Europe (Frankfurt)"},{value:"eu-north-1",text:"Europe (Stockholm)"},{value:"eu-south-1",text:"Europe (Milan)"},{value:"ap-southeast-2",text:"Asia Pacific (Sydney)"}],columns:12,help:"Optional. Defaults to project AWS_REGION if omitted."},{name:"aws_key",type:"text",label:"AWS Key (optional)",placeholder:"enter your AWS Key with S3 permissions",columns:12,help:"Optional, AWS Key with S3 permissions"},{name:"aws_secret",type:"text",label:"AWS Secret (optional)",placeholder:"enter your AWS Secret with S3 permissions",columns:12,help:"Optional, AWS Secret with S3 permissions"}]}};let a=class extends e.Model{constructor(e={}){super(e,{endpoint:"/api/fileman/file"})}isImage(){return"image"===this.get("category")}upload(e={}){return new FileUpload(this,e)}};class FileList extends e.Collection{constructor(e={}){super({ModelClass:a,endpoint:"/api/fileman/file",size:10,...e})}}const i={create:{title:"Add File",fields:[]},edit:{title:"Edit File Backend",fields:[]}},l=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,File:a,FileForms:i,FileList:FileList,FileManager:FileManager,FileManagerForms:o,FileManagerList:FileManagerList},Symbol.toStringTag,{value:"Module"}));exports.File=a,exports.FileForms=i,exports.FileList=FileList,exports.FileManager=FileManager,exports.FileManagerForms=o,exports.FileManagerList=FileManagerList,exports.FileUpload=FileUpload,exports.Files=l,exports.ProgressView=ProgressView;
2
- //# sourceMappingURL=Files-DNbHDy43.js.map