Browse Source

chore(gui-v2): move common functions to attachment cell utils file

pull/2972/head
braks 2 years ago
parent
commit
dfa6eab997
  1. 100
      packages/nc-gui-v2/components/cell/attachment/Modal.vue
  2. 9
      packages/nc-gui-v2/components/cell/attachment/index.vue
  3. 15
      packages/nc-gui-v2/components/cell/attachment/utils.ts

100
packages/nc-gui-v2/components/cell/attachment/Modal.vue

@ -1,30 +1,34 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onKeyDown } from '@vueuse/core' import { onKeyDown } from '@vueuse/core'
import FileSaver from 'file-saver'
import { useAttachmentCell } from './utils' import { useAttachmentCell } from './utils'
import { ref, useUIPermission } from '#imports' import { ref, useDropZone, useUIPermission } from '#imports'
import { isImage, openLink } from '~/utils' import { isImage, openLink } from '~/utils'
import MaterialSymbolsAttachFile from '~icons/material-symbols/attach-file' import MaterialSymbolsAttachFile from '~icons/material-symbols/attach-file'
import MdiCloseCircle from '~icons/mdi/close-circle' import MdiCloseCircle from '~icons/mdi/close-circle'
import MdiDownload from '~icons/mdi/download' import MdiDownload from '~icons/mdi/download'
import MaterialSymbolsFileCopyOutline from '~icons/material-symbols/file-copy-outline'
import IcOutlineInsertDriveFile from '~icons/ic/outline-insert-drive-file' import IcOutlineInsertDriveFile from '~icons/ic/outline-insert-drive-file'
const { isUIAllowed } = useUIPermission() const { isUIAllowed } = useUIPermission()
const { open, isLoading, isPublicGrid, isForm, visibleItems, modalVisible, column, FileIcon, removeFile } = useAttachmentCell() const { open, isLoading, isPublicGrid, isForm, visibleItems, modalVisible, column, FileIcon, removeFile, onDrop, downloadFile } =
useAttachmentCell()
// todo: replace placeholder var // todo: replace placeholder var
const isLocked = ref(false) const isLocked = ref(false)
onKeyDown('Escape', () => (modalVisible.value = false)) const dropZoneRef = ref<HTMLDivElement>()
async function downloadFile(item: Record<string, any>) { const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
FileSaver.saveAs(item.url || item.data, item.title)
} onKeyDown('Escape', () => {
modalVisible.value = false
isOverDropZone.value = false
})
</script> </script>
<template> <template>
<a-modal v-model:visible="modalVisible" width="80%" :footer="null"> <a-modal v-model:visible="modalVisible" class="nc-attachment-modal" width="80%" :footer="null">
<template #title> <template #title>
<div class="flex gap-4"> <div class="flex gap-4">
<div <div
@ -43,7 +47,15 @@ async function downloadFile(item: Record<string, any>) {
</div> </div>
</template> </template>
<div class="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6"> <div ref="dropZoneRef" class="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6 relative p-6">
<div
:class="isOverDropZone ? 'opacity-100' : 'opacity-0 pointer-events-none'"
class="transition-all duration-150 ease-in-out ring ring-pink-500 rounded bg-blue-100/75 flex items-center justify-center gap-4 z-99 absolute top-0 bottom-0 left-0 right-0 backdrop-blur-xl"
>
<MaterialSymbolsFileCopyOutline class="text-pink-500" height="35" width="35" />
<div class="text-3xl text-primary">Drop here</div>
</div>
<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-tooltip> <a-tooltip>
@ -59,7 +71,7 @@ async function downloadFile(item: Record<string, any>) {
<a-tooltip placement="bottom"> <a-tooltip placement="bottom">
<template #title> Download file </template> <template #title> Download file </template>
<div class="nc-attachment-download"> <div class="nc-attachment-download group-hover:(opacity-100)">
<MdiDownload @click.stop="downloadFile(item)" /> <MdiDownload @click.stop="downloadFile(item)" />
</div> </div>
</a-tooltip> </a-tooltip>
@ -87,45 +99,51 @@ async function downloadFile(item: Record<string, any>) {
</a-modal> </a-modal>
</template> </template>
<style lang="scss" scoped> <style lang="scss">
.nc-attach-file { .nc-attachment-modal {
@apply select-none cursor-pointer color-transition flex items-center gap-1 border-1 p-2 rounded .nc-attach-file {
@apply hover:(bg-primary/10 text-primary ring); @apply select-none cursor-pointer color-transition flex items-center gap-1 border-1 p-2 rounded
@apply active:(ring-pink-500 bg-primary/20); @apply hover:(bg-primary/10 text-primary ring);
} @apply active:(ring-pink-500 bg-primary/20);
}
.nc-attachment-item { .nc-attachment-item {
@apply cursor-pointer !h-2/3 !min-h-[200px] flex items-center justify-center relative; @apply cursor-pointer !h-2/3 !min-h-[200px] flex items-center justify-center relative;
&::after { &::after {
@apply pointer-events-none rounded absolute top-0 left-0 right-0 bottom-0 transition-all duration-150 ease-in-out; @apply pointer-events-none rounded absolute top-0 left-0 right-0 bottom-0 transition-all duration-150 ease-in-out;
content: ''; content: '';
} }
&:hover::after { &:hover::after {
@apply ring shadow transform scale-103; @apply ring shadow transform scale-103;
}
&:active::after {
@apply ring ring-pink-500 shadow transform scale-103;
}
} }
&:active::after { .nc-attachment-download {
@apply ring ring-pink-500 shadow transform scale-103; @apply absolute bottom-2 right-2;
@apply transition-opacity duration-150 ease-in opacity-0 hover:ring;
@apply cursor-pointer rounded shadow flex items-center p-1 border-1;
@apply active:(ring border-0 ring-pink-500);
} }
}
.nc-attachment-download { .nc-attachment-remove {
@apply absolute bottom-2 right-2; @apply absolute top-2 right-2;
@apply transition-opacity duration-150 ease-in opacity-0 group-hover:(opacity-100) hover:ring; @apply hover:(ring ring-red-500);
@apply cursor-pointer rounded shadow flex items-center p-1 border-1; @apply cursor-pointer rounded-full border-1;
@apply active:(ring border-0 ring-pink-500); @apply active:(ring border-0 ring-red-500);
} }
.nc-attachment-remove { .ant-card-body {
@apply absolute top-2 right-2; @apply !p-2;
@apply hover:(ring ring-red-500); }
@apply cursor-pointer rounded-full border-1;
@apply active:(ring border-0 ring-red-500);
}
:deep(.ant-card-body) { .ant-modal-body {
@apply !p-2; @apply !p-0;
}
} }
</style> </style>

9
packages/nc-gui-v2/components/cell/attachment/index.vue

@ -23,7 +23,7 @@ const emits = defineEmits<Emits>()
const dropZoneRef = ref<HTMLDivElement>() const dropZoneRef = ref<HTMLDivElement>()
const { modalVisible, attachments, visibleItems, onFileSelect, isLoading, open, FileIcon, fileRemovedHook, fileAddedHook } = const { modalVisible, attachments, visibleItems, onDrop, isLoading, open, FileIcon, fileRemovedHook, fileAddedHook } =
useProvideAttachmentCell() useProvideAttachmentCell()
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop) const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
@ -46,13 +46,6 @@ fileAddedHook.on((data) => {
emits('update:modelValue', data) emits('update:modelValue', data)
}) })
function onDrop(droppedFiles: File[] | null) {
if (droppedFiles) {
// set files
onFileSelect(droppedFiles)
}
}
const selectImage = (file: any, i: unknown) => { const selectImage = (file: any, i: unknown) => {
// todo: implement // todo: implement
} }

15
packages/nc-gui-v2/components/cell/attachment/utils.ts

@ -1,4 +1,5 @@
import { notification } from 'ant-design-vue' import { notification } from 'ant-design-vue'
import FileSaver from 'file-saver'
import { computed, createEventHook, inject, ref, useApi, useFileDialog, useInjectionState, useProject, watch } from '#imports' import { computed, createEventHook, inject, ref, useApi, useFileDialog, useInjectionState, useProject, watch } from '#imports'
import { ColumnInj, EditModeInj, MetaInj } from '~/context' import { ColumnInj, EditModeInj, MetaInj } from '~/context'
import { isImage } from '~/utils' import { isImage } from '~/utils'
@ -93,6 +94,17 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState((
fileAddedHook.trigger([...attachments.value, ...newAttachments]) fileAddedHook.trigger([...attachments.value, ...newAttachments])
} }
function onDrop(droppedFiles: File[] | null) {
if (droppedFiles) {
// set files
onFileSelect(droppedFiles)
}
}
async function downloadFile(item: Record<string, any>) {
FileSaver.saveAs(item.url || item.data, item.title)
}
const FileIcon = (icon: string) => { const FileIcon = (icon: string) => {
switch (icon) { switch (icon) {
case 'mdi-pdf-box': case 'mdi-pdf-box':
@ -125,11 +137,12 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState((
isLoading, isLoading,
api, api,
open, open,
onFileSelect, onDrop,
modalVisible, modalVisible,
FileIcon, FileIcon,
fileRemovedHook, fileRemovedHook,
fileAddedHook, fileAddedHook,
removeFile, removeFile,
downloadFile,
} }
}, 'attachmentCell') }, 'attachmentCell')

Loading…
Cancel
Save