mirror of
https://github.com/nocodb/nocodb.git
synced 2026-05-01 03:26:51 +00:00
193 lines
6.1 KiB
TypeScript
193 lines
6.1 KiB
TypeScript
import type { AttachmentType, ColumnType, SerializerOrParserFnProps } from 'nocodb-sdk'
|
|
import { ColumnHelper, UITypes, populateUniqueFileName } from 'nocodb-sdk'
|
|
|
|
import type { AppInfo } from '~/composables/useGlobal/types'
|
|
|
|
export default function convertCellData(
|
|
args: {
|
|
to: UITypes
|
|
value: string
|
|
column: ColumnType
|
|
appInfo: AppInfo
|
|
files?: FileList | File[]
|
|
oldValue?: unknown
|
|
maxAttachmentsAllowedInCell?: number
|
|
showUpgradeToAddMoreAttachmentsInCell?: (args: {
|
|
callback?: (type: 'ok' | 'cancel') => void
|
|
totalAttachments: number
|
|
}) => boolean | undefined
|
|
isInfoShown?: boolean
|
|
markInfoShown?: () => void
|
|
clipboardItem?: SerializerOrParserFnProps['params']['clipboardItem']
|
|
},
|
|
isMysql = false,
|
|
isMultiple = false,
|
|
) {
|
|
const {
|
|
to,
|
|
value,
|
|
column,
|
|
files = [],
|
|
oldValue,
|
|
maxAttachmentsAllowedInCell: _maxAttachmentsAllowedInCell,
|
|
showUpgradeToAddMoreAttachmentsInCell: _showUpgradeToAddMoreAttachmentsInCell,
|
|
markInfoShown,
|
|
} = args
|
|
|
|
const maxAttachmentsAllowedInCell =
|
|
_maxAttachmentsAllowedInCell || Math.max(1, +args.appInfo.ncMaxAttachmentsAllowed || 50) || 50
|
|
const showUpgradeToAddMoreAttachmentsInCell = ncIsFunction(_showUpgradeToAddMoreAttachmentsInCell)
|
|
? _showUpgradeToAddMoreAttachmentsInCell
|
|
: ({
|
|
totalAttachments,
|
|
avoidShowError,
|
|
}: {
|
|
callback?: (type: 'ok' | 'cancel') => void
|
|
totalAttachments: number
|
|
forceShowToastMessage?: boolean
|
|
avoidShowError?: boolean
|
|
}) => {
|
|
// If it's not ee or total attachments are less than or equal to max attachments allowed in cell, then return
|
|
if (!args.appInfo.ee || totalAttachments <= maxAttachmentsAllowedInCell) return
|
|
|
|
if (avoidShowError) return true
|
|
|
|
message.error(
|
|
`You can only upload at most ${maxAttachmentsAllowedInCell} file${
|
|
maxAttachmentsAllowedInCell > 1 ? 's' : ''
|
|
} to this cell.`,
|
|
)
|
|
return true
|
|
}
|
|
|
|
// return null if value is empty
|
|
if (value === '' && to !== UITypes.Attachment) return null
|
|
|
|
let serializedValue = value
|
|
|
|
/* eslint-disable no-useless-catch */
|
|
try {
|
|
/**
|
|
* This method can throw errors. so it's important to use a try-catch block when calling it.
|
|
*/
|
|
serializedValue = ColumnHelper.serializeValue(value, {
|
|
col: column,
|
|
isMysql: (_sourceId) => isMysql,
|
|
isMultipleCellPaste: isMultiple,
|
|
clipboardItem: args.clipboardItem,
|
|
})
|
|
|
|
serializedValue = handlePostSerialize(serializedValue, value)
|
|
} catch (ex) {
|
|
throw ex
|
|
}
|
|
/* eslint-enable no-useless-catch */
|
|
|
|
function handlePostSerialize(serializedValue: any, value: any) {
|
|
switch (to) {
|
|
case UITypes.Attachment: {
|
|
const parsedOldValue = parseProp(oldValue)
|
|
const oldAttachments = parsedOldValue && Array.isArray(parsedOldValue) ? parsedOldValue : []
|
|
|
|
if (!value && !files.length) {
|
|
if (oldAttachments.length) return undefined
|
|
return null
|
|
}
|
|
|
|
let parsedVal: Array<Record<string, any>> = []
|
|
|
|
if (value) {
|
|
if (!serializedValue) return null
|
|
|
|
parsedVal = serializedValue
|
|
}
|
|
|
|
// TODO(refactor): duplicate logic in attachment/utils.ts
|
|
const defaultAttachmentMeta = {
|
|
...(args.appInfo.ee && {
|
|
// Maximum Number of Attachments per cell
|
|
maxNumberOfAttachments: maxAttachmentsAllowedInCell,
|
|
// Maximum File Size per file
|
|
maxAttachmentSize: Math.max(1, +args.appInfo.ncAttachmentFieldSize || 20) || 20,
|
|
supportedAttachmentMimeTypes: ['*'],
|
|
}),
|
|
}
|
|
|
|
const attachmentMeta = {
|
|
...defaultAttachmentMeta,
|
|
...parseProp(column?.meta),
|
|
}
|
|
|
|
const attachments: Record<string, any>[] = []
|
|
|
|
const totalNewAttachments = value ? parsedVal.length : files.length
|
|
|
|
for (const attachment of value ? parsedVal : files) {
|
|
if (args.appInfo.ee) {
|
|
// verify number of files
|
|
if (
|
|
showUpgradeToAddMoreAttachmentsInCell({
|
|
totalAttachments: oldAttachments.length + totalNewAttachments,
|
|
forceShowToastMessage: isMultiple,
|
|
avoidShowError: args.isInfoShown,
|
|
})
|
|
) {
|
|
markInfoShown?.()
|
|
return
|
|
}
|
|
|
|
// verify file size
|
|
if (attachment.size > attachmentMeta.maxAttachmentSize * 1024 * 1024) {
|
|
message.error(
|
|
`The size of ${attachment.name} exceeds the maximum file size ${attachmentMeta.maxAttachmentSize} MB.`,
|
|
)
|
|
continue
|
|
}
|
|
// verify mime type
|
|
if (
|
|
!attachmentMeta.supportedAttachmentMimeTypes.includes('*') &&
|
|
!attachmentMeta.supportedAttachmentMimeTypes.includes(attachment.type) &&
|
|
!attachmentMeta.supportedAttachmentMimeTypes.includes(attachment.type.split('/')[0])
|
|
) {
|
|
message.error(`${attachment.name} has the mime type ${attachment.type} which is not allowed in this column.`)
|
|
continue
|
|
}
|
|
}
|
|
|
|
attachments.push(attachment)
|
|
}
|
|
|
|
// Todo: on paste file add it don't replace
|
|
if (oldAttachments.length && !attachments.length) {
|
|
return undefined
|
|
} else if (value && attachments.length) {
|
|
const newAttachments: AttachmentType[] = []
|
|
|
|
for (const att of attachments) {
|
|
if (!ncIsObject(att)) continue
|
|
|
|
newAttachments.push({
|
|
...att,
|
|
title: populateUniqueFileName(
|
|
att.title,
|
|
oldAttachments.concat(newAttachments).map((fn) => fn?.title || fn?.fileName),
|
|
att.mimetype,
|
|
),
|
|
})
|
|
}
|
|
return JSON.stringify(oldAttachments.concat(newAttachments))
|
|
} else if (files.length && attachments.length) {
|
|
return attachments
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
default: {
|
|
return serializedValue
|
|
}
|
|
}
|
|
}
|
|
|
|
return serializedValue
|
|
}
|