From 188f92eb529d772de3961282704ca484ef19ed4c Mon Sep 17 00:00:00 2001 From: denis-vlasov Date: Thu, 4 Jul 2024 04:06:41 +0300 Subject: [PATCH] feat: add valueType in dateInput --- docs/spec.md | 9 +++--- src/lib/core/components/Form/types/string.ts | 4 ++- src/lib/core/components/Form/types/value.ts | 1 + src/lib/core/constants.ts | 2 ++ src/lib/core/types/specs.ts | 3 +- src/lib/core/types/value.ts | 10 +++++- .../components/Inputs/DateInput/DateInput.tsx | 32 +++++++++++++++---- .../FormatedDateView/FormatedDateView.tsx | 21 ++++++++---- src/stories/Editor.stories.tsx | 1 + .../components/InputPreview/constants.ts | 5 +++ 10 files changed, 69 insertions(+), 19 deletions(-) diff --git a/docs/spec.md b/docs/spec.md index e610ee8b..e32eebe2 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -165,10 +165,11 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; #### DateInput -| Property | Type | Required | Description | -| :----------- | :------- | :------: | :-------------------------------------------------------------------------------------------------------------- | -| outputFormat | `string` | | Format returning string (for backend and logic). [Available formats](https://day.js.org/docs/en/display/format) | -| printFormat | `string` | | Format print string (for view in read form). [Available formats](https://day.js.org/docs/en/display/format) | +| Property | Type | Required | Description | +| :----------- | :----------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------- | +| outputFormat | `string` | | Format returning string (for backend and logic). [Available formats](https://day.js.org/docs/en/display/format) | +| printFormat | `string` | | Format print string (for view in read form). [Available formats](https://day.js.org/docs/en/display/format) | +| valueType | `string` \| `date` \| `timestamp` \| `date_time` | | Type of value for output or print. Ignore, if value is empty or set viewSpec.dateInput.outputFormat | You can provide all props of [original component](https://preview.gravity-ui.com/date-components/?path=/docs/components-datepicker--docs) through [viewSpec.inputProps](./input-props-map.md). diff --git a/src/lib/core/components/Form/types/string.ts b/src/lib/core/components/Form/types/string.ts index 14cdde24..53611aa5 100644 --- a/src/lib/core/components/Form/types/string.ts +++ b/src/lib/core/components/Form/types/string.ts @@ -1,6 +1,7 @@ import {StringSpec} from '../../../types'; import { + FieldValue, IndependentInputEntity, IndependentInputProps, IndependentInputType, @@ -17,8 +18,9 @@ import { export type StringInputProps< InputComponentProps extends Record | undefined = undefined, + Value extends FieldValue = string, > = InputProps< - string, + Value, InputComponentProps, undefined, StringSpec diff --git a/src/lib/core/components/Form/types/value.ts b/src/lib/core/components/Form/types/value.ts index ec5acff4..4f3ce548 100644 --- a/src/lib/core/components/Form/types/value.ts +++ b/src/lib/core/components/Form/types/value.ts @@ -11,6 +11,7 @@ export type FieldValue = | number | boolean | string + | Date | FieldArrayValue | FieldObjectValue | null diff --git a/src/lib/core/constants.ts b/src/lib/core/constants.ts index 49edf9b1..90ceac13 100644 --- a/src/lib/core/constants.ts +++ b/src/lib/core/constants.ts @@ -11,3 +11,5 @@ export type ReadAsMethod = | 'readAsBinaryString' | 'readAsDataURL' | 'readAsText'; + +export type DateValueType = 'string' | 'date' | 'timestamp' | 'date_time'; diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index dc9a6b52..c3688c79 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -1,7 +1,7 @@ import {LabelProps} from '@gravity-ui/uikit'; import {ColorTextBaseProps} from '@gravity-ui/uikit/build/esm/components/Text/colorText/colorText'; -import {ReadAsMethod, SpecTypes} from '../constants'; +import {DateValueType, ReadAsMethod, SpecTypes} from '../constants'; import {ArrayValue, ObjectValue} from './'; @@ -177,6 +177,7 @@ export interface StringSpec< dateInput?: { outputFormat?: string; printFormat?: string; + valueType?: DateValueType; }; copy?: boolean; selectParams?: { diff --git a/src/lib/core/types/value.ts b/src/lib/core/types/value.ts index 0a6d914e..87fdfefc 100644 --- a/src/lib/core/types/value.ts +++ b/src/lib/core/types/value.ts @@ -2,4 +2,12 @@ export type AnyObject = Record; export type ArrayValue = FormValue[]; export interface ObjectValue extends Record {} -export type FormValue = number | boolean | string | ArrayValue | ObjectValue | null | undefined; +export type FormValue = + | number + | boolean + | string + | Date + | ArrayValue + | ObjectValue + | null + | undefined; diff --git a/src/lib/kit/components/Inputs/DateInput/DateInput.tsx b/src/lib/kit/components/Inputs/DateInput/DateInput.tsx index 24e7f0e3..0431e63d 100644 --- a/src/lib/kit/components/Inputs/DateInput/DateInput.tsx +++ b/src/lib/kit/components/Inputs/DateInput/DateInput.tsx @@ -1,7 +1,7 @@ import React, {useCallback} from 'react'; import {DatePicker, DatePickerProps} from '@gravity-ui/date-components'; -import {StringInputProps} from '../../../../core'; +import {FieldObjectValue, StringInputProps} from '../../../../core'; import {DateTime, dateTimeParse} from '@gravity-ui/date-utils'; import {block} from '../../../utils'; @@ -12,25 +12,45 @@ const b = block('date-input'); export interface DateProps extends Omit {} -export const DateInput: React.FC> = ({ +export type DateValueProps = string | number | Date | FieldObjectValue | undefined; + +export const DateInput: React.FC> = ({ name, input, spec, inputProps, }) => { const {value, onChange, onBlur, onFocus} = input; + const {dateInput: {outputFormat, valueType} = {}} = spec.viewSpec; const onUpdate = useCallback( (date: DateTime | null) => { if (!date) { onChange(''); - } else if (spec.viewSpec.dateInput?.outputFormat) { - onChange(date.format(spec.viewSpec.dateInput.outputFormat)); + } else if (outputFormat) { + onChange(date.format(outputFormat)); } else { - onChange(date.toISOString()); + switch (valueType) { + case 'date_time': + onChange(date as object as FieldObjectValue); + break; + case 'date': + onChange(date.toDate()); + break; + case 'timestamp': + onChange({ + seconds: date.second(), + nanos: 0, + } as FieldObjectValue); + break; + case 'string': + default: + onChange(date.toISOString()); + break; + } } }, - [spec.viewSpec.dateInput?.outputFormat], + [outputFormat], ); const props: DatePickerProps = { diff --git a/src/lib/kit/components/Views/FormatedDateView/FormatedDateView.tsx b/src/lib/kit/components/Views/FormatedDateView/FormatedDateView.tsx index 359fee93..9de36724 100644 --- a/src/lib/kit/components/Views/FormatedDateView/FormatedDateView.tsx +++ b/src/lib/kit/components/Views/FormatedDateView/FormatedDateView.tsx @@ -2,16 +2,25 @@ import React from 'react'; import isString from 'lodash/isString'; -import {StringViewProps} from '../../../../core'; -import {BaseView} from '../../../components'; +import {StringSpec, ViewProps} from '../../../../core'; +import {BaseView, DateValueProps} from '../../../components'; import {dateTimeParse} from '@gravity-ui/date-utils'; +import isObject from 'lodash/isObject'; -export const FormatedDateView = ({ +interface Timestamp { + seconds: string; + nanos?: number; +} + +export const FormatedDateView: React.FC> = ({ value, spec, ...restProps -}: React.PropsWithChildren) => { - let formatedValue = value; +}) => { + let formatedValue = + value && isObject(value) && (value as object as Timestamp).seconds + ? (value as object as Timestamp)?.seconds + : value; const dateSpec = spec.viewSpec.dateInput; const format = dateSpec && (dateSpec.printFormat || dateSpec.outputFormat); @@ -19,5 +28,5 @@ export const FormatedDateView = ({ formatedValue = dateTimeParse(value)?.format(format) || formatedValue; } - return ; + return ; }; diff --git a/src/stories/Editor.stories.tsx b/src/stories/Editor.stories.tsx index 4f623dd2..4c8fe620 100644 --- a/src/stories/Editor.stories.tsx +++ b/src/stories/Editor.stories.tsx @@ -24,6 +24,7 @@ const spec: ObjectSpec = { name: 'Bar', age: 12345, license: true, + birthday: new Date('2020-01-01'), }, }, }, diff --git a/src/stories/components/InputPreview/constants.ts b/src/stories/components/InputPreview/constants.ts index 62bebe5a..668d000f 100644 --- a/src/stories/components/InputPreview/constants.ts +++ b/src/stories/components/InputPreview/constants.ts @@ -486,6 +486,11 @@ const dateInput: ObjectSpec = { type: SpecTypes.String, viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Print format'}, }, + valueType: { + type: SpecTypes.String, + enum: ['string', 'date', 'timestamp', 'date_time'], + viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Value type'}, + }, }, viewSpec: { type: 'base',