@opensig/opendesign
Version:
394 lines (393 loc) • 14.2 kB
JavaScript
import { defineComponent, useSlots, ref, watch, inject, computed, useTemplateRef, createElementBlock, openBlock, normalizeClass, createVNode, createCommentVNode, createElementVNode, createSlots, renderList, unref, withCtx, renderSlot, normalizeProps, guardReactiveProps, Fragment, createBlock, mergeProps, createTextVNode, toDisplayString } from "vue";
import { uploadProps } from "./types.mjs";
import { isArray, isFunction } from "../_utils/is.mjs";
import { filterSlots } from "../_utils/vue-utils.mjs";
import _sfc_main$3 from "./UploadItem.vue.mjs";
import slot from "./slot.mjs";
import { doUploadFileList, isPictureType, generateImageDataUrl, doUploadFile } from "./util.mjs";
import _sfc_main$2 from "./UploadSelect.vue.mjs";
import { IconAdd } from "../_utils/icons.mjs";
import _sfc_main$1 from "./InputSelect.vue.mjs";
import { formItemInjectKey } from "../form/provide.mjs";
import { useI18n } from "../locale/index.mjs";
import { log } from "../_utils/log.mjs";
const _hoisted_1 = {
key: 0,
class: "o-upload-select-wrap"
};
const _hoisted_2 = {
key: 0,
class: "o-upload-select-extra"
};
const _hoisted_3 = { class: "o-upload-card-label" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "OUpload",
props: uploadProps,
emits: ["progress", "success", "error", "change", "select", "update:modelValue", "itemRemove", "itemRetry", "itemReplace", "itemPreview", "itemClick", "download"],
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const slots = useSlots();
const emits = __emit;
const emitUpdateValue = (value) => {
emits("update:modelValue", value);
};
const { t } = useI18n();
const fileList = ref(props.modelValue ?? props.defaultFileList ?? []);
watch(
() => props.modelValue,
(v) => {
if (fileList.value === v) {
return;
}
if (isArray(v)) {
fileList.value = [...v];
} else {
fileList.value = [];
}
}
);
const formItemInjection = inject(formItemInjectKey, null);
let fileId = 1;
const uploadOption = computed(() => {
return {
uploadRequest: props.uploadRequest,
onBeforeUpload: props.onBeforeUpload,
onProgress: (file) => {
emits("progress", file);
},
onSuccess: (file) => {
emits("success", file);
emitUpdateValue(fileList.value);
emits("change", fileList.value);
},
onError: (file) => {
emits("error", file);
emitUpdateValue(fileList.value);
emits("change", fileList.value);
}
};
});
const selectRef = ref(null);
let replaceId = "";
const uploadAll = () => {
return doUploadFileList(fileList.value, uploadOption.value);
};
const afterSelected = (files) => {
var _a, _b, _c, _d, _e, _f, _g;
if (replaceId) {
const idx = fileList.value.findIndex((item) => item.id === replaceId);
if (idx > -1) {
const f = fileList.value[idx];
(_a = f.request) == null ? void 0 : _a.abort();
fileList.value[idx] = files[0];
replaceId = "";
emitUpdateValue(fileList.value);
emits("select", fileList.value);
(_c = formItemInjection == null ? void 0 : (_b = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _c.call(_b);
if (!props.lazyUpload) {
doUploadFile(fileList.value[idx], uploadOption.value);
}
}
} else {
let s = fileList.value.length;
let l = files.length;
if (props.multiple) {
fileList.value = fileList.value.concat(files);
} else {
(_e = (_d = fileList.value[0]) == null ? void 0 : _d.request) == null ? void 0 : _e.abort();
fileList.value = files;
s = 0;
l = 1;
}
emitUpdateValue(fileList.value);
emits("select", fileList.value);
(_g = formItemInjection == null ? void 0 : (_f = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _g.call(_f);
if (!props.lazyUpload) {
doUploadFileList(fileList.value.slice(s, s + l), uploadOption.value);
}
}
};
const onFileSelected = async (files) => {
let list = [];
const isPicture = isPictureType(props.listType);
if (isFunction(props.onAfterSelect)) {
list = await props.onAfterSelect(files);
if (isPicture) {
list.forEach((item) => {
if (!item.imgUrl && item.file) {
item.imgUrl = generateImageDataUrl(item.file);
}
});
}
} else {
list = Array.from(files).map((item) => {
return {
id: `${fileId++}`,
name: item.name,
file: item,
imgUrl: isPicture ? generateImageDataUrl(item) : ""
};
});
}
afterSelected(list);
};
const doRemoveFile = async (file) => {
var _a, _b, _c;
if (isFunction(props.onBeforeRemove)) {
const sure = await props.onBeforeRemove(file);
if (sure === false) {
return false;
}
}
(_a = file.request) == null ? void 0 : _a.abort();
const index = fileList.value.findIndex((item) => item.id === file.id);
fileList.value.splice(index, 1);
(_c = formItemInjection == null ? void 0 : (_b = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _c.call(_b);
emitUpdateValue(fileList.value);
return true;
};
const removeFileByIndex = (index) => {
if (index < 0 && index >= fileList.value.length) {
return;
}
doRemoveFile(fileList.value[index]);
};
const removeById = (id) => {
const index = fileList.value.findIndex((item) => item.id === id);
removeFileByIndex(index);
};
const removeAllFiles = () => {
return new Promise((resolve) => {
Promise.allSettled(fileList.value.map((f) => doRemoveFile(f))).then((res) => {
resolve(res);
fileList.value = [];
emitUpdateValue(fileList.value);
emits("change", fileList.value);
});
});
};
const onRemoveFile = (file, e) => {
doRemoveFile(file).then(() => {
emits("itemRemove", file, e);
emits("change", fileList.value);
});
};
const doRetryUpload = (file, force) => {
var _a, _b;
if (!file.file) {
log.warn("retry file not found!");
return;
}
if (!file.retry && !force) {
return;
}
doUploadFile(file, uploadOption.value);
(_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _b.call(_a);
};
const onFileUploadRetry = (file, e) => {
doRetryUpload(file);
emits("itemRetry", file, e);
};
const doReplaceFile = (file) => {
var _a;
replaceId = file.id;
(_a = selectRef.value) == null ? void 0 : _a.select(false);
};
const replaceByIndex = (index, newFile) => {
var _a, _b, _c;
const file = fileList.value[index];
if (!file) {
log.warn("file not found!");
}
(_a = file.request) == null ? void 0 : _a.abort();
if (newFile) {
fileList.value.splice(index, 1, newFile);
emits("change", fileList.value);
(_c = formItemInjection == null ? void 0 : (_b = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _c.call(_b);
} else {
doReplaceFile(file);
}
};
const replaceById = (id, newFile) => {
const index = fileList.value.findIndex((item) => item.id === id);
replaceByIndex(index, newFile);
};
const onFileReplace = (file, e) => {
var _a, _b;
doReplaceFile(file);
emits("itemReplace", file, e);
(_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _b.call(_a);
};
const doSelect = async () => {
var _a;
if (isFunction(props.beforeSelect)) {
const goon = await props.beforeSelect(fileList.value);
if (goon === false) {
return;
}
}
(_a = selectRef.value) == null ? void 0 : _a.select(props.multiple);
};
const onUploadItemLabelClick = (file, e) => {
emits("itemClick", file, e);
};
const onFilePreview = (file, e) => {
emits("itemPreview", file, e);
};
const uploadItems = useTemplateRef("uploadItems");
const previewItemByIndex = (index) => {
var _a;
const item = (_a = uploadItems.value) == null ? void 0 : _a[index];
item == null ? void 0 : item.preview();
};
const previewItemById = (id) => {
const idx = fileList.value.findIndex((item) => item.id === id);
previewItemByIndex(idx);
};
const onFileDownload = (file, e) => {
if (isFunction(props.downloadFile)) {
if (file.file) {
props.downloadFile(file.file);
}
}
emits("download", file, e);
};
__expose({
upload: uploadAll,
select: doSelect,
retry: doRetryUpload,
replace: doReplaceFile,
replaceById,
replaceByIndex,
removeById,
removeByIndex: removeFileByIndex,
removeAll: removeAllFiles,
previewItemByIndex,
previewItemById
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock(
"div",
{
class: normalizeClass(["o-upload", { "o-upload-draggable": _ctx.draggable }])
},
[
createVNode(_sfc_main$1, {
ref_key: "selectRef",
ref: selectRef,
accept: props.accept,
disabled: props.disabled,
onSelected: onFileSelected
}, null, 8, ["accept", "disabled"]),
["text", "picture"].includes(props.listType) ? (openBlock(), createElementBlock("div", _hoisted_1, [
createVNode(_sfc_main$2, {
disabled: props.disabled,
draggable: props.draggable,
"btn-label": props.btnLabel,
"drag-label": props.dragLabel,
"drag-hover-label": props.dragHoverLabel,
onToSelect: doSelect,
onSelected: onFileSelected
}, createSlots({
_: 2
/* DYNAMIC */
}, [
renderList(unref(filterSlots)(slots, unref(slot).names), (name) => {
return {
name,
fn: withCtx((slotData) => [
renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(slotData)))
])
};
})
]), 1032, ["disabled", "draggable", "btn-label", "drag-label", "drag-hover-label"]),
slots["select-extra"] ? (openBlock(), createElementBlock("div", _hoisted_2, [
renderSlot(_ctx.$slots, "select-extra")
])) : createCommentVNode("v-if", true)
])) : createCommentVNode("v-if", true),
createElementVNode(
"div",
{
class: normalizeClass(["o-upload-list", {
"o-upload-card-list": props.listType === "picture-card"
}])
},
[
(openBlock(true), createElementBlock(
Fragment,
null,
renderList(fileList.value, (item) => {
return openBlock(), createBlock(_sfc_main$3, {
ref_for: true,
ref_key: "uploadItems",
ref: uploadItems,
key: item.id,
file: item,
"list-type": props.listType,
"show-progress": props.showProgress,
draggable: props.draggable,
onRemove: onRemoveFile,
onRetry: onFileUploadRetry,
onReplace: onFileReplace,
onPreview: onFilePreview,
onItemClick: onUploadItemLabelClick,
onDownload: onFileDownload
}, createSlots({
_: 2
/* DYNAMIC */
}, [
renderList(unref(filterSlots)(slots, unref(slot).names), (name) => {
return {
name,
fn: withCtx((slotData) => [
renderSlot(_ctx.$slots, name, mergeProps({ ref_for: true }, slotData))
])
};
})
]), 1032, ["file", "list-type", "show-progress", "draggable"]);
}),
128
/* KEYED_FRAGMENT */
)),
props.listType === "picture-card" ? (openBlock(), createElementBlock(
"div",
{
key: 0,
class: normalizeClass(["o-upload-card-add", {
"is-disabled": props.disabled
}]),
onClick: doSelect
},
[
createElementVNode("div", null, [
renderSlot(_ctx.$slots, "select-add", {}, () => [
createVNode(unref(IconAdd), { class: "o-upload-card-add-icon" }),
createElementVNode("div", _hoisted_3, [
renderSlot(_ctx.$slots, "select-add-label", {}, () => [
createTextVNode(
toDisplayString(props.btnLabel ?? unref(t)("upload.buttonLabel")),
1
/* TEXT */
)
])
])
])
])
],
2
/* CLASS */
)) : createCommentVNode("v-if", true)
],
2
/* CLASS */
)
],
2
/* CLASS */
);
};
}
});
export {
_sfc_main as default
};