diff --git a/packages/nc-gui-v2/components/cell/attachment/Carousel.vue b/packages/nc-gui-v2/components/cell/attachment/Carousel.vue index ecd08c8675..ee5eb47d24 100644 --- a/packages/nc-gui-v2/components/cell/attachment/Carousel.vue +++ b/packages/nc-gui-v2/components/cell/attachment/Carousel.vue @@ -13,6 +13,7 @@ const carouselRef = ref() const imageItems = computed(() => visibleItems.value.filter((item) => isImage(item.title, item.mimetype))) +/** navigate to previous image on button click */ onKeyDown( (e) => ['Left', 'ArrowLeft', 'A'].includes(e.key), () => { @@ -20,6 +21,7 @@ onKeyDown( }, ) +/** navigate to next image on button click */ onKeyDown( (e) => ['Right', 'ArrowRight', 'D'].includes(e.key), () => { @@ -27,21 +29,22 @@ onKeyDown( }, ) +/** set our selected image when slide changes */ function onSlideChange(index: number) { selectedImage.value = imageItems.value[index] } -watch( - carouselRef, - () => { - carouselRef.value?.goTo( - imageItems.value.findIndex((item) => item === selectedImage.value), - true, - ) - }, - { immediate: true }, -) +/** set our carousel ref and move to initial slide */ +const setCarouselRef = (el: Element) => { + carouselRef.value = el + + carouselRef.value?.goTo( + imageItems.value.findIndex((item) => item === selectedImage.value), + true, + ) +} +/** close overlay view when clicking outside of image */ onClickOutside(carouselRef, () => { selectedImage.value = false }) @@ -64,7 +67,7 @@ onClickOutside(carouselRef, () => { modelValue, (nextModel) => { @@ -45,19 +46,18 @@ watch( { immediate: true }, ) +/** updates attachments array for autosave */ function updateModelValue(data: string | Record) { emits('update:modelValue', typeof data !== 'string' ? JSON.stringify(data) : data) } -const selectImage = (file: any) => { - selectedImage.value = file -} - +/** Close modal on escape press, disable dropzone as well */ onKeyDown('Escape', () => { modalVisible.value = false isOverDropZone.value = false }) +/** if possible, on mounted we try to fetch the relevant `td` cell to use as a dropzone */ onMounted(() => { if (typeof document !== 'undefined') { dropZoneRef.value = document.querySelector(`td[data-col="${column.id}"]`) as HTMLTableDataCellElement @@ -121,7 +121,7 @@ onMounted(() => { :alt="item.title || `#${i}`" :src="item.url || item.data" class="ring-1 ring-gray-300 rounded" - @click="selectImage(item)" + @click="selectedImage = item" /> diff --git a/packages/nc-gui-v2/components/cell/attachment/utils.ts b/packages/nc-gui-v2/components/cell/attachment/utils.ts index 0909787fb7..e97275449a 100644 --- a/packages/nc-gui-v2/components/cell/attachment/utils.ts +++ b/packages/nc-gui-v2/components/cell/attachment/utils.ts @@ -41,6 +41,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( const { files, open } = useFileDialog() + /** remove a file from our stored attachments (either locally stored or saved ones) */ function removeFile(i: number) { if (isPublicForm) { storedFiles.value.splice(i, 1) @@ -52,6 +53,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( } } + /** save a file on select / drop, either locally (in-memory) or in the db */ async function onFileSelect(selectedFiles: FileList | File[]) { if (!selectedFiles.length || isPublicGrid) return @@ -95,6 +97,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( updateModelValue([...attachments.value, ...newAttachments]) } + /** save files on drop */ async function onDrop(droppedFiles: File[] | null) { if (droppedFiles) { // set files @@ -102,6 +105,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( } } + /** download a file */ async function downloadFile(item: Record) { FileSaver.saveAs(item.url || item.data, item.title) } @@ -121,6 +125,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( } } + /** our currently visible items, either the locally stored or the ones from db, depending on isPublicForm status */ const visibleItems = computed(() => (isPublicForm ? storedFiles.value : attachments.value) || ([] as any[])) watch(files, (nextFiles) => nextFiles && onFileSelect(nextFiles))