Browse Source

fix(nc-gui): give proper suffix for duplicate filename

pull/7695/head
Ramesh Mane 10 months ago
parent
commit
e033c9b79f
  1. 5
      packages/nc-gui/components/cell/attachment/utils.ts
  2. 8
      packages/nc-gui/composables/useMultiSelect/convertCellData.ts
  3. 12
      packages/nc-gui/composables/useMultiSelect/index.ts
  4. 18
      packages/nc-gui/utils/fileUtils.ts
  5. 31
      packages/nocodb-sdk/src/lib/helperFunctions.ts

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

@ -1,4 +1,5 @@
import type { AttachmentReqType, AttachmentType } from 'nocodb-sdk' import type { AttachmentReqType, AttachmentType } from 'nocodb-sdk'
import { populateUniqueFileName } from 'nocodb-sdk'
import DOMPurify from 'isomorphic-dompurify' import DOMPurify from 'isomorphic-dompurify'
import RenameFile from './RenameFile.vue' import RenameFile from './RenameFile.vue'
import { import {
@ -161,7 +162,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
} else { } else {
const fileName = populateUniqueFileName( const fileName = populateUniqueFileName(
(file as AttachmentReqType).fileName ?? '', (file as AttachmentReqType).fileName ?? '',
[...attachments.value, ...imageUrls], [...attachments.value, ...imageUrls].map((fn) => fn?.title || fn?.fileName || 'image'),
(file as File)?.type || (file as AttachmentReqType)?.mimetype || '', (file as File)?.type || (file as AttachmentReqType)?.mimetype || '',
) )
@ -225,7 +226,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
...uploadedFile, ...uploadedFile,
title: populateUniqueFileName( title: populateUniqueFileName(
uploadedFile?.title, uploadedFile?.title,
[...attachments.value, ...newAttachments], [...attachments.value, ...newAttachments].map((fn) => fn?.title || fn?.fileName || 'image'),
uploadedFile?.mimetype, uploadedFile?.mimetype,
), ),
}) })

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

@ -1,6 +1,6 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import type { AttachmentType, ColumnType, LinkToAnotherRecordType, SelectOptionsType } from 'nocodb-sdk' import type { AttachmentType, ColumnType, LinkToAnotherRecordType, SelectOptionsType } from 'nocodb-sdk'
import { UITypes } from 'nocodb-sdk' import { UITypes, populateUniqueFileName } from 'nocodb-sdk'
import type { AppInfo } from '~/composables/useGlobal' import type { AppInfo } from '~/composables/useGlobal'
import { isBt, isMm, parseProp } from '#imports' import { isBt, isMm, parseProp } from '#imports'
@ -203,7 +203,11 @@ export default function convertCellData(
for (const att of attachments) { for (const att of attachments) {
newAttachments.push({ newAttachments.push({
...att, ...att,
title: populateUniqueFileName(att?.title, [...oldAttachments, ...newAttachments], att?.mimetype), title: populateUniqueFileName(
att?.title,
[...oldAttachments, ...newAttachments].map((fn) => fn?.title || fn?.fileName || 'image'),
att?.mimetype,
),
}) })
} }
return JSON.stringify([...oldAttachments, ...newAttachments]) return JSON.stringify([...oldAttachments, ...newAttachments])

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

@ -11,7 +11,15 @@ import type {
UserFieldRecordType, UserFieldRecordType,
ViewType, ViewType,
} from 'nocodb-sdk' } from 'nocodb-sdk'
import { UITypes, dateFormats, isDateMonthFormat, isSystemColumn, isVirtualCol, timeFormats } from 'nocodb-sdk' import {
UITypes,
dateFormats,
isDateMonthFormat,
isSystemColumn,
isVirtualCol,
timeFormats,
populateUniqueFileName,
} from 'nocodb-sdk'
import { parse } from 'papaparse' import { parse } from 'papaparse'
import type { Cell } from './cellRange' import type { Cell } from './cellRange'
import { CellRange } from './cellRange' import { CellRange } from './cellRange'
@ -1253,7 +1261,7 @@ export function useMultiSelect(
...uploadedFile, ...uploadedFile,
title: populateUniqueFileName( title: populateUniqueFileName(
uploadedFile?.title, uploadedFile?.title,
[...handleParseAttachmentCellData(oldValue), ...newAttachments], [...handleParseAttachmentCellData(oldValue), ...newAttachments].map((fn) => fn?.title || fn?.fileName || 'image'),
uploadedFile?.mimetype, uploadedFile?.mimetype,
), ),
}) })

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

@ -77,21 +77,3 @@ export function extractImageSrcFromRawHtml(rawText: string) {
return imgElement.getAttribute('src') return imgElement.getAttribute('src')
} }
} }
export function populateUniqueFileName(fn: string, attachments: any[], mimeType: string) {
if (!mimeType) return fn
// 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 (!fn?.endsWith(mimeType.split('/')[1])) {
fn = `${fn}.${mimeType.split('/')[1]}`
}
let c = 1
let originalFn = fn
while (attachments.some((att) => att?.title === fn || att?.fileName === fn)) {
const match = fn.match(/^(.+?)(\(\d+\))?(\.[^.]+)$/)
fn = match ? `${match[1]}(${c++})${match[3]}` : `${originalFn}(${c++})`
}
return fn
}

31
packages/nocodb-sdk/src/lib/helperFunctions.ts

@ -97,6 +97,36 @@ const getAvailableRollupForUiType = (type: string) => {
} }
}; };
function populateUniqueFileName(
fileName: string,
attachments: string[],
mimeType: string
) {
if (!mimeType) return fileName;
// If the file extension is not present, the while loop will go into an infinite loop. So, add the extension first if not present.
if (!fileName?.endsWith(`.${mimeType.split('/')[1]}`)) {
fileName = `${fileName}.${mimeType.split('/')[1]}`;
} else if (
fileName?.endsWith(`.${mimeType.split('/')[1]}`) &&
fileName.length === `.${mimeType.split('/')[1]}`.length
) {
fileName = `image.${mimeType.split('/')[1]}`;
}
let match = fileName.match(/^(.+?)(\((\d+)\))?(\.[^.]+)$/);
if (!match) return fileName;
let c = match && !isNaN(parseInt(match[3])) ? parseInt(match[3]) : 1;
while (attachments.some((fn) => fn === fileName)) {
fileName = `${match[1]}(${c++})${match[4]}`;
}
return fileName;
}
export { export {
filterOutSystemColumns, filterOutSystemColumns,
getSystemColumnsIds, getSystemColumnsIds,
@ -106,4 +136,5 @@ export {
extractRolesObj, extractRolesObj,
stringifyRolesObj, stringifyRolesObj,
getAvailableRollupForUiType, getAvailableRollupForUiType,
populateUniqueFileName,
}; };

Loading…
Cancel
Save