Browse Source

fic(nc-gui): allow duplicate file name file to upload in atttachment

pull/7605/head
Ramesh Mane 8 months ago
parent
commit
c5e0a076a2
  1. 38
      packages/nc-gui/components/cell/attachment/utils.ts
  2. 19
      packages/nc-gui/composables/useMultiSelect/convertCellData.ts
  3. 36
      packages/nc-gui/composables/useMultiSelect/index.ts
  4. 8
      packages/nc-gui/utils/fileUtils.ts

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

@ -108,7 +108,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
...parseProp(column?.value?.meta),
}
const newAttachments = []
const newAttachments: AttachmentType[] = []
const files: File[] = []
@ -159,13 +159,12 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
if (selectedFiles.length) {
files.push(file as File)
} else {
let fileName = (file as AttachmentReqType).fileName ?? ''
let count = 1
while ([...attachments.value, ...imageUrls].some((el) => el.title === fileName)) {
fileName = fileName.replace(/(.+?)(\.[^.]+)$/, `$1(${count})$2`)
count++
}
imageUrls.push({ ...(file as AttachmentReqType), fileName })
const fileName = populateUniqueFileName((file as AttachmentReqType).fileName ?? '', [
...attachments.value,
...imageUrls,
])
imageUrls.push({ ...(file as AttachmentReqType), fileName, title: fileName })
}
}
@ -221,13 +220,10 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
)
// add suffix in duplicate file title
for (const uploadedFile of data) {
let fileName = uploadedFile?.title
let count = 1
while ([...attachments.value, ...newAttachments].some((el) => el.title === fileName)) {
fileName = fileName.replace(/(.+?)(\.[^.]+)$/, `$1(${count})$2`)
count++
}
newAttachments.push({ ...uploadedFile, title: fileName })
newAttachments.push({
...uploadedFile,
title: populateUniqueFileName(uploadedFile?.title, [...attachments.value, ...newAttachments]),
})
}
} catch (e: any) {
message.error(e.message || t('msg.error.internalError'))
@ -283,7 +279,17 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
const imageData = imageUrl ? await getImageDataFromUrl(imageUrl) : ''
if (imageData) {
await onFileSelect([], [{ ...imageData, url: imageUrl, fileName: `image.${imageData.mimetype?.split('/')[1]}` }])
await onFileSelect(
[],
[
{
...imageData,
url: imageUrl,
fileName: `image.${imageData.mimetype?.split('/')[1]}`,
title: `image.${imageData.mimetype?.split('/')[1]}`,
},
],
)
}
}
}

19
packages/nc-gui/composables/useMultiSelect/convertCellData.ts

@ -1,5 +1,5 @@
import dayjs from 'dayjs'
import type { ColumnType, LinkToAnotherRecordType, SelectOptionsType } from 'nocodb-sdk'
import type { AttachmentType, ColumnType, LinkToAnotherRecordType, SelectOptionsType } from 'nocodb-sdk'
import { UITypes } from 'nocodb-sdk'
import type { AppInfo } from '~/composables/useGlobal'
import { isBt, isMm, parseProp } from '#imports'
@ -191,16 +191,6 @@ export default function convertCellData(
continue
}
}
// this prevent file with same names
const isFileNameAlreadyExist = oldAttachments.some((el) => el.title === (attachment?.title || attachment?.name))
if (isFileNameAlreadyExist) {
if (isMultiple) {
message.error(`File with name ${attachment?.title || attachment?.name} already attached`)
continue
} else {
throw new Error(`File with name ${attachment?.title || attachment?.name} already attached`)
}
}
attachments.push(attachment)
}
@ -208,7 +198,12 @@ export default function convertCellData(
if (oldAttachments.length && !attachments.length) {
return undefined
} else if (value && attachments.length) {
return JSON.stringify([...oldAttachments, ...attachments])
const newAttachments: AttachmentType[] = []
for (const att of attachments) {
newAttachments.push({ ...att, title: populateUniqueFileName(att?.title, [...oldAttachments, ...newAttachments]) })
}
return JSON.stringify([...oldAttachments, ...newAttachments])
} else if (files.length && attachments.length) {
return attachments
} else {

36
packages/nc-gui/composables/useMultiSelect/index.ts

@ -2,7 +2,7 @@ import type { Ref } from 'vue'
import { computed } from 'vue'
import dayjs from 'dayjs'
import type { MaybeRef } from '@vueuse/core'
import type { ColumnType, LinkToAnotherRecordType, PaginatedType, TableType, UserFieldRecordType, ViewType } from 'nocodb-sdk'
import type { AttachmentType, ColumnType, LinkToAnotherRecordType, PaginatedType, TableType, UserFieldRecordType, ViewType } from 'nocodb-sdk'
import { UITypes, dateFormats, isDateMonthFormat, isSystemColumn, isVirtualCol, timeFormats } from 'nocodb-sdk'
import { parse } from 'papaparse'
import type { Cell } from './cellRange'
@ -1115,12 +1115,9 @@ export function useMultiSelect(
)
if (columnObj.uidt === UITypes.Attachment && e.clipboardData?.files?.length && pasteValue?.length) {
const uploadedFiles = await handleFileUpload(pasteValue, columnObj.id!)
const newAttachments = await handleFileUploadAndGetCellValue(pasteValue, columnObj.id!, rowObj.row[columnObj.title!])
rowObj.row[columnObj.title!] =
Array.isArray(uploadedFiles) && uploadedFiles.length
? JSON.stringify([...handleParseAttachmentCellData(rowObj.row[columnObj.title!]), ...uploadedFiles])
: null
rowObj.row[columnObj.title!] = newAttachments ? JSON.stringify(newAttachments) : null
} else if (pasteValue !== undefined) {
rowObj.row[columnObj.title!] = pasteValue
}
@ -1177,12 +1174,9 @@ export function useMultiSelect(
)
if (fileUploadPayload?.length) {
const uploadedFiles = await handleFileUpload(fileUploadPayload, col.id!)
const newAttachments = await handleFileUploadAndGetCellValue(fileUploadPayload, col.id!, row.row[col.title!])
pasteValue =
Array.isArray(uploadedFiles) && uploadedFiles.length
? JSON.stringify([...handleParseAttachmentCellData(row.row[col.title]), ...uploadedFiles])
: null
pasteValue = newAttachments ? JSON.stringify(newAttachments) : null
}
}
} else {
@ -1232,7 +1226,9 @@ export function useMultiSelect(
event.preventDefault()
}
async function handleFileUpload(files: File[], columnId: string) {
async function handleFileUploadAndGetCellValue(files: File[], columnId: string, oldValue: AttachmentType[]) {
const newAttachments: AttachmentType[] = []
try {
const data = await api.storage.upload(
{
@ -1242,19 +1238,27 @@ export function useMultiSelect(
files,
},
)
return data
// add suffix in duplicate file title
for (const uploadedFile of data) {
newAttachments.push({
...uploadedFile,
title: populateUniqueFileName(uploadedFile?.title, [...handleParseAttachmentCellData(oldValue), ...newAttachments]),
})
}
return newAttachments
} catch (e: any) {
message.error(e.message || t('msg.error.internalError'))
}
}
function handleParseAttachmentCellData(value: string | null) {
function handleParseAttachmentCellData<T>(value: T): T {
const parsedVal = parseProp(value)
if (parsedVal && Array.isArray(parsedVal)) {
return parsedVal
return parsedVal as T
} else {
return []
return [] as T
}
}

8
packages/nc-gui/utils/fileUtils.ts

@ -62,3 +62,11 @@ export function extractImageSrcFromRawHtml(rawText: string) {
return imgElement.getAttribute('src')
}
}
export function populateUniqueFileName(fn: string, attachments: any[]) {
let c = 1
while (attachments.some((att) => att?.title === fn || att?.fileName === fn)) {
fn = fn.replace(/(.+?)(\.[^.]+)$/, `$1(${c++})$2`)
}
return fn
}

Loading…
Cancel
Save