mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
DateTimeInput component to leave formatting to page level, do not format within the component itself
This commit is contained in:
1 parent
b91c2bd29d
commit
09e659bf8a
7 files changed
+66
-70
No files matched your search
-3
@@ -1,3 +0,0 @@
|
||||
export const TIMESTAMP_TYPES = ['timestamp', 'timestamptz']
|
||||
export const DATE_TYPES = ['date']
|
||||
export const TIME_TYPES = ['time', 'timetz']
|
||||
+4
-9
@@ -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
-39
@@ -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'
|
||||
|
||||
+2
-2
@@ -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}
|
||||
|
||||
+3
-3
@@ -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>
|
||||
|
||||
+50
-13
@@ -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
|
||||
}
|
||||
|
||||
+6
-1
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user