Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): [date-ranger] improve func and add more props #810

Merged
merged 10 commits into from
Nov 7, 2024
22 changes: 13 additions & 9 deletions packages/ui/src/DateRanger/PickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,16 +243,15 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
return (
<div className={classNames(prefix)}>
<Space direction="vertical" size={12} style={{ margin: '12px 0' }}>
{tip && <Alert message={tip} type="info" showIcon></Alert>}
<Form
layout="vertical"
autoComplete="off"
requiredMark={false}
style={{ width: 280 }}
form={form}
>
<Row gutter={12}>
<Col span={15}>
<Row gutter={12} style={{ marginBottom: 4 }}>
<Col span={12} style={{ paddingLeft: 12 }}>
<Form.Item
name="startDate"
label={locale.startDate}
Expand Down Expand Up @@ -281,7 +280,7 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
/>
</Form.Item>
</Col>
<Col span={9} style={{ paddingRight: 0 }}>
<Col span={12} style={{ paddingRight: 8 }}>
<Form.Item
name="startTime"
label={locale.startTime}
Expand Down Expand Up @@ -311,7 +310,7 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
</Row>

<Row gutter={12}>
<Col span={15}>
<Col span={12} style={{ paddingLeft: 12 }}>
<Form.Item
name="endDate"
label={locale.endDate}
Expand Down Expand Up @@ -339,7 +338,7 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
/>
</Form.Item>
</Col>
<Col span={9} style={{ paddingRight: 0 }}>
<Col span={12} style={{ paddingRight: 8 }}>
<Form.Item
name="endTime"
label={locale.endTime}
Expand Down Expand Up @@ -368,7 +367,6 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
</Col>
</Row>
</Form>
{errorMessage && <Alert message={errorMessage} type="error" showIcon></Alert>}
</Space>
{wrapCSSVar(
<div
Expand Down Expand Up @@ -407,8 +405,14 @@ const InternalPickerPanel = (props: PickerPanelProps) => {
/>
</div>
)}
<Divider style={{ margin: '12px 0' }}></Divider>
<Space style={{ width: '100%', justifyContent: 'flex-end' }}>
<Divider style={{ margin: '8px 0' }}></Divider>
{tip && !errorMessage && (
<Alert message={tip} type="info" style={{ marginBottom: 8 }} showIcon></Alert>
)}
{errorMessage && (
<Alert message={errorMessage} type="error" style={{ marginBottom: 8 }} showIcon></Alert>
)}
<Space style={{ width: '100%', justifyContent: 'flex-end', padding: '0 12px 4px 0' }}>
<Button
size="small"
onClick={() => {
Expand Down
58 changes: 41 additions & 17 deletions packages/ui/src/DateRanger/Ranger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CaretRightOutlined,
RightOutlined,
ZoomOutOutlined,
SyncOutlined,
} from '@oceanbase/icons';
import type { RangePickerProps } from '@oceanbase/design/es/date-picker';
import type { Dayjs } from 'dayjs';
Expand All @@ -29,6 +30,8 @@ import {
NEAR_TIME_LIST,
YEAR_DATE_TIME_FORMAT,
LAST_3_DAYS,
DATE_TIME_SECOND_FORMAT,
YEAR_DATE_TIME_SECOND_FORMAT,
} from './constant';
import type { RangeOption } from './typing';
import InternalPickerPanel, { Rule } from './PickerPanel';
Expand All @@ -53,14 +56,24 @@ export interface DateRangerProps
// ui 相关
hasRewind?: boolean;
hasPlay?: boolean;
hasNow?: boolean;
hasSync?: boolean;
hasForward?: boolean;
hasZoomOut?: boolean;
// 是否在选项面板中展示Tag
hasTagInPicker?: boolean;
// 时间选择提示
tip?: string;
rules?: Rule[];
/** 是否只允许选择过去时间 */
pastOnly?: boolean;
// 是否启用极简模式
simpleMode?: boolean;
// 当时间范围在本年时,隐藏年份
hideYear?: boolean;
// 隐藏 秒
hideSecond?: boolean;
// 自动计算时间范围并回显到选择器tag
autoCalcRange?: boolean;
isMoment?: boolean;
//固定 rangeName
stickRangeName?: boolean;
Expand Down Expand Up @@ -89,10 +102,15 @@ const Ranger = (props: DateRangerProps) => {
defaultQuickValue,
hasRewind = true,
hasPlay = false,
hasNow = true,
hasSync = true,
hasForward = true,
hasZoomOut = false,
hasTagInPicker = false,
pastOnly = false,
simpleMode = false,
hideYear = false,
hideSecond = false,
autoCalcRange = false,
onChange = noop,
disabledDate,
locale,
Expand Down Expand Up @@ -200,6 +218,10 @@ const Ranger = (props: DateRangerProps) => {
const differenceYears = endTime?.diff(startTime as any, 'years');

const getCustomizeRangeLabel = () => {
if (!autoCalcRange) {
return locale.customize;
}

if (differenceYears > 0) {
return `${differenceYears}y`;
}
Expand Down Expand Up @@ -359,23 +381,18 @@ const Ranger = (props: DateRangerProps) => {
rangeChange(selected.range(isMoment ? moment() : dayjs()) as RangeValue);
}
},
items: [
...selects,
{
name: CUSTOMIZE,
rangeLabel: locale.customize,
label: locale.customTime,
},
]
items: selects
.filter(item => {
return !!item;
})
.map(item => {
return {
key: item.name,
label: (
<Space size={8}>
<span className={`${prefix}-label`}>{item.rangeLabel}</span>
<Space size={8} style={{ minWidth: 100 }}>
{hasTagInPicker && (
<span className={`${prefix}-label`}>{item.rangeLabel}</span>
)}
{/* @ts-ignore */}
{locale[item.label] || item.label}
</Space>
Expand All @@ -393,10 +410,10 @@ const Ranger = (props: DateRangerProps) => {
>
{rangeLabel}
</span>
{isPlay && <div className={`${prefix}-play`}>{label}</div>}
{simpleMode && isPlay && <div className={`${prefix}-play`}>{label}</div>}
</Space>
</Dropdown>
{!isPlay && (
{(!simpleMode || !isPlay) && (
<span
onClick={() => {
setOpen(true);
Expand All @@ -411,7 +428,14 @@ const Ranger = (props: DateRangerProps) => {
}}
format={v => {
// format 会影响布局,原先采用 v.year() === new Date().getFullYear() 进行判断,value 一共会传入三次(range0 range1 now), 会传入最新的时间导致判断异常
return isThisYear ? v.format(DATE_TIME_FORMAT) : v.format(YEAR_DATE_TIME_FORMAT);
if (hideYear && isThisYear) {
return hideSecond
? v.format(DATE_TIME_FORMAT)
: v.format(DATE_TIME_SECOND_FORMAT);
}
return hideSecond
? v.format(YEAR_DATE_TIME_FORMAT)
: v.format(YEAR_DATE_TIME_SECOND_FORMAT);
}}
// @ts-ignore
value={innerValue}
Expand Down Expand Up @@ -474,14 +498,14 @@ const Ranger = (props: DateRangerProps) => {
)}
</Radio.Group>
</Space>
{hasNow && (
{hasSync && (
<Button
style={{ paddingInline: 8 }}
onClick={() => {
setNow();
}}
>
{locale.current}
<SyncOutlined />
</Button>
)}
{hasZoomOut && (
Expand Down
37 changes: 16 additions & 21 deletions packages/ui/src/DateRanger/__test__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ describe('DateRanger', () => {
});
it('Support setting default quick value' /** 支持设置默认的快捷选项值 */, () => {
// NEAR_1_MINUTES is default value of defaultQuickValue
const { container } = render(<DateRanger />);
const { container } = render(<DateRanger hasTagInPicker simpleMode />);
expect(container.querySelector('.ob-date-ranger-label').textContent).toBe(
NEAR_1_MINUTES.rangeLabel
);
expect(container.querySelector('.ob-date-ranger-play').textContent).toBe(NEAR_1_MINUTES.label);

// Custom defaultQuickValue
const { container: containerWith30Minutes } = render(
<DateRanger defaultQuickValue={NEAR_30_MINUTES.name} />
<DateRanger defaultQuickValue={NEAR_30_MINUTES.name} hasTagInPicker simpleMode />
);
expect(containerWith30Minutes.querySelector('.ob-date-ranger-label').textContent).toBe(
NEAR_30_MINUTES.rangeLabel
Expand All @@ -38,7 +38,7 @@ describe('DateRanger', () => {
);
});
it('Should be simple mode when selected shortcut option' /** 选中快捷选项时,应当处于简单模式 */, () => {
const { container } = render(<DateRanger />);
const { container } = render(<DateRanger simpleMode />);
// As simple mode
expect(container.querySelector('.ob-date-ranger-play')).toBeTruthy();
expect(container.querySelector('.ob-date-ranger-picker')).toBeFalsy();
Expand All @@ -53,7 +53,9 @@ describe('DateRanger', () => {
});
suite('Panel shortcut options' /** 选择面板中的快捷选项 */, () => {
it('In simple mode, the shortcut option that is consistent with the ranger label should be selected' /** 在简单模式下,快捷选项应选中和ranger label 一致的快捷选项 */, () => {
const { container } = render(<DateRanger defaultQuickValue={NEAR_30_MINUTES.name} />);
const { container } = render(
<DateRanger defaultQuickValue={NEAR_30_MINUTES.name} hasTagInPicker simpleMode />
);
const dropdownTrigger = container.querySelector(
'.ob-date-ranger-wrapper > .ant-dropdown-trigger'
);
Expand All @@ -68,7 +70,11 @@ describe('DateRanger', () => {
});
it('In normal mode, the shortcut option should be selected custom item' /** 设置了时间值即为普通模式,选择面板中的快捷选项应当选中“自定义”项 */, () => {
const { container } = render(
<DateRanger defaultValue={[dayjs('2024/10/12'), dayjs('2024/10/20')]} />
<DateRanger
defaultValue={[dayjs('2024/10/12'), dayjs('2024/10/20')]}
hasTagInPicker
simpleMode
/>
);
const dropdownTrigger = container.querySelector(
'.ob-date-ranger-wrapper > .ant-dropdown-trigger'
Expand All @@ -78,15 +84,17 @@ describe('DateRanger', () => {
expect(
dropdownLayerPicker.querySelector(
'.ant-dropdown-menu .ant-dropdown-menu-item-selected .ob-date-ranger-label'
).textContent
).toBe('自定义');
)
).toBeFalsy();
});
it('Should selected shortcut option and close panel when click quick time item' /** 当点击快捷时间选项时应该选中该项的时间并关闭选择面板 */, () => {
let value = [dayjs('2024/10/12'), dayjs('2024/10/20')];
const onChange = vi.fn(v => {
value = v;
});
const { container } = render(<DateRanger value={value} onChange={onChange} />);
const { container } = render(
<DateRanger value={value} onChange={onChange} hasTagInPicker simpleMode />
);
const dropdownTrigger = container.querySelector(
'.ob-date-ranger-wrapper > .ant-dropdown-trigger'
);
Expand All @@ -102,18 +110,5 @@ describe('DateRanger', () => {
expect(dropdownTrigger.classList.contains('ant-dropdown-open')).toBeFalsy();
expect(document.querySelector('.ob-date-ranger-dropdown-picker')).toBeFalsy();
});
it('Should not close panel when select custom time option' /** 当选中“自定义时间”时不应该关闭选择面板 */, () => {
const { container } = render(<DateRanger />);
const dropdownTrigger = container.querySelector(
'.ob-date-ranger-wrapper > .ant-dropdown-trigger'
);
fireEvent.click(dropdownTrigger);
const dropdownLayerPicker = document.querySelector('.ob-date-ranger-dropdown-picker');
// By default, "CUSTOMIZE" is the last option.
fireEvent.click(dropdownLayerPicker.querySelector('.ant-dropdown-menu').lastChild);
// The panel should remain open when select the custom option.
expect(dropdownTrigger.classList.contains('ant-dropdown-open')).toBeTruthy();
expect(document.querySelector('.ob-date-ranger-dropdown-picker')).toBeTruthy();
});
});
});
2 changes: 2 additions & 0 deletions packages/ui/src/DateRanger/constant/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ const WEEK_UNIT = 'week';
const MONTH_UNIT = 'month';
const YEAR_UNIT = 'year';

export const YEAR_DATE_TIME_SECOND_FORMAT = 'YYYY-MM-DD HH:mm:ss';
export const YEAR_DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm';
export const DATE_TIME_SECOND_FORMAT = 'MM-DD HH:mm:ss';
export const DATE_TIME_FORMAT = 'MM-DD HH:mm';

export const NEAR_1_MINUTES: RangeOption = {
Expand Down
7 changes: 6 additions & 1 deletion packages/ui/src/DateRanger/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ nav:
| defaultQuickValue | 快速选择的默认值(优先级低于 value/defaultValue) | string | - | - |
| hasRewind | 后退按钮 | boolean | true | - |
| hasForward | 前进按钮 | boolean | true | - |
| hasNow | 当前按钮 | boolean | true | - |
| hasSync | 刷新按钮 | boolean | true | - |
| hasTagInPicker | 在选项面板中是否展示Tag | boolean | false | - |
| pastOnly | 只能选择过去时间 | boolean | false | - |
| disabledDate | 不可选择的日期 | (currentDate: Dayjs \| Moment) => boolean | - | - |
| simpleMode | 是否启用极简模式 | boolean | false | - |
| hideYear | 当时间范围在本年时,隐藏年份 | boolean | false | - |
| hideSecond | 隐藏"秒” | boolean | false | - |
| autoCalcRange | 自动计算时间范围并回显到选择器tag | boolean | false | - |
| 其他 antd/RangePicker 的 `props` | [antd-RangePicker](https://ant.design/components/date-picker-cn/#RangePicker) | - | - | - |

### RangeOption
Expand Down
Loading