DateTimeInput component to leave formatting to page level, do not format within the component itself

This commit is contained in:
Joshen Lim committed 2022-05-12 16:48:35 +08:00
1 parent b91c2bd29d
commit 09e659bf8a
7 files changed
+66 -70

No files matched your search

@@ -1,3 +0,0 @@
export const TIMESTAMP_TYPES = ['timestamp', 'timestamptz']
export const DATE_TYPES = ['date']
export const TIME_TYPES = ['time', 'timetz']
@@ -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<Props> = ({ 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<Props> = ({ 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}
@@ -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'
@@ -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<Props> = ({
)
}
if (includes(TIMESTAMP_TYPES, field.format)) {
if (includes(DATETIME_TYPES, field.format)) {
return (
<DateTimeInput
name={field.name}
@@ -142,7 +142,7 @@ const RowEditor: FC<Props> = ({
key="RowEditor"
visible={visible}
header={<HeaderTitle isNewRecord={isNewRecord} tableName={selectedTable.name} />}
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<Props> = ({
<SidePanel.Content>
<div className="space-y-10 py-6">
<div>
<h3 className="text-base text-scale-1200">Optional Fields</h3>
<p className="text-sm text-scale-900">
<h3 className="text-scale-1200 text-base">Optional Fields</h3>
<p className="text-scale-900 text-sm">
These are columns that do not need any value
</p>
</div>
@@ -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<any> | 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
}
@@ -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)