123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import React, { FormEvent, useMemo } from 'react';
- import { useAsync } from 'react-use';
- import { DataFrameJSON, SelectableValue } from '@grafana/data';
- import {
- InlineField,
- InlineFieldRow,
- Button,
- FieldSet,
- InlineSwitch,
- Input,
- Label,
- Select,
- Form,
- TextArea,
- } from '@grafana/ui';
- import { EditorProps } from '../QueryEditor';
- import { SimulationQuery } from '../types';
- // Type string `json:"type"`
- // Name string `json:"name"`
- // Description string `json:"description"`
- // OnlyForward bool `json:"forward"`
- // ConfigFields *data.Frame `json:"config"`
- interface SimInfo {
- type: string;
- name: string;
- description: string;
- forward: boolean;
- config: DataFrameJSON;
- }
- interface FormDTO {
- config: string;
- }
- export const SimulationQueryEditor = ({ onChange, query, ds }: EditorProps) => {
- const simQuery = query.sim ?? ({} as SimulationQuery);
- const simKey = simQuery.key ?? ({} as typeof simQuery.key);
- // This only changes once
- const info = useAsync(async () => {
- const v = (await ds.getResource('sims')) as SimInfo[];
- return {
- sims: v,
- options: v.map((s) => ({ label: s.name, value: s.type, description: s.description })),
- };
- }, [ds]);
- const current = useMemo(() => {
- const type = simKey.type;
- if (!type || !info.value) {
- return {};
- }
- return {
- details: info.value.sims.find((v) => v.type === type),
- option: info.value.options.find((v) => v.value === type),
- };
- }, [info.value, simKey?.type]);
- let config = useAsync(async () => {
- let path = simKey.type + '/' + simKey.tick + 'hz';
- if (simKey.uid) {
- path += '/' + simKey.uid;
- }
- return (await ds.getResource('sim/' + path))?.config;
- }, [simKey.type, simKey.tick, simKey.uid]);
- const onUpdateKey = (key: typeof simQuery.key) => {
- onChange({ ...query, sim: { ...simQuery, key } });
- };
- const onUIDChanged = (e: FormEvent<HTMLInputElement>) => {
- const { value } = e.target as HTMLInputElement;
- onUpdateKey({ ...simKey, uid: value ?? undefined });
- };
- const onTickChanged = (e: FormEvent<HTMLInputElement>) => {
- const tick = e.currentTarget.valueAsNumber;
- onUpdateKey({ ...simKey, tick });
- };
- const onTypeChange = (v: SelectableValue<string>) => {
- onUpdateKey({ ...simKey, type: v.value! });
- };
- const onToggleStream = () => {
- onChange({ ...query, sim: { ...simQuery, stream: !simQuery.stream } });
- };
- const onToggleLast = () => {
- onChange({ ...query, sim: { ...simQuery, last: !simQuery.last } });
- };
- const onSubmitChange = (data: FormDTO) => {
- let path = simKey.type + '/' + simKey.tick + 'hz';
- if (simKey.uid) {
- path += '/' + simKey.uid;
- }
- ds.postResource('sim/' + path, JSON.parse(data.config));
- };
- return (
- <>
- <InlineFieldRow>
- <InlineField labelWidth={14} label="Simulation" tooltip="">
- <Select
- isLoading={info.loading}
- options={info.value?.options ?? []}
- value={current.option}
- onChange={onTypeChange}
- width={32}
- />
- </InlineField>
- </InlineFieldRow>
- <InlineFieldRow>
- <InlineField labelWidth={14} label="Stream" tooltip="connect to the live channel">
- <InlineSwitch value={Boolean(simQuery.stream)} onChange={onToggleStream} />
- </InlineField>
- <InlineField label="Interval" tooltip="the rate a simulation will spit out events">
- <Input
- width={10}
- type="number"
- value={simKey.tick}
- onChange={onTickChanged}
- min={1 / 10}
- max={50}
- suffix="hz"
- />
- </InlineField>
- <InlineField label="Last" tooltip="Only return the last value">
- <Label>
- <InlineSwitch value={Boolean(simQuery.last)} onChange={onToggleLast} />
- </Label>
- </InlineField>
- <InlineField label="UID" tooltip="A UID will allow multiple simulations to run at the same time">
- <Input type="text" placeholder="optional" value={simQuery.key.uid} onChange={onUIDChanged} />
- </InlineField>
- </InlineFieldRow>
- <div>
- <Form onSubmit={onSubmitChange}>
- {({ register }) => (
- <FieldSet>
- <TextArea {...register('config')} defaultValue={JSON.stringify(config.value, null, 2)} rows={7} />
- <Button type="submit">Submit</Button>
- </FieldSet>
- )}
- </Form>
- SCHEMA:
- <pre>{JSON.stringify(current.details?.config.schema, null, 2)}</pre>
- </div>
- </>
- );
- };
|