in web-console/src/views/load-data-view/load-data-view.tsx [1267:1465]
renderConnectStep() {
const { inputQueryState, sampleStrategy } = this.state;
const spec = this.getEffectiveSpec();
const specType = getSpecType(spec);
const ioConfig: IoConfig = deepGet(spec, 'spec.ioConfig') || EMPTY_OBJECT;
const inlineMode = deepGet(spec, 'spec.ioConfig.inputSource.type') === 'inline';
const fixedFormatSource = isFixedFormatSource(spec);
const druidSource = isDruidSource(spec);
const specialSource = druidSource
? 'druid'
: fixedFormatSource
? 'fixedFormat'
: isKafkaOrKinesis(specType)
? specType
: undefined;
let mainFill: JSX.Element | string;
if (inlineMode) {
mainFill = (
<TextArea
className="inline-data"
placeholder="Paste your data here"
value={deepGet(spec, 'spec.ioConfig.inputSource.data')}
onChange={(e: any) => {
const stringValue = e.target.value.slice(0, MAX_INLINE_DATA_LENGTH);
this.updateSpecPreview(deepSet(spec, 'spec.ioConfig.inputSource.data', stringValue));
}}
/>
);
} else if (inputQueryState.isInit()) {
mainFill = (
<CenterMessage>
Please fill out the fields on the right sidebar to get started{' '}
<Icon icon={IconNames.ARROW_RIGHT} />
</CenterMessage>
);
} else {
const data = inputQueryState.getSomeData();
const inputData = data ? data.data : undefined;
mainFill = (
<>
{inputData && (
<TextArea
className="raw-lines"
readOnly
value={formatSampleEntries(inputData, specialSource).join('\n')}
/>
)}
{inputQueryState.isLoading() && <Loader />}
{inputQueryState.error && (
<CenterMessage>{inputQueryState.getErrorMessage()}</CenterMessage>
)}
</>
);
}
const ingestionComboType = getIngestionComboType(spec);
const ioConfigFields = ingestionComboType
? getIoConfigFormFields(ingestionComboType)
: undefined;
return (
<>
<div className="main">{mainFill}</div>
<div className="control">
<ConnectMessage inlineMode={inlineMode} spec={spec} />
{ioConfigFields ? (
<>
<AutoForm
fields={ioConfigFields}
model={ioConfig}
onChange={c => this.updateSpecPreview(deepSet(spec, 'spec.ioConfig', c))}
/>
{deepGet(spec, 'spec.ioConfig.inputSource.properties.secretAccessKey.password') && (
<FormGroup>
<Callout intent={Intent.WARNING}>
This key will be visible to anyone accessing this console and may appear in
server logs. For production scenarios, use of a more secure secret key type is
strongly recommended.
</Callout>
</FormGroup>
)}
</>
) : (
<FormGroup label="IO Config">
<JsonInput
value={ioConfig}
onChange={c => this.updateSpecPreview(deepSet(spec, 'spec.ioConfig', c))}
height="300px"
/>
</FormGroup>
)}
{deepGet(spec, 'spec.ioConfig.inputSource.type') === 'local' && (
<FormGroup>
<Callout intent={Intent.WARNING}>
This path must be available on the local filesystem of all Druid services.
</Callout>
</FormGroup>
)}
{isStreamingSpec(spec) && (
<FormGroup label="Where should the data be sampled from?">
<RadioGroup
selectedValue={sampleStrategy}
onChange={e => this.setState({ sampleStrategy: e.currentTarget.value as any })}
>
<Radio value="start">Start of stream</Radio>
<Radio value="end">End of stream</Radio>
</RadioGroup>
</FormGroup>
)}
{this.renderApplyButtonBar(
inputQueryState,
ioConfigFields ? AutoForm.issueWithModel(ioConfig, ioConfigFields) : undefined,
)}
</div>
{this.renderNextBar({
disabled: !inputQueryState.data,
nextStep: druidSource ? 'transform' : fixedFormatSource ? 'timestamp' : 'parser',
onNextStep: () => {
if (!inputQueryState.data) return false;
const inputData = inputQueryState.data;
if (druidSource) {
let newSpec = deepSet(spec, 'spec.dataSchema.timestampSpec', {
column: TIME_COLUMN,
format: 'millis',
});
if (typeof inputData.rollup === 'boolean') {
newSpec = deepSet(
newSpec,
'spec.dataSchema.granularitySpec.rollup',
inputData.rollup,
);
}
newSpec = deepSet(
newSpec,
'spec.dataSchema.granularitySpec.queryGranularity',
'none',
);
if (inputData.columns) {
const aggregators = inputData.aggregators || {};
newSpec = deepSet(
newSpec,
'spec.dataSchema.dimensionsSpec.dimensions',
filterMap(inputData.columns, column => {
if (column === TIME_COLUMN || aggregators[column]) return;
return {
name: column,
type: String(inputData.columnInfo?.[column]?.type || 'string').toLowerCase(),
};
}),
);
if (inputData.aggregators) {
newSpec = deepSet(
newSpec,
'spec.dataSchema.metricsSpec',
filterMap(inputData.columns, column => aggregators[column]),
);
}
}
this.updateSpec(fillDataSourceNameIfNeeded(newSpec));
}
if (fixedFormatSource) {
const newSpec = deepSet(
spec,
'spec.dataSchema.timestampSpec',
getTimestampSpec(inputQueryState.data),
);
this.updateSpec(fillDataSourceNameIfNeeded(newSpec));
} else {
const issue = issueWithSampleData(
filterMap(inputData.data, l => l.input?.raw),
isStreamingSpec(spec),
);
if (issue) {
AppToaster.show({
icon: IconNames.WARNING_SIGN,
intent: Intent.WARNING,
message: issue,
timeout: 30000,
});
return false;
}
this.updateSpec(fillDataSourceNameIfNeeded(fillInputFormatIfNeeded(spec, inputData)));
}
return true;
},
})}
</>
);
}