renderConnectStep()

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;
          },
        })}
      </>
    );
  }