@grafana/data#PanelEditorProps TypeScript Examples

The following examples show how to use @grafana/data#PanelEditorProps. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PieChartOptionsBox.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export class PieChartOptionsBox extends PureComponent<PanelEditorProps<PieChartOptions>> {
  onPieTypeChange = (pieType: any) => this.props.onOptionsChange({ ...this.props.options, pieType: pieType.value });
  onStrokeWidthChange = ({ target }: any) =>
    this.props.onOptionsChange({ ...this.props.options, strokeWidth: target.value });

  render() {
    const { options } = this.props;
    const { pieType, strokeWidth } = options;

    return (
      <PanelOptionsGroup title="PieChart">
        <div className="gf-form">
          <FormLabel width={labelWidth}>Type</FormLabel>
          <Select
            width={12}
            options={pieChartOptions}
            onChange={this.onPieTypeChange}
            value={pieChartOptions.find(option => option.value === pieType)}
          />
        </div>
        <div className="gf-form">
          <FormField
            label="Divider width"
            labelWidth={labelWidth}
            onChange={this.onStrokeWidthChange}
            value={strokeWidth}
          />
        </div>
      </PanelOptionsGroup>
    );
  }
}
Example #2
Source File: TablePanelEditor.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export class TablePanelEditor extends PureComponent<PanelEditorProps<Options>> {
  onToggleShowHeader = () => {
    this.props.onOptionsChange({ ...this.props.options, showHeader: !this.props.options.showHeader });
  };

  render() {
    const { showHeader } = this.props.options;

    return (
      <div>
        <div className="section gf-form-group">
          <h5 className="section-heading">Header</h5>
          <Switch label="Show" labelClass="width-6" checked={showHeader} onChange={this.onToggleShowHeader} />
        </div>
      </div>
    );
  }
}
Example #3
Source File: TextPanelEditor.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export class TextPanelEditor extends PureComponent<PanelEditorProps<TextOptions>> {
  modes: Array<SelectableValue<TextMode>> = [
    { value: 'markdown', label: 'Markdown' },
    { value: 'text', label: 'Text' },
    { value: 'html', label: 'HTML' },
  ];

  onModeChange = (item: SelectableValue<TextMode>) =>
    this.props.onOptionsChange({ ...this.props.options, mode: item.value! });

  onContentChange = (evt: ChangeEvent<HTMLTextAreaElement>) => {
    this.props.onOptionsChange({ ...this.props.options, content: (evt.target as any).value });
  };

  render() {
    const { mode, content } = this.props.options;

    return (
      <PanelOptionsGroup title="Text">
        <div className="gf-form-inline">
          <div className="gf-form">
            <span className="gf-form-label">Mode</span>
            <Select onChange={this.onModeChange} value={this.modes.find(e => mode === e.value)} options={this.modes} />
          </div>
        </div>
        <textarea value={content} onChange={this.onContentChange} className="gf-form-input" rows={10} />
      </PanelOptionsGroup>
    );
  }
}
Example #4
Source File: AnnoListEditor.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
constructor(props: PanelEditorProps<AnnoOptions>) {
    super(props);

    this.state = {
      tag: '',
    };
  }
Example #5
Source File: LogsPanelEditor.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export class LogsPanelEditor extends PureComponent<PanelEditorProps<Options>> {
  onToggleLabels = () => {
    const { options, onOptionsChange } = this.props;
    const { showLabels } = options;

    onOptionsChange({ ...options, showLabels: !showLabels });
  };

  onToggleTime = () => {
    const { options, onOptionsChange } = this.props;
    const { showTime } = options;

    onOptionsChange({ ...options, showTime: !showTime });
  };

  onTogglewrapLogMessage = () => {
    const { options, onOptionsChange } = this.props;
    const { wrapLogMessage } = options;

    onOptionsChange({ ...options, wrapLogMessage: !wrapLogMessage });
  };

  onShowValuesChange = (item: SelectableValue<SortOrder>) => {
    const { options, onOptionsChange } = this.props;
    onOptionsChange({ ...options, sortOrder: item.value });
  };

  render() {
    const { showLabels, showTime, wrapLogMessage, sortOrder } = this.props.options;
    const value = sortOrderOptions.filter(option => option.value === sortOrder)[0];

    return (
      <>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Columns">
            <Switch label="Time" labelClass="width-10" checked={showTime} onChange={this.onToggleTime} />
            <Switch label="Unique labels" labelClass="width-10" checked={showLabels} onChange={this.onToggleLabels} />
            <Switch
              label="Wrap lines"
              labelClass="width-10"
              checked={wrapLogMessage}
              onChange={this.onTogglewrapLogMessage}
            />
            <div className="gf-form">
              <FormLabel>Order</FormLabel>
              <Select options={sortOrderOptions} value={value} onChange={this.onShowValuesChange} />
            </div>
          </PanelOptionsGroup>
        </PanelOptionsGrid>
      </>
    );
  }
}
Example #6
Source File: NewsPanelEditor.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
constructor(props: PanelEditorProps<NewsOptions>) {
    super(props);

    this.state = {
      feedUrl: props.options.feedUrl,
    };
  }
Example #7
Source File: NewsPanelEditor.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export class NewsPanelEditor extends PureComponent<PanelEditorProps<NewsOptions>, State> {
  constructor(props: PanelEditorProps<NewsOptions>) {
    super(props);

    this.state = {
      feedUrl: props.options.feedUrl,
    };
  }

  onUpdatePanel = () =>
    this.props.onOptionsChange({
      ...this.props.options,
      feedUrl: this.state.feedUrl,
    });

  onFeedUrlChange = ({ target }: any) => this.setState({ feedUrl: target.value });

  onSetProxyPrefix = () => {
    const feedUrl = PROXY_PREFIX + this.state.feedUrl;
    this.setState({ feedUrl });
    this.props.onOptionsChange({
      ...this.props.options,
      feedUrl,
    });
  };

  render() {
    const feedUrl = this.state.feedUrl || '';
    const suggestProxy = feedUrl && !feedUrl.startsWith(PROXY_PREFIX);
    return (
      <>
        <PanelOptionsGroup title="Feed">
          <div className="gf-form">
            <FormField
              label="URL"
              labelWidth={7}
              inputWidth={30}
              value={feedUrl || ''}
              placeholder={DEFAULT_FEED_URL}
              onChange={this.onFeedUrlChange}
              tooltip="Only RSS feed formats are supported (not Atom)."
              onBlur={this.onUpdatePanel}
            />
          </div>
          {suggestProxy && (
            <div>
              <br />
              <div>If the feed is unable to connect, consider a CORS proxy</div>
              <Button variant="inverse" onClick={this.onSetProxyPrefix}>
                Use Proxy
              </Button>
            </div>
          )}
        </PanelOptionsGroup>
      </>
    );
  }
}
Example #8
Source File: PieChartPanelEditor.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export class PieChartPanelEditor extends PureComponent<PanelEditorProps<PieChartOptions>> {
  onValueMappingsChanged = (mappings: ValueMapping[]) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      mappings,
    });
  };

  onDisplayOptionsChanged = (fieldOptions: FieldDisplayOptions) =>
    this.props.onOptionsChange({
      ...this.props.options,
      fieldOptions,
    });

  onDefaultsChange = (field: FieldConfig) => {
    this.onDisplayOptionsChanged({
      ...this.props.options.fieldOptions,
      defaults: field,
    });
  };

  render() {
    const { onOptionsChange, options, data } = this.props;
    const { fieldOptions } = options;
    const { defaults } = fieldOptions;

    return (
      <>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Display">
            <FieldDisplayEditor onChange={this.onDisplayOptionsChanged} value={fieldOptions} />
          </PanelOptionsGroup>

          <PanelOptionsGroup title="Field (default)">
            <FieldPropertiesEditor showMinMax={true} onChange={this.onDefaultsChange} value={defaults} />
          </PanelOptionsGroup>

          <PieChartOptionsBox data={data} onOptionsChange={onOptionsChange} options={options} />
        </PanelOptionsGrid>

        <ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />
      </>
    );
  }
}
Example #9
Source File: SimpleEditor.tsx    From grafana-weathermap-panel with Apache License 2.0 4 votes vote down vote up
/**
 * class SimpleEditor
 */
export class SimpleEditor extends React.PureComponent<PanelEditorProps<SimpleOptions>, State, Props> {
  constructor(props: Props) {
    super(props);
    this.state = {
      // collapseDashboardData: false,
      // collapsePanelData: false,
      // collapseTimeSelector: false,
      // collapsePrincipalTarget: false,
      tabsVariable: [true, false, false, false, false],
      tabsCoordinateSpace: [true, false, false, false],
    };
  }
  /********************* Display Button in relation to View or Edit */

  // /**
  //  * edit default text
  //  */
  // myCallBackDefaultText = (datafromChild: {
  // 	/**
  // 	 * new police
  // 	 */
  // 	police: string,
  // 	/**
  // 	 * new size
  // 	 */
  // 	size: string,
  // 	/**
  // 	 * new style (italic, bold, ...)
  // 	 */
  // 	style: string,
  // }) => {
  // 	this.props.onOptionsChange({
  // 		...this.props.options,
  // 		police: datafromChild.police,
  // 		size: datafromChild.size,
  // 		style: datafromChild.style,
  // 	});
  // }

  /// Adrien
  // onInfoChanged = ({ target }: any) => {
  // 	this.props.onOptionsChange({ ...this.props.options, info: target.value });
  // }

  onRefreshChanged = ({ target }: any) => {
    this.props.onOptionsChange({ ...this.props.options, refresh: target.value });
  };

  onTimeZoneChanged = ({ target }: any) => {
    this.props.onOptionsChange({ ...this.props.options, timezone: target.value });
  };

  onPanelChanged = ({ target }: any, index: any) => {
    this.props.onOptionsChange({ ...this.props.options, Id: target.value });
  };

  // onToggleDashboardData = (isOpen: boolean): void => {
  //   this.setState({
  //     collapseDashboardData: isOpen,
  //   });
  // };

  // onToggleTimeSelector = (isOpen: boolean): void => {
  //   this.setState({
  //     collapseTimeSelector: isOpen,
  //   });
  // };

  // onTogglePanelData = (isOpen: boolean): void => {
  //   this.setState({
  //     collapsePanelData: isOpen,
  //   });
  // };

  // onTogglePrincipalTargets = (isOpen: boolean): void => {
  //   this.setState({
  //     collapsePrincipalTarget: isOpen,
  //   });
  // };

  /**
   * switch tab
   * @param {number} id id to to new tab
   */
  private goToTab = (id: number) => {
    const oldValue: boolean[] = this.state.tabsVariable.slice();
    const size: number = oldValue.length;
    for (let i = 0; i < size; i++) {
      oldValue[i] = i === id ? true : false;
    }
    this.setState({
      tabsVariable: oldValue,
    });
  };

  /**
   * swtith tab Coordinate space
   */
  private goToTabCoordinateSpace = (id: number) => {
    const oldValue: boolean[] = this.state.tabsCoordinateSpace.slice();
    const size: number = oldValue.length;
    for (let i = 0; i < size; i++) {
      oldValue[i] = i === id ? true : false;
    }
    this.setState({
      tabsCoordinateSpace: oldValue,
    });
  };

  componentDidMount = async () => {
    // delete data if new dashboard
    const url: string = window.location.pathname;
    const arrayUrl: string[] = url.split('/');
    for (const element of arrayUrl) {
      if (element === 'new' && !this.props.options.currentDashboard) {
        this.props.onOptionsChange({
          ...this.props.options,
          arrayPoints: [],
          arrayOrientedLinks: [],
          regionCoordinateSpace: [],
          saveImportUrl: { total: [], mono: [], multi: [] },
          saveImportFile: [],
          totalUrlInput: '',
          multiUrlInput: '',
          monoUrlInput: '',
          baseMap: {
            image: '',
            layerImage: '',
            modeSVG: true,
            idSVG: '',
            width: '',
            height: '',
            isUploaded: false,
          },
        });
      }
    }

    // display Button of Panel if is mode Edit
    await Promise.resolve('Success').then(() => {
      this.props.onOptionsChange({
        ...this.props.options,
        displayButton: true,
        currentDashboard: false,
      });
    });
  };

  componentWillUnmount = async () => {
    // not display Button of Panel if is mode View
    await Promise.resolve('Success').then(() => {
      this.props.onOptionsChange({
        ...this.props.options,
        displayButton: false,
        currentDashboard: true,
      });
    });
  };

  /**
   * HTML code
   */
  render() {
    // const tt = new TextObject(
    //   '',
    //   false,
    //   'white',
    //   'black',
    //   { bold: false, italic: false, underline: false },
    //   true,
    //   {
    //     legendElement: '',
    //     numericFormatElement: '5',
    //     unit: '',
    //     displayObjectInTooltip: false,
    //     addColorTextElement: false,
    //     colorTextElement: 'white',
    //     addColorBackElement: false,
    //     colorBackElement: 'black',
    //   },
    //   {
    //     legendElement: '',
    //     numericFormatElement: '5',
    //     unit: '',
    //     displayObjectInTooltip: true,
    //     addColorTextElement: true,
    //     colorTextElement: 'white',
    //     addColorBackElement: true,
    //     colorBackElement: 'black',
    //   }
    // );

    // const testtt: Metadata = { meta: '', obj: tt };

    const l10n = require('Localization/en.json');

    return (
      <div className="divSimpleEditor">
        <TabsBar className="page-header tabs" hideBorder={false}>
          <Tab key="tabDisplay" label={l10n.simpleEditor.display} active={this.state.tabsVariable[0]} onChangeTab={() => this.goToTab(0)} />
          <Tab
            key="tabSpaceInitialVisualisation"
            label={l10n.simpleEditor.spaceInitialVisualisation}
            active={this.state.tabsVariable[1]}
            onChangeTab={() => this.goToTab(1)}
          />
          <Tab
            key="tabCoordinateSpace"
            label={l10n.simpleEditor.CoordinateSpace}
            active={this.state.tabsVariable[2]}
            onChangeTab={() => this.goToTab(2)}
          />
          {/* <Tab key='tabMetricsSettings'
						label={l10n.simpleEditor.metricsSettings}
						active={this.state.tabsVariable[3]}
						onChangeTab={() => this.goToTab(3)}
					/> */}
          <Tab key="tabGabarit" label="Gabarit" active={this.state.tabsVariable[3]} onChangeTab={() => this.goToTab(3)} />
          <Tab key="tabImportInput" label="Import Files" active={this.state.tabsVariable[4]} onChangeTab={() => this.goToTab(4)} />
        </TabsBar>
        <TabContent>
          {this.state.tabsVariable[0] && <Display options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />}
          {this.state.tabsVariable[1] && (
            <CoordinateSpaceInitialClass options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
          )}
          {this.state.tabsVariable[2] && (
            <div>
              <TabsBar className="page-header tabs" hideBorder={false}>
                <Tab
                  key="tabDisplayManageCoordinateSpace"
                  label="Region"
                  active={this.state.tabsCoordinateSpace[0]}
                  onChangeTab={() => this.goToTabCoordinateSpace(0)}
                />
                <Tab
                  key="tabDisplayPoint"
                  label="Point"
                  active={this.state.tabsCoordinateSpace[1]}
                  onChangeTab={() => this.goToTabCoordinateSpace(1)}
                />
                {/* <Tab key='tabDisplayLink'
									label='Link'
									active={this.state.tabsCoordinateSpace[2]}
									onChangeTab={() => this.goToTabCoordinateSpace(2)}
								/> */}
                <Tab
                  key="tabDisplayOrientedLink"
                  label="OrientedLink"
                  active={this.state.tabsCoordinateSpace[3]}
                  onChangeTab={() => this.goToTabCoordinateSpace(3)}
                />
              </TabsBar>
              <TabContent>
                {this.state.tabsCoordinateSpace[0] && (
                  <ManageCoordinateSpace
                    options={this.props.options}
                    onOptionsChange={this.props.onOptionsChange}
                    data={this.props.data}
                    isRegion={true}
                    isPoint={false}
                    isLink={false}
                  />
                )}
                {this.state.tabsCoordinateSpace[1] && (
                  <ManageCoordinateSpace
                    options={this.props.options}
                    onOptionsChange={this.props.onOptionsChange}
                    data={this.props.data}
                    isRegion={false}
                    isPoint={true}
                    isLink={false}
                  />
                )}
                {this.state.tabsCoordinateSpace[3] && (
                  <ManageCoordinateSpace
                    options={this.props.options}
                    onOptionsChange={this.props.onOptionsChange}
                    data={this.props.data}
                    isRegion={false}
                    isPoint={false}
                    isLink={true}
                  />
                )}
              </TabContent>
            </div>
          )}
          {/*
						this.state.tabsVariable[3] &&

						<div className='adrien'>
							<Collapse isOpen={this.state.collapseDashboardData}
								label='Dashboard Data Display' onToggle={this.onToggleDashboardData}>
								<DashboardData options={this.props.options}
									onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
							</Collapse>
							<Collapse isOpen={this.state.collapseTimeSelector}
								label='Time Selector Display' onToggle={this.onToggleTimeSelector}>
								<TimeSelector options={this.props.options}
									onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
							</Collapse>
							<Collapse isOpen={this.state.collapsePrincipalTarget}
								label='Metrics Principal' onToggle={this.onTogglePrincipalTargets}>
								<MainTarget options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
							</Collapse>
							<Collapse isOpen={this.state.collapsePanelData} label='Metrics Aux' onToggle={this.onTogglePanelData}>
								<PanelData options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
							</Collapse>
						</div>
					} */}
          {this.state.tabsVariable[3] && (
            <div>
              <Gabarit options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
            </div>
          )}
          {this.state.tabsVariable[4] && (
            <div>
              <ImportInput options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} />
            </div>
          )}
        </TabContent>
        {/* <MetadataComponent options={this.props.options} onOptionsChange={this.props.onOptionsChange} data={this.props.data} meta={testtt} /> */}
      </div>
    );
  }
}
Example #10
Source File: VariableColor.tsx    From grafana-weathermap-panel with Apache License 2.0 4 votes vote down vote up
/**
 * edit colors in variable mode
 */
class VariableColor extends React.Component<Props, State, PanelEditorProps<SimpleOptions>> {
  constructor(props: Props) {
    super(props);
    this.state = {
      arrayInputClass: [],
      lowerLimit: [],
      index: 0,
      nbVariation: '3',
      dynamicInput: <br />,
      //displayInput: false,
    };
  }

  /**
   * set state for arrayInputClass with Promise
   */
  setStateAsyncArrayInputClass = (state: {
    /**
     * edit arrayInputClass
     */
    arrayInputClass: ArrayInputClass[];
  }) => {
    return new Promise((resolve) => {
      this.setState(state, resolve);
    });
  };

  /**
   * set state for seuil with Promise
   */
  setStateAsyncLowerLimit = (state: {
    /**
     * edit seuil
     */
    lowerLimit: LowerLimitClass[];
  }) => {
    return new Promise((resolve) => {
      this.setState(state, resolve);
    });
  };

  /**
   * set state for index with Promise
   */
  setStateAsyncIndex = (state: {
    /**
     * edit index
     */
    index: number;
  }) => {
    return new Promise((resolve) => {
      this.setState(state, resolve);
    });
  };

  /**
   * set state for nbVariation with Promise
   */
  setStateAsyncNbVariation = (state: {
    /**
     * edit nbVariation
     */
    nbVariation: string;
  }) => {
    return new Promise((resolve) => {
      this.setState(state, resolve);
    });
  };

  /**
   * send data to parent
   */
  callBack = () => {
    this.fillVarInput();
    this.props.lowerLimitCallBack(this.state.lowerLimit);
  };

  /** old function */
  saveData = () => {
    // const { onOptionsChange } = this.props;
    // console.table(this.state.seuil);
    // onOptionsChange({
    // 	...this.props.options,
    // 	seuil: this.state.seuil,
    // });
  };

  /**
   * add new seuil
   * @param idx index for id
   */
  addInput = async (idx: number, newLowerLimit: LowerLimitClass) => {
    await this.setStateAsyncArrayInputClass({
      arrayInputClass: this.state.arrayInputClass
        .slice()
        .concat(
          new ArrayInputClass(idx, [
            new InputClass('gestCouleurMin' + idx.toString(), 'Seuil min', 'lowerLimitMin', 'text', false, 'Seuil min', undefined),
            new InputClass('gestCouleurMax' + idx.toString(), 'Seuil max', 'lowerLimitMax', 'text', false, 'Seuil max', undefined),
          ])
        ),
    });

    await this.setStateAsyncLowerLimit({
      lowerLimit: this.state.lowerLimit.concat(newLowerLimit),
    });

    await this.setStateAsyncIndex({
      index: idx + 1,
    });
  };

  /**
   * call function with value input change
   * @param event event input
   * @param idInput id input
   * @param idLine index array
   */
  handleValueChange = async (event: string, idInput: string, idLine: number) => {
    const cpy: LowerLimitClass[] = this.state.lowerLimit.slice();
    if (idInput === 'lowerLimitMin') {
      cpy[idLine].lowerLimitMin = event;
    } else {
      cpy[idLine].lowerLimitMax = event;
      if (cpy.length > idLine + 1) {
        cpy[idLine + 1].lowerLimitMin = '>' + event;
      }
    }
    await this.setStateAsyncLowerLimit({
      lowerLimit: cpy,
    });
    this.callBack();
  };

  /**
   * call function when colorFond value change
   * @param key line index to modify
   * @param color the new color to add
   */
  onChangeColorFond = async (key: number, color: string) => {
    const cpy: LowerLimitClass[] = this.state.lowerLimit;
    cpy[key].backColor = color;
    await this.setStateAsyncLowerLimit({
      lowerLimit: cpy,
    });
    this.callBack();
  };

  /**
   * call fonction when colorContour change
   * @param key line index to modify
   * @param color the new color to add
   */
  onChangeColorContour = async (key: number, color: string) => {
    const cpy: LowerLimitClass[] = this.state.lowerLimit;
    cpy[key].borderColor = color;
    await this.setStateAsyncLowerLimit({
      lowerLimit: cpy,
    });
    this.callBack();
  };

  /**
   * call function when sizeBorder value change
   * @param key line index to modify
   * @param size the new size to add
   */
  onChangeSzContour = async (key: number, size: string) => {
    const cpy: LowerLimitClass[] = this.state.lowerLimit;
    cpy[key].sizeBorder = size;
    await this.setStateAsyncLowerLimit({
      lowerLimit: cpy,
    });
    this.callBack();
  };

  /**
   * insert color picker
   * @param keyInt index to edit line
   * @returns JSX.Element
   */
  addButtonColor = (keyInt: number): JSX.Element[] => {
    const key = keyInt.toString();
    const couleur: JSX.Element[] = [];
    const l10n = require('Localization/en.json');

    if (this.props.traceBack) {
      const keyFondColorPicker = key + 'FondcolorPicker';

      couleur.push(
        <InputSeriesColorPicker
          key={keyFondColorPicker}
          color={this.state.lowerLimit[keyInt].backColor}
          keyInt={keyInt}
          text={l10n.colorVariable.switchBackgroundColor}
          _onChange={this.onChangeColorFond}
        />
      );
    }
    if (this.props.traceBorder) {
      const keyContourDiv = key + 'ContourDiv';
      let nameInputSize = '';
      if (this.props.isLink) {
        nameInputSize = 'Size';
      } else {
        nameInputSize = l10n.colorVariable.thicknessOutline;
      }

      couleur.push(
        <div key={keyContourDiv}>
          <InputSeriesColorPicker
            color={this.state.lowerLimit[keyInt].borderColor}
            keyInt={keyInt}
            text={l10n.colorVariable.switchOutlineColor}
            _onChange={this.onChangeColorContour}
          />

          <FormField
            labelWidth={15}
            label={nameInputSize}
            name="epaisseurContour"
            placeholder={l10n.colorVariable.thicknessOutline}
            value={this.state.lowerLimit[keyInt].sizeBorder}
            onChange={(event) => this.onChangeSzContour(keyInt, event.currentTarget.value)}
          />
        </div>
      );
    }
    return couleur;
  };

  /**
   * call fonction when edit nbVariation
   */
  onChangeVariation = async (event: {
    /** currentTarget is item that is being edited */
    currentTarget: HTMLInputElement;
  }) => {
    await this.setStateAsyncNbVariation({ nbVariation: event.currentTarget.value });
  };

  /** generate array input */
  test = async (newSeuil: LowerLimitClass[]) => {
    const arrayInput: ArrayInputClass[] = this.state.arrayInputClass.slice();
    let idx = this.state.index;
    const pSeuil: LowerLimitClass[] = this.state.lowerLimit;

    for (const line of newSeuil) {
      arrayInput.push(
        new ArrayInputClass(idx, [
          new InputClass('gestCouleurMin' + idx.toString(), 'Seuil min', 'lowerLimitMin', 'text', false, 'Seuil min', undefined),
          new InputClass('gestCouleurMax' + idx.toString(), 'Seuil max', 'lowerLimitMax', 'text', false, 'Seuil max', undefined),
        ])
      );
      idx++;
      pSeuil.push(line);
    }
    await this.setStateAsyncArrayInputClass({
      arrayInputClass: arrayInput,
    });

    await this.setStateAsyncLowerLimit({
      lowerLimit: pSeuil,
    });

    await this.setStateAsyncIndex({
      index: idx,
    });
  };

  /**
   * call addInput to prepare new inputs
   * @param nb number inputs to add
   */
  addMultipleVariation = async (nb: number, seuil?: LowerLimitClass[]) => {
    if (seuil) {
      await this.test(seuil);
      this.fillVarInput();
    }
  };

  /** add new lower limit */
  addVariation = async (nb: number, seuil?: LowerLimitClass[]) => {
    for (let i = 0; i < nb; i++) {
      let newSeuil: LowerLimitClass = seuil ? seuil[i] : new LowerLimitClass(i, '', '', '', '', '');
      if (this.props.isLink) {
        newSeuil = seuil ? seuil[i] : new LowerLimitClass(i, '', '', '', '', '10');
      }
      await this.addInput(i, newSeuil);
    }
    this.fillVarInput();
  };

  /**
   * call function when display n input according to nbVariation
   */
  onClickVariation = async () => {
    await this.setStateAsyncArrayInputClass({
      arrayInputClass: [],
    });
    await this.setStateAsyncIndex({
      index: 0,
    });
    await this.setStateAsyncLowerLimit({
      lowerLimit: [],
    });

    // this.setState({
    //   displayInput: true,
    // });

    const nb: number = parseInt(this.state.nbVariation, 10);
    await this.addVariation(nb);
  };

  /**
   * generate input seuil min and max with value
   * @returns JSX.Element
   */
  fillVarInput = (): void => {
    let final: JSX.Element[] = [];

    if (this.state.lowerLimit.length === 0) {
      this.setState({
        dynamicInput: <br />,
      });
      return;
    }

    let i = 0;
    for (const line of this.state.arrayInputClass) {
      if (line.uneClassInput.length <= 0) {
        this.setState({
          dynamicInput: <br />,
        });
        return;
      }
      const result = line.uneClassInput.map((obj: InputClass) => (
        <InputTextField
          key={obj.id}
          label={obj.label}
          name={obj.name}
          placeholder={obj.placeholder || ''}
          required={obj.required}
          value={
            obj.name === 'lowerLimitMin'
              ? line.id === 0
                ? '-∞'
                : this.state.lowerLimit[i].lowerLimitMin
              : line.id === this.state.index - 1
              ? '+∞'
              : this.state.lowerLimit[i].lowerLimitMax
          }
          _handleChange={(event: {
            /**
             * get currentTarget in event element
             */
            currentTarget: HTMLInputElement;
          }) => this.handleValueChange(event.currentTarget.value, obj.name, line.id)}
          disabled={obj.name === 'lowerLimitMin' || line.id === this.state.index - 1}
        />
      ));
      i++;
      const couleur: JSX.Element[] = this.addButtonColor(line.id);
      const newKey = line.id.toString() + 'brGestColor';
      final = final.concat(result.concat(couleur.concat(<br key={newKey} />)));
    }
    this.setState({
      dynamicInput: <ul>{final}</ul>,
    });
  };

  /**
   * debug
   */
  infoSeuil = () => {};

  /**
   * component mount
   */
  componentDidMount = () => {
    if (this.props.lowerLimit.length > 0) {
      const nb: number = parseInt(this.state.nbVariation, 10);
      this.addMultipleVariation(nb, this.props.lowerLimit);
    }
  };

  componentDidUpdate = (prevProps: Props) => {
    if (prevProps.traceBorder !== this.props.traceBorder || prevProps.traceBack !== this.props.traceBack) {
      this.fillVarInput();
    }
  };

  /**
   * render
   */
  render() {
    const l10n = require('Localization/en.json');

    return (
      <div>
        <InputTextField
          label={l10n.colorVariable.variationNumber}
          name="nbVariation"
          placeholder={l10n.colorVariable.number}
          required={true}
          value={this.state.nbVariation}
          _handleChange={this.onChangeVariation}
        />
        <Button onClick={this.onClickVariation}>{l10n.colorVariable.addColor}</Button>
        <br />
        <br />
        {this.state.dynamicInput}
      </div>
    );
  }
}
Example #11
Source File: AnnoListEditor.tsx    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
export class AnnoListEditor extends PureComponent<PanelEditorProps<AnnoOptions>, State> {
  constructor(props: PanelEditorProps<AnnoOptions>) {
    super(props);

    this.state = {
      tag: '',
    };
  }

  // Display
  //-----------

  onToggleShowUser = () =>
    this.props.onOptionsChange({ ...this.props.options, showUser: !this.props.options.showUser });

  onToggleShowTime = () =>
    this.props.onOptionsChange({ ...this.props.options, showTime: !this.props.options.showTime });

  onToggleShowTags = () =>
    this.props.onOptionsChange({ ...this.props.options, showTags: !this.props.options.showTags });

  // Navigate
  //-----------

  onNavigateBeforeChange = (event: ChangeEvent<HTMLInputElement>) => {
    this.props.onOptionsChange({ ...this.props.options, navigateBefore: event.target.value });
  };

  onNavigateAfterChange = (event: ChangeEvent<HTMLInputElement>) => {
    this.props.onOptionsChange({ ...this.props.options, navigateAfter: event.target.value });
  };

  onToggleNavigateToPanel = () =>
    this.props.onOptionsChange({ ...this.props.options, navigateToPanel: !this.props.options.navigateToPanel });

  // Search
  //-----------
  onLimitChange = (event: ChangeEvent<HTMLInputElement>) => {
    const v = toIntegerOrUndefined(event.target.value);
    this.props.onOptionsChange({ ...this.props.options, limit: v });
  };

  onToggleOnlyFromThisDashboard = () =>
    this.props.onOptionsChange({
      ...this.props.options,
      onlyFromThisDashboard: !this.props.options.onlyFromThisDashboard,
    });

  onToggleOnlyInTimeRange = () =>
    this.props.onOptionsChange({ ...this.props.options, onlyInTimeRange: !this.props.options.onlyInTimeRange });

  // Tags
  //-----------

  onTagTextChange = (event: ChangeEvent<HTMLInputElement>) => {
    this.setState({ tag: event.target.value });
  };

  onTagClick = (e: React.SyntheticEvent, tag: string) => {
    e.stopPropagation();

    const tags = this.props.options.tags.filter(item => item !== tag);
    this.props.onOptionsChange({
      ...this.props.options,
      tags,
    });
  };

  renderTags = (tags: string[]): JSX.Element => {
    if (!tags || !tags.length) {
      return null;
    }
    return (
      <>
        {tags.map(tag => {
          return (
            <span key={tag} onClick={e => this.onTagClick(e, tag)} className="pointer">
              <TagBadge label={tag} removeIcon={true} count={0} />
            </span>
          );
        })}
      </>
    );
  };

  render() {
    const { options } = this.props;
    const labelWidth = 8;

    return (
      <PanelOptionsGrid>
        <PanelOptionsGroup title="Display">
          <Switch
            label="Show User"
            labelClass={`width-${labelWidth}`}
            checked={options.showUser}
            onChange={this.onToggleShowUser}
          />
          <Switch
            label="Show Time"
            labelClass={`width-${labelWidth}`}
            checked={options.showTime}
            onChange={this.onToggleShowTime}
          />
          <Switch
            label="Show Tags"
            labelClass={`width-${labelWidth}`}
            checked={options.showTags}
            onChange={this.onToggleShowTags}
          />
        </PanelOptionsGroup>
        <PanelOptionsGroup title="Navigate">
          <FormField
            label="Before"
            labelWidth={labelWidth}
            onChange={this.onNavigateBeforeChange}
            value={options.navigateBefore}
          />
          <FormField
            label="After"
            labelWidth={labelWidth}
            onChange={this.onNavigateAfterChange}
            value={options.navigateAfter}
          />
          <Switch
            label="To Panel"
            labelClass={`width-${labelWidth}`}
            checked={options.navigateToPanel}
            onChange={this.onToggleNavigateToPanel}
          />
        </PanelOptionsGroup>
        <PanelOptionsGroup title="Search">
          <Switch
            label="Only This Dashboard"
            labelClass={`width-12`}
            checked={options.onlyFromThisDashboard}
            onChange={this.onToggleOnlyFromThisDashboard}
          />
          <Switch
            label="Within Time Range"
            labelClass={`width-12`}
            checked={options.onlyInTimeRange}
            onChange={this.onToggleOnlyInTimeRange}
          />
          <div className="form-field">
            <FormLabel width={6}>Tags</FormLabel>
            {this.renderTags(options.tags)}
            <input
              type="text"
              className={`gf-form-input width-${8}`}
              value={this.state.tag}
              onChange={this.onTagTextChange}
              onKeyPress={ev => {
                if (this.state.tag && ev.key === 'Enter') {
                  const tags = [...options.tags, this.state.tag];
                  this.props.onOptionsChange({
                    ...this.props.options,
                    tags,
                  });
                  this.setState({ tag: '' });
                  ev.preventDefault();
                }
              }}
            />
          </div>

          <FormField
            label="Limit"
            labelWidth={6}
            onChange={this.onLimitChange}
            value={toNumberString(options.limit)}
            type="number"
          />
        </PanelOptionsGroup>
      </PanelOptionsGrid>
    );
  }
}
Example #12
Source File: BarGaugePanelEditor.tsx    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGaugeOptions>> {
  onThresholdsChanged = (thresholds: ThresholdsConfig) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      thresholds,
    });
  };

  onValueMappingsChanged = (mappings: ValueMapping[]) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      mappings,
    });
  };

  onDisplayOptionsChanged = (fieldOptions: FieldDisplayOptions) =>
    this.props.onOptionsChange({
      ...this.props.options,
      fieldOptions,
    });

  onDefaultsChange = (field: FieldConfig) => {
    this.onDisplayOptionsChanged({
      ...this.props.options.fieldOptions,
      defaults: field,
    });
  };

  onOrientationChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, orientation: value });
  onDisplayModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
  onToggleShowUnfilled = () => {
    this.props.onOptionsChange({ ...this.props.options, showUnfilled: !this.props.options.showUnfilled });
  };

  onDataLinksChanged = (links: DataLink[]) => {
    this.onDefaultsChange({
      ...this.props.options.fieldOptions.defaults,
      links,
    });
  };
  render() {
    const { options } = this.props;
    const { fieldOptions } = options;
    const { defaults } = fieldOptions;

    const suggestions = fieldOptions.values
      ? getDataLinksVariableSuggestions(this.props.data.series)
      : getCalculationValueDataLinksVariableSuggestions(this.props.data.series);
    const labelWidth = 6;

    return (
      <>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Display">
            <FieldDisplayEditor onChange={this.onDisplayOptionsChanged} value={fieldOptions} labelWidth={labelWidth} />
            <div className="form-field">
              <FormLabel width={labelWidth}>Orientation</FormLabel>
              <Select
                width={12}
                options={orientationOptions}
                defaultValue={orientationOptions[0]}
                onChange={this.onOrientationChange}
                value={orientationOptions.find(item => item.value === options.orientation)}
              />
            </div>
            <div className="form-field">
              <FormLabel width={labelWidth}>Mode</FormLabel>
              <Select
                width={12}
                options={displayModes}
                defaultValue={displayModes[0]}
                onChange={this.onDisplayModeChange}
                value={displayModes.find(item => item.value === options.displayMode)}
              />
            </div>
            {options.displayMode !== 'lcd' && (
              <Switch
                label="Unfilled"
                labelClass={`width-${labelWidth}`}
                checked={options.showUnfilled}
                onChange={this.onToggleShowUnfilled}
              />
            )}
          </PanelOptionsGroup>
          <PanelOptionsGroup title="Field">
            <FieldPropertiesEditor
              showMinMax={true}
              showTitle={true}
              onChange={this.onDefaultsChange}
              value={defaults}
            />
          </PanelOptionsGroup>

          <ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
        </PanelOptionsGrid>

        <ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />

        <PanelOptionsGroup title="Data links">
          <DataLinksEditor
            value={defaults.links}
            onChange={this.onDataLinksChanged}
            suggestions={suggestions}
            maxLinks={10}
          />
        </PanelOptionsGroup>
      </>
    );
  }
}
Example #13
Source File: GaugePanelEditor.tsx    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
export class GaugePanelEditor extends PureComponent<PanelEditorProps<GaugeOptions>> {
  labelWidth = 6;

  onToggleThresholdLabels = () =>
    this.props.onOptionsChange({ ...this.props.options, showThresholdLabels: !this.props.options.showThresholdLabels });

  onToggleThresholdMarkers = () =>
    this.props.onOptionsChange({
      ...this.props.options,
      showThresholdMarkers: !this.props.options.showThresholdMarkers,
    });

  onThresholdsChanged = (thresholds: ThresholdsConfig) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      thresholds,
    });
  };

  onValueMappingsChanged = (mappings: ValueMapping[]) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      mappings,
    });
  };

  onDisplayOptionsChanged = (
    fieldOptions: FieldDisplayOptions,
    event?: React.SyntheticEvent<HTMLElement>,
    callback?: () => void
  ) =>
    this.props.onOptionsChange(
      {
        ...this.props.options,
        fieldOptions,
      },
      callback
    );

  onDefaultsChange = (field: FieldConfig, event?: React.SyntheticEvent<HTMLElement>, callback?: () => void) => {
    this.onDisplayOptionsChanged(
      {
        ...this.props.options.fieldOptions,
        defaults: field,
      },
      event,
      callback
    );
  };

  onDataLinksChanged = (links: DataLink[], callback?: () => void) => {
    this.onDefaultsChange(
      {
        ...this.props.options.fieldOptions.defaults,
        links,
      },
      undefined,
      callback
    );
  };

  render() {
    const { options } = this.props;
    const { fieldOptions, showThresholdLabels, showThresholdMarkers } = options;
    const { defaults } = fieldOptions;

    const suggestions = fieldOptions.values
      ? getDataLinksVariableSuggestions(this.props.data.series)
      : getCalculationValueDataLinksVariableSuggestions(this.props.data.series);

    return (
      <>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Display">
            <FieldDisplayEditor
              onChange={this.onDisplayOptionsChanged}
              value={fieldOptions}
              labelWidth={this.labelWidth}
            />
            <Switch
              label="Labels"
              labelClass={`width-${this.labelWidth}`}
              checked={showThresholdLabels}
              onChange={this.onToggleThresholdLabels}
            />
            <Switch
              label="Markers"
              labelClass={`width-${this.labelWidth}`}
              checked={showThresholdMarkers}
              onChange={this.onToggleThresholdMarkers}
            />
          </PanelOptionsGroup>

          <PanelOptionsGroup title="Field">
            <FieldPropertiesEditor
              showMinMax={true}
              showTitle={true}
              onChange={this.onDefaultsChange}
              value={defaults}
            />
          </PanelOptionsGroup>

          <ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
        </PanelOptionsGrid>

        <ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />

        <PanelOptionsGroup title="Data links">
          <DataLinksEditor
            value={defaults.links}
            onChange={this.onDataLinksChanged}
            suggestions={suggestions}
            maxLinks={10}
          />
        </PanelOptionsGroup>
      </>
    );
  }
}
Example #14
Source File: GraphPanelEditor.tsx    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
export class GraphPanelEditor extends PureComponent<PanelEditorProps<Options>> {
  onGraphOptionsChange = (options: Partial<GraphOptions>) => {
    this.props.onOptionsChange({
      ...this.props.options,
      graph: {
        ...this.props.options.graph,
        ...options,
      },
    });
  };

  onLegendOptionsChange = (options: LegendOptions) => {
    this.props.onOptionsChange({ ...this.props.options, legend: options });
  };

  onTooltipOptionsChange = (options: GraphTooltipOptions) => {
    this.props.onOptionsChange({ ...this.props.options, tooltipOptions: options });
  };

  onToggleLines = () => {
    this.onGraphOptionsChange({ showLines: !this.props.options.graph.showLines });
  };

  onToggleBars = () => {
    this.onGraphOptionsChange({ showBars: !this.props.options.graph.showBars });
  };

  onTogglePoints = () => {
    this.onGraphOptionsChange({ showPoints: !this.props.options.graph.showPoints });
  };

  onDefaultsChange = (field: FieldConfig) => {
    this.props.onOptionsChange({
      ...this.props.options,
      fieldOptions: {
        ...this.props.options.fieldOptions,
        defaults: field,
      },
    });
  };

  render() {
    const {
      graph: { showBars, showPoints, showLines },
      tooltipOptions: { mode },
    } = this.props.options;

    return (
      <>
        <div className="section gf-form-group">
          <h5 className="section-heading">Draw Modes</h5>
          <Switch label="Lines" labelClass="width-5" checked={showLines} onChange={this.onToggleLines} />
          <Switch label="Bars" labelClass="width-5" checked={showBars} onChange={this.onToggleBars} />
          <Switch label="Points" labelClass="width-5" checked={showPoints} onChange={this.onTogglePoints} />
        </div>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Field">
            <FieldPropertiesEditor
              showMinMax={false}
              onChange={this.onDefaultsChange}
              value={this.props.options.fieldOptions.defaults}
            />
          </PanelOptionsGroup>
          <PanelOptionsGroup title="Tooltip">
            <Select
              value={{ value: mode, label: mode === 'single' ? 'Single' : 'All series' }}
              onChange={value => {
                this.onTooltipOptionsChange({ mode: value.value as any });
              }}
              options={[
                { label: 'All series', value: 'multi' },
                { label: 'Single', value: 'single' },
              ]}
            />
          </PanelOptionsGroup>
          <GraphLegendEditor options={this.props.options.legend} onChange={this.onLegendOptionsChange} />
        </PanelOptionsGrid>
      </>
    );
  }
}
Example #15
Source File: StatPanelEditor.tsx    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
export class StatPanelEditor extends PureComponent<PanelEditorProps<StatPanelOptions>> {
  onThresholdsChanged = (thresholds: ThresholdsConfig) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      thresholds,
    });
  };

  onValueMappingsChanged = (mappings: ValueMapping[]) => {
    const current = this.props.options.fieldOptions.defaults;
    this.onDefaultsChange({
      ...current,
      mappings,
    });
  };

  onDisplayOptionsChanged = (fieldOptions: FieldDisplayOptions) =>
    this.props.onOptionsChange({
      ...this.props.options,
      fieldOptions,
    });

  onColorModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, colorMode: value });
  onGraphModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, graphMode: value });
  onJustifyModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, justifyMode: value });
  onOrientationChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, orientation: value });

  onDefaultsChange = (field: FieldConfig) => {
    this.onDisplayOptionsChanged({
      ...this.props.options.fieldOptions,
      defaults: field,
    });
  };

  onDataLinksChanged = (links: DataLink[]) => {
    this.onDefaultsChange({
      ...this.props.options.fieldOptions.defaults,
      links,
    });
  };

  render() {
    const { options } = this.props;
    const { fieldOptions } = options;
    const { defaults } = fieldOptions;
    const suggestions = fieldOptions.values
      ? getDataLinksVariableSuggestions(this.props.data.series)
      : getCalculationValueDataLinksVariableSuggestions(this.props.data.series);

    return (
      <>
        <PanelOptionsGrid>
          <PanelOptionsGroup title="Display">
            <FieldDisplayEditor onChange={this.onDisplayOptionsChanged} value={fieldOptions} labelWidth={8} />
            <div className="form-field">
              <FormLabel width={8}>Orientation</FormLabel>
              <Select
                width={12}
                options={orientationOptions}
                defaultValue={orientationOptions[0]}
                onChange={this.onOrientationChange}
                value={orientationOptions.find(item => item.value === options.orientation)}
              />
            </div>
            <div className="form-field">
              <FormLabel width={8}>Color</FormLabel>
              <Select
                width={12}
                options={colorModes}
                defaultValue={colorModes[0]}
                onChange={this.onColorModeChanged}
                value={colorModes.find(item => item.value === options.colorMode)}
              />
            </div>
            <div className="form-field">
              <FormLabel width={8}>Graph</FormLabel>
              <Select
                width={12}
                options={graphModes}
                defaultValue={graphModes[0]}
                onChange={this.onGraphModeChanged}
                value={graphModes.find(item => item.value === options.graphMode)}
              />
            </div>
            <div className="form-field">
              <FormLabel width={8}>Justify</FormLabel>
              <Select
                width={12}
                options={justifyModes}
                defaultValue={justifyModes[0]}
                onChange={this.onJustifyModeChanged}
                value={justifyModes.find(item => item.value === options.justifyMode)}
              />
            </div>
          </PanelOptionsGroup>

          <PanelOptionsGroup title="Field">
            <FieldPropertiesEditor
              showMinMax={true}
              onChange={this.onDefaultsChange}
              value={defaults}
              showTitle={true}
            />
          </PanelOptionsGroup>

          <ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
        </PanelOptionsGrid>

        <ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />

        <PanelOptionsGroup title="Data links">
          <DataLinksEditor
            value={defaults.links}
            onChange={this.onDataLinksChanged}
            suggestions={suggestions}
            maxLinks={10}
          />
        </PanelOptionsGroup>
      </>
    );
  }
}
Example #16
Source File: GraphPanelEditor.tsx    From loudml-grafana-app with MIT License 4 votes vote down vote up
export class GraphPanelEditor extends PureComponent<PanelEditorProps<Options>> {
  datasources: DataSourceSelectItem[] = getDataSourceSrv().getMetricSources();

  constructor(props) {
    super(props);
  }

  datasourcesList = function() {
    var res = new Array({ label: 'Not selected', value: '' });

    this.datasources.forEach(function(val) {
      if (val.meta.id === 'loudml-datasource') {
        res.push({ label: val.name, value: val.value });
      }
    });

    return res;
  };

  onChangeDataSource = (value: any) => {
    this.props.options.datasourceOptions.datasource = value.value;
    this.setState({ value: value.value });
  };

  onChangeInputBucket = (event: any) => {
    this.props.options.datasourceOptions.input_bucket = event.target.value;
    this.setState({ value: event.target.value });
  };

  onBlurInputBucket = () => {
    // window.console.log("onBlurInputBucket", this.state);
  };

  onChangeOutputBucket = (event: any) => {
    this.props.options.datasourceOptions.output_bucket = event.target.value;
    this.setState({ value: event.target.value });
  };

  onBlurOutputBucket = () => {
    // window.console.log("onBlurOutputBucket", this.state);
  };

  onGraphOptionsChange = (options: Partial<GraphOptions>) => {
    this.props.onOptionsChange({
      ...this.props.options,
      graph: {
        ...this.props.options.graph,
        ...options,
      },
    });
  };

  onLegendOptionsChange = (options: LegendOptions) => {
    this.props.onOptionsChange({ ...this.props.options, legend: options });
  };

  onTooltipOptionsChange = (options: GraphTooltipOptions) => {
    this.props.onOptionsChange({ ...this.props.options, tooltipOptions: options });
  };

  onToggleLines = () => {
    this.onGraphOptionsChange({ showLines: !this.props.options.graph.showLines });
  };

  onToggleBars = () => {
    this.onGraphOptionsChange({ showBars: !this.props.options.graph.showBars });
  };

  onTogglePoints = () => {
    this.onGraphOptionsChange({ showPoints: !this.props.options.graph.showPoints });
  };

  onToggleisStacked = () => {
    this.onGraphOptionsChange({ isStacked: !this.props.options.graph.isStacked });
  };

  onChangeFill = (value: any) => {
    this.onGraphOptionsChange({ fill: value.value });
    this.setState({ value: value.value });
  };

  onChangeFillGradient = (value: any) => {
    this.onGraphOptionsChange({ fillGradient: value.value });
    this.setState({ value: value.value });
  };

  onChangeLineWidth = (value: any) => {
    this.onGraphOptionsChange({ lineWidth: value.value });
    this.setState({ value: value.value });
  };

  onDefaultsChange = (field: FieldConfig) => {
    this.props.onOptionsChange({
      ...this.props.options,
      fieldOptions: {
        ...this.props.options.fieldOptions,
        defaults: field,
      },
    });
  };

  render() {
    const {
      graph: { showBars, showPoints, showLines, isStacked, lineWidth, fill, fillGradient },
      tooltipOptions: { mode },
      datasourceOptions: { datasource, input_bucket, output_bucket },
    } = this.props.options;

    return (
      <>
        <PanelOptionsGroup title="Loud ML">
          <div className="gf-form max-width-40">
            <span className="gf-form-label width-10">Loud ML Server</span>
            <Select
              value={{ value: datasource, label: datasource }}
              onChange={value => {
                this.onChangeDataSource({ value: value.value as any });
              }}
              options={this.datasourcesList()}
            />
          </div>
          <div className="gf-form max-width-40">
            <span className="gf-form-label width-10">Input Bucket</span>
            <Input
              value={this.props.options.datasourceOptions.input_bucket}
              className="gf-form-input"
              type="text"
              placeholder="Datasource/Database used in Query"
              min-length="0"
              onBlur={this.onBlurInputBucket}
              onChange={this.onChangeInputBucket}
            />
          </div>
          <p>Bucket to get data for ML Model (Equal to Datasource used on Query tab; it should be in Loud ML YAML config)</p>

          <div className="gf-form max-width-40">
            <span className="gf-form-label width-10">Output Bucket</span>
            <Input
              value={this.props.options.datasourceOptions.output_bucket}
              className="gf-form-input"
              type="text"
              placeholder="Database to store ML Model training results"
              min-length="0"
              onBlur={this.onBlurOutputBucket}
              onChange={this.onChangeOutputBucket}
            />
          </div>
          <p>Specify a bucket to store ML training results (It should be in Loud ML YAML config)</p>
        </PanelOptionsGroup>

        <PanelOptionsGroup title="Draw">
          <div className="section gf-form-group">
            <h5 className="section-heading">Draw Modes</h5>
            <Switch label="Lines" labelClass="width-5" checked={showLines} onChange={this.onToggleLines} />
            <Switch label="Bars" labelClass="width-5" checked={showBars} onChange={this.onToggleBars} />
            <Switch label="Points" labelClass="width-5" checked={showPoints} onChange={this.onTogglePoints} />
          </div>
          <div className="section gf-form-group">
            <h5 className="section-heading">Mode Options</h5>
            <div className="gf-form max-width-20">
              <span className="gf-form-label width-8">Fill</span>
              <Select
                className="width-5"
                value={{ value: fill, label: fill }}
                onChange={value => {
                  this.onChangeFill({ value: value.value as any });
                }}
                options={[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(t => ({ value: t, label: t }))}
              />
            </div>
            <div className="gf-form max-width-20">
              <span className="gf-form-label width-8">Fill Gradient</span>
              <Select
                className="width-5"
                value={{ value: fillGradient, label: fillGradient }}
                onChange={value => {
                  this.onChangeFillGradient({ value: value.value as any });
                }}
                options={[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(t => ({ value: t, label: t }))}
              />
            </div>

            <div className="gf-form max-width-20">
              <span className="gf-form-label width-8">Line Width</span>
              <Select
                className="width-5"
                value={{ value: lineWidth, label: lineWidth }}
                onChange={value => {
                  this.onChangeLineWidth({ value: value.value as any });
                }}
                options={[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(t => ({ value: t, label: t }))}
              />
            </div>
          </div>
          <div className="section gf-form-group">
            <h5 className="section-heading">Stacking & Null value</h5>
            <div className="gf-form max-width-20">
              <Switch label="Stack" labelClass="width-5" checked={isStacked} onChange={this.onToggleisStacked} />
            </div>
          </div>
        </PanelOptionsGroup>

        <PanelOptionsGrid>
          <PanelOptionsGroup title="Field">
            <FieldPropertiesEditor showMinMax={false} onChange={this.onDefaultsChange} value={this.props.options.fieldOptions.defaults} />
          </PanelOptionsGroup>
          <PanelOptionsGroup title="Tooltip">
            <Select
              value={{ value: mode, label: mode === 'single' ? 'Single' : 'All series' }}
              onChange={value => {
                this.onTooltipOptionsChange({ mode: value.value as any });
              }}
              options={[
                { label: 'All series', value: 'multi' },
                { label: 'Single', value: 'single' },
              ]}
            />
          </PanelOptionsGroup>
          <GraphLegendEditor options={this.props.options.legend} onChange={this.onLegendOptionsChange} />
        </PanelOptionsGrid>
      </>
    );
  }
}