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