From 23d6ed006733d946574f9744a74a354cfcd34c80 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Fri, 14 Mar 2025 16:09:06 -0700 Subject: [PATCH 1/5] show loader on aux queries --- .../src/utils/query-manager/query-manager.ts | 4 +- .../src/views/lookups-view/lookups-view.tsx | 23 +++---- .../src/views/segments-view/segments-view.tsx | 25 ++++---- .../src/views/services-view/services-view.tsx | 23 +++---- .../supervisors-view/supervisors-view.tsx | 35 ++++++----- .../src/views/tasks-view/tasks-view.tsx | 60 ++++++++++++++----- 6 files changed, 104 insertions(+), 66 deletions(-) diff --git a/web-console/src/utils/query-manager/query-manager.ts b/web-console/src/utils/query-manager/query-manager.ts index 1023b23412ad..0b7fcf5680ed 100644 --- a/web-console/src/utils/query-manager/query-manager.ts +++ b/web-console/src/utils/query-manager/query-manager.ts @@ -246,8 +246,8 @@ export class QueryManager { } private trigger() { - if (this.currentRunCancelFn) { - // Currently loading + if (this.currentRunCancelFn && !this.state.auxiliaryLoading) { + // Currently loading main query void this.runWhenLoading(); } else { this.setState( diff --git a/web-console/src/views/lookups-view/lookups-view.tsx b/web-console/src/views/lookups-view/lookups-view.tsx index 25f45455e224..39b7a920f1cb 100644 --- a/web-console/src/views/lookups-view/lookups-view.tsx +++ b/web-console/src/views/lookups-view/lookups-view.tsx @@ -332,17 +332,18 @@ export class LookupsView extends React.PureComponent ( - - {row.value} - - ); + return function FilterableCell(row: { value: any }) { + return ( + + {row.value} + + ); + }; } private renderLookupsTable() { diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx index ff3b0f76d8b7..c5bbcbffde69 100644 --- a/web-console/src/views/segments-view/segments-view.tsx +++ b/web-console/src/views/segments-view/segments-view.tsx @@ -516,18 +516,19 @@ export class SegmentsView extends React.PureComponent ( - - {valueFn(row.value)} - - ); + return function FilterableCell(row: { value: any }) { + return ( + + {valueFn(row.value)} + + ); + }; } renderSegmentsTable() { diff --git a/web-console/src/views/services-view/services-view.tsx b/web-console/src/views/services-view/services-view.tsx index 2a68eaed1cdc..b4de19e89482 100644 --- a/web-console/src/views/services-view/services-view.tsx +++ b/web-console/src/views/services-view/services-view.tsx @@ -366,17 +366,18 @@ ORDER BY private renderFilterableCell(field: string) { const { filters, onFiltersChange } = this.props; - // eslint-disable-next-line react/display-name - return (row: { value: any }) => ( - - {row.value} - - ); + return function FilterableCell(row: { value: any }) { + return ( + + {row.value} + + ); + }; } renderServicesTable() { diff --git a/web-console/src/views/supervisors-view/supervisors-view.tsx b/web-console/src/views/supervisors-view/supervisors-view.tsx index a81fda3d7f00..08decc6178a5 100644 --- a/web-console/src/views/supervisors-view/supervisors-view.tsx +++ b/web-console/src/views/supervisors-view/supervisors-view.tsx @@ -67,6 +67,7 @@ import { changeByIndex, checkedCircleIcon, deepGet, + filterMap, formatByteRate, formatBytes, formatInteger, @@ -333,9 +334,11 @@ export class SupervisorsView extends React.PureComponent< if (visibleColumns.shown('Stats')) { auxiliaryQueries.push( - ...supervisors.map( - (supervisor, i): AuxiliaryQueryFn => - async (rows, cancelToken) => { + ...filterMap( + supervisors, + (supervisor, i): AuxiliaryQueryFn | undefined => { + if (oneOf(supervisor.type, 'autocompact', 'scheduled_batch')) return; // These supervisors do not report stats + return async (rows, cancelToken) => { const stats = ( await Api.instance.get( `/druid/indexer/v1/supervisor/${Api.encodePath( @@ -345,7 +348,8 @@ export class SupervisorsView extends React.PureComponent< ) ).data; return changeByIndex(rows, i, row => ({ ...row, stats })); - }, + }; + }, ), ); } @@ -662,17 +666,18 @@ export class SupervisorsView extends React.PureComponent< private renderSupervisorFilterableCell(field: string) { const { filters, onFiltersChange } = this.props; - // eslint-disable-next-line react/display-name - return (row: { value: any }) => ( - - {row.value} - - ); + return function SupervisorFilterableCell(row: { value: any }) { + return ( + + {row.value} + + ); + }; } private onSupervisorDetail(supervisor: SupervisorQueryResultRow) { diff --git a/web-console/src/views/tasks-view/tasks-view.tsx b/web-console/src/views/tasks-view/tasks-view.tsx index 7dc9b2ab5b00..5972f5ef7ead 100644 --- a/web-console/src/views/tasks-view/tasks-view.tsx +++ b/web-console/src/views/tasks-view/tasks-view.tsx @@ -18,7 +18,8 @@ import { Button, ButtonGroup, Intent, Label, MenuItem, Tag } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; -import React from 'react'; +import { formatDistanceToNow } from 'date-fns'; +import React, { type ReactNode } from 'react'; import type { Filter } from 'react-table'; import ReactTable from 'react-table'; @@ -319,20 +320,26 @@ ORDER BY ); } - private renderTaskFilterableCell(field: string) { + private renderTaskFilterableCell( + field: string, + enableComparisons = false, + valueFn: (value: string) => ReactNode = String, + ) { const { filters, onFiltersChange } = this.props; - // eslint-disable-next-line react/display-name - return (row: { value: any }) => ( - - {row.value} - - ); + return function TaskFilterableCell(row: { value: any }) { + return ( + + {valueFn(row.value)} + + ); + }; } private onTaskDetail(task: TaskQueryResultRow) { @@ -473,7 +480,16 @@ ORDER BY Header: 'Created time', accessor: 'created_time', width: 190, - Cell: this.renderTaskFilterableCell('created_time'), + Cell: this.renderTaskFilterableCell('created_time', true, value => { + const valueAsDate = new Date(value); + return isNaN(valueAsDate.valueOf()) ? ( + String(value) + ) : ( + + {value} + + ); + }), Aggregated: () => '', show: visibleColumns.shown('Created time'), }, @@ -486,7 +502,21 @@ ORDER BY Cell({ value, original, aggregated }) { if (aggregated) return ''; if (value > 0) { - return formatDuration(value); + const shownDuration = formatDuration(value); + + const start = new Date(original.created_time); + if (isNaN(start.valueOf())) return shownDuration; + + const end = new Date(start.valueOf() + value); + return ( + + {shownDuration} + + ); } if (oneOf(original.status, 'RUNNING', 'PENDING') && original.created_time) { // Compute running duration from the created time if it exists From 7ac71dcc039e3d0f7fad97d22da2dbe79df1db65 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 19 Mar 2025 15:34:36 -0700 Subject: [PATCH 2/5] show supervisors if not on page 0 --- web-console/src/views/segments-view/segments-view.tsx | 2 +- web-console/src/views/supervisors-view/supervisors-view.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx index c5bbcbffde69..ef44b83dc6ff 100644 --- a/web-console/src/views/segments-view/segments-view.tsx +++ b/web-console/src/views/segments-view/segments-view.tsx @@ -581,7 +581,7 @@ export class SegmentsView extends React.PureComponent this.setState({ pageSize })} pageSizeOptions={STANDARD_TABLE_PAGE_SIZE_OPTIONS} - showPagination={segments.length >= STANDARD_TABLE_PAGE_SIZE} + showPagination={segments.length >= STANDARD_TABLE_PAGE_SIZE || page > 0} showPageJump={false} ofText="" pivotBy={groupByInterval ? ['interval'] : []} diff --git a/web-console/src/views/supervisors-view/supervisors-view.tsx b/web-console/src/views/supervisors-view/supervisors-view.tsx index 08decc6178a5..719b993e3165 100644 --- a/web-console/src/views/supervisors-view/supervisors-view.tsx +++ b/web-console/src/views/supervisors-view/supervisors-view.tsx @@ -736,7 +736,7 @@ export class SupervisorsView extends React.PureComponent< pageSize={pageSize} onPageSizeChange={pageSize => this.setState({ pageSize })} pageSizeOptions={SMALL_TABLE_PAGE_SIZE_OPTIONS} - showPagination={supervisors.length >= SMALL_TABLE_PAGE_SIZE} + showPagination={supervisors.length >= SMALL_TABLE_PAGE_SIZE || page > 0} showPageJump={false} ofText="" columns={[ From f76d54025dfdd8281933c3ef01f45e5d9c75634a Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 19 Mar 2025 16:14:51 -0700 Subject: [PATCH 3/5] refactor --- web-console/src/react-table/index.ts | 2 +- .../{react-table-utils.spec.ts => react-table-filters.spec.ts} | 2 +- .../{react-table-utils.ts => react-table-filters.ts} | 0 web-console/src/react-table/react-table-inputs.tsx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename web-console/src/react-table/{react-table-utils.spec.ts => react-table-filters.spec.ts} (98%) rename web-console/src/react-table/{react-table-utils.ts => react-table-filters.ts} (100%) diff --git a/web-console/src/react-table/index.ts b/web-console/src/react-table/index.ts index 3f1900fb6109..65b62cff5b4d 100644 --- a/web-console/src/react-table/index.ts +++ b/web-console/src/react-table/index.ts @@ -16,6 +16,6 @@ * limitations under the License. */ +export * from './react-table-filters'; export * from './react-table-inputs'; export * from './react-table-pagination/react-table-pagination'; -export * from './react-table-utils'; diff --git a/web-console/src/react-table/react-table-utils.spec.ts b/web-console/src/react-table/react-table-filters.spec.ts similarity index 98% rename from web-console/src/react-table/react-table-utils.spec.ts rename to web-console/src/react-table/react-table-filters.spec.ts index 1dd245b49f70..03737825cbd9 100644 --- a/web-console/src/react-table/react-table-utils.spec.ts +++ b/web-console/src/react-table/react-table-filters.spec.ts @@ -20,7 +20,7 @@ import { sqlQueryCustomTableFilter, stringToTableFilters, tableFiltersToString, -} from './react-table-utils'; +} from './react-table-filters'; describe('react-table-utils', () => { describe('sqlQueryCustomTableFilter', () => { diff --git a/web-console/src/react-table/react-table-utils.ts b/web-console/src/react-table/react-table-filters.ts similarity index 100% rename from web-console/src/react-table/react-table-utils.ts rename to web-console/src/react-table/react-table-filters.ts diff --git a/web-console/src/react-table/react-table-inputs.tsx b/web-console/src/react-table/react-table-inputs.tsx index 79932b490e4f..6794cff42822 100644 --- a/web-console/src/react-table/react-table-inputs.tsx +++ b/web-console/src/react-table/react-table-inputs.tsx @@ -31,7 +31,7 @@ import { filterModeToIcon, filterModeToTitle, parseFilterModeAndNeedle, -} from './react-table-utils'; +} from './react-table-filters'; interface FilterRendererProps { column: Column; From b5ebd2b8075fd73eb5035c20bab399b28fc63021 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Thu, 20 Mar 2025 15:18:42 -0700 Subject: [PATCH 4/5] fix bug fetching data when columns are added or removed --- .../datasources-view/datasources-view.tsx | 39 +++++++------------ .../src/views/services-view/services-view.tsx | 11 ++++-- .../supervisors-view/supervisors-view.tsx | 1 + 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/web-console/src/views/datasources-view/datasources-view.tsx b/web-console/src/views/datasources-view/datasources-view.tsx index 4921027100ad..ea0df40bb0a4 100644 --- a/web-console/src/views/datasources-view/datasources-view.tsx +++ b/web-console/src/views/datasources-view/datasources-view.tsx @@ -527,9 +527,7 @@ GROUP BY 1, 2`; return datasourcesAndDefaultRules; } }); - } - - if (capabilities.hasOverlordAccess()) { + } else if (capabilities.hasOverlordAccess()) { auxiliaryQueries.push(async (datasourcesAndDefaultRules, cancelToken) => { try { const taskList = await getApiArray( @@ -684,14 +682,14 @@ GROUP BY 1, 2`; } }; - private fetchDatasourceData() { + private readonly fetchData = () => { const { capabilities } = this.props; const { visibleColumns, showUnused } = this.state; this.datasourceQueryManager.runQuery({ capabilities, visibleColumns, showUnused }); - } + }; componentDidMount(): void { - this.fetchDatasourceData(); + this.fetchData(); } componentWillUnmount(): void { @@ -730,9 +728,7 @@ GROUP BY 1, 2`; onClose={() => { this.setState({ datasourceToMarkAsUnusedAllSegmentsIn: undefined }); }} - onSuccess={() => { - this.fetchDatasourceData(); - }} + onSuccess={this.fetchData} >

{`Are you sure you want to mark as unused all segments in '${datasourceToMarkAsUnusedAllSegmentsIn}'?`} @@ -774,9 +770,7 @@ GROUP BY 1, 2`; onClose={() => { this.setState({ datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: undefined }); }} - onSuccess={() => { - this.fetchDatasourceData(); - }} + onSuccess={this.fetchData} >

{`Are you sure you want to mark as used all non-overshadowed segments in '${datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn}'?`}

@@ -811,9 +805,7 @@ GROUP BY 1, 2`; onClose={() => { this.setState({ datasourceToMarkSegmentsByIntervalIn: undefined }); }} - onSuccess={() => { - this.fetchDatasourceData(); - }} + onSuccess={this.fetchData} >

{`Please select the interval in which you want to mark segments as ${usedWord} in '${datasourceToMarkSegmentsByIntervalIn}'?`}

@@ -840,9 +832,7 @@ GROUP BY 1, 2`; onClose={() => { this.setState({ killDatasource: undefined }); }} - onSuccess={() => { - this.fetchDatasourceData(); - }} + onSuccess={this.fetchData} /> ); } @@ -930,7 +920,7 @@ GROUP BY 1, 2`; message: 'Retention rules submitted successfully', intent: Intent.SUCCESS, }); - this.fetchDatasourceData(); + this.fetchData(); }; private readonly editDefaultRules = () => { @@ -956,7 +946,7 @@ GROUP BY 1, 2`; try { await Api.instance.post(`/druid/coordinator/v1/config/compaction`, compactionConfig); this.setState({ compactionDialogOpenOn: undefined }); - this.fetchDatasourceData(); + this.fetchData(); } catch (e) { AppToaster.show({ message: getDruidErrorMessage(e), @@ -980,7 +970,7 @@ GROUP BY 1, 2`; await Api.instance.delete( `/druid/coordinator/v1/config/compaction/${Api.encodePath(datasource)}`, ); - this.setState({ compactionDialogOpenOn: undefined }, () => this.fetchDatasourceData()); + this.setState({ compactionDialogOpenOn: undefined }, () => this.fetchData()); } catch (e) { AppToaster.show({ message: getDruidErrorMessage(e), @@ -995,7 +985,7 @@ GROUP BY 1, 2`; private toggleUnused(showUnused: boolean) { this.setState({ showUnused: !showUnused }, () => { if (showUnused) return; - this.fetchDatasourceData(); + this.fetchData(); }); } @@ -1759,10 +1749,7 @@ GROUP BY 1, 2`; visibleColumns: prevState.visibleColumns.toggle(column), })) } - onClose={added => { - if (!added) return; - this.fetchDatasourceData(); - }} + onClose={this.fetchData} tableColumnsHidden={visibleColumns.getHiddenColumns()} /> diff --git a/web-console/src/views/services-view/services-view.tsx b/web-console/src/views/services-view/services-view.tsx index b4de19e89482..58dca1410348 100644 --- a/web-console/src/views/services-view/services-view.tsx +++ b/web-console/src/views/services-view/services-view.tsx @@ -354,15 +354,19 @@ ORDER BY } componentDidMount(): void { - const { capabilities } = this.props; - const { visibleColumns } = this.state; - this.serviceQueryManager.runQuery({ capabilities, visibleColumns }); + this.fetchData(); } componentWillUnmount(): void { this.serviceQueryManager.terminate(); } + private readonly fetchData = () => { + const { capabilities } = this.props; + const { visibleColumns } = this.state; + this.serviceQueryManager.runQuery({ capabilities, visibleColumns }); + }; + private renderFilterableCell(field: string) { const { filters, onFiltersChange } = this.props; @@ -838,6 +842,7 @@ ORDER BY visibleColumns: prevState.visibleColumns.toggle(column), })) } + onClose={this.fetchData} tableColumnsHidden={visibleColumns.getHiddenColumns()} /> diff --git a/web-console/src/views/supervisors-view/supervisors-view.tsx b/web-console/src/views/supervisors-view/supervisors-view.tsx index 719b993e3165..8b692c26bfd1 100644 --- a/web-console/src/views/supervisors-view/supervisors-view.tsx +++ b/web-console/src/views/supervisors-view/supervisors-view.tsx @@ -1174,6 +1174,7 @@ export class SupervisorsView extends React.PureComponent< visibleColumns: prevState.visibleColumns.toggle(column), })) } + onClose={this.fetchData} tableColumnsHidden={visibleColumns.getHiddenColumns()} /> From c5a5310be2deec9c66b10974c72a361f6d60ebeb Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Thu, 20 Mar 2025 15:19:54 -0700 Subject: [PATCH 5/5] update test --- .../services-view/__snapshots__/services-view.spec.tsx.snap | 1 + .../__snapshots__/supervisors-view.spec.tsx.snap | 1 + 2 files changed, 2 insertions(+) diff --git a/web-console/src/views/services-view/__snapshots__/services-view.spec.tsx.snap b/web-console/src/views/services-view/__snapshots__/services-view.spec.tsx.snap index b304833a8cce..2cf28b8b22ca 100644 --- a/web-console/src/views/services-view/__snapshots__/services-view.spec.tsx.snap +++ b/web-console/src/views/services-view/__snapshots__/services-view.spec.tsx.snap @@ -62,6 +62,7 @@ exports[`ServicesView renders data 1`] = ` ] } onChange={[Function]} + onClose={[Function]} tableColumnsHidden={[]} /> diff --git a/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap b/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap index a3fdd9212785..84b5cbe6e34a 100644 --- a/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap +++ b/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap @@ -93,6 +93,7 @@ exports[`SupervisorsView matches snapshot 1`] = ` ] } onChange={[Function]} + onClose={[Function]} tableColumnsHidden={[]} />