mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ux: worked on add panel function
This commit is contained in:
parent
48b6692491
commit
772ab7812f
72
public/app/features/dashboard/dashgrid/AddPanelPanel.tsx
Normal file
72
public/app/features/dashboard/dashgrid/AddPanelPanel.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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} />
|
||||
);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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-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-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>
|
||||
|
@ -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',
|
||||
});
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export interface GridPos {
|
||||
y: number;
|
||||
w: number;
|
||||
h: number;
|
||||
static?: boolean;
|
||||
}
|
||||
|
||||
const notPersistedProperties: {[str: string]: boolean} = {
|
||||
|
@ -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";
|
||||
|
41
public/sass/components/_panel_add_panel.scss
Normal file
41
public/sass/components/_panel_add_panel.scss
Normal 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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ li.sidemenu-org-switcher {
|
||||
img {
|
||||
width: 30px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
top: 5px;
|
||||
left: 4px;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ div.flot-text {
|
||||
}
|
||||
|
||||
.panel {
|
||||
height: 100%;
|
||||
|
||||
&--solo {
|
||||
.panel-container {
|
||||
border: none;
|
||||
|
Loading…
Reference in New Issue
Block a user