Browse Source

fix(nc-gui): allow duplicate attachment name if user copy paste from another cell

pull/7605/head
Ramesh Mane 9 months ago
parent
commit
2eb0abf7d5
  1. 43
      packages/nc-gui/components/cell/attachment/utils.ts
  2. 5
      packages/nc-gui/composables/useMultiSelect/convertCellData.ts
  3. 6
      packages/nc-gui/composables/useMultiSelect/index.ts
  4. 7
      packages/nc-gui/utils/fileUtils.ts

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

@ -159,10 +159,11 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
if (selectedFiles.length) { if (selectedFiles.length) {
files.push(file as File) files.push(file as File)
} else { } else {
const fileName = populateUniqueFileName((file as AttachmentReqType).fileName ?? '', [ const fileName = populateUniqueFileName(
...attachments.value, (file as AttachmentReqType).fileName ?? '',
...imageUrls, [...attachments.value, ...imageUrls],
]) (file as File)?.type || (file as AttachmentReqType)?.mimetype || '',
)
imageUrls.push({ ...(file as AttachmentReqType), fileName, title: fileName }) imageUrls.push({ ...(file as AttachmentReqType), fileName, title: fileName })
} }
@ -222,7 +223,11 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
for (const uploadedFile of data) { for (const uploadedFile of data) {
newAttachments.push({ newAttachments.push({
...uploadedFile, ...uploadedFile,
title: populateUniqueFileName(uploadedFile?.title, [...attachments.value, ...newAttachments]), title: populateUniqueFileName(
uploadedFile?.title,
[...attachments.value, ...newAttachments],
uploadedFile?.mimetype,
),
}) })
} }
} catch (e: any) { } catch (e: any) {
@ -277,16 +282,16 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
const imageUrl = extractImageSrcFromRawHtml(sanitizedHtml) ?? '' const imageUrl = extractImageSrcFromRawHtml(sanitizedHtml) ?? ''
const imageData = imageUrl ? await getImageDataFromUrl(imageUrl) : '' const imageData = imageUrl ? ((await getImageDataFromUrl(imageUrl)) as AttachmentReqType) : {}
if (imageData) { if (imageData?.mimetype) {
await onFileSelect( await onFileSelect(
[], [],
[ [
{ {
...imageData, ...imageData,
url: imageUrl, ...(isPublic.value && isForm.value ? {} : { url: imageUrl }),
fileName: `image.${imageData.mimetype?.split('/')[1]}`, fileName: `image.${imageData?.mimetype?.split('/')[1]}`,
title: `image.${imageData.mimetype?.split('/')[1]}`, title: `image.${imageData?.mimetype?.split('/')[1]}`,
}, },
], ],
) )
@ -314,10 +319,26 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
try { try {
const response = await fetch(imageUrl) const response = await fetch(imageUrl)
if (response.ok && response.headers.get('content-type')?.startsWith('image/')) { if (response.ok && response.headers.get('content-type')?.startsWith('image/')) {
return { const res = {
mimetype: response.headers.get('content-type') || undefined, mimetype: response.headers.get('content-type') || undefined,
size: +(response.headers.get('content-length') || 0) || undefined, size: +(response.headers.get('content-length') || 0) || undefined,
data: undefined,
} as { minetype?: string; size?: number; data?: any }
if (isPublic.value && isForm.value) {
const blob = await response.blob()
res.data = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => {
resolve(reader.result)
}
reader.onerror = reject
reader.readAsDataURL(blob)
})
} }
return res
} }
throw new Error('Field to parse image url') throw new Error('Field to parse image url')
} catch (err) { } catch (err) {

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

@ -201,7 +201,10 @@ export default function convertCellData(
const newAttachments: AttachmentType[] = [] const newAttachments: AttachmentType[] = []
for (const att of attachments) { for (const att of attachments) {
newAttachments.push({ ...att, title: populateUniqueFileName(att?.title, [...oldAttachments, ...newAttachments]) }) newAttachments.push({
...att,
title: populateUniqueFileName(att?.title, [...oldAttachments, ...newAttachments], att?.mimetype),
})
} }
return JSON.stringify([...oldAttachments, ...newAttachments]) return JSON.stringify([...oldAttachments, ...newAttachments])
} else if (files.length && attachments.length) { } else if (files.length && attachments.length) {

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

@ -1243,7 +1243,11 @@ export function useMultiSelect(
for (const uploadedFile of data) { for (const uploadedFile of data) {
newAttachments.push({ newAttachments.push({
...uploadedFile, ...uploadedFile,
title: populateUniqueFileName(uploadedFile?.title, [...handleParseAttachmentCellData(oldValue), ...newAttachments]), title: populateUniqueFileName(
uploadedFile?.title,
[...handleParseAttachmentCellData(oldValue), ...newAttachments],
uploadedFile?.mimetype,
),
}) })
} }
return newAttachments return newAttachments

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

@ -63,7 +63,12 @@ export function extractImageSrcFromRawHtml(rawText: string) {
} }
} }
export function populateUniqueFileName(fn: string, attachments: any[]) { export function populateUniqueFileName(fn: string, attachments: any[], mimeType: string) {
// If the image extension is not present, the while loop will go into an infinite loop. So, add the extension first if not present.
if (!isImage(fn)) {
fn = `${fn}.${mimeType.split('/')[1]}`
}
let c = 1 let c = 1
while (attachments.some((att) => att?.title === fn || att?.fileName === fn)) { while (attachments.some((att) => att?.title === fn || att?.fileName === fn)) {
fn = fn.replace(/(.+?)(\.[^.]+)$/, `$1(${c++})$2`) fn = fn.replace(/(.+?)(\.[^.]+)$/, `$1(${c++})$2`)

Loading…
Cancel
Save