Merge branch 'ifrost/graphite-on-react-4' into ifrost/graphite-on-react-6

This commit is contained in:
Piotr Jamróz
2021-08-16 14:48:48 +02:00
16 changed files with 85 additions and 83 deletions
@@ -1,25 +0,0 @@
import React from 'react';
import { SectionFill } from './SectionFill';
import { SectionLabel } from './SectionLabel';
/**
* @alpha
*/
export const Section = ({
label,
children,
fill,
}: {
label: string;
children: React.ReactNode;
inline?: boolean;
fill?: boolean;
}) => (
<div className="gf-form-inline">
<div className="gf-form">
<SectionLabel name={label} className="width-7" />
{children}
</div>
{fill && <SectionFill />}
</div>
);
@@ -1,2 +0,0 @@
export { Section } from './Section';
export { SectionLabel } from './SectionLabel';
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { action } from '@storybook/addon-actions';
import { Segment, Icon, Section } from '@grafana/ui';
import { Segment, Icon, SegmentSection } from '@grafana/ui';
const AddButton = (
<a className="gf-form-label query-part">
@@ -17,10 +17,10 @@ const groupedOptions = [
const SegmentFrame = ({ options, children }: any) => (
<>
<Section label="Segment Name">
<SegmentSection label="Segment Name">
{children}
<Segment Component={AddButton} onChange={({ value }) => action('New value added')(value)} options={options} />
</Section>
</SegmentSection>
</>
);
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { AsyncState } from 'react-use/lib/useAsync';
import { action } from '@storybook/addon-actions';
import { SelectableValue } from '@grafana/data';
import { SegmentAsync, Icon, Section } from '@grafana/ui';
import { SegmentAsync, Icon, SegmentSection } from '@grafana/ui';
const AddButton = (
<a className="gf-form-label query-part">
@@ -21,14 +21,14 @@ const loadOptionsErr = (): Promise<Array<SelectableValue<string>>> =>
const SegmentFrame = ({ loadOptions, children }: any) => (
<>
<Section label="Segment Name">
<SegmentSection label="Segment Name">
{children}
<SegmentAsync
Component={AddButton}
onChange={(value) => action('New value added')(value)}
loadOptions={() => loadOptions(options)}
/>
</Section>
</SegmentSection>
</>
);
@@ -1,10 +1,10 @@
import React, { useState } from 'react';
import { action } from '@storybook/addon-actions';
import { SegmentInput, Icon, Section } from '@grafana/ui';
import { SegmentInput, Icon, SegmentSection } from '@grafana/ui';
const SegmentFrame = ({ children }: any) => (
<>
<Section label="Section Name">{children}</Section>
<SegmentSection label="Segment Name">{children}</SegmentSection>
</>
);
@@ -0,0 +1,44 @@
import React from 'react';
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { SegmentSectionFill } from './SegmentSectionFill';
import { SegmentSectionLabel } from './SegmentSectionLabel';
import { useStyles2 } from '../../themes';
/**
* Horizontal section for editor components.
*
* @alpha
*/
export const SegmentSection = ({
label,
children,
fill,
}: {
// Name of the section
label: string;
// List of components in the section
children: React.ReactNode;
// Fill the space at the end
fill?: boolean;
}) => {
const styles = useStyles2(getStyles);
return (
<>
<div className={styles.container}>
<SegmentSectionLabel name={label} className="width-7" />
{children}
{fill && <SegmentSectionFill />}
</div>
</>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
container: css`
display: flex;
flex-wrap: wrap;
row-gap: ${theme.spacing(0.5)};
align-content: flex-start;
`,
});
@@ -3,7 +3,7 @@ import React from 'react';
/**
* @alpha
*/
export const SectionFill = () => (
export const SegmentSectionFill = () => (
<div className="gf-form gf-form--grow">
<label className="gf-form-label gf-form-label--grow" />
</div>
@@ -4,6 +4,6 @@ import { cx } from '@emotion/css';
/**
* @alpha
*/
export const SectionLabel = ({ name, className }: { name: string; className?: string }) => (
export const SegmentSectionLabel = ({ name, className }: { name: string; className?: string }) => (
<label className={cx('gf-form-label query-keyword', className)}>{name}</label>
);
@@ -2,5 +2,7 @@ export { Segment } from './Segment';
export { SegmentAsync } from './SegmentAsync';
export { SegmentSelect } from './SegmentSelect';
export { SegmentInput } from './SegmentInput';
export { SegmentSection } from './SegmentSection';
export { SegmentSectionLabel } from './SegmentSectionLabel';
export { SegmentProps } from './types';
export { useExpandableLabel } from './useExpandableLabel';
+1 -2
View File
@@ -152,8 +152,7 @@ export { CertificationKey } from './DataSourceSettings/CertificationKey';
export { Spinner } from './Spinner/Spinner';
export { FadeTransition } from './transitions/FadeTransition';
export { SlideOutTransition } from './transitions/SlideOutTransition';
export { Segment, SegmentAsync, SegmentInput, SegmentSelect } from './Segment/';
export { Section, SectionLabel } from './Section/';
export { Segment, SegmentAsync, SegmentInput, SegmentSelect, SegmentSection, SegmentSectionLabel } from './Segment/';
export { Drawer } from './Drawer/Drawer';
export { Slider } from './Slider/Slider';
export { RangeSlider } from './Slider/RangeSlider';
@@ -2,7 +2,7 @@ import React from 'react';
import { FuncDefs, FuncInstance } from '../gfunc';
import { GraphiteFunctionEditor } from './GraphiteFunctionEditor';
import { AddGraphiteFunction } from './AddGraphiteFunction';
import { Section } from '@grafana/ui';
import { SegmentSection } from '@grafana/ui';
type Props = {
functions: FuncInstance[];
@@ -11,11 +11,11 @@ type Props = {
export function FunctionsSection({ functions = [], funcDefs }: Props) {
return (
<Section label="Functions" fill={true}>
<SegmentSection label="Functions" fill={true}>
{functions.map((func: FuncInstance, index: number) => {
return !func.hidden && <GraphiteFunctionEditor key={index} func={func} />;
})}
<AddGraphiteFunction funcDefs={funcDefs} />
</Section>
</SegmentSection>
);
}
@@ -82,6 +82,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
borderRadius: theme.shape.borderRadius(),
marginRight: theme.spacing(0.5),
padding: `0 ${theme.spacing(1)}`,
height: `${theme.v1.spacing.formInputHeight}px`,
}),
error: css`
border: 1px solid ${theme.colors.error.main};
@@ -2,8 +2,6 @@ import React from 'react';
import { GraphiteSegment } from '../types';
import { GraphiteQueryEditorState } from '../state/store';
import { MetricSegment } from './MetricSegment';
import { css } from '@emotion/css';
import { useStyles2 } from '@grafana/ui';
type Props = {
segments: GraphiteSegment[];
@@ -11,22 +9,11 @@ type Props = {
};
export function MetricsSection({ segments = [], state }: Props) {
const styles = useStyles2(getStyles);
return (
<div className={styles.container}>
<>
{segments.map((segment, index) => {
return <MetricSegment segment={segment} metricIndex={index} key={index} state={state} />;
})}
</div>
</>
);
}
function getStyles() {
return {
container: css`
display: flex;
flex-direction: row;
`,
};
}
@@ -2,7 +2,7 @@ import React from 'react';
import { GraphiteQueryEditorState } from '../state/store';
import { TagsSection } from './TagsSection';
import { MetricsSection } from './MetricsSection';
import { Section } from '@grafana/ui';
import { SegmentSection } from '@grafana/ui';
type Props = {
state: GraphiteQueryEditorState;
@@ -16,8 +16,8 @@ export function SeriesSection({ state }: Props) {
);
return (
<Section label="Series" fill={true}>
<SegmentSection label="Series" fill={true}>
{sectionContent}
</Section>
</SegmentSection>
);
}
@@ -40,7 +40,7 @@ export function TagsSection({ tags, state }: Props) {
]);
return (
<div className={styles.container}>
<>
{tags.map((tag, index) => {
return <TagEditor key={index} tagIndex={index} tag={tag} state={state} />;
})}
@@ -56,16 +56,12 @@ export function TagsSection({ tags, state }: Props) {
/>
)}
{state.paused && <PlayButton />}
</div>
</>
);
}
function getStyles(theme: GrafanaTheme2) {
return {
container: css`
display: flex;
flex-direction: row;
`,
button: css`
margin-right: ${theme.spacing(0.5)};
`,
@@ -26,7 +26,7 @@ import {
import { FormatAsSection } from './FormatAsSection';
import { DEFAULT_RESULT_FORMAT } from '../constants';
import { getNewSelectPartOptions, getNewGroupByPartOptions, makePartList } from './partListUtils';
import { Section, SectionLabel } from '@grafana/ui';
import { SegmentSection, SegmentSectionLabel } from '@grafana/ui';
type Props = {
query: InfluxQuery;
@@ -103,7 +103,7 @@ export const Editor = (props: Props): JSX.Element => {
return (
<div>
<Section label="FROM" fill={true}>
<SegmentSection label="FROM" fill={true}>
<FromSection
policy={policy}
measurement={measurement}
@@ -115,7 +115,7 @@ export const Editor = (props: Props): JSX.Element => {
}
onChange={handleFromSectionChange}
/>
<SectionLabel name="WHERE" />
<SegmentSectionLabel name="WHERE" />
<TagsSection
tags={query.tags ?? []}
onChange={handleTagsSectionChange}
@@ -124,9 +124,9 @@ export const Editor = (props: Props): JSX.Element => {
withTemplateVariableOptions(getTagValues(key, measurement, policy, query.tags ?? [], datasource))
}
/>
</Section>
</SegmentSection>
{selectLists.map((sel, index) => (
<Section key={index} label={index === 0 ? 'SELECT' : ''} fill={true}>
<SegmentSection key={index} label={index === 0 ? 'SELECT' : ''} fill={true}>
<PartListSection
parts={sel}
getNewPartOptions={() => Promise.resolve(getNewSelectPartOptions())}
@@ -141,9 +141,9 @@ export const Editor = (props: Props): JSX.Element => {
onAppliedChange(removeSelectPart(query, partIndex, index));
}}
/>
</Section>
</SegmentSection>
))}
<Section label="GROUP BY" fill={true}>
<SegmentSection label="GROUP BY" fill={true}>
<PartListSection
parts={groupByList}
getNewPartOptions={() => getNewGroupByPartOptions(query, getTagKeys)}
@@ -158,8 +158,8 @@ export const Editor = (props: Props): JSX.Element => {
onAppliedChange(removeGroupByPart(query, partIndex));
}}
/>
</Section>
<Section label="TIMEZONE" fill={true}>
</SegmentSection>
<SegmentSection label="TIMEZONE" fill={true}>
<InputSection
placeholder="(optional)"
value={query.tz}
@@ -167,20 +167,20 @@ export const Editor = (props: Props): JSX.Element => {
onAppliedChange({ ...query, tz });
}}
/>
<SectionLabel name="ORDER BY TIME" />
<SegmentSectionLabel name="ORDER BY TIME" />
<OrderByTimeSection
value={query.orderByTime === 'DESC' ? 'DESC' : 'ASC' /* FIXME: make this shared with influx_query_model */}
onChange={(v) => {
onAppliedChange({ ...query, orderByTime: v });
}}
/>
</Section>
</SegmentSection>
{/* query.fill is ignored in the query-editor, and it is deleted whenever
query-editor changes. the influx_query_model still handles it, but the new
approach seem to be to handle "fill" inside query.groupBy. so, if you
have a panel where in the json you have query.fill, it will be applied,
as long as you do not edit that query. */}
<Section label="LIMIT" fill={true}>
<SegmentSection label="LIMIT" fill={true}>
<InputSection
placeholder="(optional)"
value={query.limit?.toString()}
@@ -188,7 +188,7 @@ export const Editor = (props: Props): JSX.Element => {
onAppliedChange({ ...query, limit });
}}
/>
<SectionLabel name="SLIMIT" />
<SegmentSectionLabel name="SLIMIT" />
<InputSection
placeholder="(optional)"
value={query.slimit?.toString()}
@@ -196,8 +196,8 @@ export const Editor = (props: Props): JSX.Element => {
onAppliedChange({ ...query, slimit });
}}
/>
</Section>
<Section label="FORMAT AS" fill={true}>
</SegmentSection>
<SegmentSection label="FORMAT AS" fill={true}>
<FormatAsSection
format={query.resultFormat ?? DEFAULT_RESULT_FORMAT}
onChange={(format) => {
@@ -206,7 +206,7 @@ export const Editor = (props: Props): JSX.Element => {
/>
{query.resultFormat !== 'table' && (
<>
<SectionLabel name="ALIAS" />
<SegmentSectionLabel name="ALIAS" />
<InputSection
isWide
placeholder="Naming pattern"
@@ -217,7 +217,7 @@ export const Editor = (props: Props): JSX.Element => {
/>
</>
)}
</Section>
</SegmentSection>
</div>
);
};