From 51d86bd418c926b6a84787b0722a87aa8b8e3e9a Mon Sep 17 00:00:00 2001 From: Nikita Zolotykh Date: Fri, 8 Nov 2024 15:33:07 +0100 Subject: [PATCH] fix: date picker components value parser --- docs/spec.md | 9 ++--- package-lock.json | 36 +++++++++---------- package.json | 4 +-- src/lib/core/types/specs.ts | 1 + .../components/Inputs/DateInput/DateInput.tsx | 12 +++++-- .../components/Views/DateView/DateView.tsx | 27 ++++++++------ .../components/InputPreview/constants.ts | 4 +++ 7 files changed, 55 insertions(+), 38 deletions(-) diff --git a/docs/spec.md b/docs/spec.md index d2b3e8c5..66f4f57f 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -166,10 +166,11 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; #### DateInput -| Property | Type | Required | Description | -| :----------- | :--------------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------- | -| outputFormat | `string` \| string \| date \| timestamp \| date_time | | 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` \| string \| date \| timestamp \| date_time | | 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) | +| timeZone | `string` | | Sets the time zone. [Learn more about time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) | 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/package-lock.json b/package-lock.json index 6acff987..9a78c862 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/components": "^3.0.0", - "@gravity-ui/date-components": "^2.4.0", - "@gravity-ui/date-utils": "^2.4.0", + "@gravity-ui/date-components": "^2.10.3", + "@gravity-ui/date-utils": "^2.5.5", "@gravity-ui/i18n": "^1.2.0", "@gravity-ui/icons": "^2.8.1", "lodash": "^4.17.20" @@ -3661,25 +3661,25 @@ } }, "node_modules/@gravity-ui/date-components": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.4.0.tgz", - "integrity": "sha512-S2csYch90OT6SvvjxzO1TtkGR0BEF8mGdxJzQ/5mbm1Tpk6ilHAjZ2dlAvzYQxdHNKqqmfA92NV+GjyfgsuGBg==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.10.3.tgz", + "integrity": "sha512-hGcXSnDIKA1YDr/6k/xGXJJv/AcA2xi5jFB1nYWakz5umvB11/yqudfSBndFfDbfBINtREPjlYzTIzGqz5TEbg==", "dependencies": { "@bem-react/classname": "^1.6.0", - "@gravity-ui/date-utils": "^2.0.1", + "@gravity-ui/date-utils": "^2.5.3", "@gravity-ui/icons": "^2.2.0", "tslib": "^2.6.2" }, "peerDependencies": { "@gravity-ui/uikit": "^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": ">=17.0.0", + "react-dom": ">=17.0.0" } }, "node_modules/@gravity-ui/date-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.4.0.tgz", - "integrity": "sha512-Bm2s4tsrRoNeBjc1Jxz16xRouR4OljADkPUE1aRAf+aQqZfS1hog/sHnXX802B/LrseoYJbxgLE98aNm5cryZg==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.5.tgz", + "integrity": "sha512-82IzJwmOaDqrJVa7IXOhWqI60epNx63gseiRhUOMDfAza+ra4tRORfTNa9ofV/lGYW5DVqoWJulMNpzDU0cM2g==", "dependencies": { "dayjs": "1.11.10", "lodash": "^4.17.0" @@ -31511,20 +31511,20 @@ } }, "@gravity-ui/date-components": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.4.0.tgz", - "integrity": "sha512-S2csYch90OT6SvvjxzO1TtkGR0BEF8mGdxJzQ/5mbm1Tpk6ilHAjZ2dlAvzYQxdHNKqqmfA92NV+GjyfgsuGBg==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.10.3.tgz", + "integrity": "sha512-hGcXSnDIKA1YDr/6k/xGXJJv/AcA2xi5jFB1nYWakz5umvB11/yqudfSBndFfDbfBINtREPjlYzTIzGqz5TEbg==", "requires": { "@bem-react/classname": "^1.6.0", - "@gravity-ui/date-utils": "^2.0.1", + "@gravity-ui/date-utils": "^2.5.3", "@gravity-ui/icons": "^2.2.0", "tslib": "^2.6.2" } }, "@gravity-ui/date-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.4.0.tgz", - "integrity": "sha512-Bm2s4tsrRoNeBjc1Jxz16xRouR4OljADkPUE1aRAf+aQqZfS1hog/sHnXX802B/LrseoYJbxgLE98aNm5cryZg==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.5.tgz", + "integrity": "sha512-82IzJwmOaDqrJVa7IXOhWqI60epNx63gseiRhUOMDfAza+ra4tRORfTNa9ofV/lGYW5DVqoWJulMNpzDU0cM2g==", "requires": { "dayjs": "1.11.10", "lodash": "^4.17.0" diff --git a/package.json b/package.json index 370ad85f..fae669b5 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,8 @@ "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/components": "^3.0.0", - "@gravity-ui/date-components": "^2.4.0", - "@gravity-ui/date-utils": "^2.4.0", + "@gravity-ui/date-components": "^2.10.3", + "@gravity-ui/date-utils": "^2.5.5", "@gravity-ui/i18n": "^1.2.0", "@gravity-ui/icons": "^2.8.1", "lodash": "^4.17.20" diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index 02aa0ce7..611e2bff 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -182,6 +182,7 @@ export interface StringSpec< dateInput?: { outputFormat?: string; printFormat?: string; + timeZone?: string; }; copy?: boolean; selectParams?: { diff --git a/src/lib/kit/components/Inputs/DateInput/DateInput.tsx b/src/lib/kit/components/Inputs/DateInput/DateInput.tsx index d765b594..d3d1fe87 100644 --- a/src/lib/kit/components/Inputs/DateInput/DateInput.tsx +++ b/src/lib/kit/components/Inputs/DateInput/DateInput.tsx @@ -2,12 +2,12 @@ import React, {useCallback} from 'react'; import {DatePicker, DatePickerProps} from '@gravity-ui/date-components'; import {StringInputProps} from '../../../../core'; -import {DateTime, dateTimeParse} from '@gravity-ui/date-utils'; +import {DateTime, dateTimeParse, isValidTimeZone} from '@gravity-ui/date-utils'; import {block} from '../../../utils'; import './DateInput.scss'; -export const DEFAULT_DATE_FORMAT = 'DD-MM-YYYY'; +export const DEFAULT_DATE_FORMAT = 'DD.MM.YYYY HH:mm'; const b = block('date-input'); @@ -22,6 +22,8 @@ export const DateInput: React.FC> = ({ }) => { const {value, onChange, onBlur, onFocus} = input; const dateInput = spec.viewSpec.dateInput; + const timeZone = + dateInput?.timeZone && isValidTimeZone(dateInput.timeZone) ? dateInput.timeZone : undefined; const outputFormat = dateInput?.outputFormat; const onUpdate = useCallback( @@ -63,11 +65,15 @@ export const DateInput: React.FC> = ({ onBlur: onBlur as (e: React.FocusEvent) => void, onFocus: onFocus as (e: React.FocusEvent) => void, value: value - ? dateTimeParse((value as any).seconds ? (value as any).seconds * 1000 : value) || null + ? dateTimeParse((value as any).seconds ? (value as any).seconds * 1000 : value, { + format: dateInput?.outputFormat, + timeZone, + }) || null : null, onUpdate, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, + timeZone, }; return ; diff --git a/src/lib/kit/components/Views/DateView/DateView.tsx b/src/lib/kit/components/Views/DateView/DateView.tsx index ec23a7eb..84a65121 100644 --- a/src/lib/kit/components/Views/DateView/DateView.tsx +++ b/src/lib/kit/components/Views/DateView/DateView.tsx @@ -1,10 +1,9 @@ import React from 'react'; -import {StringSpec, StringViewProps} from '../../../../core'; +import {StringViewProps} from '../../../../core'; import {BaseView, DEFAULT_DATE_FORMAT} from '../../../components'; import {dateTimeParse} from '@gravity-ui/date-utils'; import isObject from 'lodash/isObject'; -import {DatePickerProps} from '@gravity-ui/date-components/dist/esm/components/DatePicker/DatePicker'; interface Timestamp { seconds: string; @@ -12,18 +11,24 @@ interface Timestamp { } export const DateView: React.FC = ({value, spec, ...restProps}) => { - let formatedValue = - value && isObject(value) && (value as object as Timestamp).seconds - ? (value as any)?.seconds * 1000 - : value; + const { + printFormat = DEFAULT_DATE_FORMAT, + outputFormat, + timeZone, + } = spec.viewSpec.dateInput || {}; - const localSpec = (spec as StringSpec)!.viewSpec; + let formatedValue: string | number | undefined = value; - const format = - localSpec.inputProps?.format || localSpec.dateInput?.printFormat || DEFAULT_DATE_FORMAT; + if (isObject(value) && (value as Timestamp).seconds) { + formatedValue = Number((value as unknown as Timestamp).seconds) * 1000; + } + + if (formatedValue) { + const date = dateTimeParse(formatedValue, {format: outputFormat, timeZone}); - if (formatedValue && format) { - formatedValue = dateTimeParse(formatedValue)?.format(format) || formatedValue; + if (date) { + formatedValue = date.format(printFormat); + } } return ; diff --git a/src/stories/components/InputPreview/constants.ts b/src/stories/components/InputPreview/constants.ts index 0ddd8eb0..af589c9f 100644 --- a/src/stories/components/InputPreview/constants.ts +++ b/src/stories/components/InputPreview/constants.ts @@ -549,6 +549,10 @@ const dateInput: ObjectSpec = { type: SpecTypes.String, viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Print format'}, }, + timeZone: { + type: SpecTypes.String, + viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Time zone'}, + }, }, viewSpec: { type: 'base',