From 6fff8e4a1caf78359b2210c0504b30ad5ff17a90 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 6 Dec 2018 17:09:32 +0100 Subject: [PATCH 01/32] initial stuff --- .../core/components/Picker/SimplePicker.tsx | 4 +- .../app/plugins/panel/gauge/ValueMappings.tsx | 96 +++++++++++++++++++ public/app/plugins/panel/gauge/module.tsx | 20 +++- public/app/types/index.ts | 4 +- public/app/types/panel.ts | 14 +++ 5 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 public/app/plugins/panel/gauge/ValueMappings.tsx diff --git a/public/app/core/components/Picker/SimplePicker.tsx b/public/app/core/components/Picker/SimplePicker.tsx index 2ca8be43c75..4d127b7d82f 100644 --- a/public/app/core/components/Picker/SimplePicker.tsx +++ b/public/app/core/components/Picker/SimplePicker.tsx @@ -6,8 +6,8 @@ import ResetStyles from './ResetStyles'; interface Props { className?: string; defaultValue?: any; - getOptionLabel: (item: any) => string; - getOptionValue: (item: any) => string; + getOptionLabel?: (item: any) => string; + getOptionValue?: (item: any) => string; onSelected: (item: any) => {} | void; options: any[]; placeholder?: string; diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/public/app/plugins/panel/gauge/ValueMappings.tsx new file mode 100644 index 00000000000..b7749889110 --- /dev/null +++ b/public/app/plugins/panel/gauge/ValueMappings.tsx @@ -0,0 +1,96 @@ +import React, { PureComponent } from 'react'; +import { Label } from 'app/core/components/Label/Label'; +import SimplePicker from 'app/core/components/Picker/SimplePicker'; +import { OptionModuleProps } from './module'; +import { RangeMap, ValueMap } from 'app/types'; + +interface State { + valueMaps: ValueMap[]; + rangeMaps: RangeMap[]; +} + +enum MappingType { + ValueToText = 1, + RangeToText = 2, +} + +const mappingOptions = [ + { name: 'Value to text', value: MappingType.ValueToText }, + { name: 'Range to text', value: MappingType.RangeToText }, +]; + +export default class ValueMappings extends PureComponent { + constructor(props) { + super(props); + + this.state = { + valueMaps: props.options.valueMaps, + rangeMaps: props.options.rangeMaps, + }; + } + onMappingTypeChange = option => this.props.onChange({ ...this.props.options, mappingType: option.value }); + + addValueMap = () => + this.setState(prevState => ({ + valueMaps: [...prevState.valueMaps, { op: '', value: '', text: '' }], + })); + + addRangeMap = () => { + this.setState = () => + this.setState(prevState => ({ + valueMaps: [...prevState.valueMaps, { op: '', value: '', text: '', from: '', to: '' }], + })); + }; + + updateGauge = () => {}; + + renderValueMapList() { + const { mappingType, rangeMaps, valueMaps } = this.props.options; + + if (mappingType === MappingType.RangeToText) { + return ( +
+ {rangeMaps.length > 0 + ? rangeMaps.map((range, index) => { + return
{`${range.from}-${range.to}`}
; + }) + : 'aint no ranges, add one?'} +
+ ); + } + + return ( +
+ {valueMaps.length > 0 + ? valueMaps.map((value, index) => { + return
{`${value}`}
; + }) + : 'aint no values, add one?'} +
+ ); + } + + render() { + const { mappingType } = this.props.options; + + return ( +
+
+ + i.name} + onSelected={option => this.onMappingTypeChange(option)} + width={5} + value={mappingType} + /> +
+
+
Set value mappings
+
{this.renderValueMapList()}
+
+
+ ); + } +} diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 87e25612f61..81e047e6434 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -1,10 +1,11 @@ import React, { PureComponent } from 'react'; import Gauge from 'app/viz/Gauge'; -import { NullValueMode, PanelOptionsProps, PanelProps, Threshold } from 'app/types'; +import { NullValueMode, PanelOptionsProps, PanelProps, RangeMap, Threshold, ValueMap } from 'app/types'; import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; import ValueOptions from './ValueOptions'; import GaugeOptions from './GaugeOptions'; import Thresholds from './Thresholds'; +import ValueMappings from './ValueMappings'; export interface OptionsProps { decimals: number; @@ -15,6 +16,9 @@ export interface OptionsProps { suffix: string; unit: string; thresholds: Threshold[]; + valueMaps: ValueMap[]; + rangeMaps: RangeMap[]; + mappingType: number; } export interface OptionModuleProps { @@ -52,11 +56,19 @@ class Options extends PureComponent> { static defaultProps = defaultProps; render() { + const { onChange, options } = this.props; return (
- - - +
+
Options
+ + + +
+
+
Value mappings
+ +
); } diff --git a/public/app/types/index.ts b/public/app/types/index.ts index a13bf28c3ca..e66153ab723 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -20,7 +20,7 @@ import { DataQueryResponse, DataQueryOptions, } from './series'; -import { PanelProps, PanelOptionsProps, Threshold } from './panel'; +import { PanelProps, PanelOptionsProps, RangeMap, Threshold, ValueMap } from './panel'; import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; import { Organization, OrganizationState } from './organization'; import { @@ -92,6 +92,8 @@ export { Threshold, ValidationEvents, ValidationRule, + ValueMap, + RangeMap, }; export interface StoreState { diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index 049b07973de..0736ae47acb 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -36,3 +36,17 @@ export interface Threshold { color?: string; canRemove: boolean; } + +interface BaseMap { + op: string; + text: string; +} + +export interface ValueMap extends BaseMap { + value: string; +} + +export interface RangeMap extends BaseMap { + from: string; + to: string; +} From 368f1f67e4fb255fc21d3ceced3dc41b3d37938b Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Fri, 7 Dec 2018 16:55:58 +0100 Subject: [PATCH 02/32] render a value mapping row --- public/app/plugins/panel/gauge/MappingRow.tsx | 141 ++++++++++++++++++ .../app/plugins/panel/gauge/ValueMappings.tsx | 89 ++++------- public/app/plugins/panel/gauge/module.tsx | 2 + 3 files changed, 168 insertions(+), 64 deletions(-) create mode 100644 public/app/plugins/panel/gauge/MappingRow.tsx diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/public/app/plugins/panel/gauge/MappingRow.tsx new file mode 100644 index 00000000000..63930d617cd --- /dev/null +++ b/public/app/plugins/panel/gauge/MappingRow.tsx @@ -0,0 +1,141 @@ +import React, { PureComponent } from 'react'; +import { Label } from 'app/core/components/Label/Label'; +import ToggleButtonGroup, { ToggleButton } from 'app/core/components/ToggleButtonGroup/ToggleButtonGroup'; +import { RangeMap, ValueMap } from 'app/types'; + +enum MappingType { + ValueToText = 1, + RangeToText = 2, +} + +interface Props { + mapping: ValueMap | RangeMap; + updateMapping: (mapping) => void; +} + +interface State { + mapping: ValueMap | RangeMap; + mappingType: MappingType; +} + +export default class MappingRow extends PureComponent { + constructor(props) { + super(props); + + this.state = { + mappingType: MappingType.ValueToText, + mapping: props.mapping, + }; + } + + onMappingValueChange = event => { + const { mapping } = this.state; + + const updatedMapping = { ...mapping, value: event.target.value }; + + this.setState({ mapping: updatedMapping }); + }; + + onMappingFromChange = event => { + const { mapping } = this.state; + + const updatedMapping = { ...mapping, from: event.target.value }; + + this.setState({ mapping: updatedMapping }); + }; + + onMappingToChange = event => { + const { mapping } = this.state; + + const updatedMapping = { ...mapping, to: event.target.value }; + + this.setState({ mapping: updatedMapping }); + }; + + onMappingTextChange = event => { + const { mapping } = this.state; + + const updatedMapping = { ...mapping, text: event.target.value }; + this.setState({ mapping: updatedMapping }); + }; + + onMappingTypeChange = mappingType => this.setState({ mappingType }); + + renderRow() { + const { mapping, mappingType } = this.state; + + if (mappingType === MappingType.RangeToText) { + const rangeMap = mapping as RangeMap; + + return ( +
+
+ + +
+
+ + +
+
+ + +
+
+ ); + } + + const valueMap = mapping as ValueMap; + + return ( +
+
+ + +
+
+ + +
+
+ ); + } + + render() { + const { mappingType } = this.state; + + return ( +
+
+ this.onMappingTypeChange(mappingType)} + render={({ selectedValue, onChange }) => { + return [ + + Value + , + + Range + , + ]; + }} + /> +
{this.renderRow()}
+
+
+ ); + } +} diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/public/app/plugins/panel/gauge/ValueMappings.tsx index b7749889110..897fd462a78 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.tsx +++ b/public/app/plugins/panel/gauge/ValueMappings.tsx @@ -1,94 +1,55 @@ import React, { PureComponent } from 'react'; -import { Label } from 'app/core/components/Label/Label'; -import SimplePicker from 'app/core/components/Picker/SimplePicker'; +import MappingRow from './MappingRow'; import { OptionModuleProps } from './module'; import { RangeMap, ValueMap } from 'app/types'; interface State { + combinedMappings: any[]; valueMaps: ValueMap[]; rangeMaps: RangeMap[]; } -enum MappingType { - ValueToText = 1, - RangeToText = 2, -} - -const mappingOptions = [ - { name: 'Value to text', value: MappingType.ValueToText }, - { name: 'Range to text', value: MappingType.RangeToText }, -]; - export default class ValueMappings extends PureComponent { constructor(props) { super(props); this.state = { - valueMaps: props.options.valueMaps, + combinedMappings: props.options.valueMaps.concat(props.options.rangeMaps), rangeMaps: props.options.rangeMaps, + valueMaps: props.options.valueMaps, }; } - onMappingTypeChange = option => this.props.onChange({ ...this.props.options, mappingType: option.value }); - addValueMap = () => + addMapping = () => this.setState(prevState => ({ - valueMaps: [...prevState.valueMaps, { op: '', value: '', text: '' }], + combinedMappings: [...prevState.combinedMappings, { op: '', value: '', text: '' }], })); - addRangeMap = () => { - this.setState = () => - this.setState(prevState => ({ - valueMaps: [...prevState.valueMaps, { op: '', value: '', text: '', from: '', to: '' }], - })); + updateGauge = mapping => { + this.setState(prevState => ({ + combinedMappings: prevState.combinedMappings.map(m => { + if (m === mapping) { + return { ...mapping }; + } + + return m; + }), + })); }; - updateGauge = () => {}; - - renderValueMapList() { - const { mappingType, rangeMaps, valueMaps } = this.props.options; - - if (mappingType === MappingType.RangeToText) { - return ( -
- {rangeMaps.length > 0 - ? rangeMaps.map((range, index) => { - return
{`${range.from}-${range.to}`}
; - }) - : 'aint no ranges, add one?'} -
- ); - } - - return ( -
- {valueMaps.length > 0 - ? valueMaps.map((value, index) => { - return
{`${value}`}
; - }) - : 'aint no values, add one?'} -
- ); - } - render() { - const { mappingType } = this.props.options; + const { combinedMappings } = this.state; return ( -
+
- - i.name} - onSelected={option => this.onMappingTypeChange(option)} - width={5} - value={mappingType} - /> -
-
-
Set value mappings
-
{this.renderValueMapList()}
+
+ {combinedMappings.length > 0 && + combinedMappings.map((mapping, index) => { + return ; + })} +
+
Add mapping
); diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 81e047e6434..5a4b96b0647 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -34,6 +34,8 @@ export const defaultProps = { showThresholdMarkers: true, showThresholdLabels: false, suffix: '', + valueMaps: [], + rangeMaps: [], }, }; From a0a06911d81604d8eb3f05241c35fcc91b48e14f Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Fri, 7 Dec 2018 17:08:28 +0100 Subject: [PATCH 03/32] Toggle buttons --- public/app/plugins/panel/gauge/MappingRow.tsx | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/public/app/plugins/panel/gauge/MappingRow.tsx index 63930d617cd..93d17c24692 100644 --- a/public/app/plugins/panel/gauge/MappingRow.tsx +++ b/public/app/plugins/panel/gauge/MappingRow.tsx @@ -88,7 +88,7 @@ export default class MappingRow extends PureComponent { const valueMap = mapping as ValueMap; return ( -
+
@@ -105,36 +105,34 @@ export default class MappingRow extends PureComponent { const { mappingType } = this.state; return ( -
-
- this.onMappingTypeChange(mappingType)} - render={({ selectedValue, onChange }) => { - return [ - - Value - , - - Range - , - ]; - }} - /> -
{this.renderRow()}
-
+
+ this.onMappingTypeChange(mappingType)} + value={mappingType} + render={({ selectedValue, onChange }) => { + return [ + + Value + , + + Range + , + ]; + }} + /> +
{this.renderRow()}
); } From ee55a9c18be67bd3de8445183bdd160ed5f6803e Mon Sep 17 00:00:00 2001 From: ijin08 Date: Mon, 10 Dec 2018 11:59:02 +0100 Subject: [PATCH 04/32] removed side menu for column styles, added small header to column styles with a border --- .../plugins/panel/table/column_options.html | 332 +++++++++--------- public/sass/components/edit_sidemenu.scss | 4 + 2 files changed, 165 insertions(+), 171 deletions(-) diff --git a/public/app/plugins/panel/table/column_options.html b/public/app/plugins/panel/table/column_options.html index 6f9adb4ae0f..ffb6ea8e67f 100644 --- a/public/app/plugins/panel/table/column_options.html +++ b/public/app/plugins/panel/table/column_options.html @@ -1,200 +1,190 @@ -
- - -
- -
-
Options
-
-
- - +

{{style.pattern || 'New rule'}}

+
+
Options
+
+
+ + -
-
- - -
-
+
+ + +
+ +
-
-
Type
+
+
Type
-
- -
- -
+
+ +
+
-
- - +
+ + - -
+
+
-
- + -
-
- +
+ -
+
-
-
- -
-
-
- - +
+ +
+
+
+ + -
+
-
-
Value Mappings
-
-
-
- - Type - -
- -
-
-
-
- - - - - - -
-
- -
-
-
-
- - - - From - - To - - Text - -
-
- -
-
-
- -
-
Thresholds
-
- - -
-
- -
- -
-
-
- - - - - - - - - - -
- Invert -
-
-
- -
-
Link
-
-
-
-
+
+ +
+
Thresholds
+
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + +
+ Invert +
+
+
+ +
+
Link
+
+ + +
+
+ - + + + -
-
+ +
-
- +
+
-
-
-
+
+
+ +
diff --git a/public/sass/components/edit_sidemenu.scss b/public/sass/components/edit_sidemenu.scss index 87d90f18162..4fc6795c068 100644 --- a/public/sass/components/edit_sidemenu.scss +++ b/public/sass/components/edit_sidemenu.scss @@ -28,6 +28,10 @@ } } +.column-styles-heading { + border-bottom: 1px solid $gray-1; +} + @include media-breakpoint-down(sm) { .edit-tab-with-sidemenu { flex-direction: column; From 4a57d594e571ba3dbeec070c0df741b7a6ef37c5 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Mon, 10 Dec 2018 14:50:32 +0100 Subject: [PATCH 05/32] fixed styling --- .../ToggleButtonGroup/ToggleButtonGroup.tsx | 9 +- public/app/plugins/panel/gauge/MappingRow.tsx | 91 +++++++++++-------- .../app/plugins/panel/gauge/ValueMappings.tsx | 18 ++-- public/app/plugins/panel/gauge/module.tsx | 2 - public/sass/_grafana.scss | 1 + .../sass/components/_toggle_button_group.scss | 4 + public/sass/components/_value-mappings.scss | 30 ++++++ 7 files changed, 105 insertions(+), 50 deletions(-) create mode 100644 public/sass/components/_value-mappings.scss diff --git a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx index 1e9ae4732df..b90e1d6a320 100644 --- a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -5,9 +5,14 @@ interface ToggleButtonGroupProps { value?: any; label?: string; render: (props) => void; + stackedButtons?: boolean; } export default class ToggleButtonGroup extends PureComponent { + static defaultProps = { + stackedButtons: false, + }; + getValues() { const { children } = this.props; return React.Children.toArray(children).map((c: ReactElement) => c.props.value); @@ -27,14 +32,14 @@ export default class ToggleButtonGroup extends PureComponent -
+
{label && } {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this) })}
diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/public/app/plugins/panel/gauge/MappingRow.tsx index 93d17c24692..507d0148379 100644 --- a/public/app/plugins/panel/gauge/MappingRow.tsx +++ b/public/app/plugins/panel/gauge/MappingRow.tsx @@ -68,18 +68,24 @@ export default class MappingRow extends PureComponent { const rangeMap = mapping as RangeMap; return ( -
-
- - +
+
+ +
+ +
-
- - +
+ +
+ +
-
- - +
+ +
+ +
); @@ -91,11 +97,15 @@ export default class MappingRow extends PureComponent {
- +
+ +
- +
+ +
); @@ -105,33 +115,36 @@ export default class MappingRow extends PureComponent { const { mappingType } = this.state; return ( -
- this.onMappingTypeChange(mappingType)} - value={mappingType} - render={({ selectedValue, onChange }) => { - return [ - - Value - , - - Range - , - ]; - }} - /> +
+
+ this.onMappingTypeChange(mappingType)} + value={mappingType} + stackedButtons={true} + render={({ selectedValue, onChange }) => { + return [ + + Value + , + + Range + , + ]; + }} + /> +
{this.renderRow()}
); diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/public/app/plugins/panel/gauge/ValueMappings.tsx index 897fd462a78..8ce41bdb83a 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.tsx +++ b/public/app/plugins/panel/gauge/ValueMappings.tsx @@ -42,14 +42,18 @@ export default class ValueMappings extends PureComponent -
-
- {combinedMappings.length > 0 && - combinedMappings.map((mapping, index) => { - return ; - })} +
Value mappings
+
+ {combinedMappings.length > 0 && + combinedMappings.map((mapping, index) => { + return ; + })} +
+
+
+
-
Add mapping
+
Add mapping
); diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 5a4b96b0647..ffe18cb9482 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -62,13 +62,11 @@ class Options extends PureComponent> { return (
-
Options
-
Value mappings
diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 892a576fc87..1164d810099 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -106,6 +106,7 @@ @import 'components/unit-picker'; @import 'components/thresholds'; @import 'components/toggle_button_group'; +@import 'components/value-mappings'; // PAGES @import 'pages/login'; diff --git a/public/sass/components/_toggle_button_group.scss b/public/sass/components/_toggle_button_group.scss index ed701a489a9..2f657f91d7e 100644 --- a/public/sass/components/_toggle_button_group.scss +++ b/public/sass/components/_toggle_button_group.scss @@ -13,6 +13,10 @@ } } + &.stacked { + flex-direction: column; + } + .btn { background-color: $typeahead-selected-bg; border-radius: 0; diff --git a/public/sass/components/_value-mappings.scss b/public/sass/components/_value-mappings.scss new file mode 100644 index 00000000000..7f587672e5a --- /dev/null +++ b/public/sass/components/_value-mappings.scss @@ -0,0 +1,30 @@ +.mapping-row { + display: flex; + align-items: center; + margin-bottom: 15px; +} + +.mapping-row-type { + margin-right: 5px; +} + +.add-mapping-row { + display: flex; + overflow: hidden; + height: 37px; + cursor: pointer; +} + +.add-mapping-row-icon { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + background-color: $green; +} + +.add-mapping-row-label { + align-items: center; + display: flex; + padding: 5px 8px; +} From 76f296e29948b562dee3fd9c50035e9dc2e42799 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Mon, 10 Dec 2018 16:57:34 +0100 Subject: [PATCH 06/32] fixed typings and remove --- public/app/plugins/panel/gauge/MappingRow.tsx | 69 ++++++++++++++----- .../app/plugins/panel/gauge/ValueMappings.tsx | 54 ++++++++++----- public/app/plugins/panel/gauge/module.tsx | 3 +- public/app/types/index.ts | 3 +- public/app/types/panel.ts | 6 ++ 5 files changed, 95 insertions(+), 40 deletions(-) diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/public/app/plugins/panel/gauge/MappingRow.tsx index 507d0148379..4dee7f81be9 100644 --- a/public/app/plugins/panel/gauge/MappingRow.tsx +++ b/public/app/plugins/panel/gauge/MappingRow.tsx @@ -1,21 +1,16 @@ import React, { PureComponent } from 'react'; import { Label } from 'app/core/components/Label/Label'; import ToggleButtonGroup, { ToggleButton } from 'app/core/components/ToggleButtonGroup/ToggleButtonGroup'; -import { RangeMap, ValueMap } from 'app/types'; - -enum MappingType { - ValueToText = 1, - RangeToText = 2, -} +import { MappingType, RangeMap, ValueMap } from 'app/types'; interface Props { mapping: ValueMap | RangeMap; updateMapping: (mapping) => void; + removeMapping: () => void; } interface State { mapping: ValueMap | RangeMap; - mappingType: MappingType; } export default class MappingRow extends PureComponent { @@ -23,7 +18,6 @@ export default class MappingRow extends PureComponent { super(props); this.state = { - mappingType: MappingType.ValueToText, mapping: props.mapping, }; } @@ -59,12 +53,23 @@ export default class MappingRow extends PureComponent { this.setState({ mapping: updatedMapping }); }; - onMappingTypeChange = mappingType => this.setState({ mappingType }); + updateMapping = () => { + const { mapping } = this.state; + + this.props.updateMapping(mapping); + }; + + onMappingTypeChange = mappingType => { + const { mapping } = this.state; + + const updatedMapping = { ...mapping, type: mappingType }; + this.setState({ mapping: updatedMapping }); + }; renderRow() { - const { mapping, mappingType } = this.state; + const { mapping } = this.state; - if (mappingType === MappingType.RangeToText) { + if (mapping.type === MappingType.RangeToText) { const rangeMap = mapping as RangeMap; return ( @@ -72,19 +77,34 @@ export default class MappingRow extends PureComponent {
- +
- +
- +
@@ -98,13 +118,23 @@ export default class MappingRow extends PureComponent {
- +
- +
@@ -112,14 +142,14 @@ export default class MappingRow extends PureComponent { } render() { - const { mappingType } = this.state; + const { mapping } = this.state; return (
this.onMappingTypeChange(mappingType)} - value={mappingType} + value={mapping.type} stackedButtons={true} render={({ selectedValue, onChange }) => { return [ @@ -146,6 +176,9 @@ export default class MappingRow extends PureComponent { />
{this.renderRow()}
+
+ +
); } diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/public/app/plugins/panel/gauge/ValueMappings.tsx index 8ce41bdb83a..58b257e386a 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.tsx +++ b/public/app/plugins/panel/gauge/ValueMappings.tsx @@ -1,12 +1,10 @@ import React, { PureComponent } from 'react'; import MappingRow from './MappingRow'; import { OptionModuleProps } from './module'; -import { RangeMap, ValueMap } from 'app/types'; +import { MappingType, RangeMap, ValueMap } from 'app/types'; interface State { - combinedMappings: any[]; - valueMaps: ValueMap[]; - rangeMaps: RangeMap[]; + mappings: Array; } export default class ValueMappings extends PureComponent { @@ -14,39 +12,57 @@ export default class ValueMappings extends PureComponent this.setState(prevState => ({ - combinedMappings: [...prevState.combinedMappings, { op: '', value: '', text: '' }], + mappings: [ + ...prevState.mappings, + { op: '', value: '', text: '', type: MappingType.ValueToText, from: '', to: '' }, + ], + })); + + onRemoveMapping = index => + this.setState(prevState => ({ + mappings: prevState.mappings.filter((m, i) => i !== index), })); updateGauge = mapping => { - this.setState(prevState => ({ - combinedMappings: prevState.combinedMappings.map(m => { - if (m === mapping) { - return { ...mapping }; - } + this.setState( + prevState => ({ + mappings: prevState.mappings.map(m => { + if (m === mapping) { + return { ...mapping }; + } - return m; + return m; + }), }), - })); + () => { + this.props.onChange({ ...this.props.options, mappings: this.state.mappings }); + } + ); }; render() { - const { combinedMappings } = this.state; + const { mappings } = this.state; return (
Value mappings
- {combinedMappings.length > 0 && - combinedMappings.map((mapping, index) => { - return ; + {mappings.length > 0 && + mappings.map((mapping, index) => { + return ( + this.onRemoveMapping(index)} + /> + ); })}
diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index ffe18cb9482..b04cc4d72f9 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -16,8 +16,7 @@ export interface OptionsProps { suffix: string; unit: string; thresholds: Threshold[]; - valueMaps: ValueMap[]; - rangeMaps: RangeMap[]; + mappings: Array; mappingType: number; } diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 89d1f3a79a1..ed883bfd1c7 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -21,7 +21,7 @@ import { DataQueryOptions, IntervalValues, } from './series'; -import { PanelProps, PanelOptionsProps, RangeMap, Threshold, ValueMap } from './panel'; +import { MappingType, PanelProps, PanelOptionsProps, RangeMap, Threshold, ValueMap } from './panel'; import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; import { Organization, OrganizationState } from './organization'; import { @@ -96,6 +96,7 @@ export { ValueMap, RangeMap, IntervalValues, + MappingType, }; export interface StoreState { diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index 0736ae47acb..93e908db302 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -37,9 +37,15 @@ export interface Threshold { canRemove: boolean; } +export enum MappingType { + ValueToText = 1, + RangeToText = 2, +} + interface BaseMap { op: string; text: string; + type: MappingType; } export interface ValueMap extends BaseMap { From d6c6ba642e62cb03e2707216117d23c38d942f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 11 Dec 2018 10:33:09 +0100 Subject: [PATCH 07/32] Don't show heading for first tab --- .../app/features/dashboard/dashgrid/VisualizationTab.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 97e4e3aa556..19026754f83 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -87,10 +87,11 @@ export class VisualizationTab extends PureComponent { let template = ''; for (let i = 0; i < panelCtrl.editorTabs.length; i++) { - template += ` -
-
{{ctrl.editorTabs[${i}].title}}
-
+ template += + ` +
` + + (i > 0 ? `
{{ctrl.editorTabs[${i}].title}}
` : '') + + `
From 4591c3555caa47b925fc0dc1aa3b0e598c165629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 11 Dec 2018 13:36:44 +0100 Subject: [PATCH 08/32] Moved more metrics tab to react --- .../features/dashboard/dashboard_migration.ts | 2 +- .../app/features/dashboard/dashboard_model.ts | 10 - .../dashboard/dashgrid/QueriesTab.tsx | 111 ++++++++--- public/app/features/dashboard/panel_model.ts | 18 ++ public/app/features/panel/metrics_tab.ts | 176 +----------------- .../features/panel/partials/metrics_tab.html | 37 ++-- public/app/features/panel/query_editor_row.ts | 2 +- public/sass/components/_gf-form.scss | 1 - 8 files changed, 136 insertions(+), 221 deletions(-) diff --git a/public/app/features/dashboard/dashboard_migration.ts b/public/app/features/dashboard/dashboard_migration.ts index 5f1deae6e14..c5a960304fd 100644 --- a/public/app/features/dashboard/dashboard_migration.ts +++ b/public/app/features/dashboard/dashboard_migration.ts @@ -143,7 +143,7 @@ export class DashboardMigrator { panelUpgrades.push(panel => { _.each(panel.targets, target => { if (!target.refId) { - target.refId = this.dashboard.getNextQueryLetter(panel); + target.refId = panel.getNextQueryLetter(); } }); }); diff --git a/public/app/features/dashboard/dashboard_model.ts b/public/app/features/dashboard/dashboard_model.ts index 18a16d5c1d4..6f98bc5a17a 100644 --- a/public/app/features/dashboard/dashboard_model.ts +++ b/public/app/features/dashboard/dashboard_model.ts @@ -806,16 +806,6 @@ export class DashboardModel { return this.timezone === 'browser' ? moment(date).fromNow() : moment.utc(date).fromNow(); } - getNextQueryLetter(panel) { - const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - return _.find(letters, refId => { - return _.every(panel.targets, other => { - return other.refId !== refId; - }); - }); - } - isTimezoneUtc() { return this.getTimezone() === 'utc'; } diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index 4c341f684f7..1e00e193456 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -1,21 +1,27 @@ +// Libraries import React, { SFC, PureComponent } from 'react'; +import Remarkable from 'remarkable'; +import _ from 'lodash'; + +// Components import DataSourceOption from './DataSourceOption'; -import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; import { EditorTabBody } from './EditorTabBody'; import { DataSourcePicker } from './DataSourcePicker'; -import { PanelModel } from '../panel_model'; -import { DashboardModel } from '../dashboard_model'; -import './../../panel/metrics_tab'; -import config from 'app/core/config'; import { QueryInspector } from './QueryInspector'; import { TimeRangeOptions } from './TimeRangeOptions'; +import './../../panel/metrics_tab'; +import { AngularQueryComponentScope } from 'app/features/panel/metrics_tab'; // Services import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv'; -import { DataSourceSelectItem } from 'app/types'; +import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +import config from 'app/core/config'; -import Remarkable from 'remarkable'; +// Types +import { PanelModel } from '../panel_model'; +import { DashboardModel } from '../dashboard_model'; +import { DataSourceSelectItem, DataQuery } from 'app/types'; interface Props { panel: PanelModel; @@ -40,7 +46,7 @@ interface LoadingPlaceholderProps { const LoadingPlaceholder: SFC = ({ text }) =>

{text}

; export class QueriesTab extends PureComponent { - element: any; + element: HTMLElement; component: AngularComponent; datasources: DataSourceSelectItem[] = getDatasourceSrv().getMetricSources(); backendSrv: BackendSrv = getBackendSrv(); @@ -59,20 +65,30 @@ export class QueriesTab extends PureComponent { }; } + getAngularQueryComponentScope(): AngularQueryComponentScope { + const { panel, dashboard } = this.props; + + return { + panel: panel, + dashboard: dashboard, + refresh: () => panel.refresh(), + render: () => panel.render, + addQuery: this.onAddQuery, + moveQuery: this.onMoveQuery, + removeQuery: this.onRemoveQuery, + events: panel.events, + }; + } + componentDidMount() { if (!this.element) { return; } - const { panel, dashboard } = this.props; const loader = getAngularLoader(); const template = ''; const scopeProps = { - ctrl: { - panel: panel, - dashboard: dashboard, - refresh: () => panel.refresh(), - }, + ctrl: this.getAngularQueryComponentScope(), }; this.component = loader.load(this.element, scopeProps, template); @@ -87,6 +103,7 @@ export class QueriesTab extends PureComponent { onChangeDataSource = datasource => { const { panel } = this.props; const { currentDatasource } = this.state; + // switching to mixed if (datasource.meta.mixed) { panel.targets.forEach(target => { @@ -95,10 +112,16 @@ export class QueriesTab extends PureComponent { target.datasource = config.defaultDatasource; } }); - } else if (currentDatasource && currentDatasource.meta.mixed) { - panel.targets.forEach(target => { - delete target.datasource; - }); + } else if (currentDatasource) { + // if switching from mixed + if (currentDatasource.meta.mixed) { + for (const target of panel.targets) { + delete target.datasource; + } + } else if (currentDatasource.meta.id !== datasource.meta.id) { + // we are changing data source type, clear queries + panel.targets = [{ refId: 'A' }]; + } } panel.datasource = datasource.value; @@ -227,9 +250,41 @@ export class QueriesTab extends PureComponent { return isLoading ? : helpHtml; }; + onAddQuery = (query?: DataQuery) => { + this.props.panel.addQuery(query); + this.forceUpdate(); + }; + + onAddQueryClick = () => { + this.props.panel.addQuery(); + this.component.digest(); + this.forceUpdate(); + }; + + onRemoveQuery = (query: DataQuery) => { + const { panel } = this.props; + + const index = _.indexOf(panel.targets, query); + panel.targets.splice(index, 1); + panel.refresh(); + + this.forceUpdate(); + }; + + onMoveQuery = (query: DataQuery, direction: number) => { + const { panel } = this.props; + + const index = _.indexOf(panel.targets, query); + _.move(panel.targets, index, index + direction); + + this.forceUpdate(); + }; + render() { + const { panel } = this.props; const { currentDatasource } = this.state; const { hasQueryHelp } = currentDatasource.meta; + const dsInformation = { title: currentDatasource.name, imgSrc: currentDatasource.meta.info.logos.small, @@ -266,9 +321,23 @@ export class QueriesTab extends PureComponent { return ( - <> -
(this.element = element)} style={{ width: '100%' }} /> - +
+
(this.element = element)} /> + +
+
+ + +
+
+
); } diff --git a/public/app/features/dashboard/panel_model.ts b/public/app/features/dashboard/panel_model.ts index a664e3d8ea1..e0a3e6707cb 100644 --- a/public/app/features/dashboard/panel_model.ts +++ b/public/app/features/dashboard/panel_model.ts @@ -1,6 +1,7 @@ import { Emitter } from 'app/core/utils/emitter'; import _ from 'lodash'; import { PANEL_OPTIONS_KEY_PREFIX } from 'app/core/constants'; +import { DataQuery } from 'app/types'; export interface GridPos { x: number; @@ -237,6 +238,23 @@ export class PanelModel { this.restorePanelOptions(pluginId); } + addQuery(query?: DataQuery) { + query = query || { refId: 'A' }; + (query.refId = this.getNextQueryLetter()), (query.isNew = true); + + this.targets.push(query); + } + + getNextQueryLetter(): string { + const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + return _.find(letters, refId => { + return _.every(this.targets, other => { + return other.refId !== refId; + }); + }); + } + destroy() { this.events.emit('panel-teardown'); this.events.removeAllListeners(); diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index 2ceb39e8a82..70b3571e30d 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -1,181 +1,24 @@ // Libraries import _ from 'lodash'; -import Remarkable from 'remarkable'; // Services & utils import coreModule from 'app/core/core_module'; -import config from 'app/core/config'; import { Emitter } from 'app/core/utils/emitter'; // Types import { DashboardModel } from '../dashboard/dashboard_model'; +import { PanelModel } from '../dashboard/panel_model'; +import { DataQuery } from 'app/types'; -export class MetricsTabCtrl { - dsName: string; - panel: any; - panelCtrl: any; - datasources: any[]; - datasourceInstance: any; - nextRefId: string; +export interface AngularQueryComponentScope { + panel: PanelModel; dashboard: DashboardModel; - panelDsValue: any; - addQueryDropdown: any; - queryTroubleshooterOpen: boolean; - helpOpen: boolean; - optionsOpen: boolean; - hasQueryHelp: boolean; - helpHtml: string; - queryOptions: any; events: Emitter; - - /** @ngInject */ - constructor($scope, private $sce, datasourceSrv, private backendSrv) { - this.panelCtrl = $scope.ctrl; - $scope.ctrl = this; - - this.panel = this.panelCtrl.panel; - this.panel.datasource = this.panel.datasource || null; - this.panel.targets = this.panel.targets || [{}]; - - this.dashboard = this.panelCtrl.dashboard; - this.datasources = datasourceSrv.getMetricSources(); - this.panelDsValue = this.panelCtrl.panel.datasource; - - // added here as old query controller expects this on panelCtrl but - // they are getting MetricsTabCtrl instead - this.events = this.panel.events; - - for (const ds of this.datasources) { - if (ds.value === this.panelDsValue) { - this.datasourceInstance = ds; - } - } - - this.addQueryDropdown = { text: 'Add Query', value: null, fake: true }; - - // update next ref id - this.nextRefId = this.dashboard.getNextQueryLetter(this.panel); - this.updateDatasourceOptions(); - } - - updateDatasourceOptions() { - if (this.datasourceInstance) { - this.hasQueryHelp = this.datasourceInstance.meta.hasQueryHelp; - this.queryOptions = this.datasourceInstance.meta.queryOptions; - } - } - - getOptions(includeBuiltin) { - return Promise.resolve( - this.datasources - .filter(value => { - return includeBuiltin || !value.meta.builtIn; - }) - .map(ds => { - return { value: ds.value, text: ds.name, datasource: ds }; - }) - ); - } - - datasourceChanged(option) { - if (!option) { - return; - } - - this.setDatasource(option.datasource); - this.updateDatasourceOptions(); - } - - setDatasource(datasource) { - // switching to mixed - if (datasource.meta.mixed) { - _.each(this.panel.targets, target => { - target.datasource = this.panel.datasource; - if (!target.datasource) { - target.datasource = config.defaultDatasource; - } - }); - } else if (this.datasourceInstance) { - // if switching from mixed - if (this.datasourceInstance.meta.mixed) { - _.each(this.panel.targets, target => { - delete target.datasource; - }); - } else if (this.datasourceInstance.meta.id !== datasource.meta.id) { - // we are changing data source type, clear queries - this.panel.targets = [{ refId: 'A' }]; - this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel); - } - } - - this.datasourceInstance = datasource; - this.panel.datasource = datasource.value; - this.panel.refresh(); - } - - addMixedQuery(option) { - if (!option) { - return; - } - - this.panelCtrl.addQuery({ - isNew: true, - datasource: option.datasource.name, - }); - this.addQueryDropdown = { text: 'Add Query', value: null, fake: true }; - } - - toggleHelp() { - this.optionsOpen = false; - this.queryTroubleshooterOpen = false; - this.helpOpen = !this.helpOpen; - - this.backendSrv.get(`/api/plugins/${this.datasourceInstance.meta.id}/markdown/query_help`).then(res => { - const md = new Remarkable(); - this.helpHtml = this.$sce.trustAsHtml(md.render(res)); - }); - } - - toggleOptions() { - this.helpOpen = false; - this.queryTroubleshooterOpen = false; - this.optionsOpen = !this.optionsOpen; - } - - toggleQueryTroubleshooter() { - this.helpOpen = false; - this.optionsOpen = false; - this.queryTroubleshooterOpen = !this.queryTroubleshooterOpen; - } - - addQuery(query?) { - query = query || {}; - query.refId = this.dashboard.getNextQueryLetter(this.panel); - query.isNew = true; - - this.panel.targets.push(query); - this.nextRefId = this.dashboard.getNextQueryLetter(this.panel); - } - - refresh() { - this.panel.refresh(); - } - - render() { - this.panel.render(); - } - - removeQuery(target) { - const index = _.indexOf(this.panel.targets, target); - this.panel.targets.splice(index, 1); - this.nextRefId = this.dashboard.getNextQueryLetter(this.panel); - this.panel.refresh(); - } - - moveQuery(target, direction) { - const index = _.indexOf(this.panel.targets, target); - _.move(this.panel.targets, index, index + direction); - } + refresh: () => void; + render: () => void; + removeQuery: (query: DataQuery) => void; + addQuery: (query?: DataQuery) => void; + moveQuery: (query: DataQuery, direction: number) => void; } /** @ngInject */ @@ -185,7 +28,6 @@ export function metricsTabDirective() { restrict: 'E', scope: true, templateUrl: 'public/app/features/panel/partials/metrics_tab.html', - controller: MetricsTabCtrl, }; } diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index ecee1f76ea9..5e9f23ba2ef 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -1,5 +1,3 @@ - -
@@ -7,21 +5,20 @@
-
-
- - - -
-
-
+ + + + + + + + + + + + + + + + + diff --git a/public/app/features/panel/query_editor_row.ts b/public/app/features/panel/query_editor_row.ts index 39bd6008873..a44c1e8be6d 100644 --- a/public/app/features/panel/query_editor_row.ts +++ b/public/app/features/panel/query_editor_row.ts @@ -20,7 +20,7 @@ export class QueryRowCtrl { this.hideEditorRowActions = this.panelCtrl.hideEditorRowActions; if (!this.target.refId) { - this.target.refId = this.panelCtrl.dashboard.getNextQueryLetter(this.panel); + this.target.refId = this.panel.getNextQueryLetter(); } this.toggleCollapse(true); diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 0c6ef7d1fa0..f0855ead897 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -110,7 +110,6 @@ $input-border: 1px solid $input-border-color; &--grow { flex-grow: 1; - min-height: 2.6rem; } &--error { From ddf080dab6808ea526ff129ae653328f847da2ef Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Tue, 11 Dec 2018 14:17:58 +0100 Subject: [PATCH 09/32] Using an id to identify mappings --- .../ToggleButtonGroup/ToggleButtonGroup.tsx | 14 ++++- public/app/plugins/panel/gauge/MappingRow.tsx | 26 +++++---- public/app/plugins/panel/gauge/Thresholds.tsx | 13 +---- .../panel/gauge/ValueMappings.test.tsx | 54 ++++++++++++++++++ .../app/plugins/panel/gauge/ValueMappings.tsx | 57 +++++++++++++------ public/app/plugins/panel/gauge/module.tsx | 23 ++++++-- public/app/types/index.ts | 3 +- public/app/types/panel.ts | 9 ++- .../sass/components/_toggle_button_group.scss | 4 ++ public/sass/components/_value-mappings.scss | 8 +++ 10 files changed, 161 insertions(+), 50 deletions(-) create mode 100644 public/app/plugins/panel/gauge/ValueMappings.test.tsx diff --git a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx index b90e1d6a320..2a59e5a5662 100644 --- a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -41,7 +41,7 @@ export default class ToggleButtonGroup extends PureComponent
{label && } - {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this) })} + {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this), stackedButtons: stackedButtons })}
); @@ -54,9 +54,17 @@ interface ToggleButtonProps { value: any; className?: string; children: ReactNode; + stackedButtons?: boolean; } -export const ToggleButton: SFC = ({ children, selected, className = '', value, onChange }) => { +export const ToggleButton: SFC = ({ + children, + selected, + className = '', + value, + onChange, + stackedButtons, +}) => { const handleChange = event => { event.stopPropagation(); if (onChange) { @@ -64,7 +72,7 @@ export const ToggleButton: SFC = ({ children, selected, class } }; - const btnClassName = `btn ${className} ${selected ? 'active' : ''}`; + const btnClassName = `btn ${className} ${selected ? 'active' : ''} ${stackedButtons ? 'stacked' : ''}`; return ( +
+
+
+ {filteredPluginList.map((plugin, index) => this.renderVizPlugin(plugin, index))} +
+
+
); } } diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index ca9e1a38249..7e76fc841d5 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -271,7 +271,7 @@ $menu-dropdown-shadow: 5px 5px 20px -5px $black; $tab-border-color: $dark-4; // Toolbar -$toolbar-bg: $black; +$toolbar-bg: $input-bg; // Pagination // ------------------------- @@ -375,6 +375,7 @@ $checkbox-color: $dark-1; //Panel Edit // ------------------------- $panel-editor-shadow: 0 0 20px black; +$panel-editor-border: 1px solid $dark-3; $panel-editor-side-menu-shadow: drop-shadow(0 0 10px $black); $panel-editor-toolbar-view-bg: $black; $panel-editor-viz-item-shadow: 0 0 8px $dark-5; diff --git a/public/sass/_variables.light.scss b/public/sass/_variables.light.scss index dd84b7af869..657e9eb3509 100644 --- a/public/sass/_variables.light.scss +++ b/public/sass/_variables.light.scss @@ -384,6 +384,7 @@ $checkbox-color: $gray-7; //Panel Edit // ------------------------- $panel-editor-shadow: 2px 2px 8px $gray-3; +$panel-editor-border: 1px solid $dark-4; $panel-editor-side-menu-shadow: drop-shadow(0 0 2px $gray-3); $panel-editor-toolbar-view-bg: $white; $panel-editor-viz-item-shadow: 0 0 4px $gray-3; diff --git a/public/sass/components/_buttons.scss b/public/sass/components/_buttons.scss index 27055551b4b..4e032d7b9d1 100644 --- a/public/sass/components/_buttons.scss +++ b/public/sass/components/_buttons.scss @@ -78,6 +78,7 @@ .btn-link { color: $btn-link-color; + background: transparent; } // Set the backgrounds diff --git a/public/sass/components/_panel_editor.scss b/public/sass/components/_panel_editor.scss index 898139afd3a..e2dbbc6f532 100644 --- a/public/sass/components/_panel_editor.scss +++ b/public/sass/components/_panel_editor.scss @@ -34,8 +34,8 @@ flex-grow: 1; background: $page-bg; margin: 0 20px 0 84px; - border-left: 2px solid $orange; border-radius: 3px; + border: $panel-editor-border; box-shadow: $panel-editor-shadow; } @@ -133,17 +133,14 @@ } .viz-picker { - background: $panel-editor-toolbar-view-bg; display: flex; flex-wrap: wrap; - margin: -40px -20px; - margin-bottom: 13px; - padding: 20px; + margin-bottom: 40px; } .viz-picker__item { - background: $panel-editor-viz-item-bg; - border: $panel-editor-viz-item-border; + background: $panel-bg; + border: $panel-border; border-radius: 3px; height: 100px; width: 150px; @@ -323,6 +320,13 @@ margin-bottom: 20px; background: $input-label-bg; border-radius: 3px; + position: relative; + + .btn { + position: absolute; + right: 0; + top: 2px; + } } .form-section__body { From 5adb0f79dfb7f0451815e1ff16dd034f8065f3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 12 Dec 2018 14:25:07 +0100 Subject: [PATCH 29/32] wip --- .../dashboard/dashgrid/VisualizationTab.tsx | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 42023d9de35..793baf15586 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -106,7 +106,7 @@ export class VisualizationTab extends PureComponent { template += `
` + - (i > -1 ? `
{{ctrl.editorTabs[${i}].title}}
` : '') + + (i > 0 ? `
{{ctrl.editorTabs[${i}].title}}
` : '') + `
@@ -155,23 +155,23 @@ export class VisualizationTab extends PureComponent { const { plugin } = this.props; const { searchQuery } = this.state; - if (this.state.isVizPickerOpen) { - return ( - <> - - - ); - } else { + // if (this.state.isVizPickerOpen) { + // return ( + // <> + // + // + // ); + // } else { return (
@@ -179,7 +179,7 @@ export class VisualizationTab extends PureComponent {
); - } + // } }; onTypeChanged = (plugin: PanelPlugin) => { @@ -201,12 +201,7 @@ export class VisualizationTab extends PureComponent { <> - + {this.renderPanelOptions()} From 1751a5108893c0fe8cb7885e3daab501675cd187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 12 Dec 2018 14:44:40 +0100 Subject: [PATCH 30/32] wip --- .../dashboard/dashgrid/VisualizationTab.tsx | 60 +++++++++++-------- .../dashboard/dashgrid/VizTypePicker.tsx | 14 +---- public/sass/components/_panel_editor.scss | 12 +++- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 793baf15586..ae976ddfd54 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -5,7 +5,7 @@ import React, { PureComponent } from 'react'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; // Components -import { EditorTabBody } from './EditorTabBody'; +import { EditorTabBody, EditorToolBarView } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; @@ -155,23 +155,23 @@ export class VisualizationTab extends PureComponent { const { plugin } = this.props; const { searchQuery } = this.state; - // if (this.state.isVizPickerOpen) { - // return ( - // <> - // - // - // ); - // } else { + if (this.state.isVizPickerOpen) { + return ( + <> + + + ); + } else { return (
@@ -179,7 +179,7 @@ export class VisualizationTab extends PureComponent {
); - // } + } }; onTypeChanged = (plugin: PanelPlugin) => { @@ -190,18 +190,26 @@ export class VisualizationTab extends PureComponent { render() { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; + const toolbarItems: EditorToolBarView = []; - const panelHelp = { - title: '', - icon: 'fa fa-question', - render: () =>

Help

, - }; + if (!isVizPickerOpen) { + toolbarItems.push({ + title: '', + icon: 'fa fa-question', + render: () =>

Help

, + }); + } return ( - + <> - + {this.renderPanelOptions()} diff --git a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx index e9f8d895e40..76c6c3af9ce 100644 --- a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx +++ b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx @@ -66,17 +66,9 @@ export class VizTypePicker extends PureComponent { const filteredPluginList = this.getFilteredPluginList(); return ( -
-
- Type selection - -
-
-
- {filteredPluginList.map((plugin, index) => this.renderVizPlugin(plugin, index))} -
+
+
+ {filteredPluginList.map((plugin, index) => this.renderVizPlugin(plugin, index))}
); diff --git a/public/sass/components/_panel_editor.scss b/public/sass/components/_panel_editor.scss index e2dbbc6f532..34a19ceb72f 100644 --- a/public/sass/components/_panel_editor.scss +++ b/public/sass/components/_panel_editor.scss @@ -133,14 +133,20 @@ } .viz-picker { + background: $toolbar-bg; + margin: -40px -20px 40px 106px; + padding: 20px; + position: relative; +} + +.viz-picker-list { display: flex; flex-wrap: wrap; - margin-bottom: 40px; } .viz-picker__item { - background: $panel-bg; - border: $panel-border; + background: $panel-editor-viz-item-bg; + border: $panel-editor-viz-item-border; border-radius: 3px; height: 100px; width: 150px; From 666e8e8330cb5205dc16148e5470f505bba06bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 13 Dec 2018 07:44:58 +0100 Subject: [PATCH 31/32] wip: changes --- .../features/dashboard/dashgrid/EditorTabBody.tsx | 10 +++++++--- .../dashboard/dashgrid/VisualizationTab.tsx | 13 ++++++++++--- .../features/dashboard/dashgrid/VizTypePicker.tsx | 1 - public/sass/_variables.dark.scss | 6 +++--- public/sass/components/_panel_editor.scss | 3 +-- public/sass/utils/_utils.scss | 4 ++++ 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx index e76edb1840a..42c6b33764b 100644 --- a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -5,7 +5,7 @@ import { FadeIn } from 'app/core/components/Animations/FadeIn'; interface Props { children: JSX.Element; heading: string; - renderToolbar?: () => JSX.Element | JSX.Element[]; + renderToolbar?: () => JSX.Element; toolbarItems?: EditorToolBarView[]; } @@ -106,8 +106,12 @@ export class EditorTabBody extends PureComponent {
{heading}
{renderToolbar && renderToolbar()} -
- {toolbarItems.map(item => this.renderButton(item))} + {toolbarItems.length > 0 && ( + <> +
+ {toolbarItems.map(item => this.renderButton(item))} + + )}
diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index ae976ddfd54..e52475149be 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -169,6 +169,10 @@ export class VisualizationTab extends PureComponent { /> +
+ ); } else { @@ -183,14 +187,17 @@ export class VisualizationTab extends PureComponent { }; onTypeChanged = (plugin: PanelPlugin) => { - // this.setState({ isVizPickerOpen: false }); - this.props.onTypeChanged(plugin); + if (plugin.id === this.props.plugin.id) { + this.setState({ isVizPickerOpen: false }); + } else { + this.props.onTypeChanged(plugin); + } }; render() { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; - const toolbarItems: EditorToolBarView = []; + const toolbarItems: EditorToolBarView[] = []; if (!isVizPickerOpen) { toolbarItems.push({ diff --git a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx index 76c6c3af9ce..f0dd7d0f2c7 100644 --- a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx +++ b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx @@ -62,7 +62,6 @@ export class VizTypePicker extends PureComponent { }; render() { - const { onClose } = this.props; const filteredPluginList = this.getFilteredPluginList(); return ( diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 7e76fc841d5..4e756be7f59 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -271,7 +271,7 @@ $menu-dropdown-shadow: 5px 5px 20px -5px $black; $tab-border-color: $dark-4; // Toolbar -$toolbar-bg: $input-bg; +$toolbar-bg: $input-black; // Pagination // ------------------------- @@ -377,12 +377,12 @@ $checkbox-color: $dark-1; $panel-editor-shadow: 0 0 20px black; $panel-editor-border: 1px solid $dark-3; $panel-editor-side-menu-shadow: drop-shadow(0 0 10px $black); -$panel-editor-toolbar-view-bg: $black; +$panel-editor-toolbar-view-bg: $input-black; $panel-editor-viz-item-shadow: 0 0 8px $dark-5; $panel-editor-viz-item-border: 1px solid $dark-5; $panel-editor-viz-item-shadow-hover: 0 0 4px $blue; $panel-editor-viz-item-border-hover: 1px solid $blue; -$panel-editor-viz-item-bg: $black; +$panel-editor-viz-item-bg: $input-black; $panel-editor-tabs-line-color: #e3e3e3; $panel-editor-viz-item-bg-hover: darken($blue, 47%); $panel-editor-viz-item-bg-hover-active: darken($orange, 45%); diff --git a/public/sass/components/_panel_editor.scss b/public/sass/components/_panel_editor.scss index 34a19ceb72f..d43a44d615c 100644 --- a/public/sass/components/_panel_editor.scss +++ b/public/sass/components/_panel_editor.scss @@ -35,7 +35,6 @@ background: $page-bg; margin: 0 20px 0 84px; border-radius: 3px; - border: $panel-editor-border; box-shadow: $panel-editor-shadow; } @@ -134,7 +133,7 @@ .viz-picker { background: $toolbar-bg; - margin: -40px -20px 40px 106px; + margin: -40px -20px 40px -20px; padding: 20px; position: relative; } diff --git a/public/sass/utils/_utils.scss b/public/sass/utils/_utils.scss index 811731660eb..ce59c68a23f 100644 --- a/public/sass/utils/_utils.scss +++ b/public/sass/utils/_utils.scss @@ -83,6 +83,10 @@ button.close { position: absolute; } +.flex-grow { + flex-grow: 1; +} + .center-vh { display: flex; align-items: center; From f39fd7655ef296d820e6d63a43e7b80e4bdfb022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 13 Dec 2018 08:56:20 +0100 Subject: [PATCH 32/32] wip: minor style changes --- .../dashboard/dashgrid/VisualizationTab.tsx | 13 ++----------- public/sass/components/_json_explorer.scss | 8 +++++--- public/sass/components/_panel_editor.scss | 7 +++---- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index e52475149be..f598ae5f7a0 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -5,7 +5,7 @@ import React, { PureComponent } from 'react'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; // Components -import { EditorTabBody, EditorToolBarView } from './EditorTabBody'; +import { EditorTabBody } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; @@ -197,18 +197,9 @@ export class VisualizationTab extends PureComponent { render() { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; - const toolbarItems: EditorToolBarView[] = []; - - if (!isVizPickerOpen) { - toolbarItems.push({ - title: '', - icon: 'fa fa-question', - render: () =>

Help

, - }); - } return ( - + <>