Skip to content

Commit

Permalink
ui: open TimeScaleDropdown directly to the custom menu when custom is…
Browse files Browse the repository at this point in the history
… selected

Fixes cockroachdb#78499

This commit modifies the TimeScaleDropdown so that if a custom time is currently
select it opens directly to the custom selection menu, and a "Preset Time
Ranges" navigation link to go to the preset options from the custom menu.

This commit also cleans up the unused DateRange component.

Release note (ui): The time picker now opens directly to the custom time
selection menu when a custom time is already selected. A "Preset Time Ranges"
navigation link has been added to go to the preset options from the custom
menu.
  • Loading branch information
jocrl committed May 25, 2022
1 parent c03f7a0 commit a798c0a
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 184 deletions.
16 changes: 0 additions & 16 deletions pkg/ui/workspaces/cluster-ui/src/dateRange/dateRange.fixtures.tsx

This file was deleted.

32 changes: 0 additions & 32 deletions pkg/ui/workspaces/cluster-ui/src/dateRange/dateRange.stories.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
@import "../core/index.module";

.popup-container {
width: 506px;
height: 240px;
.popup-content {
.icon {
font-size: 13px;
margin-right: 3px;
}

.return-to-preset-options-wrapper {
padding-top: 10px;
padding-bottom: 10px;

:global(.ant-popover-arrow) {
display: none;
a {
// Matches the color of .ant-dropdown, needed to override default anchor color. A cleaner way would be to install
// and set up antd-scss-theme-plugin, and use the antd text-color variable.
color: rgba(0, 0, 0, 0.65);
}
}
}

.popup-content {
.label {
display: block;
}
Expand Down Expand Up @@ -43,18 +50,3 @@
margin-left: 8px;
}
}

.date-range-form {
width: 300px;
height: 40px;

:global(.ant-input-affix-wrapper) {
height: 40px;
&:hover {
:global(.ant-input:not(.ant-input-disabled)) {
border-color: $colors--primary-blue-3;
border-right-width: 2px !important;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,24 @@
// licenses/APL.txt.

import React, { useState } from "react";
import { Alert, DatePicker, Form, Input, Popover, TimePicker } from "antd";
import { Alert, DatePicker, Icon, TimePicker } from "antd";
import moment, { Moment } from "moment";
import classNames from "classnames/bind";
import { Time as TimeIcon, ErrorCircleFilled } from "@cockroachlabs/icons";
import { Button } from "src/button";
import { Text, TextTypes } from "src/text";

import styles from "./dateRange.module.scss";
import styles from "./dateRangeMenu.module.scss";

const cx = classNames.bind(styles);

function rangeToString(start: Moment, end: Moment): string {
const formatStr = "MMM D, H:mm";
const formatStrSameDay = "H:mm";

const isSameDay = start.isSame(end, "day");
return `${start.utc().format(formatStr)} - ${end
.utc()
.format(isSameDay ? formatStrSameDay : formatStr)} (UTC)`;
}

type DateRangeMenuProps = {
startInit?: Moment;
endInit?: Moment;
allowedInterval?: [Moment, Moment];
onSubmit: (start: Moment, end: Moment) => void;
onCancel: () => void;
onReturnToPresetOptionsClick: () => void;
};

export const dateFormat = "MMMM D, YYYY";
Expand All @@ -47,6 +38,7 @@ export function DateRangeMenu({
allowedInterval,
onSubmit,
onCancel,
onReturnToPresetOptionsClick,
}: DateRangeMenuProps): React.ReactElement {
/**
* Local startMoment and endMoment state are stored here so that users can change the time before clicking "Apply".
Expand Down Expand Up @@ -108,6 +100,12 @@ export function DateRangeMenu({

return (
<div className={cx("popup-content")}>
<div className={cx("return-to-preset-options-wrapper")}>
<a onClick={onReturnToPresetOptionsClick}>
<Icon type={"arrow-left"} className={cx("icon")} />
<Text textType={TextTypes.BodyStrong}>Preset Time Ranges</Text>
</a>
</div>
<Text className={cx("label")} textType={TextTypes.BodyStrong}>
Start (UTC)
</Text>
Expand Down Expand Up @@ -169,61 +167,3 @@ export function DateRangeMenu({
</div>
);
}

type DateRangeProps = {
start: Moment;
end: Moment;
allowedInterval?: [Moment, Moment];
onSubmit: (start: Moment, end: Moment) => void;
};

export function DateRange({
allowedInterval,
start,
end,
onSubmit,
}: DateRangeProps): React.ReactElement {
const [menuVisible, setMenuVisible] = useState<boolean>(false);
const displayStr = rangeToString(start, end);

const onVisibleChange = (visible: boolean): void => {
setMenuVisible(visible);
};

const closeMenu = (): void => {
setMenuVisible(false);
};

const _onSubmit = (start: Moment, end: Moment) => {
onSubmit(start, end);
closeMenu();
};

const menu = (
<DateRangeMenu
allowedInterval={allowedInterval}
startInit={start}
endInit={end}
onSubmit={_onSubmit}
onCancel={closeMenu}
/>
);

return (
<Form className={cx("date-range-form")}>
<Form.Item>
<Popover
destroyTooltipOnHide
content={menu}
overlayClassName={cx("popup-container")}
placement="bottomLeft"
visible={menuVisible}
onVisibleChange={onVisibleChange}
trigger="click"
>
<Input value={displayStr} prefix={<TimeIcon />} />
</Popover>
</Form.Item>
</Form>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

export * from "./dateRange";
export * from "./dateRangeMenu";
87 changes: 60 additions & 27 deletions pkg/ui/workspaces/cluster-ui/src/timeScaleDropdown/rangeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import React, { useState, useRef } from "react";
import { Button, Dropdown } from "antd";
import moment, { Moment } from "moment";
import { DateRangeMenu } from "src/dateRange";
import { DateRangeMenu } from "src/dateRangeMenu";
import { CaretDown } from "src/icon/caretDown";
import classNames from "classnames/bind";

Expand All @@ -38,9 +38,8 @@ export type Selected = {

interface RangeSelectProps {
options: RangeOption[];
onChange: (arg0: RangeOption) => void;
changeDate: (dateRange: [moment.Moment, moment.Moment]) => void;
onClosed?: () => void;
onPresetOptionSelect: (arg0: RangeOption) => void;
onCustomSelect: (dateRange: [moment.Moment, moment.Moment]) => void;
selected: Selected;
}

Expand Down Expand Up @@ -82,42 +81,75 @@ const OptionButton = ({ option, onClick, isSelected }: OptionButtonProps) => {

const RangeSelect = ({
options,
onChange,
changeDate,
onClosed,
onPresetOptionSelect,
onCustomSelect,
selected,
}: RangeSelectProps): React.ReactElement => {
const [isVisible, setIsVisible] = useState<boolean>(false);
const [custom, setCustom] = useState<boolean>(false);
/**
* customDropdownOptionWasJustSelected holds whether the user had just clicked the "Custom date range" option in
* the dropdown menu.
* It is NOT whether the user had just selected a custom time by clicking "Apply".
*/
const [
customDropdownOptionWasJustSelected,
setCustomDropdownOptionWasJustSelected,
] = useState<boolean>(false);

/**
* customBackWasJustSelected holds whether the "Back", as in back to preset options, button in the custom menu was
* just selected.
*/
const [
customBackWasJustSelected,
setReturnToPresetOptionsWasJustSelected,
] = useState<boolean>(false);

const rangeContainer = useRef<HTMLDivElement>();

const onChangeDate = (start: Moment, end: Moment) => {
closeDropdown();
changeDate([start, end]);
const handleEvent = (
eventIsSelectingCustomDropdownOption: boolean,
eventIsReturnToPresetOptions: boolean,
) => {
setCustomDropdownOptionWasJustSelected(
eventIsSelectingCustomDropdownOption,
);
setReturnToPresetOptionsWasJustSelected(eventIsReturnToPresetOptions);
};

const onVisibleChange = (visible: boolean): void => {
handleEvent(false, false);
setIsVisible(visible);
};

const closeDropdown = () => {
setCustom(false);
setIsVisible(false);
if (onClosed) {
onClosed();
}
onVisibleChange(false);
};

const handleOptionButtonOnClick = (option: RangeOption): void => {
const onDropdownOptionClick = (option: RangeOption): void => {
if (option.value === "Custom") {
setCustom(true);
// Switch to showing the DateRangeMenu, for users to select a custom time. The dropdown remains open.
handleEvent(true, false);
return;
}
onPresetOptionSelect(option);
closeDropdown();
onChange(option);
};

const onVisibleChange = (visible: boolean): void => {
setIsVisible(visible);
const onCustomSelectWrapper = (start: Moment, end: Moment) => {
onCustomSelect([start, end]);
closeDropdown();
};

const onReturnToPresetOptionsClick = () => {
handleEvent(false, true);
};

const selectedIsCustom = selected.key === "Custom";
const shouldShowCustom =
customDropdownOptionWasJustSelected ||
(selectedIsCustom && !customBackWasJustSelected);

const menu = (
<>
{/**
Expand All @@ -132,16 +164,17 @@ const RangeSelect = ({
<div
className={cx(
"range-selector",
`${custom ? "__custom" : "__options"}`,
`${shouldShowCustom ? "__custom" : "__options"}`,
)}
>
{custom ? (
{shouldShowCustom ? (
<div className={cx("custom-menu")}>
<DateRangeMenu
startInit={selected.timeWindow.start}
endInit={selected.timeWindow.end}
onSubmit={onChangeDate}
onCancel={() => setCustom(false)}
onSubmit={onCustomSelectWrapper}
onCancel={closeDropdown}
onReturnToPresetOptionsClick={onReturnToPresetOptionsClick}
/>
</div>
) : (
Expand All @@ -151,7 +184,7 @@ const RangeSelect = ({
key={option.label}
isSelected={selected.key === option.value}
option={option}
onClick={handleOptionButtonOnClick}
onClick={onDropdownOptionClick}
/>
))}
</div>
Expand All @@ -176,7 +209,7 @@ const RangeSelect = ({
<div>
<TimeLabel>{selected.timeLabel}</TimeLabel>
<span className={cx("Select-value-label", "title")}>
{selected.key !== "Custom" ? (
{!selectedIsCustom ? (
selected.key
) : (
<>
Expand Down
Loading

0 comments on commit a798c0a

Please sign in to comment.