render()

in web/timebase-datasource-plugin/src/QueryEditor.tsx [631:920]


  render() {
    const filters = this.props.query.filters == null ? [] : this.props.query.filters;
    const selects = this.props.query.selects == null ? [{ ...EMPTY_SELECT }] : this.props.query.selects;
    if (this.props.query.selects === null && this.state.schema != null) {
      selects[0].selectedAggregations = [getDefaultFunctionDescription(this.state.schema)];
    }

    return (
      <div>
        <div className={cx('gf-form-inline width', styles)}>
          <SegmentFrame title="STREAM">
            <Field
              className="invalid-mess"
              invalid={!this.state.validStreamControl}
              error={!this.state.validStreamControl ? `No stream ${this.state.selectedStream?.value}` : ''}
            >
              <div title={this.state.selectedStream?.value as string}>
                <AsyncPaginate
                  className={cx('select', styles)}
                  backspaceRemovesValue={true}
                  isClearable={true}
                  classNamePrefix="grafana-custom"
                  value={this.state.selectedStream}
                  loadOptions={this.loadStreams as any}
                  onChange={this.onChangeStream}
                />
              </div>
            </Field>

            <SegmentFrame
              className={cx('gf-form gf-form-mb', styles)}
              resetTitleWidth={true}
              title="WHERE"
              hideShadow={true}
              options={getListFields(this.state.schema?.types, true)}
              onChange={this.addFilter}
            >
              {filters.length !== 0 ? (
                <SegmentFrame resetTitleWidth={true} hideShadow={true} className={cx('gf-form gf-form-mb', styles)}>
                  <Field
                    className="invalid-mess"
                    invalid={this.state.invalidFieldsMap[filters[0].field] || this.props.datasource.queryError != null}
                    error={getErrorForFields(
                      separateTypeAndField(filters[0].field)[0],
                      separateTypeAndField(filters[0].field)[1],
                      this.state.selectedStream?.value as string,
                      this.state.schema?.types,
                      this.props.datasource.queryError,
                      true
                    )}
                  >
                    <FilterComponent
                      index={0}
                      selectedField={filters[0].field}
                      selectedOperators={filters[0].operator}
                      filterValue={filters[0].values}
                      schema={this.state.schema?.types}
                      onChangeFilter={this.onChangeFilter}
                      removeFilter={this.removeFilter}
                    />
                  </Field>
                </SegmentFrame>
              ) : null}
            </SegmentFrame>
          </SegmentFrame>
        </div>

        {filters.map((filter, index) => {
          if (index === 0) {
            return;
          }
          return (
            <div className={cx('gf-form-inline width gf-form-ml', styles)}>
              <SegmentFrame
                resetTitleWidth={true}
                hideShadow={true}
                className={cx('gf-form gf-form-mb', styles)}
                title="AND"
              >
                <Field
                  className="invalid-mess"
                  invalid={this.state.invalidFieldsMap[filter.field] || this.props.datasource.queryError != null}
                  error={getErrorForFields(
                    separateTypeAndField(filter.field)[0],
                    separateTypeAndField(filter.field)[1],
                    this.state.selectedStream?.value as string,
                    this.state.schema?.types,
                    this.props.datasource.queryError,
                    true
                  )}
                >
                  <FilterComponent
                    index={index}
                    selectedField={filter.field}
                    selectedOperators={filter.operator}
                    filterValue={filter.values}
                    schema={this.state.schema?.types}
                    onChangeFilter={this.onChangeFilter}
                    removeFilter={this.removeFilter}
                  />
                </Field>
              </SegmentFrame>
            </div>
          );
        })}
        <div className={cx('gf-form-inline width', styles)}>
          <div className="gf-form">
            <span className="gf-form-label width-8 query-keyword">SYMBOL</span>
          </div>
          <Field
            className="invalid-mess"
            invalid={!this.state.validSymbolControl}
            error={
              !this.state.validSymbolControl
                ? `No symbols [${this.state.selectedSymbol?.value}] in ${this.state.selectedStream?.value}.`
                : ''
            }
          >
            {this.state.hideControl ? (
              <div></div>
            ) : (
              <div title={this.state.selectedSymbol?.value as string}>
                <AsyncPaginate
                  className={cx('select', styles)}
                  backspaceRemovesValue={true}
                  classNamePrefix="grafana-custom"
                  isClearable={true}
                  value={this.state.selectedSymbol}
                  loadOptions={this.loadSymbols as any}
                  onChange={this.onChangeSymbol}
                />
              </div>
            )}
          </Field>
          <div className="gf-form-label gf-form-label--grow"></div>
        </div>
        <div className={cx('gf-form-inline width', styles)}>
          {selects.map((select, index) => {
            return (
              <SegmentFrame
                index={index}
                title={index === 0 ? 'SELECT' : ''}
                options={this.getSelectOptions(index)}
                onChange={this.addSelectSection}
              >
                {select.selectedField != null && select.selectedRecordType != null ? (
                  <Field
                    className="invalid-mess"
                    invalid={
                      this.state.invalidFieldsMap[getTypeWithField(select.selectedField, select.selectedRecordType)]
                    }
                    error={getErrorForFields(
                      select.selectedRecordType,
                      select.selectedField,
                      this.state.selectedStream?.value as string,
                      this.state.schema?.types,
                      this.props.datasource.queryError
                    )}
                  >
                    <Segment
                      Component={
                        <ColoredFieldLabelComponent
                          fun="field"
                          needFiledFun={true}
                          value={select.selectedField}
                          type={select.selectedRecordType}
                          index={index}
                          onRemove={this.removeField}
                        />
                      }
                      options={getListFields(this.state.schema?.types, true)}
                      onChange={(item: SelectableValue<string>) => this.onChangeField(item, index)}
                    />
                  </Field>
                ) : null}
                {select.selectedFunction != null ? (
                  <FunctionComponent
                    value={select.selectedFunction}
                    index={index}
                    schema={this.state.schema as Schema}
                    onChangeFunction={this.onChangeFunctionByIndex}
                    description={
                      this.state.schema?.functions.find(
                        f => f.id === select.selectedFunction?.id
                      ) as FunctionDeclaration
                    }
                    onRemove={this.removeField}
                  />
                ) : null}
                {select.selectedAggregations.map(aggregation => (
                  <FunctionComponent
                    index={index}
                    disableColoring={true}
                    schema={this.state.schema as Schema}
                    description={this.state.schema?.functions.find(f => f.id === aggregation.id) as FunctionDeclaration}
                    value={aggregation}
                    dependsSelect={select}
                    onRemove={index => this.removeAggregation(aggregation.id, index)}
                    onChangeFunction={this.changeAggregation}
                  />
                ))}
              </SegmentFrame>
            );
          })}
        </div>
        <div className={cx('gf-form-inline width', styles)}>
          <SegmentFrame
            title="GROUP BY"
            options={getListFields(this.state.schema?.types, false, true)}
            onChange={this.addGroup}
          >
            <Segment
              Component={<FieldLabelComponent needFiledFun={true} fun="time" value={this.getCurrentInterval()} />}
              options={this.props.datasource.intervals}
              onChange={this.onChangeInterval}
            />
            {this.props.query.selectedGroups != null
              ? this.props.query.selectedGroups.map((group, index) => {
                  return (
                    <Field
                      className="invalid-mess"
                      invalid={this.state.invalidFieldsMap[group] || this.props.datasource.queryError != null}
                      error={getErrorForFields(
                        separateTypeAndField(group)[0],
                        separateTypeAndField(group)[1],
                        this.state.selectedStream?.value as string,
                        this.state.schema?.types,
                        this.props.datasource.queryError,
                        true
                      )}
                    >
                      <Segment
                        Component={
                          <ColoredFieldLabelComponent
                            fun="field"
                            needFiledFun={true}
                            value={separateTypeAndField(group)[1]}
                            type={separateTypeAndField(group)[0]}
                            index={index}
                            onRemove={this.removeGroup}
                          />
                        }
                        options={getListFields(this.state.schema?.types, false, true)}
                        onChange={(item: SelectableValue<string>) => this.onChangeGroup(item, index)}
                      />
                    </Field>
                  );
                })
              : null}
          </SegmentFrame>
        </div>

        {this.props.query.selectedGroups == null || this.props.query.selectedGroups.length === 0 ? null : (
          <div className={cx('gf-form-inline width', styles)}>
            <SegmentFrame title="OPTION">
              <Select
                backspaceRemovesValue={true}
                isClearable={true}
                className={cx('select', styles)}
                disableDeletion={false}
                classNamePrefix="grafana-custom"
                value={toOption(
                  this.props.query.selectedOption === undefined ? 'COLUMN' : this.props.query.selectedOption
                )}
                options={this.state.groupByViewOptions as any}
                onChange={this.onChangeOrientation}
              ></Select>
            </SegmentFrame>
          </div>
        )}

        <div className={cx('gf-form-inline width', styles)}>
          <SegmentFrame title="VIEW">
            <Select
              backspaceRemovesValue={true}
              isClearable={true}
              disableDeletion={false}
              classNamePrefix="grafana-custom"
              className={cx('select', styles)}
              value={toOption(
                this.props.query.requestType === undefined ? DATAFRAME_KEY : this.props.query.requestType
              )}
              options={REQUEST_TYPE.map(toOption)}
              onChange={this.onChangeRequestType}
            ></Select>
          </SegmentFrame>
        </div>
      </div>
    );
  }