This is an automated email from the ASF dual-hosted git repository. vogievetsky pushed a commit to branch segment_timeline2 in repository https://gitbox.apache.org/repos/asf/druid.git
commit 91af28e729930a8d86b58df3c4732a281a5cd509 Author: Vadim Ogievetsky <[email protected]> AuthorDate: Mon Nov 4 15:55:57 2024 -0800 more fixes --- .../src/components/segment-timeline/common.ts | 18 +++ .../segment-timeline/segment-timeline.scss | 4 +- .../segment-timeline/segment-timeline.tsx | 129 +++++++++------------ 3 files changed, 78 insertions(+), 73 deletions(-) diff --git a/web-console/src/components/segment-timeline/common.ts b/web-console/src/components/segment-timeline/common.ts index efd2a0b1b45..7371aada27f 100644 --- a/web-console/src/components/segment-timeline/common.ts +++ b/web-console/src/components/segment-timeline/common.ts @@ -22,6 +22,24 @@ import type { Duration } from '../../utils'; export type IntervalStat = 'segments' | 'size' | 'rows'; +export const INTERVAL_STATS: IntervalStat[] = ['segments', 'size', 'rows']; + +export function getIntervalStatTitle(intervalStat: IntervalStat): string { + switch (intervalStat) { + case 'segments': + return 'Num. segments'; + + case 'size': + return 'Size'; + + case 'rows': + return 'Rows'; + + default: + return intervalStat; + } +} + export function aggregateSegmentStats( xs: readonly Record<IntervalStat, number>[], ): Record<IntervalStat, number> { diff --git a/web-console/src/components/segment-timeline/segment-timeline.scss b/web-console/src/components/segment-timeline/segment-timeline.scss index 6582394869e..b1844016041 100644 --- a/web-console/src/components/segment-timeline/segment-timeline.scss +++ b/web-console/src/components/segment-timeline/segment-timeline.scss @@ -21,7 +21,7 @@ .segment-timeline { .control-bar { @include card-like; - height: 40px; + height: 34px; display: flex; align-items: start; padding: 5px; @@ -37,7 +37,7 @@ .chart-container { position: absolute; - top: 40px; + top: 34px; width: 100%; bottom: 0; overflow: hidden; diff --git a/web-console/src/components/segment-timeline/segment-timeline.tsx b/web-console/src/components/segment-timeline/segment-timeline.tsx index 92761368d53..81b26c04d8b 100644 --- a/web-console/src/components/segment-timeline/segment-timeline.tsx +++ b/web-console/src/components/segment-timeline/segment-timeline.tsx @@ -16,25 +16,17 @@ * limitations under the License. */ -import { - Button, - ButtonGroup, - FormGroup, - MenuItem, - Popover, - ResizeSensor, - SegmentedControl, -} from '@blueprintjs/core'; +import { Button, ButtonGroup, Menu, MenuItem, Popover, ResizeSensor } from '@blueprintjs/core'; import type { NonNullDateRange } from '@blueprintjs/datetime'; import { DateRangePicker3 } from '@blueprintjs/datetime2'; import { IconNames } from '@blueprintjs/icons'; import { Select } from '@blueprintjs/select'; -import type React from 'react'; import { useState } from 'react'; import type { Capabilities } from '../../helpers'; import { useQueryManager } from '../../hooks'; import { + checkedCircleIcon, day, Duration, getApiArray, @@ -48,6 +40,7 @@ import { import { Stage } from '../../utils/stage'; import type { IntervalStat } from './common'; +import { getIntervalStatTitle, INTERVAL_STATS } from './common'; import { SegmentBarChart } from './segment-bar-chart'; import './segment-timeline.scss'; @@ -102,45 +95,6 @@ export const SegmentTimeline = function SegmentTimeline(props: SegmentTimelinePr }, }); - const DatasourceSelect: React.FC = () => { - const datasourcesWzAll = [SHOW_ALL].concat(datasourcesState.data || []); - return ( - <Select<string> - items={datasourcesWzAll} - onItemSelect={(selectedItem: string) => { - setFocusDatasource(selectedItem === SHOW_ALL ? undefined : selectedItem); - }} - itemRenderer={(val, { handleClick, handleFocus, modifiers }) => { - if (!modifiers.matchesPredicate) return null; - return ( - <MenuItem - key={val} - disabled={modifiers.disabled} - active={modifiers.active} - onClick={handleClick} - onFocus={handleFocus} - roleStructure="listoption" - text={val} - /> - ); - }} - noResults={<MenuItem disabled text="No results" roleStructure="listoption" />} - itemPredicate={(query, val, _index, exactMatch) => { - const normalizedTitle = val.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return normalizedTitle.includes(normalizedQuery); - } - }} - > - <Button text={focusDatasource ?? SHOW_ALL} rightIcon={IconNames.CARET_DOWN} /> - </Select> - ); - }; - return ( <div className="segment-timeline"> <div className="control-bar"> @@ -208,30 +162,63 @@ export const SegmentTimeline = function SegmentTimeline(props: SegmentTimelinePr /> </Popover> </ButtonGroup> - <FormGroup label="Show" inline> - <SegmentedControl - value={activeSegmentStat} - onValueChange={s => setActiveSegmentStat(s as IntervalStat)} + <Popover + content={ + <Menu> + {INTERVAL_STATS.map(stat => ( + <MenuItem + key={stat} + icon={checkedCircleIcon(stat === activeSegmentStat)} + text={getIntervalStatTitle(stat)} + onClick={() => setActiveSegmentStat(stat)} + /> + ))} + </Menu> + } + > + <Button + text={`Stat: ${getIntervalStatTitle(activeSegmentStat)}`} + small + rightIcon={IconNames.CARET_DOWN} + /> + </Popover> + <Select<string> + items={[SHOW_ALL].concat(datasourcesState.data || [])} + onItemSelect={(selectedItem: string) => { + setFocusDatasource(selectedItem === SHOW_ALL ? undefined : selectedItem); + }} + itemRenderer={(val, { handleClick, handleFocus, modifiers }) => { + if (!modifiers.matchesPredicate) return null; + return ( + <MenuItem + key={val} + disabled={modifiers.disabled} + active={modifiers.active} + onClick={handleClick} + onFocus={handleFocus} + roleStructure="listoption" + text={val} + /> + ); + }} + noResults={<MenuItem disabled text="No results" roleStructure="listoption" />} + itemPredicate={(query, val, _index, exactMatch) => { + const normalizedTitle = val.toLowerCase(); + const normalizedQuery = query.toLowerCase(); + + if (exactMatch) { + return normalizedTitle === normalizedQuery; + } else { + return normalizedTitle.includes(normalizedQuery); + } + }} + > + <Button + text={`Datasource: ${focusDatasource ?? 'all'}`} small - options={[ - { - label: 'Size', - value: 'size', - }, - { - label: 'Num. rows', - value: 'rows', - }, - { - label: 'Num. segments', - value: 'segments', - }, - ]} + rightIcon={IconNames.CARET_DOWN} /> - </FormGroup> - <FormGroup label="Datasource" inline> - <DatasourceSelect /> - </FormGroup> + </Select> </div> <ResizeSensor onResize={(entries: ResizeObserverEntry[]) => { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
