ux: worked on add panel function

This commit is contained in:
Torkel Ödegaard 2017-10-16 09:55:55 +02:00
parent 48b6692491
commit 772ab7812f
12 changed files with 164 additions and 157 deletions

View File

@ -0,0 +1,72 @@
import React from 'react';
import config from 'app/core/config';
import {PanelModel} from '../panel_model';
import {PanelContainer} from './PanelContainer';
import _ from 'lodash';
export interface AddPanelPanelProps {
panel: PanelModel;
getPanelContainer: () => PanelContainer;
}
export interface AddPanelPanelState {
filter: string;
panelPlugins: any[];
}
export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelPanelState> {
constructor(props) {
super(props);
this.state = {
panelPlugins: this.getPanelPlugins(),
filter: '',
};
this.onPanelSelected = this.onPanelSelected.bind(this);
}
getPanelPlugins() {
return _.chain(config.panels)
.filter({hideFromList: false})
.map(item => item)
.orderBy('sort')
.value();
}
onPanelSelected(panelPluginInfo) {
const panelContainer = this.props.getPanelContainer();
const dashboard = panelContainer.getDashboard();
// remove add-panel panel
dashboard.removePanel(this.props.panel);
dashboard.addPanel({
type: panelPluginInfo.id,
title: 'Panel Title',
gridPos: {
x: this.props.panel.gridPos.x,
y: this.props.panel.gridPos.y,
w: this.props.panel.gridPos.w,
h: this.props.panel.gridPos.h
}
});
}
renderPanelItem(panel) {
return (
<div key={panel.id} className="add-panel__item" onClick={() => this.onPanelSelected(panel)} title={panel.name}>
<img className="add-panel__item-img" src={panel.info.logos.small} />
<div className="add-panel__item-name">{panel.name}</div>
</div>
);
}
render() {
return (
<div className="panel-container">
<div className="add-panel">{this.state.panelPlugins.map(this.renderPanelItem.bind(this))}</div>
</div>
);
}
}

View File

@ -91,6 +91,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
y: panel.gridPos.y,
w: panel.gridPos.w,
h: panel.gridPos.h,
static: panel.gridPos.static,
});
}

View File

@ -2,6 +2,8 @@ import React from 'react';
import {PanelModel} from '../panel_model';
import {PanelContainer} from './PanelContainer';
import {AttachedPanel} from './PanelLoader';
import {DashboardRow} from './DashboardRow';
import {AddPanelPanel} from './AddPanelPanel';
export interface DashboardPanelProps {
panel: PanelModel;
@ -18,10 +20,13 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
}
componentDidMount() {
if (!this.element) {
return;
}
const panelContainer = this.props.getPanelContainer();
const dashboard = panelContainer.getDashboard();
const loader = panelContainer.getPanelLoader();
this.attachedPanel = loader.load(this.element, this.props.panel, dashboard);
}
@ -31,9 +36,16 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
}
}
render() {
// special handling for rows
if (this.props.panel.type === 'row') {
return <DashboardRow panel={this.props.panel} />;
}
if (this.props.panel.type === 'add-panel') {
return <AddPanelPanel panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
}
return (
<div ref={element => this.element = element} />
);

View File

@ -5,7 +5,7 @@ export interface DashboardRowProps {
panel: PanelModel;
}
export class DashboardPanel extends React.Component<DashboardRowProps, any> {
export class DashboardRow extends React.Component<DashboardRowProps, any> {
constructor(props) {
super(props);

View File

@ -22,32 +22,33 @@
</ul>
<ul class="nav dashnav-action-icons">
<li ng-show="::ctrl.dashboard.meta.canShare" class="dropdown">
<a class="pointer" ng-click="ctrl.hideTooltip($event)" bs-tooltip="'Share dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-share-square-o"></i></a>
<ul class="dropdown-menu">
<li>
<a class="pointer" ng-click="ctrl.shareDashboard(0)">
<i class="fa fa-link"></i> Link to Dashboard
<div class="dropdown-desc">Share an internal link to the current dashboard. Some configuration options available.</div>
</a>
</li>
<li>
<a class="pointer" ng-click="ctrl.shareDashboard(1)">
<i class="icon-gf icon-gf-snapshot"></i>Snapshot
<div class="dropdown-desc">Interactive, publically accessible dashboard. Sensitive data is stripped out.</div>
</a>
</li>
<li>
<a class="pointer" ng-click="ctrl.shareDashboard(2)">
<i class="fa fa-cloud-upload"></i>Export
<div class="dropdown-desc">Export the dashboard to a JSON file for others and to share on Grafana.com</div>
</a>
</li>
</ul>
</li>
<li ng-show="::ctrl.dashboard.meta.canSave">
<a ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom"><i class="fa fa-save"></i></a>
</li>
<!-- <li ng&#45;show="::ctrl.dashboard.meta.canShare" class="dropdown"> -->
<!-- <a class="pointer" ng&#45;click="ctrl.hideTooltip($event)" bs&#45;tooltip="'Share dashboard'" data&#45;placement="bottom" data&#45;toggle="dropdown"><i class="fa fa&#45;share&#45;square&#45;o"></i></a> -->
<!-- <ul class="dropdown&#45;menu"> -->
<!-- <li> -->
<!-- <a class="pointer" ng&#45;click="ctrl.shareDashboard(0)"> -->
<!-- <i class="fa fa&#45;link"></i> Link to Dashboard -->
<!-- <div class="dropdown&#45;desc">Share an internal link to the current dashboard. Some configuration options available.</div> -->
<!-- </a> -->
<!-- </li> -->
<!-- <li> -->
<!-- <a class="pointer" ng&#45;click="ctrl.shareDashboard(1)"> -->
<!-- <i class="icon&#45;gf icon&#45;gf&#45;snapshot"></i>Snapshot -->
<!-- <div class="dropdown&#45;desc">Interactive, publically accessible dashboard. Sensitive data is stripped out.</div> -->
<!-- </a> -->
<!-- </li> -->
<!-- <li> -->
<!-- <a class="pointer" ng&#45;click="ctrl.shareDashboard(2)"> -->
<!-- <i class="fa fa&#45;cloud&#45;upload"></i>Export -->
<!-- <div class="dropdown&#45;desc">Export the dashboard to a JSON file for others and to share on Grafana.com</div> -->
<!-- </a> -->
<!-- </li> -->
<!-- </ul> -->
<!-- </li> -->
<!-- <li ng&#45;show="::ctrl.dashboard.meta.canSave"> -->
<!-- <a ng&#45;click="ctrl.saveDashboard()" bs&#45;tooltip="'Save dashboard <br> CTRL+S'" data&#45;placement="bottom"><i class="fa fa&#45;save"></i></a> -->
<!-- </li> -->
<li ng-if="::ctrl.dashboard.snapshot.originalUrl">
<a ng-href="{{ctrl.dashboard.snapshot.originalUrl}}" bs-tooltip="'Open original dashboard'" data-placement="bottom"><i class="fa fa-link"></i></a>
</li>

View File

@ -147,8 +147,8 @@ export class DashNavCtrl {
addPanel() {
this.dashboard.addPanel({
type: 'graph',
gridPos: {x: 0, y: 0, w: 12, h: 9},
type: 'add-panel',
gridPos: {x: 0, y: 0, w: 12, h: 9, static: true},
title: 'New Graph',
});
}

View File

@ -6,6 +6,7 @@ export interface GridPos {
y: number;
w: number;
h: number;
static?: boolean;
}
const notPersistedProperties: {[str: string]: boolean} = {

View File

@ -54,6 +54,7 @@
@import "components/panel_table";
@import "components/panel_text";
@import "components/panel_heatmap";
@import "components/panel_add_panel";
@import "components/settings_permissions";
@import "components/tagsinput";
@import "components/tables_lists";

View File

@ -0,0 +1,41 @@
.add-panel {
display: flex;
flex-direction: row;
flex-wrap: wrap;
overflow: hidden;
height: 100%;
align-content: flex-start;
justify-content: space-around;
padding: 3px 0;
}
.add-panel__item {
background: $card-background;
box-shadow: $card-shadow;
border: $panel-border;
padding: $spacer/3 $spacer;
width: 31%;
height: 60px;
text-align: center;
margin: $gf-form-margin;
cursor: pointer;
&.active,
&:hover {
background: $card-background-hover;
}
}
.add-panel__item-name {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: $font-size-sm;
}
.add-panel__item-img {
height: calc(100% - 15px);
}

View File

@ -101,127 +101,3 @@ $dashboard-row-height: 30px;
right: 0;
}
.panels-wrapper {
flex-grow: 1;
position: relative;
}
.dash-row-dropview {
position: relative;
background: $panel-bg;
border: $panel-border;
margin: 0 $panel-margin $panel-margin*2 $panel-margin;
padding: $panel-margin*2;
display: flex;
}
.dash-row-dropview-close {
position: absolute;
right: -12px;
top: -10px;
width: 20px;
height: 20px;
}
.add-panel-panels-scroll {
width: 100%;
overflow: auto;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none
}
}
.add-panel-panels {
display: flex;
flex-direction: row;
}
.add-panel-item {
background: $input-label-bg;
border: $panel-border;
padding: $spacer/3 $spacer;
min-width: 9rem;
max-width: 9rem;
text-align: center;
margin: $gf-form-margin;
cursor: pointer;
&.active,
&:hover {
box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 1px rgba(82,168,236,5.8)
}
}
.add-panel-item-name {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: $font-size-sm;
}
.add-panel-item-img {
width: 2rem;
}
$dash-row-menu-animation-speed: 0.20s;
.dash-row-menu-container {
position: absolute;
top: 0px;
width: 138px;
min-height: 100%;
transform: translate(-131px, 0);
transition: 0.1s ease-out 0.4s;
z-index: 0;
display: flex;
flex-direction: row;
&:hover {
transform: translate(-$panel-margin, 0);
transition: $dash-row-menu-animation-speed ease-in 0.05s;
z-index: 101;
.dash-row-menu-grip {
opacity: 0;
transition: $dash-row-menu-animation-speed ease-in 0.05s;
}
}
}
.dash-row-menu {
list-style: none;
flex-grow: 1;
box-shadow: $menu-dropdown-shadow;
background: $menu-dropdown-bg;
li a {
display: block;
white-space: nowrap;
color: $dropdownLinkColor;
font-size: $font-size-sm;
padding: $spacer/2 $spacer;
border-left: 2px solid $menu-dropdown-bg;
i {
display: inline-block;
padding-right: $spacer/2;
}
&:hover {
@include left-brand-border-gradient();
color: $link-color;
background: $input-label-bg;
}
}
}
.dash-row-menu-grip {
text-align: center;
font-size: 130%;
color: $text-color-weak;
opacity: 1;
transition: $dash-row-menu-animation-speed ease-out 0.5s;
width: 1rem;
}

View File

@ -169,7 +169,7 @@ li.sidemenu-org-switcher {
img {
width: 30px;
position: relative;
top: 3px;
top: 5px;
left: 4px;
}
}

View File

@ -14,6 +14,8 @@ div.flot-text {
}
.panel {
height: 100%;
&--solo {
.panel-container {
border: none;