diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.constants.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.constants.ts deleted file mode 100644 index c4938da40c7..00000000000 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const TIMESTAMP_TYPES = ['timestamp', 'timestamptz'] -export const DATE_TYPES = ['date'] -export const TIME_TYPES = ['time', 'timetz'] diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.tsx index aa2ed5060bd..29b3ceb4ad5 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.tsx @@ -1,10 +1,6 @@ import { FC } from 'react' import { Input } from '@supabase/ui' -import { - convertInputToPostgresValue, - convertPostgresToInputValue, - getColumnType, -} from './DateTimeInput.utils' +import { getColumnType } from './DateTimeInput.utils' interface Props { name: string @@ -20,12 +16,11 @@ interface Props { */ const DateTimeInput: FC = ({ value, onChange, name, format, description }) => { const inputType = getColumnType(format) - const formattedValue = convertPostgresToInputValue(inputType, value) function handleOnChange(e: any) { const temp = e.target.value - const value = convertInputToPostgresValue({ inputType, format, value: temp }) - onChange(value) + if (temp.length === 0) return + onChange(temp) } return ( @@ -42,7 +37,7 @@ const DateTimeInput: FC = ({ value, onChange, name, format, description } } labelOptional={format} size="small" - value={formattedValue} + value={value} type={inputType} onChange={handleOnChange} step={inputType == 'datetime-local' || inputType == 'time' ? '1' : undefined} diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.utils.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.utils.ts index a9d56a7936d..53b07120875 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.utils.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/DateTimeInput/DateTimeInput.utils.ts @@ -1,47 +1,9 @@ import dayjs from 'dayjs' import customParseFormat from 'dayjs/plugin/customParseFormat' -import { TIMESTAMP_TYPES, DATE_TYPES, TIME_TYPES } from './DateTimeInput.constants' -import { DATE_FORMAT } from '../../SidePanelEditor.constants' +import { TIMESTAMP_TYPES, DATE_TYPES, TIME_TYPES } from '../../SidePanelEditor.constants' dayjs.extend(customParseFormat) -export function convertPostgresToInputValue(inputType: string, value?: string) { - if (!value || value.length == 0) return '' - - switch (inputType) { - case 'datetime-local': { - return dayjs(value, DATE_FORMAT).format('YYYY-MM-DDTHH:mm:ss') - } - case 'time': { - const serverTimeFormat = value && value.includes('+') ? 'HH:mm:ssZZ' : 'HH:mm:ss' - return dayjs(value, serverTimeFormat).format('HH:mm:ss') - } - default: - return value - } -} - -export function convertInputToPostgresValue(params: { - inputType: string - format: string - value?: string -}) { - const { inputType, format, value } = params - if (!value || value.length == 0) return '' - - switch (inputType) { - case 'datetime-local': { - return dayjs(value, 'YYYY-MM-DDTHH:mm:ss').format(DATE_FORMAT) - } - case 'time': { - const serverTimeFormat = format.toLowerCase() == 'timetz' ? 'HH:mm:ssZZ' : 'HH:mm:ss' - return dayjs(value, 'HH:mm:ss').format(serverTimeFormat) - } - default: - return value - } -} - export function getColumnType(format: string) { if (isDateColumn(format)) { return 'date' diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx index 51c5bccb9be..9bf2c7a8757 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx @@ -4,7 +4,7 @@ import { Button, Select, Input, IconLink, Typography, IconArrowRight } from '@su import { RowField } from './RowEditor.types' import DateTimeInput from './DateTimeInput' -import { TEXT_TYPES, JSON_TYPES, TIMESTAMP_TYPES } from '../SidePanelEditor.constants' +import { TEXT_TYPES, JSON_TYPES, DATETIME_TYPES } from '../SidePanelEditor.constants' interface Props { field: RowField @@ -122,7 +122,7 @@ const InputField: FC = ({ ) } - if (includes(TIMESTAMP_TYPES, field.format)) { + if (includes(DATETIME_TYPES, field.format)) { return ( = ({ key="RowEditor" visible={visible} header={} - className={`transition-all ease-in duration-100 ${ + className={`transition-all duration-100 ease-in ${ isEditingJson || isViewingReferenceRow ? ' mr-32' : '' }`} onCancel={closePanel} @@ -177,8 +177,8 @@ const RowEditor: FC = ({
-

Optional Fields

-

+

Optional Fields

+

These are columns that do not need any value

diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts index 7ccad72a0d8..4be4a5eae1d 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts @@ -5,7 +5,13 @@ import { PostgresTable } from '@supabase/postgres-meta' import { uuidv4, minifyJSON, tryParseJson } from 'lib/helpers' import { RowField } from './RowEditor.types' -import { JSON_TYPES, NUMERICAL_TYPES } from '../SidePanelEditor.constants' +import { + DATE_FORMAT, + JSON_TYPES, + NUMERICAL_TYPES, + DATETIME_TYPES, + TIME_TYPES, +} from '../SidePanelEditor.constants' export const generateRowFields = ( row: Dictionary | undefined, @@ -13,6 +19,7 @@ export const generateRowFields = ( isNewRecord?: boolean ): RowField[] => { const { relationships, primary_keys } = table + // @ts-ignore const primaryKeyColumns = primary_keys.map((key) => key.name) return table.columns.map((column) => { @@ -21,6 +28,8 @@ export const generateRowFields = ( ? nowDateTimeValue(column.format) : isUndefined(row) ? '' + : DATETIME_TYPES.includes(column.format) + ? convertPostgresDatetimeToInputDatetime(column.format, row[column.name]) : parseValue(row[column.name], column.format, column.data_type) const foreignKey = find(relationships, (relationship) => { @@ -146,6 +155,44 @@ const parseDescription = (description: string | null) => { } } +const nowDateTimeValue = (format: string) => { + if (format?.includes('timestamp')) { + return dayjs().format('YYYY-MM-DDTHH:mm:ss') + } else if (format == 'time') { + return dayjs().format('HH:mm:ss') + } else if (format == 'timetz') { + return dayjs().format('HH:mm:ssZZ') + } else { + return dayjs().format('YYYY-MM-DD') + } +} + +const convertPostgresDatetimeToInputDatetime = (format: string, value: string) => { + if (!value || value.length == 0) return '' + + if (DATETIME_TYPES.includes(format)) { + return dayjs(value, DATE_FORMAT).format('YYYY-MM-DDTHH:mm:ss') + } else if (TIME_TYPES.includes(format)) { + const serverTimeFormat = value && value.includes('+') ? 'HH:mm:ssZZ' : 'HH:mm:ss' + return dayjs(value, serverTimeFormat).format('HH:mm:ss') + } else { + return value + } +} + +const convertInputDatetimeToPostgresDatetime = (format: string, value: string | null) => { + if (!value || value.length == 0) return null + + if (DATETIME_TYPES.includes(format)) { + return dayjs(value, 'YYYY-MM-DDTHH:mm:ss').format(DATE_FORMAT) + } else if (TIME_TYPES.includes(format)) { + const serverTimeFormat = format.toLowerCase() === 'timetz' ? 'HH:mm:ssZZ' : 'HH:mm:ss' + return dayjs(value, 'HH:mm:ss').format(serverTimeFormat) + } else { + return value + } +} + /** * postgres-meta can return default value with format like * 'hello world'::character varying @@ -208,18 +255,6 @@ const _unescapeLiteralArray = (value: any) => { } } -const nowDateTimeValue = (format: string) => { - if (format?.includes('timestamp')) { - return dayjs().format() - } else if (format == 'time') { - return dayjs().format('HH:mm:ss') - } else if (format == 'timetz') { - return dayjs().format('HH:mm:ssZZ') - } else { - return dayjs().format('YYYY-MM-DD') - } -} - export const generateRowObjectFromFields = ( fields: RowField[], includeNullProperties = false @@ -239,6 +274,8 @@ export const generateRowObjectFromFields = ( rowObject[field.name] = Number(value) } else if (field.format === 'bool' && value) { rowObject[field.name] = value === 'true' + } else if (DATETIME_TYPES.includes(field.format)) { + rowObject[field.name] = convertInputDatetimeToPostgresDatetime(field.format, value) } else { rowObject[field.name] = value } diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.constants.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.constants.ts index 6a49278b97c..e9610418474 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.constants.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.constants.ts @@ -5,7 +5,12 @@ export const DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ssZ' export const NUMERICAL_TYPES = ['int2', 'int4', 'int8', 'float4', 'float8', 'numeric'] export const JSON_TYPES = ['json', 'jsonb'] export const TEXT_TYPES = ['text', 'varchar'] -export const TIMESTAMP_TYPES = ['date', 'time', 'timestamp', 'timetz', 'timestamptz'] + +export const TIMESTAMP_TYPES = ['timestamp', 'timestamptz'] +export const DATE_TYPES = ['date'] +export const TIME_TYPES = ['time', 'timetz'] +export const DATETIME_TYPES = concat(TIMESTAMP_TYPES, DATE_TYPES, TIME_TYPES) + export const OTHER_DATA_TYPES = ['uuid', 'bool'] export const POSTGRES_DATA_TYPES = sortBy( concat(NUMERICAL_TYPES, JSON_TYPES, TEXT_TYPES, TIMESTAMP_TYPES, OTHER_DATA_TYPES)