You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by fj...@apache.org on 2019/07/31 14:13:37 UTC
[incubator-druid] branch master updated: Web console: better action
linking between views (#8203)
This is an automated email from the ASF dual-hosted git repository.
fjy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push:
new 15dd3d7 Web console: better action linking between views (#8203)
15dd3d7 is described below
commit 15dd3d7256f924341b21630a024a9124be581057
Author: Vadim Ogievetsky <va...@gmail.com>
AuthorDate: Wed Jul 31 07:13:25 2019 -0700
Web console: better action linking between views (#8203)
* better actions
* better action linking
---
.../components/center-message/center-message.tsx | 4 +-
.../src/components/show-history/show-history.tsx | 8 +-
web-console/src/components/show-log/show-log.tsx | 4 +-
web-console/src/console-application.tsx | 36 ++++---
.../compaction-dialog/compaction-dialog.spec.tsx | 2 +-
.../compaction-dialog/compaction-dialog.tsx | 23 +++--
.../segment-table-action-dialog.spec.tsx.snap | 58 +++++++++--
.../segment-table-action-dialog.spec.tsx | 2 +-
.../segment-table-action-dialog.tsx | 10 +-
.../supervisor-table-action-dialog.spec.tsx.snap | 88 +++++++++-------
.../supervisor-table-action-dialog.tsx | 4 +-
.../table-action-dialog.spec.tsx.snap | 3 -
.../table-action-dialog/table-action-dialog.tsx | 29 +++++-
.../task-table-action-dialog.spec.tsx.snap | 58 +++++++++--
.../task-table-action-dialog.tsx | 4 +-
web-console/src/utils/basic-action.tsx | 23 +----
.../src/views/datasource-view/datasource-view.tsx | 112 ++++++++++++++++-----
.../src/views/load-data-view/load-data-view.tsx | 5 +-
.../__snapshots__/segments-view.spec.tsx.snap | 2 +-
.../src/views/segments-view/segments-view.tsx | 7 +-
.../src/views/task-view/tasks-view.spec.tsx | 3 +-
web-console/src/views/task-view/tasks-view.tsx | 50 ++++++---
22 files changed, 374 insertions(+), 161 deletions(-)
diff --git a/web-console/src/components/center-message/center-message.tsx b/web-console/src/components/center-message/center-message.tsx
index 6e88141..c9f4b8c 100644
--- a/web-console/src/components/center-message/center-message.tsx
+++ b/web-console/src/components/center-message/center-message.tsx
@@ -24,9 +24,11 @@ export interface CenterMessageProps {}
export class CenterMessage extends React.PureComponent<CenterMessageProps> {
render(): JSX.Element {
+ const { children } = this.props;
+
return (
<div className="center-message bp3-input">
- <div className="center-message-inner">{this.props.children}</div>
+ <div className="center-message-inner">{children}</div>
</div>
);
}
diff --git a/web-console/src/components/show-history/show-history.tsx b/web-console/src/components/show-history/show-history.tsx
index 9fd2637..3dc20c3 100644
--- a/web-console/src/components/show-history/show-history.tsx
+++ b/web-console/src/components/show-history/show-history.tsx
@@ -42,7 +42,7 @@ export interface ShowHistoryState {
}
export class ShowHistory extends React.PureComponent<ShowHistoryProps, ShowHistoryState> {
- private showHistoryQueryManager: QueryManager<null, string>;
+ private showHistoryQueryManager: QueryManager<string, PastSupervisor[]>;
constructor(props: ShowHistoryProps, context: any) {
super(props, context);
this.state = {
@@ -51,8 +51,8 @@ export class ShowHistory extends React.PureComponent<ShowHistoryProps, ShowHisto
};
this.showHistoryQueryManager = new QueryManager({
- processQuery: async () => {
- const resp = await axios.get(this.props.endpoint);
+ processQuery: async (endpoint: string) => {
+ const resp = await axios.get(endpoint);
return resp.data;
},
onStateChange: ({ result, loading, error }) => {
@@ -66,7 +66,7 @@ export class ShowHistory extends React.PureComponent<ShowHistoryProps, ShowHisto
}
componentDidMount(): void {
- this.showHistoryQueryManager.runQuery(null);
+ this.showHistoryQueryManager.runQuery(this.props.endpoint);
}
render(): JSX.Element | null {
diff --git a/web-console/src/components/show-log/show-log.tsx b/web-console/src/components/show-log/show-log.tsx
index 801de24..9a6dddc 100644
--- a/web-console/src/components/show-log/show-log.tsx
+++ b/web-console/src/components/show-log/show-log.tsx
@@ -60,7 +60,9 @@ export class ShowLog extends React.PureComponent<ShowLogProps, ShowLogState> {
}
componentDidMount(): void {
- if (this.props.status === 'RUNNING') {
+ const { status } = this.props;
+
+ if (status === 'RUNNING') {
this.tail();
}
}
diff --git a/web-console/src/console-application.tsx b/web-console/src/console-application.tsx
index 08f253a..1898f39 100644
--- a/web-console/src/console-application.tsx
+++ b/web-console/src/console-application.tsx
@@ -105,13 +105,13 @@ export class ConsoleApplication extends React.PureComponent<
});
}
- private supervisorId: string | undefined;
- private taskId: string | undefined;
- private openDialog: string | undefined;
- private datasource: string | undefined;
- private onlyUnavailable: boolean | undefined;
- private initQuery: string | undefined;
- private middleManager: string | undefined;
+ private supervisorId?: string;
+ private taskId?: string;
+ private openDialog?: string;
+ private datasource?: string;
+ private onlyUnavailable?: boolean;
+ private initQuery?: string;
+ private middleManager?: string;
constructor(props: ConsoleApplicationProps, context: any) {
super(props, context);
@@ -158,27 +158,33 @@ export class ConsoleApplication extends React.PureComponent<
}, 50);
}
- private goToLoadDataView = (supervisorId?: string, taskId?: string) => {
+ private goToLoadData = (supervisorId?: string, taskId?: string) => {
if (taskId) this.taskId = taskId;
if (supervisorId) this.supervisorId = supervisorId;
window.location.hash = 'load-data';
this.resetInitialsWithDelay();
};
- private goToTask = (taskId: string | undefined, openDialog?: string) => {
- this.taskId = taskId;
- if (openDialog) this.openDialog = openDialog;
- window.location.hash = 'tasks';
+ private goToDatasources = (datasource: string) => {
+ this.datasource = datasource;
+ window.location.hash = 'datasources';
this.resetInitialsWithDelay();
};
private goToSegments = (datasource: string, onlyUnavailable = false) => {
- this.datasource = `"${datasource}"`;
+ this.datasource = datasource;
this.onlyUnavailable = onlyUnavailable;
window.location.hash = 'segments';
this.resetInitialsWithDelay();
};
+ private goToTask = (taskId: string | undefined, openDialog?: string) => {
+ this.taskId = taskId;
+ if (openDialog) this.openDialog = openDialog;
+ window.location.hash = 'tasks';
+ this.resetInitialsWithDelay();
+ };
+
private goToMiddleManager = (middleManager: string) => {
this.middleManager = middleManager;
window.location.hash = 'servers';
@@ -232,6 +238,7 @@ export class ConsoleApplication extends React.PureComponent<
return this.wrapInViewContainer(
'datasources',
<DatasourcesView
+ initDatasource={this.datasource}
goToQuery={this.goToQuery}
goToSegments={this.goToSegments}
noSqlMode={noSqlMode}
@@ -259,9 +266,10 @@ export class ConsoleApplication extends React.PureComponent<
<TasksView
taskId={this.taskId}
openDialog={this.openDialog}
+ goToDatasource={this.goToDatasources}
goToQuery={this.goToQuery}
goToMiddleManager={this.goToMiddleManager}
- goToLoadDataView={this.goToLoadDataView}
+ goToLoadData={this.goToLoadData}
noSqlMode={noSqlMode}
/>,
);
diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
index 44ae80b..c944313 100644
--- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
+++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
@@ -29,7 +29,7 @@ describe('compaction dialog', () => {
onSave={() => {}}
onDelete={() => {}}
datasource={'test'}
- configData={'test'}
+ compactionConfig={{}}
/>
);
render(compactionDialog);
diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
index 46976a5..f195145 100644
--- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
+++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
@@ -25,10 +25,10 @@ import './compaction-dialog.scss';
export interface CompactionDialogProps {
onClose: () => void;
- onSave: (config: any) => void;
+ onSave: (config: Record<string, any>) => void;
onDelete: () => void;
datasource: string;
- configData: any;
+ compactionConfig?: Record<string, any>;
}
export interface CompactionDialogState {
@@ -48,7 +48,7 @@ export class CompactionDialog extends React.PureComponent<
}
componentDidMount(): void {
- const { datasource, configData } = this.props;
+ const { datasource, compactionConfig } = this.props;
let config: Record<string, any> = {
dataSource: datasource,
inputSegmentSizeBytes: 419430400,
@@ -59,16 +59,23 @@ export class CompactionDialog extends React.PureComponent<
taskPriority: 25,
tuningConfig: null,
};
- if (configData !== undefined) {
- config = configData;
+ if (compactionConfig !== undefined) {
+ config = compactionConfig;
}
this.setState({
currentConfig: config,
});
}
+ private handleSubmit = () => {
+ const { onSave } = this.props;
+ const { currentConfig } = this.state;
+ if (!currentConfig) return;
+ onSave(currentConfig);
+ };
+
render(): JSX.Element {
- const { onClose, onSave, onDelete, datasource, configData } = this.props;
+ const { onClose, onDelete, datasource, compactionConfig } = this.props;
const { currentConfig, allJSONValid } = this.state;
return (
<Dialog
@@ -119,13 +126,13 @@ export class CompactionDialog extends React.PureComponent<
text="Delete"
intent={Intent.DANGER}
onClick={onDelete}
- disabled={configData === undefined}
+ disabled={!compactionConfig}
/>
<Button text="Close" onClick={onClose} />
<Button
text="Submit"
intent={Intent.PRIMARY}
- onClick={() => onSave(currentConfig)}
+ onClick={this.handleSubmit}
disabled={!currentConfig || !allJSONValid}
/>
</div>
diff --git a/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
index 139e218..ac1bc4d 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
@@ -150,16 +150,62 @@ exports[`task table action dialog matches snapshot 1`] = `
<div
class="footer-actions-left"
>
- <button
- class="bp3-button"
- type="button"
+ <span
+ class="bp3-popover-wrapper"
>
<span
- class="bp3-button-text"
+ class="bp3-popover-target"
>
- test
+ <button
+ class="bp3-button"
+ type="button"
+ >
+ <span
+ class="bp3-icon bp3-icon-wrench"
+ icon="wrench"
+ >
+ <svg
+ data-icon="wrench"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ wrench
+ </desc>
+ <path
+ d="M15.83 3.7l-3.06 3.05-2.84-.7-.7-2.83L12.29.17a5.004 5.004 0 00-4.83 1.29 4.967 4.967 0 00-1.12 5.36L.58 12.58c-.36.36-.58.86-.58 1.41 0 1.1.9 2 2 2 .55 0 1.05-.22 1.41-.59l5.77-5.77c1.79.69 3.91.33 5.35-1.12 1.32-1.3 1.74-3.15 1.3-4.81z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ <span
+ class="bp3-button-text"
+ >
+ Actions
+ </span>
+ <span
+ class="bp3-icon bp3-icon-caret-down"
+ icon="caret-down"
+ >
+ <svg
+ data-icon="caret-down"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ caret-down
+ </desc>
+ <path
+ d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ </button>
</span>
- </button>
+ </span>
</div>
<div
class="bp3-dialog-footer-actions"
diff --git a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
index e51a732..46e4c57 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
@@ -25,7 +25,7 @@ describe('task table action dialog', () => {
it('matches snapshot', () => {
const taskTableActionDialog = (
<SegmentTableActionDialog
- dataSourceId="test"
+ datasourceId="test"
segmentId="test"
actions={[{ title: 'test', onAction: () => null }]}
onClose={() => {}}
diff --git a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
index 37f4702..8a952e5 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
+++ b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
@@ -20,12 +20,12 @@ import { IDialogProps } from '@blueprintjs/core';
import React from 'react';
import { ShowJson } from '../../components';
-import { BasicAction, basicActionsToButtons } from '../../utils/basic-action';
+import { BasicAction } from '../../utils/basic-action';
import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
interface SegmentTableActionDialogProps extends IDialogProps {
segmentId?: string;
- dataSourceId?: string;
+ datasourceId?: string;
actions: BasicAction[];
onClose: () => void;
}
@@ -46,7 +46,7 @@ export class SegmentTableActionDialog extends React.PureComponent<
}
render(): React.ReactNode {
- const { segmentId, onClose, dataSourceId, actions } = this.props;
+ const { segmentId, onClose, datasourceId, actions } = this.props;
const { activeTab } = this.state;
const taskTableSideButtonMetadata: SideButtonMetaData[] = [
@@ -64,11 +64,11 @@ export class SegmentTableActionDialog extends React.PureComponent<
sideButtonMetadata={taskTableSideButtonMetadata}
onClose={onClose}
title={`Segment: ${segmentId}`}
- bottomButtons={basicActionsToButtons(actions)}
+ actions={actions}
>
{activeTab === 'metadata' && (
<ShowJson
- endpoint={`/druid/coordinator/v1/metadata/datasources/${dataSourceId}/segments/${segmentId}`}
+ endpoint={`/druid/coordinator/v1/metadata/datasources/${datasourceId}/segments/${segmentId}`}
downloadFilename={`Segment-metadata-${segmentId}.json`}
/>
)}
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
index f3aee74..2673cae 100755
--- a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
@@ -237,46 +237,62 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
<div
class="footer-actions-left"
>
- <button
- class="bp3-button"
- type="button"
- >
- <span
- class="bp3-button-text"
- >
- test
- </span>
- </button>
- <button
- class="bp3-button"
- type="button"
- >
- <span
- class="bp3-button-text"
- >
- test
- </span>
- </button>
- <button
- class="bp3-button"
- type="button"
- >
- <span
- class="bp3-button-text"
- >
- test
- </span>
- </button>
- <button
- class="bp3-button"
- type="button"
+ <span
+ class="bp3-popover-wrapper"
>
<span
- class="bp3-button-text"
+ class="bp3-popover-target"
>
- test
+ <button
+ class="bp3-button"
+ type="button"
+ >
+ <span
+ class="bp3-icon bp3-icon-wrench"
+ icon="wrench"
+ >
+ <svg
+ data-icon="wrench"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ wrench
+ </desc>
+ <path
+ d="M15.83 3.7l-3.06 3.05-2.84-.7-.7-2.83L12.29.17a5.004 5.004 0 00-4.83 1.29 4.967 4.967 0 00-1.12 5.36L.58 12.58c-.36.36-.58.86-.58 1.41 0 1.1.9 2 2 2 .55 0 1.05-.22 1.41-.59l5.77-5.77c1.79.69 3.91.33 5.35-1.12 1.32-1.3 1.74-3.15 1.3-4.81z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ <span
+ class="bp3-button-text"
+ >
+ Actions
+ </span>
+ <span
+ class="bp3-icon bp3-icon-caret-down"
+ icon="caret-down"
+ >
+ <svg
+ data-icon="caret-down"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ caret-down
+ </desc>
+ <path
+ d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ </button>
</span>
- </button>
+ </span>
</div>
<div
class="bp3-dialog-footer-actions"
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
index 94acb90..8720b78 100644
--- a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
@@ -22,7 +22,7 @@ import React from 'react';
import { ShowJson } from '../../components';
import { ShowHistory } from '../../components/show-history/show-history';
import { SupervisorStatisticsTable } from '../../components/supervisor-statistics-table/supervisor-statistics-table';
-import { BasicAction, basicActionsToButtons } from '../../utils/basic-action';
+import { BasicAction } from '../../utils/basic-action';
import { deepGet } from '../../utils/object-change';
import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
@@ -83,7 +83,7 @@ export class SupervisorTableActionDialog extends React.PureComponent<
sideButtonMetadata={supervisorTableSideButtonMetadata}
onClose={onClose}
title={`Supervisor: ${supervisorId}`}
- bottomButtons={basicActionsToButtons(actions)}
+ actions={actions}
>
{activeTab === 'status' && (
<ShowJson
diff --git a/web-console/src/dialogs/table-action-dialog/__snapshots__/table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/table-action-dialog/__snapshots__/table-action-dialog.spec.tsx.snap
index 00ff48a..ec333f3 100644
--- a/web-console/src/dialogs/table-action-dialog/__snapshots__/table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/table-action-dialog/__snapshots__/table-action-dialog.spec.tsx.snap
@@ -62,9 +62,6 @@ exports[`table action dialog matches snapshot 1`] = `
class="bp3-dialog-footer"
>
<div
- class="footer-actions-left"
- />
- <div
class="bp3-dialog-footer-actions"
>
<button
diff --git a/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx b/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
index 1e9209e..5182e34 100644
--- a/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
+++ b/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
@@ -16,9 +16,21 @@
* limitations under the License.
*/
-import { Button, Classes, Dialog, Icon, IconName, IDialogProps, Intent } from '@blueprintjs/core';
+import {
+ Button,
+ Classes,
+ Dialog,
+ Icon,
+ IconName,
+ IDialogProps,
+ Intent,
+ Popover,
+} from '@blueprintjs/core';
+import { IconNames } from '@blueprintjs/icons';
import React from 'react';
+import { BasicAction, basicActionsToMenu } from '../../utils/basic-action';
+
import './table-action-dialog.scss';
export interface SideButtonMetaData {
@@ -31,7 +43,7 @@ export interface SideButtonMetaData {
interface TableActionDialogProps extends IDialogProps {
sideButtonMetadata: SideButtonMetaData[];
onClose: () => void;
- bottomButtons?: React.ReactNode;
+ actions?: BasicAction[];
}
export class TableActionDialog extends React.PureComponent<TableActionDialogProps> {
@@ -41,7 +53,8 @@ export class TableActionDialog extends React.PureComponent<TableActionDialogProp
}
render(): JSX.Element {
- const { sideButtonMetadata, isOpen, onClose, title, bottomButtons } = this.props;
+ const { sideButtonMetadata, isOpen, onClose, title, actions, children } = this.props;
+ const actionsMenu = actions ? basicActionsToMenu(actions) : undefined;
return (
<Dialog className="table-action-dialog" isOpen={isOpen} onClose={onClose} title={title}>
@@ -59,10 +72,16 @@ export class TableActionDialog extends React.PureComponent<TableActionDialogProp
/>
))}
</div>
- <div className="main-section">{this.props.children}</div>
+ <div className="main-section">{children}</div>
</div>
<div className={Classes.DIALOG_FOOTER}>
- <div className="footer-actions-left">{bottomButtons}</div>
+ {actionsMenu && (
+ <div className="footer-actions-left">
+ <Popover content={actionsMenu}>
+ <Button icon={IconNames.WRENCH} text="Actions" rightIcon={IconNames.CARET_DOWN} />
+ </Popover>
+ </div>
+ )}
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button text="Close" intent={Intent.PRIMARY} onClick={onClose} />
</div>
diff --git a/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
index ac5c9c4..927f496 100644
--- a/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
@@ -237,16 +237,62 @@ exports[`task table action dialog matches snapshot 1`] = `
<div
class="footer-actions-left"
>
- <button
- class="bp3-button"
- type="button"
+ <span
+ class="bp3-popover-wrapper"
>
<span
- class="bp3-button-text"
+ class="bp3-popover-target"
>
- test
+ <button
+ class="bp3-button"
+ type="button"
+ >
+ <span
+ class="bp3-icon bp3-icon-wrench"
+ icon="wrench"
+ >
+ <svg
+ data-icon="wrench"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ wrench
+ </desc>
+ <path
+ d="M15.83 3.7l-3.06 3.05-2.84-.7-.7-2.83L12.29.17a5.004 5.004 0 00-4.83 1.29 4.967 4.967 0 00-1.12 5.36L.58 12.58c-.36.36-.58.86-.58 1.41 0 1.1.9 2 2 2 .55 0 1.05-.22 1.41-.59l5.77-5.77c1.79.69 3.91.33 5.35-1.12 1.32-1.3 1.74-3.15 1.3-4.81z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ <span
+ class="bp3-button-text"
+ >
+ Actions
+ </span>
+ <span
+ class="bp3-icon bp3-icon-caret-down"
+ icon="caret-down"
+ >
+ <svg
+ data-icon="caret-down"
+ height="16"
+ viewBox="0 0 16 16"
+ width="16"
+ >
+ <desc>
+ caret-down
+ </desc>
+ <path
+ d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+ fill-rule="evenodd"
+ />
+ </svg>
+ </span>
+ </button>
</span>
- </button>
+ </span>
</div>
<div
class="bp3-dialog-footer-actions"
diff --git a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
index be2faae..24caa78 100644
--- a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
+++ b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
@@ -20,7 +20,7 @@ import { IDialogProps } from '@blueprintjs/core';
import React from 'react';
import { ShowJson, ShowLog } from '../../components';
-import { BasicAction, basicActionsToButtons } from '../../utils/basic-action';
+import { BasicAction } from '../../utils/basic-action';
import { deepGet } from '../../utils/object-change';
import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
@@ -83,7 +83,7 @@ export class TaskTableActionDialog extends React.PureComponent<
sideButtonMetadata={taskTableSideButtonMetadata}
onClose={onClose}
title={`Task: ${taskId}`}
- bottomButtons={basicActionsToButtons(actions)}
+ actions={actions}
>
{activeTab === 'status' && (
<ShowJson
diff --git a/web-console/src/utils/basic-action.tsx b/web-console/src/utils/basic-action.tsx
index 5f4cf23..2d0e4f8 100644
--- a/web-console/src/utils/basic-action.tsx
+++ b/web-console/src/utils/basic-action.tsx
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-import { Button, IconName, Intent, Menu, MenuItem } from '@blueprintjs/core';
+import { IconName, Intent, Menu, MenuItem } from '@blueprintjs/core';
import React from 'react';
export interface BasicAction {
@@ -26,8 +26,8 @@ export interface BasicAction {
onAction: () => void;
}
-export function basicActionsToMenu(basicActions: BasicAction[]) {
- if (!basicActions.length) return null;
+export function basicActionsToMenu(basicActions: BasicAction[]): JSX.Element | undefined {
+ if (!basicActions.length) return;
return (
<Menu>
{basicActions.map((action, i) => (
@@ -42,20 +42,3 @@ export function basicActionsToMenu(basicActions: BasicAction[]) {
</Menu>
);
}
-
-export function basicActionsToButtons(basicActions: BasicAction[]) {
- if (!basicActions.length) return null;
- return (
- <>
- {basicActions.map((action, i) => (
- <Button
- key={i}
- icon={action.icon}
- text={action.title}
- intent={action.intent}
- onClick={action.onAction}
- />
- ))}
- </>
- );
-}
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx b/web-console/src/views/datasource-view/datasource-view.tsx
index 9390984..d9dfae1 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -84,12 +84,6 @@ function formatLoadDrop(segmentsToLoad: number, segmentsToDrop: number): string
return loadDrop.join(', ') || 'No segments to load/drop';
}
-export interface DatasourcesViewProps {
- goToQuery: (initSql: string) => void;
- goToSegments: (datasource: string, onlyUnavailable?: boolean) => void;
- noSqlMode: boolean;
-}
-
interface Datasource {
datasource: string;
rules: any[];
@@ -107,17 +101,34 @@ interface DatasourceQueryResultRow {
num_rows: number;
}
+interface RetentionDialogOpenOn {
+ datasource: string;
+ rules: any[];
+}
+
+interface CompactionDialogOpenOn {
+ datasource: string;
+ compactionConfig: Record<string, any>;
+}
+
+export interface DatasourcesViewProps {
+ goToQuery: (initSql: string) => void;
+ goToSegments: (datasource: string, onlyUnavailable?: boolean) => void;
+ noSqlMode: boolean;
+ initDatasource?: string;
+}
+
export interface DatasourcesViewState {
datasourcesLoading: boolean;
datasources: Datasource[] | null;
tiers: string[];
defaultRules: any[];
datasourcesError?: string;
- datasourcesFilter: Filter[];
+ datasourceFilter: Filter[];
showDisabled: boolean;
- retentionDialogOpenOn?: { datasource: string; rules: any[] };
- compactionDialogOpenOn?: { datasource: string; configData: any };
+ retentionDialogOpenOn?: RetentionDialogOpenOn;
+ compactionDialogOpenOn?: CompactionDialogOpenOn;
dropDataDatasource?: string;
enableDatasource?: string;
killDatasource?: string;
@@ -167,12 +178,18 @@ GROUP BY 1`;
constructor(props: DatasourcesViewProps, context: any) {
super(props, context);
+
+ const datasourceFilter: Filter[] = [];
+ if (props.initDatasource) {
+ datasourceFilter.push({ id: 'datasource', value: `"${props.initDatasource}"` });
+ }
+
this.state = {
datasourcesLoading: true,
datasources: null,
tiers: [],
defaultRules: [],
- datasourcesFilter: [],
+ datasourceFilter,
showDisabled: false,
dropReloadAction: 'drop',
@@ -422,9 +439,9 @@ GROUP BY 1`;
}}
>
<p>
- {`Are you sure you want to permanently delete the data in datasource '${killDatasource}'?`}
+ {`Are you sure you want to permanently delete the deep storage data for datasource '${killDatasource}'?`}
</p>
- <p>This action can not be undone.</p>
+ <p>This action is not reversible and the data deleted will be lost.</p>
</AsyncActionDialog>
);
}
@@ -514,7 +531,12 @@ GROUP BY 1`;
this.setState({ showDisabled: !showDisabled });
}
- getDatasourceActions(datasource: string, disabled: boolean): BasicAction[] {
+ getDatasourceActions(
+ datasource: string,
+ disabled: boolean,
+ rules: any[],
+ compactionConfig: Record<string, any>,
+ ): BasicAction[] {
const { goToQuery } = this.props;
if (disabled) {
@@ -526,7 +548,7 @@ GROUP BY 1`;
},
{
icon: IconNames.TRASH,
- title: 'Permanently delete (kill task)',
+ title: 'Delete segments (issue kill task)',
intent: Intent.DANGER,
onAction: () => this.setState({ killDatasource: datasource }),
},
@@ -539,6 +561,30 @@ GROUP BY 1`;
onAction: () => goToQuery(`SELECT * FROM "${datasource}"`),
},
{
+ icon: IconNames.AUTOMATIC_UPDATES,
+ title: 'Edit retention rules',
+ onAction: () => {
+ this.setState({
+ retentionDialogOpenOn: {
+ datasource,
+ rules,
+ },
+ });
+ },
+ },
+ {
+ icon: IconNames.COMPRESSED,
+ title: 'Edit compaction configuration',
+ onAction: () => {
+ this.setState({
+ compactionDialogOpenOn: {
+ datasource,
+ compactionConfig,
+ },
+ });
+ },
+ },
+ {
icon: IconNames.EXPORT,
title: 'Reload data by interval',
onAction: () =>
@@ -556,6 +602,12 @@ GROUP BY 1`;
intent: Intent.DANGER,
onAction: () => this.setState({ dropDataDatasource: datasource }),
},
+ {
+ icon: IconNames.TRASH,
+ title: 'Delete unused segments (issue kill task)',
+ intent: Intent.DANGER,
+ onAction: () => this.setState({ killDatasource: datasource }),
+ },
];
}
}
@@ -584,7 +636,7 @@ GROUP BY 1`;
return (
<CompactionDialog
datasource={compactionDialogOpenOn.datasource}
- configData={compactionDialogOpenOn.configData}
+ compactionConfig={compactionDialogOpenOn.compactionConfig}
onClose={() => this.setState({ compactionDialogOpenOn: undefined })}
onSave={this.saveCompaction}
onDelete={this.deleteCompaction}
@@ -599,7 +651,7 @@ GROUP BY 1`;
defaultRules,
datasourcesLoading,
datasourcesError,
- datasourcesFilter,
+ datasourceFilter,
showDisabled,
hiddenColumns,
showChart,
@@ -619,9 +671,9 @@ GROUP BY 1`;
: datasourcesError || ''
}
filterable
- filtered={datasourcesFilter}
+ filtered={datasourceFilter}
onFilteredChange={filtered => {
- this.setState({ datasourcesFilter: filtered });
+ this.setState({ datasourceFilter: filtered });
}}
columns={[
{
@@ -634,7 +686,7 @@ GROUP BY 1`;
<a
onClick={() => {
this.setState({
- datasourcesFilter: addFilter(datasourcesFilter, 'datasource', value),
+ datasourceFilter: addFilter(datasourceFilter, 'datasource', value),
});
}}
>
@@ -759,10 +811,6 @@ GROUP BY 1`;
filterable: false,
Cell: row => {
const { compaction } = row.original;
- const compactionOpenOn: { datasource: string; configData: any } | null = {
- datasource: row.original.datasource,
- configData: compaction,
- };
let text: string;
if (compaction) {
text = `Target: ${formatBytes(compaction.targetCompactionSizeBytes)}`;
@@ -772,7 +820,14 @@ GROUP BY 1`;
return (
<span
className="clickable-cell"
- onClick={() => this.setState({ compactionDialogOpenOn: compactionOpenOn })}
+ onClick={() =>
+ this.setState({
+ compactionDialogOpenOn: {
+ datasource: row.original.datasource,
+ compactionConfig: compaction,
+ },
+ })
+ }
>
{text}
<ActionIcon icon={IconNames.EDIT} />
@@ -813,8 +868,13 @@ GROUP BY 1`;
filterable: false,
Cell: row => {
const datasource = row.value;
- const { disabled } = row.original;
- const datasourceActions = this.getDatasourceActions(datasource, disabled);
+ const { disabled, rules, compaction } = row.original;
+ const datasourceActions = this.getDatasourceActions(
+ datasource,
+ disabled,
+ rules,
+ compaction,
+ );
return <ActionCell actions={datasourceActions} />;
},
show: hiddenColumns.exists(ActionCell.COLUMN_LABEL),
diff --git a/web-console/src/views/load-data-view/load-data-view.tsx b/web-console/src/views/load-data-view/load-data-view.tsx
index 59bfc5d..acfe43d 100644
--- a/web-console/src/views/load-data-view/load-data-view.tsx
+++ b/web-console/src/views/load-data-view/load-data-view.tsx
@@ -348,13 +348,14 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
}
componentDidMount(): void {
+ const { initTaskId, initSupervisorId } = this.props;
const { spec } = this.state;
this.getOverlordModules();
- if (this.props.initTaskId) {
+ if (initTaskId) {
this.updateStep('loading');
this.getTaskJson();
- } else if (this.props.initSupervisorId) {
+ } else if (initSupervisorId) {
this.updateStep('loading');
this.getSupervisorJson();
} else if (isEmptyIngestionSpec(spec)) {
diff --git a/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap b/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
index 70e4003..189a921 100755
--- a/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
+++ b/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
@@ -259,7 +259,7 @@ exports[`segments-view matches snapshot 1`] = `
Array [
Object {
"id": "datasource",
- "value": "test",
+ "value": "\\"test\\"",
},
]
}
diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx
index 8ec0cc8..18583ff 100644
--- a/web-console/src/views/segments-view/segments-view.tsx
+++ b/web-console/src/views/segments-view/segments-view.tsx
@@ -137,7 +137,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
super(props, context);
const segmentFilter: Filter[] = [];
- if (props.datasource) segmentFilter.push({ id: 'datasource', value: props.datasource });
+ if (props.datasource) segmentFilter.push({ id: 'datasource', value: `"${props.datasource}"` });
if (props.onlyUnavailable) segmentFilter.push({ id: 'is_available', value: 'false' });
this.state = {
@@ -291,7 +291,8 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
}
componentDidMount(): void {
- if (this.props.noSqlMode) {
+ const { noSqlMode } = this.props;
+ if (noSqlMode) {
this.segmentsNoSqlQueryManager.runQuery(null);
}
}
@@ -673,7 +674,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
{segmentTableActionDialogId && (
<SegmentTableActionDialog
segmentId={segmentTableActionDialogId}
- dataSourceId={datasourceTableActionDialogId}
+ datasourceId={datasourceTableActionDialogId}
actions={actions}
onClose={() => this.setState({ segmentTableActionDialogId: undefined })}
isOpen
diff --git a/web-console/src/views/task-view/tasks-view.spec.tsx b/web-console/src/views/task-view/tasks-view.spec.tsx
index 93bc323..3616695 100644
--- a/web-console/src/views/task-view/tasks-view.spec.tsx
+++ b/web-console/src/views/task-view/tasks-view.spec.tsx
@@ -27,9 +27,10 @@ describe('tasks view', () => {
<TasksView
openDialog={'test'}
taskId={'test'}
+ goToDatasource={() => {}}
goToQuery={() => {}}
goToMiddleManager={() => {}}
- goToLoadDataView={() => {}}
+ goToLoadData={() => {}}
noSqlMode={false}
/>,
);
diff --git a/web-console/src/views/task-view/tasks-view.tsx b/web-console/src/views/task-view/tasks-view.tsx
index 9480d3c..d94265a 100644
--- a/web-console/src/views/task-view/tasks-view.tsx
+++ b/web-console/src/views/task-view/tasks-view.tsx
@@ -79,9 +79,10 @@ const taskTableColumns: string[] = [
export interface TasksViewProps {
taskId: string | undefined;
openDialog: string | undefined;
+ goToDatasource: (datasource: string) => void;
goToQuery: (initSql: string) => void;
goToMiddleManager: (middleManager: string) => void;
- goToLoadDataView: (supervisorId?: string, taskId?: string) => void;
+ goToLoadData: (supervisorId?: string, taskId?: string) => void;
noSqlMode: boolean;
}
@@ -350,13 +351,22 @@ ORDER BY "rank" DESC, "created_time" DESC`;
supervisorSuspended: boolean,
type: string,
): BasicAction[] {
+ const { goToDatasource, goToLoadData } = this.props;
+
const actions: BasicAction[] = [];
if (type === 'kafka' || type === 'kinesis') {
- actions.push({
- icon: IconNames.CLOUD_UPLOAD,
- title: 'Open in data loader',
- onAction: () => this.props.goToLoadDataView(id),
- });
+ actions.push(
+ {
+ icon: IconNames.MULTI_SELECT,
+ title: 'Go to datasource',
+ onAction: () => goToDatasource(id),
+ },
+ {
+ icon: IconNames.CLOUD_UPLOAD,
+ title: 'Open in data loader',
+ onAction: () => goToLoadData(id),
+ },
+ );
}
actions.push(
{
@@ -604,13 +614,27 @@ ORDER BY "rank" DESC, "created_time" DESC`;
);
}
- private getTaskActions(id: string, status: string, type: string): BasicAction[] {
+ private getTaskActions(
+ id: string,
+ datasource: string,
+ status: string,
+ type: string,
+ ): BasicAction[] {
+ const { goToDatasource, goToLoadData } = this.props;
+
const actions: BasicAction[] = [];
+ if (datasource && status === 'SUCCESS') {
+ actions.push({
+ icon: IconNames.MULTI_SELECT,
+ title: 'Go to datasource',
+ onAction: () => goToDatasource(datasource),
+ });
+ }
if (type === 'index' || type === 'index_parallel') {
actions.push({
icon: IconNames.CLOUD_UPLOAD,
title: 'Open in data loader',
- onAction: () => this.props.goToLoadDataView(undefined, id),
+ onAction: () => goToLoadData(undefined, id),
});
}
if (status === 'RUNNING' || status === 'WAITING' || status === 'PENDING') {
@@ -811,8 +835,8 @@ ORDER BY "rank" DESC, "created_time" DESC`;
if (row.aggregated) return '';
const id = row.value;
const type = row.row.type;
- const { status } = row.original;
- const taskActions = this.getTaskActions(id, status, type);
+ const { datasource, status } = row.original;
+ const taskActions = this.getTaskActions(id, datasource, status, type);
return (
<ActionCell
onDetail={() =>
@@ -949,7 +973,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
}
render(): JSX.Element {
- const { goToQuery, goToLoadDataView, noSqlMode } = this.props;
+ const { goToQuery, goToLoadData, noSqlMode } = this.props;
const {
groupTasksBy,
supervisorSpecDialogOpen,
@@ -969,7 +993,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
<MenuItem
icon={IconNames.CLOUD_UPLOAD}
text="Go to data loader"
- onClick={() => goToLoadDataView()}
+ onClick={() => goToLoadData()}
/>
<MenuItem
icon={IconNames.MANUALLY_ENTERED_DATA}
@@ -984,7 +1008,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
<MenuItem
icon={IconNames.CLOUD_UPLOAD}
text="Go to data loader"
- onClick={() => goToLoadDataView()}
+ onClick={() => goToLoadData()}
/>
<MenuItem
icon={IconNames.MANUALLY_ENTERED_DATA}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org