diff --git a/public/app/core/components/CustomScrollbar/CustomScrollbar.tsx b/public/app/core/components/CustomScrollbar/CustomScrollbar.tsx index 9b9a9c4d02a..93add925095 100644 --- a/public/app/core/components/CustomScrollbar/CustomScrollbar.tsx +++ b/public/app/core/components/CustomScrollbar/CustomScrollbar.tsx @@ -15,7 +15,7 @@ interface Props { class CustomScrollbar extends PureComponent { static defaultProps: Partial = { customClassName: 'custom-scrollbars', - autoHide: true, + autoHide: false, autoHideTimeout: 200, autoHideDuration: 200, hideTracksWhenNotNeeded: false, diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx new file mode 100644 index 00000000000..2460514eda1 --- /dev/null +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -0,0 +1,84 @@ +import React, { PureComponent } from 'react'; +import CustomScrollbar from 'app/core/components/CustomScrollbar/CustomScrollbar'; +import { FadeIn } from 'app/core/components/Animations/FadeIn'; + +interface Props { + selectedText?: string; + selectedImage?: string; + children: JSX.Element; + toolbarItems: EditorToolBarView[]; +} + +export interface EditorToolBarView { + title: string; + imgSrc: string; + render: () => JSX.Element; +} + +interface State { + openView?: EditorToolBarView; +} + +export class EditorTabBody extends PureComponent { + constructor(props) { + super(props); + + this.state = { + openView: null, + }; + } + + onToggleToolBarView = (item: EditorToolBarView) => { + this.setState({ + openView: item === this.state.openView ? null : item, + }); + } + + onCloseOpenView = () => { + this.setState({ openView: null }); + } + + renderToolBarViewToggle(item: EditorToolBarView) { + return ( +
this.onToggleToolBarView(item)} key={item.title}> + +
{item.title}
+ +
+ ); + } + + renderOpenView(view: EditorToolBarView) { + return ( +
+ + {view.render()} +
+ ); + } + + render() { + const { children, toolbarItems} = this.props; + const { openView } = this.state; + + return ( + <> +
+
{toolbarItems.map(item => this.renderToolBarViewToggle(item))}
+
+
+ +
+ + {openView && this.renderOpenView(openView)} + + {children} +
+
+
+ + ); + } +} diff --git a/public/app/features/dashboard/dashgrid/PanelEditor.tsx b/public/app/features/dashboard/dashgrid/PanelEditor.tsx index 9c4f1440096..a1b976c6c66 100644 --- a/public/app/features/dashboard/dashgrid/PanelEditor.tsx +++ b/public/app/features/dashboard/dashgrid/PanelEditor.tsx @@ -2,8 +2,7 @@ import React, { PureComponent } from 'react'; import classNames from 'classnames'; import { QueriesTab } from './QueriesTab'; -import { VizTypePicker } from './VizTypePicker'; -import CustomScrollbar from 'app/core/components/CustomScrollbar/CustomScrollbar'; +import { VisualizationTab } from './VisualizationTab'; import { store } from 'app/store/configureStore'; import { updateLocation } from 'app/core/actions'; @@ -38,35 +37,6 @@ export class PanelEditor extends PureComponent { ]; } - renderQueriesTab() { - return ; - } - - renderPanelOptions() { - const { plugin, panel } = this.props; - const { PanelOptionsComponent } = plugin.exports; - - if (PanelOptionsComponent) { - return ; - } else { - return

Visualization has no options

; - } - } - - onPanelOptionsChanged = (options: any) => { - this.props.panel.updateOptions(options); - this.forceUpdate(); - }; - - renderVizTab() { - return ( -
- - {this.renderPanelOptions()} -
- ); - } - onChangeTab = (tab: PanelEditorTab) => { store.dispatch( updateLocation({ @@ -87,50 +57,8 @@ export class PanelEditor extends PureComponent { }; render() { - return this.renderAsTabs(); - // return this.renderAsBoxes(); - // const { location } = store.getState(); - // const activeTab = location.query.tab || 'queries'; - // - // return ( - //
- //
- //
- //
- //
- //
- //
- //

- // - // Edit Panel - //

- // - // {this.tabs.map(tab => { - // return ; - // })} - // - //
- // - // - //
- //
- //
- // - // {activeTab === 'queries' && this.renderQueriesTab()} - // {activeTab === 'visualization' && this.renderVizTab()} - // - //
- //
- // ); - } - - renderAsTabs() { + const { panel, dashboard, onTypeChanged, plugin } = this.props; const { location } = store.getState(); - const { panel } = this.props; const activeTab = location.query.tab || 'queries'; return ( @@ -141,49 +69,22 @@ export class PanelEditor extends PureComponent {
-
-
-

{panel.title}

+
+
    + {this.tabs.map(tab => { + return ; + })} +
-
    - {this.tabs.map(tab => { - return ; - })} -
- - -
- -
- - {activeTab === 'queries' && this.renderQueriesTab()} - {activeTab === 'visualization' && this.renderVizTab()} - -
-
-
- ); - } - - renderAsBoxes() { - const { location } = store.getState(); - const { panel } = this.props; - const activeTab = location.query.tab || 'queries'; - - return ( -
-
-
-
-
+
- - {this.renderQueriesTab()} - {this.renderVizTab()} - + {activeTab === 'queries' && } + {activeTab === 'visualization' && ( + + )}
); } @@ -196,19 +97,6 @@ interface TabItemParams { } function TabItem({ tab, activeTab, onClick }: TabItemParams) { - const tabClasses = classNames({ - 'panel-editor__aside-item': true, - active: activeTab === tab.id, - }); - - return ( - onClick(tab)}> - {tab.text} - - ); -} - -function OldTabItem({ tab, activeTab, onClick }: TabItemParams) { const tabClasses = classNames({ 'gf-tabs-link': true, active: activeTab === tab.id, @@ -216,7 +104,9 @@ function OldTabItem({ tab, activeTab, onClick }: TabItemParams) { return (
  • onClick(tab)}> - {tab.text} + + {tab.text} +
  • ); } diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index f13f212826a..e1884992901 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -3,6 +3,7 @@ import React, { PureComponent } from 'react'; // Services & utils import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +import { EditorTabBody } from './EditorTabBody'; // Types import { PanelModel } from '../panel_model'; @@ -48,6 +49,20 @@ export class QueriesTab extends PureComponent { } render() { - return
    (this.element = element)} className="panel-height-helper" />; + const currentDataSource = { + title: 'ProductionDB', + imgSrc: 'public/app/plugins/datasource/prometheus/img/prometheus_logo.svg', + render: () => { + return ( +

    Hello

    + ); + }, + }; + + return ( + +
    (this.element = element)} style={{ width: '100%' }} /> + + ); } } diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx new file mode 100644 index 00000000000..34d37c0e61b --- /dev/null +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -0,0 +1,56 @@ +import React, { PureComponent } from 'react'; + +import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +import { EditorTabBody } from './EditorTabBody'; +import { VizTypePicker } from './VizTypePicker'; + +import { PanelModel } from '../panel_model'; +import { DashboardModel } from '../dashboard_model'; + +interface Props { + panel: PanelModel; + dashboard: DashboardModel; + plugin: PluginModel; + onTypeChanged: (newType: PanelPlugin) => void; +} + +export class VisualizationTab extends PureComponent { + + constructor(props) { + super(props); + } + + renderPanelOptions() { + const { plugin, panel } = this.props; + const { PanelOptionsComponent } = plugin.exports; + + if (PanelOptionsComponent) { + return ; + } else { + return

    Visualization has no options

    ; + } + } + + onPanelOptionsChanged = (options: any) => { + this.props.panel.updateOptions(options); + this.forceUpdate(); + }; + + render() { + const {plugin, onTypeChanged} = this.props; + + const panelSelection = { + title: plugin.name, + imgSrc: plugin.info.logos.small, + render: () => { + return ; + }, + }; + + return ( + + {this.renderPanelOptions()} + + ); + } +} diff --git a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx index 05be2ef8d41..7e87670955b 100644 --- a/public/app/features/dashboard/dashgrid/VizTypePicker.tsx +++ b/public/app/features/dashboard/dashgrid/VizTypePicker.tsx @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; import classNames from 'classnames'; import _ from 'lodash'; -import { FadeIn } from 'app/core/components/Animations/FadeIn'; import config from 'app/core/config'; import { PanelPlugin } from 'app/types/plugins'; @@ -13,7 +12,6 @@ interface Props { interface State { pluginList: PanelPlugin[]; - isOpen: boolean; } export class VizTypePicker extends PureComponent { @@ -22,7 +20,6 @@ export class VizTypePicker extends PureComponent { this.state = { pluginList: this.getPanelPlugins(''), - isOpen: false, }; } @@ -65,53 +62,20 @@ export class VizTypePicker extends PureComponent { ); } - onToggleOpen = () => { - this.setState({ isOpen: !this.state.isOpen }); - }; - render() { const { current } = this.props; - const { pluginList, isOpen } = this.state; + const { pluginList } = this.state; return ( -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    + <> +
    +
    Select visualization
    + {this.renderFilters()} +
    - -
    - - -
    -
    Select visualization
    - {this.renderFilters()} -
    -
    - -
    {pluginList.map(this.renderVizPlugin)}
    -
    - -
    +
    {pluginList.map(this.renderVizPlugin)}
    + ); } } diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index 815a99d6b74..42808ac10f7 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/public/sass/components/_dashboard_grid.scss b/public/sass/components/_dashboard_grid.scss index 7b1db117247..5f142dfd02f 100644 --- a/public/sass/components/_dashboard_grid.scss +++ b/public/sass/components/_dashboard_grid.scss @@ -19,6 +19,10 @@ transform: translate(0px, 0px) !important; } + .panel { + margin: 0 !important; + } + // Disable grid interaction indicators in fullscreen panels .panel-header:hover { background-color: inherit; diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 8ec697326be..b2d01bc5136 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -416,7 +416,7 @@ select.gf-form-input ~ .gf-form-help-icon { position: absolute; right: 0; top: -2px; - font-size: $font-size-lg; + font-size: $font-size-md; &:hover { color: $text-color-strong; diff --git a/public/sass/components/_viz_editor.scss b/public/sass/components/_viz_editor.scss index 3d82e133469..b51f6d335a3 100644 --- a/public/sass/components/_viz_editor.scss +++ b/public/sass/components/_viz_editor.scss @@ -11,16 +11,20 @@ .panel-editor-container__editor { margin-top: $panel-margin*2; display: flex; - flex-direction: row; + flex-direction: column; height: 65%; position: relative; } -.panel-editor__content { +.panel-editor__scroll { flex-grow: 1; min-width: 0; - height: 100%; - padding: 0 20px; + display: flex; + padding: 0 5px; +} + +.panel-editor__content { + padding: 40px 15px; } .panel-in-fullscreen { @@ -107,66 +111,6 @@ height: 55px; } -.panel-editor__aside { - background: $panel-bg; - display: flex; - flex-direction: column; -} - -.panel-editor__aside-item { - padding: 8px 20px; - color: $text-color; - font-size: $font-size-md; - @include left-brand-border; - - &.active { - @include left-brand-border-gradient(); - background: $page-bg; - } - - i { - width: 23px; - } - - .gicon { - margin-bottom: 2px; - } - - .fa { - font-size: 17px; - } -} - -.panel-editor__aside-actions { - display: flex; - flex-direction: column; - height: 100%; - flex-grow: 1; - padding: 60px 15px; - - button { - margin-bottom: 10px; - } -} - -.panel-editor__aside-header { - color: $text-muted; - font-size: $font-size-h3; - padding: 20px 30px 10px 20px; - white-space: nowrap; - - i { - font-size: 25px; - position: relative; - top: 1px; - padding-right: 5px; - } -} - -.viz-picker__bar { - margin-bottom: $spacer; -} - .panel-editor-resizer { position: absolute; height: 2px; @@ -223,3 +167,99 @@ font-size: $font-size-lg; margin-bottom: 20px; } + +.edit-section { + position: relative; +} + +.edit-section__header { + display: flex; + align-content: center; + align-items: center; + background: linear-gradient(90deg, #292a2d, black); + padding: 7px 30px 7px 20px; + box-shadow: 0 0 20px black; + cursor: pointer; +} + +.edit-section__selected { + padding: $input-padding-y $input-padding-x; + font-size: $font-size-md; + line-height: $input-line-height; + color: $input-color; + background-color: $input-bg; + border: $input-border; + border-radius: $input-border-radius; + display: flex; + align-items: center; + .fa { + margin-left: 20px; + display: inline-block; + position: relative; + } +} + +.edit-section__title { + font-size: $font-size-lg; + padding-right: 20px; + width: 150px; +} + +.edit-section__selected-image { + margin-right: 10px; + display: inline-block; + width: 20px; + height: 20px; +} + +.panel-editor-tabs { + z-index: 1; + box-shadow: $page-header-shadow; + border-bottom: 1px solid $page-header-border-color; + padding: 0 $dashboard-padding; + @include clearfix(); + + .active.gf-tabs-link { + background: #242427; + } +} + +.panel-editor-tabs__close { + float: right; + padding: 0; + margin: 0; + background-color: transparent; + border: none; + padding: $tabs-padding; + color: $text-color; + + i { + font-size: 120%; + } + &:hover { + color: $text-color-strong; + } +} + +.editor-toolbar-view { + position: relative; + padding: 10px 20px; + background-color: $empty-list-cta-bg; + border-top: 3px solid $orange; + margin: 0 100px; +} + +.editor-toolbar-view__close { + background: transparent; + padding: 4px 8px 4px 9px; + border: none; + position: absolute; + right: 0; + top: -2px; + font-size: $font-size-md; + + &:hover { + color: $text-color-strong; + } +} +