Browse Source

fix(gui-v2): pass unique row+col key to attachment cell for dropzone refs

pull/3052/head
braks 2 years ago
parent
commit
4786c55040
  1. 30
      packages/nc-gui-v2/components/cell/attachment/index.vue
  2. 10
      packages/nc-gui-v2/components/smartsheet/Cell.vue
  3. 9
      packages/nc-gui-v2/components/smartsheet/Grid.vue

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

@ -6,21 +6,17 @@ import { useSortable } from './sort'
import Carousel from './Carousel.vue' import Carousel from './Carousel.vue'
import { onMounted, ref, useDropZone, watch } from '#imports' import { onMounted, ref, useDropZone, watch } from '#imports'
import { isImage, openLink } from '~/utils' import { isImage, openLink } from '~/utils'
import MaterialSymbolsAttachFile from '~icons/material-symbols/attach-file'
import MaterialArrowExpandIcon from '~icons/mdi/arrow-expand'
import MaterialSymbolsFileCopyOutline from '~icons/material-symbols/file-copy-outline'
import MdiReload from '~icons/mdi/reload'
import IcOutlineInsertDriveFile from '~icons/ic/outline-insert-drive-file'
interface Props { interface Props {
modelValue: string | Record<string, any>[] | null modelValue: string | Record<string, any>[] | null
rowIndex: number
} }
interface Emits { interface Emits {
(event: 'update:modelValue', value: string | Record<string, any>): void (event: 'update:modelValue', value: string | Record<string, any>): void
} }
const { modelValue } = defineProps<Props>() const { modelValue, rowIndex } = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
@ -60,7 +56,7 @@ onKeyDown('Escape', () => {
/** if possible, on mounted we try to fetch the relevant `td` cell to use as a dropzone */ /** if possible, on mounted we try to fetch the relevant `td` cell to use as a dropzone */
onMounted(() => { onMounted(() => {
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
dropZoneRef.value = document.querySelector(`td[data-col="${column.value.id}"]`) as HTMLTableDataCellElement dropZoneRef.value = document.querySelector(`td[data-key="${rowIndex}${column.value.id}"]`) as HTMLTableDataCellElement
} }
}) })
</script> </script>
@ -73,7 +69,7 @@ onMounted(() => {
<general-overlay <general-overlay
v-model="isOverDropZone" v-model="isOverDropZone"
inline inline
:target="`td[data-col='${column.id}']`" :target="`td[data-key='${rowIndex}${column.id}']`"
class="text-white text-lg ring ring-pink-500 bg-gray-700/75 flex items-center justify-center gap-2 backdrop-blur-xl" class="text-white text-lg ring ring-pink-500 bg-gray-700/75 flex items-center justify-center gap-2 backdrop-blur-xl"
> >
<MaterialSymbolsFileCopyOutline class="text-pink-500" /> Drop here <MaterialSymbolsFileCopyOutline class="text-pink-500" /> Drop here
@ -100,12 +96,15 @@ onMounted(() => {
</div> </div>
<template v-if="visibleItems.length"> <template v-if="visibleItems.length">
<div ref="sortableRef" :class="{ dragging }" class="flex flex-wrap gap-2 p-1 scrollbar-thin-dull"> <div
ref="sortableRef"
:class="{ dragging }"
class="flex justify-center items-center flex-wrap gap-2 p-1 scrollbar-thin-dull"
>
<div <div
v-for="(item, i) of visibleItems" v-for="(item, i) of visibleItems"
:id="item.url" :id="item.url"
:key="item.url || item.title" :key="item.url || item.title"
style="flex: 1 1 50px"
:class="isImage(item.title, item.mimetype) ? '' : 'border-1 rounded'" :class="isImage(item.title, item.mimetype) ? '' : 'border-1 rounded'"
class="nc-attachment flex items-center justify-center min-h-[50px]" class="nc-attachment flex items-center justify-center min-h-[50px]"
> >
@ -120,7 +119,7 @@ onMounted(() => {
placeholder placeholder
:alt="item.title || `#${i}`" :alt="item.title || `#${i}`"
:src="item.url || item.data" :src="item.url || item.data"
class="ring-1 ring-gray-300 rounded" class="ring-1 ring-gray-300 rounded max-h-[50px] max-w-[50px]"
@click="selectedImage = item" @click="selectedImage = item"
/> />
@ -137,10 +136,7 @@ onMounted(() => {
<a-tooltip v-else placement="bottom"> <a-tooltip v-else placement="bottom">
<template #title> View attachments </template> <template #title> View attachments </template>
<MaterialArrowExpandIcon <MdiArrowExpand class="select-none transform group-hover:(text-pink-500 scale-120)" @click.stop="modalVisible = true" />
class="select-none transform group-hover:(text-pink-500 scale-120)"
@click.stop="modalVisible = true"
/>
</a-tooltip> </a-tooltip>
</div> </div>
</template> </template>
@ -152,6 +148,10 @@ onMounted(() => {
<style lang="scss"> <style lang="scss">
.nc-cell { .nc-cell {
.nc-attachment-cell { .nc-attachment-cell {
.nc-attachment {
@apply w-[50px] h-[50px] min-h-[50px] min-w-[50px];
}
.ghost, .ghost,
.ghost > * { .ghost > * {
@apply !pointer-events-none; @apply !pointer-events-none;

10
packages/nc-gui-v2/components/smartsheet/Cell.vue

@ -10,14 +10,13 @@ interface Props {
column: ColumnType column: ColumnType
modelValue: any modelValue: any
editEnabled: boolean editEnabled: boolean
} rowIndex: number
interface Emits {
(event: 'update:modelValue', value: any): void
} }
const props = defineProps<Props>() const props = defineProps<Props>()
const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editEnabled']) const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editEnabled'])
const column = toRef(props, 'column') const column = toRef(props, 'column')
provide(ColumnInj, column) provide(ColumnInj, column)
@ -25,6 +24,7 @@ provide(ColumnInj, column)
provide(EditModeInj, useVModel(props, 'editEnabled', emit)) provide(EditModeInj, useVModel(props, 'editEnabled', emit))
let changed = $ref(false) let changed = $ref(false)
const syncValue = useDebounceFn(function () { const syncValue = useDebounceFn(function () {
changed = false changed = false
emit('save') emit('save')
@ -114,7 +114,7 @@ const syncAndNavigate = (dir: NavigateDir) => {
> >
<CellTextArea v-if="isTextArea" v-model="vModel" /> <CellTextArea v-if="isTextArea" v-model="vModel" />
<CellCheckbox v-else-if="isBoolean" v-model="vModel" /> <CellCheckbox v-else-if="isBoolean" v-model="vModel" />
<CellAttachment v-else-if="isAttachment" v-model="vModel" /> <CellAttachment v-else-if="isAttachment" v-model="vModel" :row-index="props.rowIndex" />
<CellSingleSelect v-else-if="isSingleSelect" v-model="vModel" /> <CellSingleSelect v-else-if="isSingleSelect" v-model="vModel" />
<CellMultiSelect v-else-if="isMultiSelect" v-model="vModel" /> <CellMultiSelect v-else-if="isMultiSelect" v-model="vModel" />
<CellDatePicker v-else-if="isDate" v-model="vModel" /> <CellDatePicker v-else-if="isDate" v-model="vModel" />

9
packages/nc-gui-v2/components/smartsheet/Grid.vue

@ -255,7 +255,7 @@ const onNavigate = (dir: NavigateDir) => {
<a-dropdown v-model:visible="contextMenu" :trigger="['contextmenu']"> <a-dropdown v-model:visible="contextMenu" :trigger="['contextmenu']">
<table ref="smartTable" class="xc-row-table nc-grid backgroundColorDefault" @contextmenu.prevent="contextMenu = true"> <table ref="smartTable" class="xc-row-table nc-grid backgroundColorDefault" @contextmenu.prevent="contextMenu = true">
<thead> <thead>
<tr class="group"> <tr>
<th> <th>
<div class="flex align-center w-[80px]"> <div class="flex align-center w-[80px]">
<div class="group-hover:hidden" :class="{ hidden: selectedAllRecords }">#</div> <div class="group-hover:hidden" :class="{ hidden: selectedAllRecords }">#</div>
@ -264,6 +264,7 @@ const onNavigate = (dir: NavigateDir) => {
class="group-hover:flex w-full align-center" class="group-hover:flex w-full align-center"
> >
<a-checkbox v-model:checked="selectedAllRecords" /> <a-checkbox v-model:checked="selectedAllRecords" />
<span class="flex-1" /> <span class="flex-1" />
</div> </div>
</div> </div>
@ -279,6 +280,7 @@ const onNavigate = (dir: NavigateDir) => {
@xcresized="resizingCol = null" @xcresized="resizingCol = null"
> >
<SmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" /> <SmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" />
<SmartsheetHeaderCell v-else :column="col" /> <SmartsheetHeaderCell v-else :column="col" />
</th> </th>
<!-- v-if="!isLocked && !isVirtual && !isPublicView && _isUIAllowed('add-column')" --> <!-- v-if="!isLocked && !isVirtual && !isPublicView && _isUIAllowed('add-column')" -->
@ -287,6 +289,7 @@ const onNavigate = (dir: NavigateDir) => {
<div class="h-full w-[60px] flex align-center justify-center"> <div class="h-full w-[60px] flex align-center justify-center">
<MdiPlus class="text-sm" /> <MdiPlus class="text-sm" />
</div> </div>
<template #overlay> <template #overlay>
<SmartsheetColumnEditOrAdd @click.stop @cancel="addColumnDropdown = false" /> <SmartsheetColumnEditOrAdd @click.stop @cancel="addColumnDropdown = false" />
</template> </template>
@ -313,10 +316,11 @@ const onNavigate = (dir: NavigateDir) => {
<td <td
v-for="(columnObj, colIndex) of fields" v-for="(columnObj, colIndex) of fields"
:key="rowIndex + columnObj.title" :key="rowIndex + columnObj.title"
class="cell pointer nc-grid-cell" class="cell relative cursor-pointer nc-grid-cell"
:class="{ :class="{
active: !isPublicView && selected.col === colIndex && selected.row === rowIndex, active: !isPublicView && selected.col === colIndex && selected.row === rowIndex,
}" }"
:data-key="rowIndex + columnObj.id"
:data-col="columnObj.id" :data-col="columnObj.id"
:data-title="columnObj.title" :data-title="columnObj.title"
@click="selectCell(rowIndex, colIndex)" @click="selectCell(rowIndex, colIndex)"
@ -338,6 +342,7 @@ const onNavigate = (dir: NavigateDir) => {
v-model="row.row[columnObj.title]" v-model="row.row[columnObj.title]"
:column="columnObj" :column="columnObj"
:edit-enabled="editEnabled && selected.col === colIndex && selected.row === rowIndex" :edit-enabled="editEnabled && selected.col === colIndex && selected.row === rowIndex"
:row-index="rowIndex"
@update:edit-enabled="editEnabled = false" @update:edit-enabled="editEnabled = false"
@save="updateOrSaveRow(row, columnObj.title)" @save="updateOrSaveRow(row, columnObj.title)"
@navigate="onNavigate" @navigate="onNavigate"

Loading…
Cancel
Save