Skip to content

Commit

Permalink
feat(past-time-picker): 增加“显示绝对时间”特性 (#2137)
Browse files Browse the repository at this point in the history
Co-authored-by: YanHui <[email protected]>
  • Loading branch information
hiker90 and YanHui authored Jan 19, 2023
1 parent 56d1de5 commit f5c6870
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/date-picker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const DatePicker: React.FC<DatePickerProps> = (props: DatePickerProps) =>
const handleOnSelect = (currentValue: Date) => {
setControlledValue(currentValue);
setVisible(false);
onSelect?.(currentValue, formatDate(currentValue));
onSelect?.(currentValue, formatDate(currentValue) as string);
};

const content = (
Expand All @@ -67,7 +67,7 @@ export const DatePicker: React.FC<DatePickerProps> = (props: DatePickerProps) =>
placeholder={placeholder}
disabled={disabled}
allowClear={allowClear}
value={controlledValue && formatDate(controlledValue)}
value={controlledValue && (formatDate(controlledValue) as string)}
size={size}
suffix={suffix}
className={className}
Expand Down
42 changes: 37 additions & 5 deletions src/past-time-picker/PastTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { InputButton } from '../input';
import { PastTimePickerProps } from './interfaces';
import StaticPastTimePicker from '../static-past-time-picker';
import defaultLocale from '../static-past-time-picker/locales/zh-CN';
import { parseStartAndEndDate, parseQuickDate } from '../static-past-time-picker/utils';

const PastTimePicker = (props: PastTimePickerProps) => {
const {
Expand All @@ -32,6 +33,7 @@ const PastTimePicker = (props: PastTimePickerProps) => {
size,
className,
style,
showAbsDate = false,
...restProps
} = props;

Expand Down Expand Up @@ -110,17 +112,35 @@ const PastTimePicker = (props: PastTimePickerProps) => {
return defaultString;
}
if (has(QUICK_MAPPING, time)) {
return get(QUICK_MAPPING, time);
const [startTime, endTime] = parseQuickDate(time);
return showAbsDate
? `${get(QUICK_MAPPING, time)} | ${parseFnsTimeZone(startTime, 'yyyy/MM/dd')}-${parseFnsTimeZone(
endTime,
'yyyy/MM/dd'
)}`
: `${get(QUICK_MAPPING, time)}`;
}
const items = time.split(':');
const times = items[1].split(',').map((str) => parseInt(str, 10));
if (items[0] === 'since') {
const start = parseFnsTimeZone(times[0], 'yyyy/MM/dd');
return `${FromText} ${start} ${toTodayText}`;
const [startTime, endTime] = parseStartAndEndDate(time);
return showAbsDate
? `${FromText} ${start} ${toTodayText}${parseFnsTimeZone(startTime, 'yyyy/MM/dd')}-${parseFnsTimeZone(
endTime,
'yyyy/MM/dd'
)}`
: `${FromText} ${start} ${toTodayText}`;
}
if (items[0] === 'since-lt-today') {
const start = parseFnsTimeZone(times[0], 'yyyy/MM/dd');
return `${FromText} ${start} ${toYesterdayText}`;
const [startTime, endTime] = parseStartAndEndDate(time);
return showAbsDate
? `${FromText} ${start} ${toYesterdayText}${parseFnsTimeZone(startTime, 'yyyy/MM/dd')}-${parseFnsTimeZone(
endTime,
'yyyy/MM/dd'
)}`
: `${FromText} ${start} ${toYesterdayText}`;
}

if (items[0] === 'abs') {
Expand All @@ -129,10 +149,22 @@ const PastTimePicker = (props: PastTimePickerProps) => {
return `${FromText} ${start} ${ToText} ${end}`;
}
if (items[0] === 'day') {
const [startTime, endTime] = parseStartAndEndDate(time);

if (times[1] === 1) {
return `${lastText} ${times[0] - times[1]} ${dayText}`;
return showAbsDate
? `${lastText} ${times[0] - times[1]} ${dayText}${parseFnsTimeZone(
startTime,
'yyyy/MM/dd'
)}-${parseFnsTimeZone(endTime, 'yyyy/MM/dd')}`
: `${lastText} ${times[0] - times[1]} ${dayText}`;
}
return `${lastText} ${times[1]}-${times[0]} ${dayText}`;
return showAbsDate
? `${lastText} ${times[1]}-${times[0]} ${dayText}${parseFnsTimeZone(
startTime,
'yyyy/MM/dd'
)}-${parseFnsTimeZone(endTime, 'yyyy/MM/dd')}`
: `${lastText} ${times[1]}-${times[0]} ${dayText}`;
}
return defaultString;
};
Expand Down
5 changes: 5 additions & 0 deletions src/past-time-picker/demos/PastTimePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export const DisabledDate = () => {
return <PastTimePicker onSelect={action('selected value:')} placeholder="时间范围" disabledDate={disabledDate} />;
};

export const ShowAbsDate = Template.bind({});
ShowAbsDate.args = {
showAbsDate: true,
};

const StaticTemplate: Story<PastTimePickerProps> = (args) => (
<PastTimePicker.Static onSelect={action('selected value:')} placeholder="时间范围" {...args} />
);
Expand Down
4 changes: 4 additions & 0 deletions src/past-time-picker/demos/PastTimePickerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ export default function DatePickerPage() {
<Canvas>
<Story id="upgraded-pasttimepicker--disabled-date" />
</Canvas>
<Subheading>{formatMessage({ defaultMessage: '显示绝对日期' })}</Subheading>
<Canvas>
<Story id="upgraded-pasttimepicker--show-abs-date" />
</Canvas>
<Heading>{formatMessage({ defaultMessage: '参数说明' })}</Heading>
<ArgsTable of={PastTimePicker} />
</>
Expand Down
1 change: 1 addition & 0 deletions src/past-time-picker/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export interface PastTimePickerProps
*/
value?: string;
'data-testid'?: string;
showAbsDate?: boolean;
}
7 changes: 6 additions & 1 deletion src/static-past-time-picker/__tests__/utils.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { startOfToday, startOfYesterday } from 'date-fns';
import { TimeMode } from '../interfaces';
import { parseFixedMode, parseStartAndEndDate, parseTimeMode } from '../utils';
import { parseFixedMode, parseStartAndEndDate, parseTimeMode, parseQuickDate } from '../utils';

describe('test utils', () => {
it('parseTimeMode', () => {
Expand All @@ -20,6 +20,11 @@ describe('test utils', () => {
]);
expect(parseStartAndEndDate('xxx:1656115199999')).toStrictEqual([undefined, undefined]);
});
it('parseQuickDate', () => {
expect(parseQuickDate('day:1,0')).toStrictEqual([startOfToday(), startOfToday()]);
expect(parseQuickDate('day:2,1')).toStrictEqual([startOfYesterday(), startOfYesterday()]);
expect(parseQuickDate('xxx:1656115199999')).toStrictEqual([undefined, undefined]);
});
it('parseFixedMode', () => {
expect(parseFixedMode('day:2,1')).toBe('yesterday');
expect(parseFixedMode('since:1656115199999')).toBe('today');
Expand Down
41 changes: 41 additions & 0 deletions src/static-past-time-picker/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import has from 'lodash/has';
import { sub } from 'date-fns';
import momentTZ from 'moment-timezone';
import moment from 'moment';
import { TimeMode } from './interfaces';
import { QUICK_MAPPING } from './constant';

momentTZ.tz.setDefault(localStorage.getItem('timezone') || Intl.DateTimeFormat().resolvedOptions().timeZone);

export const parseTimeMode = (timeRange: string | undefined) => {
if (!timeRange) {
return undefined;
Expand Down Expand Up @@ -63,6 +66,44 @@ export const parseStartAndEndDate = (timeRange: string | undefined): [Date | und
return [undefined, undefined];
};

export const parseQuickDate = (timeRange: string | undefined): [Date | undefined, Date | undefined] => {
if (!timeRange || timeRange.split(':').length !== 2) {
return [undefined, undefined];
}
const items = timeRange.split(':');
const times = items[1].split(',').map((str) => parseInt(str, 10));
const today = startOfTodayInTimezone();

if (items[0] === 'day') {
return [sub(today, { days: times[0] - 1 }), sub(today, { days: times[1] })];
}
if (items[0] === 'week-lt-today') {
return [moment().subtract(times[0] - 1, 'week').startOf('isoWeek').toDate(), String(times[1]) === '0' ? moment().subtract(1, 'day').endOf('day').toDate() : moment().subtract(times[0] - 1, 'week').endOf('isoWeek').toDate()];
}
if (items[0] === 'month-lt-today') {
return [moment().subtract(times[0] - 1, 'month').startOf('month').toDate(), String(times[1]) === '0' ? moment().subtract(1, 'day').endOf('day').toDate() : moment().subtract(times[0] - 1, 'month').endOf('month').toDate()];
}
if (items[0] === 'quarter-lt-today') {
return [moment().subtract(times[0] - 1, 'quarter').startOf('quarter').toDate(), String(times[1]) === '0' ? moment().subtract(1, 'day').endOf('day').toDate() : moment().subtract(times[0] - 1, 'quarter').endOf('quarter').toDate()];
}
if (items[0] === 'year-lt-today') {
return [moment().subtract(times[0] - 1, 'year').startOf('year').toDate(), String(times[1]) === '0' ? moment().subtract(1, 'day').endOf('day').toDate() : moment().subtract(times[0] - 1, 'year').endOf('year').toDate()];
}
if (items[0] === 'week') {
return [moment().subtract(times[0] - 1, 'week').startOf('isoWeek').toDate(), String(times[1]) === '0' ? moment().endOf('day').toDate() : moment().subtract(times[0] - 1, 'week').endOf('isoWeek').toDate()];
}
if (items[0] === 'month') {
return [moment().subtract(times[0] - 1, 'month').startOf('month').toDate(), String(times[1]) === '0' ? moment().endOf('day').toDate() : moment().subtract(times[0] - 1, 'month').endOf('month').toDate()];
}
if (items[0] === 'quarter') {
return [moment().subtract(times[0] - 1, 'quarter').startOf('quarter').toDate(), String(times[1]) === '0' ? moment().endOf('day').toDate() : moment().subtract(times[0] - 1, 'quarter').endOf('quarter').toDate()];
}
if (items[0] === 'year') {
return [moment().subtract(times[0] - 1, 'year').startOf('year').toDate(), String(times[1]) === '0' ? moment().endOf('day').toDate() : moment().subtract(times[0] - 1, 'year').endOf('year').toDate()];
}
return [undefined, undefined];
}

export const parseFixedMode = (timeRange: string | undefined) => {
if (!timeRange || timeRange.split(':').length !== 2) {
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/time-picker/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const TimePicker: React.FC<TimePickerProps> = (props) => {
const handleOnOk = () => {
setControlledValue(time);
setVisible(false);
onSelect?.(time as Date, formatTime(time as Date));
onSelect?.(time as Date, formatTime(time as Date) as string);
};

const handleVisibleChange = (current: boolean) => {
Expand Down Expand Up @@ -100,7 +100,7 @@ export const TimePicker: React.FC<TimePickerProps> = (props) => {
prefix={prefix || <ClockOutlined />}
disabled={disabled}
allowClear={allowClear}
value={time && formatTime(time)}
value={time && (formatTime(time) as string)}
placeholder={placeholder ?? timeSelect}
size={size}
suffix={suffix}
Expand Down
4 changes: 3 additions & 1 deletion src/utils/timeHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import momentTZ from 'moment-timezone';
import moment from 'moment';
import { format as dateFnsFormat, utcToZonedTime } from 'date-fns-tz';

momentTZ.tz.setDefault(localStorage.getItem('timezone') || Intl.DateTimeFormat().resolvedOptions().timeZone);
// 时间日期转换时区 moment
export const parseTimeZone = (data?: any, format?: string) =>
momentTZ(data as string, format).tz(
localStorage.getItem('timezone') || Intl.DateTimeFormat().resolvedOptions().timeZone
);

// 时间日期转换时区 date-fns
export const parseFnsTimeZone = (date: number | Date | string, format: string) => {
export const parseFnsTimeZone = (date: number | Date | string | undefined, format: string) => {
if (!date) return date;
let finalDate = date;
if (isNumber(date)) {
finalDate = new Date(date);
Expand Down

1 comment on commit f5c6870

@vercel
Copy link

@vercel vercel bot commented on f5c6870 Jan 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

gio-design – ./

gio-design.vercel.app
gio-design-git-master-growingio.vercel.app
gio-design-growingio.vercel.app

Please sign in to comment.