diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx index 9303c52acc0..34346264898 100644 --- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx @@ -10,11 +10,11 @@ import { Select, } from 'ui' -import { MAX_CHARACTERS } from 'data/table-rows/table-rows-query' import { Edit, Edit2, Link } from 'lucide-react' import { DATETIME_TYPES, JSON_TYPES, TEXT_TYPES } from '../SidePanelEditor.constants' import { DateTimeInput } from './DateTimeInput' import type { RowField } from './RowEditor.types' +import { isValueTruncated } from './RowEditor.utils' export interface InputFieldProps { field: RowField @@ -128,7 +128,7 @@ const InputField = ({ } if (includes(TEXT_TYPES, field.format)) { - const isTruncated = field.value?.endsWith('...') && (field.value ?? '').length > MAX_CHARACTERS + const isTruncated = isValueTruncated(field.value) return (
@@ -186,7 +186,7 @@ const InputField = ({ } if (includes(JSON_TYPES, field.format)) { - const isTruncated = field.value?.endsWith('...') && (field.value ?? '').length > MAX_CHARACTERS + const isTruncated = isValueTruncated(field.value) return ( { } } if (field.format.includes('json') && (field.value?.length ?? 0) > 0) { + const isTruncated = isValueTruncated(field.value) + // don't validate if the value is truncated + if (isTruncated) return + try { minifyJSON(field.value ?? '') } catch { @@ -190,14 +196,15 @@ export const generateRowObjectFromFields = ( return includeNullProperties ? rowObject : omitBy(rowObject, isNull) } -export const generateUpdateRowPayload = (originalRow: any, field: RowField[]) => { +export const generateUpdateRowPayload = (originalRow: any, fields: RowField[]) => { const includeNullProperties = true - const rowObject = generateRowObjectFromFields(field, includeNullProperties) as any + const rowObject = generateRowObjectFromFields(fields, includeNullProperties) as any const payload = {} as any const properties = Object.keys(rowObject) properties.forEach((property) => { - const type = field.find((x) => x.name === property)?.format + const field = fields.find((x) => x.name === property) + const type = field?.format if (type !== undefined && DATETIME_TYPES.includes(type)) { // Just to ensure that the value are in the correct and consistent format for value comparison const originalFormatted = convertPostgresDatetimeToInputDatetime(type, originalRow[property]) @@ -205,6 +212,13 @@ export const generateUpdateRowPayload = (originalRow: any, field: RowField[]) => if (originalFormattedOut !== rowObject[property]) { payload[property] = rowObject[property] } + } else if (type !== undefined && JSON_TYPES.includes(type)) { + // don't update if the value is truncated. This is to enable the user to change cell values on rows which have + // truncated JSON values. If the user + const isTruncated = isValueTruncated(field?.value) + if (!isTruncated) { + payload[property] = rowObject[property] + } } else if (!isEqual(originalRow[property], rowObject[property])) { payload[property] = rowObject[property] } @@ -212,3 +226,10 @@ export const generateUpdateRowPayload = (originalRow: any, field: RowField[]) => return payload } + +/** + * Checks if the value is truncated. The JSON types are usually truncated if they're too big to show in the editor. + */ +export const isValueTruncated = (value: string | null | undefined) => { + return value?.endsWith('...') && (value ?? '').length > MAX_CHARACTERS +} diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx index e8aee162a8d..cb7b6b926c7 100644 --- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx @@ -14,6 +14,7 @@ import { useSelectedProject } from 'hooks/misc/useSelectedProject' import useTable from 'hooks/misc/useTable' import { Button, SidePanel, cn } from 'ui' import ActionBar from '../ActionBar' +import { isValueTruncated } from './RowEditor.utils' interface TextEditorProps { visible: boolean @@ -40,7 +41,7 @@ export const TextEditor = ({ const [strValue, setStrValue] = useState('') const [view, setView] = useState<'edit' | 'view'>('edit') const value = row?.[column as keyof typeof row] as unknown as string - const isTruncated = value?.endsWith('...') && value.length > MAX_CHARACTERS + const isTruncated = isValueTruncated(value) const { mutate: getCellValue, isLoading, isSuccess } = useGetCellValueMutation()