Browse Source

feat(nc-gui): selectedImages & bulk download

pull/4931/head
Wing-Kam Wong 2 years ago
parent
commit
57f9180105
  1. 17
      packages/nc-gui/components/cell/attachment/Modal.vue
  2. 19
      packages/nc-gui/components/cell/attachment/utils.ts

17
packages/nc-gui/components/cell/attachment/Modal.vue

@ -20,6 +20,8 @@ const {
downloadFile, downloadFile,
updateModelValue, updateModelValue,
selectedImage, selectedImage,
selectedImages,
bulkDownloadFiles,
} = useAttachmentCell()! } = useAttachmentCell()!
// todo: replace placeholder var // todo: replace placeholder var
@ -97,6 +99,10 @@ function onRemoveFileClick(title: any, i: number) {
Viewing Attachments of Viewing Attachments of
<div class="font-semibold underline">{{ column?.title }}</div> <div class="font-semibold underline">{{ column?.title }}</div>
</div> </div>
<div v-if="selectedImages.includes(true)" class="flex flex-1 items-center gap-3 justify-end mr-[30px]">
<a-button type="primary" class="nc-attachment-download-all" @click="bulkDownloadFiles"> Bulk Download </a-button>
</div>
</div> </div>
</template> </template>
@ -115,6 +121,12 @@ function onRemoveFileClick(title: any, i: number) {
<div ref="sortableRef" :class="{ dragging }" class="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6 relative p-6"> <div ref="sortableRef" :class="{ dragging }" class="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6 relative p-6">
<div v-for="(item, i) of visibleItems" :key="`${item.title}-${i}`" class="flex flex-col gap-1"> <div v-for="(item, i) of visibleItems" :key="`${item.title}-${i}`" class="flex flex-col gap-1">
<a-card class="nc-attachment-item group"> <a-card class="nc-attachment-item group">
<a-checkbox
v-model:checked="selectedImages[i]"
class="nc-attachment-checkbox group-hover:(opacity-100)"
:class="{ '!opacity-100': selectedImages[i] }"
/>
<a-tooltip v-if="!readOnly"> <a-tooltip v-if="!readOnly">
<template #title> Remove File </template> <template #title> Remove File </template>
<MdiCloseCircle <MdiCloseCircle
@ -210,6 +222,11 @@ function onRemoveFileClick(title: any, i: number) {
@apply active:(ring border-0 ring-accent); @apply active:(ring border-0 ring-accent);
} }
.nc-attachment-checkbox {
@apply absolute top-2 left-2;
@apply transition-opacity duration-150 ease-in opacity-0;
}
.nc-attachment-remove { .nc-attachment-remove {
@apply absolute top-2 right-2 bg-white; @apply absolute top-2 right-2 bg-white;
@apply hover:(ring ring-red-500); @apply hover:(ring ring-red-500);

19
packages/nc-gui/components/cell/attachment/utils.ts

@ -55,6 +55,8 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
const selectedImage = ref() const selectedImage = ref()
const selectedImages = ref<boolean[]>([])
const { project } = useProject() const { project } = useProject()
const { api, isLoading } = useApi() const { api, isLoading } = useApi()
@ -63,6 +65,13 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
const { t } = useI18n() const { t } = useI18n()
/** our currently visible items, either the locally stored or the ones from db, depending on isPublic & isForm status */
const visibleItems = computed<any[]>(() => {
const items = isPublic.value && isForm.value ? storedFiles.value : attachments.value
selectedImages.value = Array.from({ length: items.length }, () => false)
return items
})
/** remove a file from our stored attachments (either locally stored or saved ones) */ /** remove a file from our stored attachments (either locally stored or saved ones) */
function removeFile(i: number) { function removeFile(i: number) {
if (isPublic.value) { if (isPublic.value) {
@ -198,6 +207,11 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
} }
} }
/** bulk download selected files */
async function bulkDownloadFiles() {
await Promise.all(selectedImages.value.map(async (v, i) => v && (await downloadFile(visibleItems.value[i]))))
}
/** download a file */ /** download a file */
async function downloadFile(item: Record<string, any>) { async function downloadFile(item: Record<string, any>) {
;(await import('file-saver')).saveAs(item.url || item.data, item.title) ;(await import('file-saver')).saveAs(item.url || item.data, item.title)
@ -218,9 +232,6 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
} }
} }
/** our currently visible items, either the locally stored or the ones from db, depending on isPublic & isForm status */
const visibleItems = computed<any[]>(() => (isPublic.value && isForm.value ? storedFiles.value : attachments.value))
watch(files, (nextFiles) => nextFiles && onFileSelect(nextFiles)) watch(files, (nextFiles) => nextFiles && onFileSelect(nextFiles))
return { return {
@ -243,7 +254,9 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
downloadFile, downloadFile,
updateModelValue, updateModelValue,
selectedImage, selectedImage,
selectedImages,
storedFiles, storedFiles,
bulkDownloadFiles,
} }
}, },
'useAttachmentCell', 'useAttachmentCell',

Loading…
Cancel
Save