UNPKG

@progress/kendo-vue-upload

Version:
490 lines (489 loc) 13.8 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import { defineComponent as E, createVNode as D } from "vue"; import { validatePackage as w, templateRendering as A, getListeners as _, getTabIndex as B } from "@progress/kendo-vue-common"; import { UploadFileStatus as u } from "./interfaces/UploadFileStatus.mjs"; import { UploadNavigation as N } from "./UploadNavigation.mjs"; import m from "axios"; import F from "./utils/utils.mjs"; import r from "./utils/stateUtils.mjs"; import d from "./utils/connectionUtils.mjs"; import O from "./utils/validationUtils.mjs"; import { packageMetadata as x } from "./package-metadata.mjs"; const Q = /* @__PURE__ */ E({ name: "KendoVueUpload", props: { autoUpload: { type: Boolean, default: !0 }, batch: { type: Boolean, default: !1 }, withCredentials: { type: Boolean, default: !0 }, saveField: { type: String, default: function() { return "files"; } }, saveHeaders: { type: [String, Function, Object], default: function() { return {}; } }, saveMethod: { type: String, default: function() { return "POST"; } }, saveUrl: { type: [String, Function], default: function() { return ""; } }, responseType: { type: String, default: function() { return "json"; } }, removeField: { type: String, default: function() { return "fileNames"; } }, removeHeaders: { type: [String, Function, Object], default: function() { return {}; } }, removeMethod: { type: String, default: function() { return "POST"; } }, removeUrl: { type: [String, Function], default: function() { return ""; } }, multiple: { type: Boolean, default: !0 }, disabled: { type: Boolean, default: !1 }, showFileList: { type: Boolean, default: !0 }, showActionButtons: { type: Boolean, default: !0 }, actionsLayout: { type: String, default: function() { return "end"; } }, tabIndex: Number, accept: String, list: [String, Function, Object], restrictions: { type: Object, default: function() { return { allowedExtensions: [], maxFileSize: 0, minFileSize: 0 }; } }, validateFile: Function, files: Array, defaultFiles: Array }, emits: { add: null, beforeremove: null, beforeupload: null, cancel: null, statuschange: null, progress: null, remove: null }, created() { this._httpSubscriptions = {}, w(x), this.$props.defaultFiles && (this.currentFiles = this.$props.defaultFiles); }, data() { return { currentFiles: [] }; }, computed: { computedAsync() { const { autoUpload: s, batch: e, removeField: t, removeHeaders: i, removeMethod: n, removeUrl: o, responseType: a, saveField: p, saveHeaders: h, saveMethod: c, saveUrl: l, withCredentials: v } = this.$props; return { autoUpload: s, batch: e, removeField: t, removeHeaders: i, removeMethod: n, removeUrl: o, responseType: a, saveField: p, saveHeaders: h, saveMethod: c, saveUrl: l, withCredentials: v }; }, computedFiles() { return (this.isControlled ? this.$props.files : this.currentFiles) || []; }, isControlled() { return !this.$props.defaultFiles; }, isCustomSave() { return this.$props.saveUrl && typeof this.$props.saveUrl == "function"; }, isCustomRemove() { return this.$props.removeUrl && typeof this.$props.removeUrl == "function"; }, fileStateCopy() { return r.copyState(this.computedFiles); }, actionElement() { if (this._uploadNavigation) return this._uploadNavigation.actionElement; } }, mounted() { this._uploadNavigation = this.uploadNavigationRef; }, methods: { focus() { this._uploadNavigation && this._uploadNavigation.focus(); }, uploadFiles(s) { const e = this.computedAsync; r.setFilesStatus(s, u.Uploading), r.groupForEach(s, (t, i) => { const n = d.cloneRequestHeaders(e.saveHeaders || {}), a = { target: this, files: t, headers: n, additionalData: {} }; this.$emit("beforeupload", a); const p = d.populateRequestOptions(a.headers, this.computedAsync), h = d.populateUploadFormData(t, e.saveField, a.additionalData); if (this.isCustomSave) this.$props.saveUrl(t, { formData: h, requestOptions: p }, this.onUploadProgress).then((c) => this.onUploadSuccess(c.uid)).catch((c) => this.onUploadError(c.uid)); else { const c = m.CancelToken.source(); this._httpSubscriptions[i] = c, m({ method: e.saveMethod, url: e.saveUrl, data: h, cancelToken: c.token, ...p, onUploadProgress: (l) => this.onUploadProgress(i, l) }).then((l) => this.onUploadSuccess(i, l)).catch((l) => this.onUploadError(i, l)); } }); }, removeFiles(s) { const e = this.computedAsync; r.groupForEach(s, (t, i) => { const n = d.cloneRequestHeaders(e.removeHeaders || {}), a = { target: this, files: t, headers: n, additionalData: {} }; this.$emit("beforeremove", a); const p = t.map((l) => l.name), h = d.populateRequestOptions(a.headers, this.computedAsync), c = d.populateRemoveFormData(p, e.removeField, a.additionalData); this.isCustomRemove ? this.$props.removeUrl(t, { formData: c, requestOptions: h }).then((l) => this.onRemoveSuccess(l.uid)).catch((l) => this.onRemoveError(l.uid)) : m({ method: e.removeMethod, url: e.removeUrl, data: c, ...h }).then((l) => this.onRemoveSuccess(i, l)).catch((l) => this.onRemoveError(i, l)); }); }, onUpload() { const s = this.fileStateCopy, e = r.groupFilesByUid(s), t = r.filesForUpload(e); this.uploadFiles(t); const i = () => { const n = { target: this, newState: s, affectedFiles: r.flatFileGroup(t) }; this.$emit("statuschange", n); }; this.isControlled || (this.currentFiles = s), i(); }, onAdd(s) { let e = F.getAllFileInfo(s), t; if (e = F.assignGuidToFiles(e, this.computedAsync.batch), O.validateFiles(e, this.$props.restrictions, this.validateFile), this.$props.multiple ? t = this.fileStateCopy : t = [], r.addMany(e, t), this.computedAsync.autoUpload) { const n = r.groupFilesByUid(t); this.uploadFiles(r.filesForUpload(n)); } const i = () => { const n = { target: this, newState: t, affectedFiles: e }; this.$emit("add", n); }; this.isControlled || (this.currentFiles = t), i(); }, onUploadProgress(s, e) { const t = e.total ? Math.round(100 * e.loaded / e.total) : 0, i = this.fileStateCopy, n = i.filter((a) => a.uid === s); if (!n.length) return; n.forEach((a) => { a.progress = t; }); const o = () => { const a = { target: this, newState: i, affectedFiles: n }; this.$emit("progress", a); }; this.isControlled || (this.currentFiles = i), o(); }, onUploadSuccess(s, e) { const t = this.fileStateCopy, i = t.filter((o) => o.uid === s); i.forEach((o) => { o.status = u.Uploaded; }), delete this._httpSubscriptions[s]; const n = () => { const o = { target: this, newState: t, affectedFiles: i, response: e ? d.convertAxiosResponse(e) : void 0 }; this.$emit("statuschange", o); }; this.isControlled || (this.currentFiles = t), n(); }, onUploadError(s, e) { const t = this.fileStateCopy, i = t.filter((o) => o.uid === s); if (i.forEach((o) => { o.status = u.UploadFailed; }), delete this._httpSubscriptions[s], !i.length) return; const n = () => { const o = { target: this, newState: t, affectedFiles: i, response: e ? d.convertAxiosResponse(e) : void 0 }; this.$emit("statuschange", o); }; this.isControlled || (this.currentFiles = t), n(); }, onRemove(s) { const e = this.fileStateCopy, t = e.filter((o) => o.uid === s), i = e.filter((o) => o.uid !== s), n = [u.Uploaded, u.Initial, u.RemoveFailed]; if (t[0] && n.indexOf(t[0].status) > -1) { const o = { [s]: t }; r.setFilesStatus(o, u.Removing), this.removeFiles(o); const a = () => { const p = { target: this, newState: e, affectedFiles: t }; this.$emit("statuschange", p); }; this.isControlled || (this.currentFiles = e), a(); } else { const o = () => { const a = { target: this, newState: i, affectedFiles: t }; this.$emit("remove", a); }; this.isControlled || (this.currentFiles = i), o(); } }, onRemoveSuccess(s, e) { const t = this.fileStateCopy, i = t.filter((a) => a.uid === s), n = t.filter((a) => a.uid !== s), o = () => { const a = { target: this, newState: n, affectedFiles: i, response: e ? d.convertAxiosResponse(e) : void 0 }; this.$emit("remove", a); }; this.isControlled || (this.currentFiles = n), o(); }, onRemoveError(s, e) { const t = this.fileStateCopy, i = t.filter((o) => o.uid === s); i.forEach((o) => { o.status = u.RemoveFailed; }); const n = () => { const o = { target: this, newState: t, affectedFiles: i, response: e ? d.convertAxiosResponse(e) : void 0 }; this.$emit("statuschange", o); }; this.isControlled || (this.currentFiles = t), n(); }, onRetry(s) { const e = this.fileStateCopy, t = r.groupFilesByUid(e.filter((n) => n.uid === s)); r.setFilesStatus(t, u.Uploading), this.uploadFiles(t); const i = () => { const n = { target: this, newState: e, affectedFiles: r.flatFileGroup(t) }; this.$emit("statuschange", n); }; this.isControlled || (this.currentFiles = e), i(); }, onCancel(s) { const e = this.fileStateCopy, t = e.filter((a) => a.uid !== s), i = e.filter((a) => a.uid === s); this._httpSubscriptions[s] && (this._httpSubscriptions[s].cancel(), delete this._httpSubscriptions[s]); const n = { target: this, uid: s }; this.$emit("cancel", n); const o = () => { const a = { target: this, newState: t, affectedFiles: i }; this.$emit("remove", a); }; this.isControlled || (this.currentFiles = e), o(); }, onClear() { if (!this.computedFiles.length) return; Object.keys(this._httpSubscriptions).forEach((e) => { this._httpSubscriptions[e].cancel(); }), this._httpSubscriptions = {}; const s = () => { const e = { target: this, newState: [], affectedFiles: this.fileStateCopy }; this.$emit("remove", e); }; this.isControlled || (this.currentFiles = []), s(); } }, render() { const { showFileList: s, autoUpload: e, showActionButtons: t, actionsLayout: i, tabIndex: n, disabled: o, batch: a, withCredentials: p, saveField: h, saveHeaders: c, saveMethod: l, saveUrl: v, responseType: T, removeField: M, removeHeaders: H, removeMethod: k, removeUrl: P, multiple: g, accept: S, restrictions: y, files: U, defaultFiles: C } = this.$props, R = A.call(this, this.$props.list, _.call(this)), f = r.groupFilesByUid(this.computedFiles), b = r.filesForUpload(f); return D(N, { groupedFiles: f, className: this.$props.className, showFileList: s && !!Object.keys(f).length, showActionButtons: t && !e && !!Object.keys(b).length, actionsLayout: i, disabled: o, onAdd: this.onAdd, onRemove: this.onRemove, onClear: this.onClear, onUpload: this.onUpload, onRetry: this.onRetry, onCancel: this.onCancel, tabIndex: B(n, o), ref: ($) => { this.uploadNavigationRef = $; }, multiple: g, accept: S, list: R, restrictions: y, files: U, defaultFiles: C, async: this.computedAsync }, null); } }); export { Q as Upload };