forked from ddrilling/asb_cloud_front
Исправлена работа селектора временной зоны, добавлен метод сдвига даты на дробное время
This commit is contained in:
parent
ab0a100a05
commit
c69bcf7089
@ -1,69 +1,72 @@
|
|||||||
import { memo, ReactNode, useEffect, useState } from 'react'
|
import { memo, ReactNode, useCallback, useEffect, useState } from 'react'
|
||||||
import { Select, SelectProps } from 'antd'
|
import { Select, SelectProps } from 'antd'
|
||||||
|
|
||||||
|
import { OmitExtends } from '@utils'
|
||||||
|
import { findTimezoneId, rawTimezones, TimezoneId } from '@utils/datetime'
|
||||||
import { SimpleTimezoneDto } from '@api'
|
import { SimpleTimezoneDto } from '@api'
|
||||||
|
|
||||||
import { columnPropsOther, makeColumn } from '.'
|
import { columnPropsOther, makeColumn } from '.'
|
||||||
|
|
||||||
export const rawTimezones = {
|
const makeTimezoneLabel = (id?: string | null, hours?: number) =>
|
||||||
'Калининград': 2,
|
`UTC${hours && hours > 0 ? '+':''}${hours ? ('0' + hours).slice(-2) : '~??'} :: ${id ?? 'Неизвестно'}`
|
||||||
'Москва': 3,
|
|
||||||
'Самара': 4,
|
|
||||||
'Екатеринбург': 5,
|
|
||||||
'Омск': 6,
|
|
||||||
'Красноярск': 7,
|
|
||||||
'Новосибирск': 7,
|
|
||||||
'Иркутск': 8,
|
|
||||||
'Чита': 9,
|
|
||||||
'Владивосток': 10,
|
|
||||||
'Магадан': 11,
|
|
||||||
'Южно-Сахалинск': 11,
|
|
||||||
'Среднеколымск': 11,
|
|
||||||
'Анадырь': 12,
|
|
||||||
'Петропавловск-Камчатский': 12,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const timezoneOptions = Object
|
export const timezoneOptions = Object
|
||||||
.entries(rawTimezones)
|
.entries(rawTimezones)
|
||||||
.sort((a, b) => a[1] - b[1])
|
.sort((a, b) => a[1] - b[1])
|
||||||
.map(([id, hours]) => ({
|
.map(([id, hours]) => ({
|
||||||
label: `UTC${hours > 0 ? '+':''}${('0' + hours).slice(-2)} :: ${id}`,
|
label: makeTimezoneLabel(id, hours),
|
||||||
value: id,
|
value: id,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export const TimezoneSelect = memo<SelectProps>(({ onChange, ...other }) => {
|
|
||||||
const [id, setId] = useState<keyof typeof rawTimezones | null>(null)
|
|
||||||
|
|
||||||
useEffect(() => onChange?.({
|
|
||||||
timezoneId: id,
|
|
||||||
hours: id ? rawTimezones[id] : 0,
|
|
||||||
isOverride: false,
|
|
||||||
}, []), [id, onChange])
|
|
||||||
|
|
||||||
return (<Select {...other} onChange={setId} value={id} />)
|
|
||||||
})
|
|
||||||
|
|
||||||
export const makeTimezoneRenderer = () => (timezone?: SimpleTimezoneDto) => {
|
export const makeTimezoneRenderer = () => (timezone?: SimpleTimezoneDto) => {
|
||||||
if (!timezone) return 'UTC~?? :: Неизвестно'
|
if (!timezone) return 'UTC~?? :: Неизвестно'
|
||||||
const { hours, timezoneId } = timezone
|
const { hours, timezoneId } = timezone
|
||||||
return `UTC${hours && hours > 0 ? '+':''}${hours ? ('0' + hours).slice(-2) : '~??'} :: ${timezoneId ?? 'Неизвестно'}`
|
return makeTimezoneLabel(timezoneId, hours)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TimezoneSelectProps = OmitExtends<{
|
||||||
|
onChange?: ((value?: SimpleTimezoneDto | null) => void) | null
|
||||||
|
value?: SimpleTimezoneDto | null
|
||||||
|
defaultValue?: SimpleTimezoneDto | null
|
||||||
|
}, SelectProps<TimezoneId>>
|
||||||
|
|
||||||
|
export const TimezoneSelect = memo<TimezoneSelectProps>(({ onChange, value, defaultValue, ...other }) => {
|
||||||
|
const [id, setId] = useState<TimezoneId | null>(null)
|
||||||
|
const [defaultTimezone, setDefaultTimezone] = useState<TimezoneId | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => setDefaultTimezone(defaultValue ? findTimezoneId(defaultValue) : null), [defaultValue])
|
||||||
|
useEffect(() => setId(value ? findTimezoneId(value) : null), [value])
|
||||||
|
|
||||||
|
const onValueChanged = useCallback((id: TimezoneId | null) => {
|
||||||
|
console.log(id)
|
||||||
|
onChange?.({
|
||||||
|
timezoneId: id,
|
||||||
|
hours: id ? rawTimezones[id] : 0,
|
||||||
|
isOverride: false,
|
||||||
|
})
|
||||||
|
}, [onChange])
|
||||||
|
|
||||||
|
return (<Select {...other} onChange={onValueChanged} value={id} defaultValue={defaultTimezone} />)
|
||||||
|
})
|
||||||
|
|
||||||
export const makeTimezoneColumn = (
|
export const makeTimezoneColumn = (
|
||||||
title: ReactNode = 'Зона',
|
title: ReactNode = 'Зона',
|
||||||
key: string = 'timezone',
|
key: string = 'timezone',
|
||||||
defaultValue?: SimpleTimezoneDto,
|
defaultValue?: SimpleTimezoneDto,
|
||||||
allowClear: boolean = true,
|
allowClear: boolean = true,
|
||||||
other?: columnPropsOther
|
other?: columnPropsOther,
|
||||||
|
selectOther?: TimezoneSelectProps
|
||||||
) => makeColumn(title, key, {
|
) => makeColumn(title, key, {
|
||||||
width: 100,
|
width: 100,
|
||||||
editable: true,
|
editable: true,
|
||||||
render: makeTimezoneRenderer(),
|
render: makeTimezoneRenderer(),
|
||||||
input: (
|
input: (
|
||||||
<TimezoneSelect
|
<TimezoneSelect
|
||||||
|
key={key}
|
||||||
allowClear={allowClear}
|
allowClear={allowClear}
|
||||||
options={timezoneOptions}
|
options={timezoneOptions}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
|
{...selectOther}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
...other
|
...other
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
|
import { SimpleTimezoneDto } from '@api'
|
||||||
|
|
||||||
export type RawDate = number | string | Date
|
export type RawDate = number | string | Date
|
||||||
|
|
||||||
export const defaultFormat: string = 'YYYY.MM.DD HH:mm'
|
export const defaultFormat: string = 'YYYY.MM.DD HH:mm'
|
||||||
@ -38,7 +40,40 @@ export const periodToString = (time?: number) => {
|
|||||||
return `${days > 0 ? days : ''} ${toFixed(hours)}:${toFixed(minutes)}:${toFixed(seconds)}`
|
return `${days > 0 ? days : ''} ${toFixed(hours)}:${toFixed(minutes)}:${toFixed(seconds)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calcDuration = (start: RawDate, end: RawDate) => {
|
export const calcDuration = (start: unknown, end: unknown) => {
|
||||||
if (!isRawDate(start) || !isRawDate(end)) return
|
if (!isRawDate(start) || !isRawDate(end)) return
|
||||||
return (+new Date(end) - +new Date(start)) * timeInS.millisecond / timeInS.day
|
return (+new Date(end) - +new Date(start)) * timeInS.millisecond / timeInS.day
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fractionalSum = (date: unknown, value: number, type: keyof typeof timeInS): RawDate => {
|
||||||
|
if (!isRawDate(date) || !timeInS[type] || isNaN(value ?? NaN)) return NaN
|
||||||
|
const d = new Date(date)
|
||||||
|
d.setMilliseconds(d.getMilliseconds() + value * timeInS[type] * 1000)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
export const rawTimezones = {
|
||||||
|
'Калининград': 2,
|
||||||
|
'Москва': 3,
|
||||||
|
'Самара': 4,
|
||||||
|
'Екатеринбург': 5,
|
||||||
|
'Омск': 6,
|
||||||
|
'Красноярск': 7,
|
||||||
|
'Новосибирск': 7,
|
||||||
|
'Иркутск': 8,
|
||||||
|
'Чита': 9,
|
||||||
|
'Владивосток': 10,
|
||||||
|
'Магадан': 11,
|
||||||
|
'Южно-Сахалинск': 11,
|
||||||
|
'Среднеколымск': 11,
|
||||||
|
'Анадырь': 12,
|
||||||
|
'Петропавловск-Камчатский': 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TimezoneId = keyof typeof rawTimezones
|
||||||
|
|
||||||
|
export const isTimezoneId = (value: unknown): value is TimezoneId => !!value && String(value) in rawTimezones
|
||||||
|
|
||||||
|
export const findTimezoneId = (value: SimpleTimezoneDto): TimezoneId =>
|
||||||
|
(isTimezoneId(value.timezoneId) && value.timezoneId) ||
|
||||||
|
(Object.keys(rawTimezones) as TimezoneId[]).find(id => rawTimezones[id] === value.hours) as TimezoneId
|
||||||
|
Loading…
Reference in New Issue
Block a user