You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by cw...@apache.org on 2019/09/12 09:42:44 UTC
[incubator-druid] branch 0.16.0-incubating updated: Web console:
Force intervals config (#8514) (#8521)
This is an automated email from the ASF dual-hosted git repository.
cwylie pushed a commit to branch 0.16.0-incubating
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/0.16.0-incubating by this push:
new eb75cb8 Web console: Force intervals config (#8514) (#8521)
eb75cb8 is described below
commit eb75cb8a9d1f41c969ec0ad709a293521dceb77a
Author: Clint Wylie <cw...@apache.org>
AuthorDate: Thu Sep 12 02:42:34 2019 -0700
Web console: Force intervals config (#8514) (#8521)
* make sure intervals are required
* all truncated values everywhere
* continue to spec when going from tasks table
* remove unused thigns
* fix alert
---
.../src/components/array-input/array-input.tsx | 6 ++-
web-console/src/components/auto-form/auto-form.tsx | 8 ++-
.../src/components/table-cell/table-cell.tsx | 60 ++++++++++++++--------
web-console/src/utils/ingestion-spec.tsx | 6 +--
.../src/views/load-data-view/load-data-view.tsx | 39 ++++++++------
.../parse-data-table/parse-data-table.spec.tsx | 1 -
.../parse-data-table/parse-data-table.tsx | 3 +-
7 files changed, 75 insertions(+), 48 deletions(-)
diff --git a/web-console/src/components/array-input/array-input.tsx b/web-console/src/components/array-input/array-input.tsx
index 5411f6f..de4fbd0 100644
--- a/web-console/src/components/array-input/array-input.tsx
+++ b/web-console/src/components/array-input/array-input.tsx
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-import { TextArea } from '@blueprintjs/core';
+import { Intent, TextArea } from '@blueprintjs/core';
import React from 'react';
import { compact } from '../../utils';
@@ -28,6 +28,7 @@ export interface ArrayInputProps {
placeholder?: string;
large?: boolean;
disabled?: boolean;
+ intent?: Intent;
}
export class ArrayInput extends React.PureComponent<ArrayInputProps, { stringValue: string }> {
@@ -51,7 +52,7 @@ export class ArrayInput extends React.PureComponent<ArrayInputProps, { stringVal
};
render(): JSX.Element {
- const { className, placeholder, large, disabled } = this.props;
+ const { className, placeholder, large, disabled, intent } = this.props;
const { stringValue } = this.state;
return (
<TextArea
@@ -61,6 +62,7 @@ export class ArrayInput extends React.PureComponent<ArrayInputProps, { stringVal
placeholder={placeholder}
large={large}
disabled={disabled}
+ intent={intent}
fill
/>
);
diff --git a/web-console/src/components/auto-form/auto-form.tsx b/web-console/src/components/auto-form/auto-form.tsx
index 15c3f51..4ff5856 100644
--- a/web-console/src/components/auto-form/auto-form.tsx
+++ b/web-console/src/components/auto-form/auto-form.tsx
@@ -244,15 +244,21 @@ export class AutoForm<T extends Record<string, any>> extends React.PureComponent
private renderStringArrayInput(field: Field<T>): JSX.Element {
const { model, large } = this.props;
+ const modelValue = deepGet(model as any, field.name);
return (
<ArrayInput
- values={deepGet(model as any, field.name) || []}
+ values={modelValue || []}
onChange={(v: any) => {
this.fieldChange(field, v);
}}
placeholder={field.placeholder}
large={large}
disabled={AutoForm.evaluateFunctor(field.disabled, model)}
+ intent={
+ AutoForm.evaluateFunctor(field.required, model) && modelValue == null
+ ? Intent.PRIMARY
+ : undefined
+ }
/>
);
}
diff --git a/web-console/src/components/table-cell/table-cell.tsx b/web-console/src/components/table-cell/table-cell.tsx
index 5a6b535..8d019fe 100644
--- a/web-console/src/components/table-cell/table-cell.tsx
+++ b/web-console/src/components/table-cell/table-cell.tsx
@@ -19,15 +19,19 @@
import { IconNames } from '@blueprintjs/icons';
import React from 'react';
+import { ShowValueDialog } from '../../dialogs/show-value-dialog/show-value-dialog';
import { ActionIcon } from '../action-icon/action-icon';
import './table-cell.scss';
-export interface NullTableCellProps {
+export interface TableCellProps {
value?: any;
timestamp?: boolean;
unparseable?: boolean;
- openModal?: (str: string) => void;
+}
+
+export interface TableCellState {
+ showValue?: string;
}
interface ShortParts {
@@ -36,26 +40,9 @@ interface ShortParts {
suffix: string;
}
-export class TableCell extends React.PureComponent<NullTableCellProps> {
+export class TableCell extends React.PureComponent<TableCellProps, TableCellState> {
static MAX_CHARS_TO_SHOW = 50;
- possiblyTruncate(str: string): React.ReactNode {
- if (str.length <= TableCell.MAX_CHARS_TO_SHOW) return str;
-
- const { prefix, omitted, suffix } = TableCell.shortenString(str);
- return (
- <span className="table-cell truncated">
- {prefix}
- <span className="omitted">{omitted}</span>
- {suffix}
- <ActionIcon
- icon={IconNames.MORE}
- onClick={() => (this.props.openModal ? this.props.openModal(str) : null)}
- />
- </span>
- );
- }
-
static shortenString(str: string): ShortParts {
// Print something like:
// BAAAArAAEiQKpDAEAACwZCBAGSBgiSEAAAAQpAIDwAg...23 omitted...gwiRoQBJIC
@@ -69,6 +56,35 @@ export class TableCell extends React.PureComponent<NullTableCellProps> {
};
}
+ constructor(props: TableCellProps) {
+ super(props);
+ this.state = {};
+ }
+
+ private renderShowValueDialog(): JSX.Element | undefined {
+ const { showValue } = this.state;
+ if (!showValue) return;
+
+ return (
+ <ShowValueDialog onClose={() => this.setState({ showValue: undefined })} str={showValue} />
+ );
+ }
+
+ private renderTruncated(str: string): React.ReactNode {
+ if (str.length <= TableCell.MAX_CHARS_TO_SHOW) return str;
+
+ const { prefix, omitted, suffix } = TableCell.shortenString(str);
+ return (
+ <span className="table-cell truncated">
+ {prefix}
+ <span className="omitted">{omitted}</span>
+ {suffix}
+ <ActionIcon icon={IconNames.MORE} onClick={() => this.setState({ showValue: str })} />
+ {this.renderShowValueDialog()}
+ </span>
+ );
+ }
+
render(): React.ReactNode {
const { value, timestamp, unparseable } = this.props;
if (unparseable) {
@@ -81,9 +97,9 @@ export class TableCell extends React.PureComponent<NullTableCellProps> {
</span>
);
} else if (Array.isArray(value)) {
- return this.possiblyTruncate(`[${value.join(', ')}]`);
+ return this.renderTruncated(`[${value.join(', ')}]`);
} else {
- return this.possiblyTruncate(String(value));
+ return this.renderTruncated(String(value));
}
} else {
if (timestamp) {
diff --git a/web-console/src/utils/ingestion-spec.tsx b/web-console/src/utils/ingestion-spec.tsx
index aa04bf3..952d3ba 100644
--- a/web-console/src/utils/ingestion-spec.tsx
+++ b/web-console/src/utils/ingestion-spec.tsx
@@ -588,7 +588,7 @@ export interface GranularitySpec {
queryGranularity?: string;
segmentGranularity?: string;
rollup?: boolean;
- intervals?: string;
+ intervals?: string | string[];
}
export interface MetricSpec {
@@ -1541,11 +1541,11 @@ export interface TuningConfig {
fetchThreads?: number;
}
-export function invalidTuningConfig(tuningConfig: TuningConfig): boolean {
+export function invalidTuningConfig(tuningConfig: TuningConfig, intervals: any): boolean {
return Boolean(
tuningConfig.type === 'index_parallel' &&
tuningConfig.forceGuaranteedRollup &&
- !tuningConfig.numShards,
+ (!tuningConfig.numShards || !intervals),
);
}
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 00eb64b..87e1853 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
@@ -50,7 +50,6 @@ import {
Loader,
} from '../../components';
import { AsyncActionDialog } from '../../dialogs';
-import { ShowValueDialog } from '../../dialogs/show-value-dialog/show-value-dialog';
import { AppToaster } from '../../singletons/toaster';
import { UrlBaser } from '../../singletons/url-baser';
import {
@@ -251,8 +250,6 @@ export interface LoadDataViewState {
showResetConfirm: boolean;
newRollup?: boolean;
newDimensionMode?: DimensionMode;
- showViewValueModal: boolean;
- str: string;
// welcome
overlordModules?: string[];
@@ -317,8 +314,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
// dialogs / modals
showResetConfirm: false,
- showViewValueModal: false,
- str: '',
// general
sampleStrategy: 'start',
@@ -507,7 +502,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
{step === 'loading' && this.renderLoading()}
{this.renderResetConfirm()}
- {this.renderViewValueModal()}
</div>
);
}
@@ -651,15 +645,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
);
}
- renderViewValueModal(): JSX.Element | undefined {
- const { showViewValueModal, str } = this.state;
- if (!showViewValueModal) return;
-
- return (
- <ShowValueDialog onClose={() => this.setState({ showViewValueModal: false })} str={str} />
- );
- }
-
renderWelcomeStepMessage(): JSX.Element | undefined {
const { selectedComboType, exampleManifests } = this.state;
@@ -1225,7 +1210,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
)}
</div>
<ParseDataTable
- openModal={str => this.setState({ showViewValueModal: true, str: str })}
sampleData={parserQueryState.data}
columnFilter={columnFilter}
canFlatten={canFlatten}
@@ -2649,6 +2633,25 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
model={tuningConfig}
onChange={t => this.updateSpec(deepSet(spec, 'tuningConfig', t))}
/>
+ <AutoForm
+ fields={[
+ {
+ name: 'dataSchema.granularitySpec.intervals',
+ label: 'Time intervals',
+ type: 'string-array',
+ placeholder: 'ex: 2018-01-01/2018-06-01',
+ required: s => Boolean(deepGet(s, 'tuningConfig.forceGuaranteedRollup')),
+ info: (
+ <>
+ A comma separated list of intervals for the raw data being ingested. Ignored for
+ real-time ingestion.
+ </>
+ ),
+ },
+ ]}
+ model={spec}
+ onChange={s => this.updateSpec(s)}
+ />
</div>
<div className="control">
<Callout className="intro">
@@ -2658,7 +2661,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
{this.renderParallelPickerIfNeeded()}
</div>
{this.renderNextBar({
- disabled: invalidTuningConfig(tuningConfig),
+ disabled: invalidTuningConfig(tuningConfig, granularitySpec.intervals),
})}
</>
);
@@ -2864,6 +2867,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
try {
const resp = await axios.get(`/druid/indexer/v1/supervisor/${initSupervisorId}`);
this.updateSpec(resp.data);
+ this.setState({ continueToSpec: true });
this.updateStep('spec');
} catch (e) {
AppToaster.show({
@@ -2879,6 +2883,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
try {
const resp = await axios.get(`/druid/indexer/v1/task/${initTaskId}`);
this.updateSpec(resp.data.payload);
+ this.setState({ continueToSpec: true });
this.updateStep('spec');
} catch (e) {
AppToaster.show({
diff --git a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
index 92da603..4ec2037 100644
--- a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
+++ b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
@@ -35,7 +35,6 @@ describe('parse data table', () => {
const parseDataTable = (
<ParseDataTable
- openModal={() => {}}
sampleData={sampleData}
columnFilter=""
canFlatten={false}
diff --git a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
index 2d00968..380eab2 100644
--- a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
+++ b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
@@ -34,7 +34,6 @@ export interface ParseDataTableProps {
flattenedColumnsOnly: boolean;
flattenFields: FlattenField[];
onFlattenFieldSelect: (field: FlattenField, index: number) => void;
- openModal: (str: string) => void;
}
export class ParseDataTable extends React.PureComponent<ParseDataTableProps> {
@@ -78,7 +77,7 @@ export class ParseDataTable extends React.PureComponent<ParseDataTableProps> {
if (row.original.unparseable) {
return <TableCell unparseable />;
}
- return <TableCell value={row.value} openModal={str => this.props.openModal(str)} />;
+ return <TableCell value={row.value} />;
},
headerClassName: classNames({
flattened: flattenField,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org