Commit 2e77bd0c by Torkel Ödegaard

grid: progress on react grid

parent 10a35043
......@@ -123,7 +123,7 @@ function ($, angular, coreModule, _) {
}, 10);
}
scope.$watch("dashboardViewState.state.editview", function(newValue, oldValue) {
scope.$watch("ctrl.dashboardViewState.state.editview", function(newValue, oldValue) {
if (newValue) {
showEditorPane(null, {editview: newValue});
} else if (oldValue) {
......
......@@ -8,7 +8,6 @@ export interface GridPos {
}
const notPersistedProperties: {[str: string]: boolean} = {
"model": true,
"events": true,
};
......@@ -19,26 +18,26 @@ export class PanelModel {
title: string;
events: Emitter;
constructor(private model) {
constructor(model) {
this.events = new Emitter();
// copy properties from persisted model
for (var property in model) {
this[property] = model[property];
}
this.events = new Emitter();
}
getSaveModel() {
this.model = {};
const model: any = {};
for (var property in this) {
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
console.log('PanelModel.getSaveModel() skiping property', property);
continue;
}
this.model[property] = this[property];
model[property] = this[property];
}
return this.model;
return model;
}
updateGridPos(newPos: GridPos) {
......
......@@ -25,6 +25,7 @@ define([
'./repeat_option/repeat_option',
'./dashgrid/DashboardGrid',
'./dashgrid/PanelLoader',
'./row/add_panel',
'./acl/acl',
'./folder_picker/picker',
'./folder_modal/folder'
......
......@@ -3,12 +3,12 @@ import config from 'app/core/config';
import coreModule from 'app/core/core_module';
import {PanelContainer} from './dashgrid/PanelContainer';
import {DashboardModel} from './model';
import {PanelModel} from './PanelModel';
export class DashboardCtrl implements PanelContainer {
dashboard: DashboardModel;
dashboardViewState: any;
loadedFallbackDashboard: boolean;
editTab: number;
/** @ngInject */
constructor(
......@@ -27,6 +27,9 @@ export class DashboardCtrl implements PanelContainer {
// can't use controllerAs on route yet
$scope.ctrl = this;
// TODO: break out settings view to separate view & controller
this.editTab = 0;
// funcs called from React component bindings and needs this binding
this.getPanelContainer = this.getPanelContainer.bind(this);
}
......@@ -116,15 +119,6 @@ export class DashboardCtrl implements PanelContainer {
return this.panelLoader;
}
getPanels() {
return this.dashboard.panels;
}
panelPossitionUpdated(panel: PanelModel) {
//console.log('panel pos updated', panel);
//this.$rootScope.$broadcast('render');
}
timezoneChanged() {
this.$rootScope.$broadcast("refresh");
}
......
......@@ -3,13 +3,14 @@ import coreModule from 'app/core/core_module';
import ReactGridLayout from 'react-grid-layout';
import {CELL_HEIGHT, CELL_VMARGIN} from '../model';
import {DashboardPanel} from './DashboardPanel';
import {DashboardModel} from '../model';
import {PanelContainer} from './PanelContainer';
import {PanelModel} from '../PanelModel';
import sizeMe from 'react-sizeme';
const COLUMN_COUNT = 12;
function GridWrapper({size, layout, onLayoutChange, children}) {
function GridWrapper({size, layout, onLayoutChange, children, onResize}) {
if (size.width === 0) {
console.log('size is zero!');
}
......@@ -30,6 +31,7 @@ function GridWrapper({size, layout, onLayoutChange, children}) {
rowHeight={CELL_HEIGHT}
draggableHandle=".grid-drag-handle"
layout={layout}
onResize={onResize}
onLayoutChange={onLayoutChange}>
{children}
</ReactGridLayout>
......@@ -45,20 +47,25 @@ export interface DashboardGridProps {
export class DashboardGrid extends React.Component<DashboardGridProps, any> {
gridToPanelMap: any;
panelContainer: PanelContainer;
dashboard: DashboardModel;
panelMap: {[id: string]: PanelModel};
constructor(props) {
super(props);
this.panelContainer = this.props.getPanelContainer();
this.onLayoutChange = this.onLayoutChange.bind(this);
this.onResize = this.onResize.bind(this);
// subscribe to dashboard events
this.dashboard = this.panelContainer.getDashboard();
this.dashboard.on('panel-added', this.panelAdded.bind(this));
}
buildLayout() {
const layout = [];
const panels = this.panelContainer.getPanels();
this.panelMap = {};
for (let panel of panels) {
for (let panel of this.dashboard.panels) {
let stringId = panel.id.toString();
this.panelMap[stringId] = panel;
......@@ -85,11 +92,18 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
}
}
panelAdded() {
this.forceUpdate();
}
onResize(layout, oldItem, newItem) {
this.panelMap[newItem.i].updateGridPos(newItem);
}
renderPanels() {
const panels = this.panelContainer.getPanels();
const panelElements = [];
for (let panel of panels) {
for (let panel of this.dashboard.panels) {
panelElements.push(
<div key={panel.id.toString()} className="panel">
<DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} />
......@@ -101,8 +115,9 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
}
render() {
console.log('DashboardGrid.render()');
return (
<SizedReactLayoutGrid layout={this.buildLayout()} onLayoutChange={this.onLayoutChange}>
<SizedReactLayoutGrid layout={this.buildLayout()} onLayoutChange={this.onLayoutChange} onResize={this.onResize}>
{this.renderPanels()}
</SizedReactLayoutGrid>
);
......
import {PanelModel} from '../PanelModel';
import {DashboardModel}  from '../model';
import {PanelLoader} from './PanelLoader';
export interface PanelContainer {
getPanels(): PanelModel[];
getPanelLoader(): PanelLoader;
getDashboard(): DashboardModel;
panelPossitionUpdated(panel: PanelModel);
}
......@@ -70,7 +70,7 @@
</ul>
</li>
<li class="navbar-mini-btn-wrapper" ng-show="::ctrl.dashboard.meta.canSave">
<button class="btn btn-secondary btn-mini" ng-click="ctrl.openEditView('add-panel')">
<button class="btn btn-secondary btn-mini" ng-click="ctrl.addPanel()">
<i class="fa fa-plus-circle"></i> Add Panel
</button>
</li>
......
......@@ -145,6 +145,14 @@ export class DashNavCtrl {
this.$rootScope.appEvent('show-dash-search');
}
addPanel() {
this.dashboard.addPanel({
type: 'graph',
gridPos: {x: 0, y: 0, w: 6, h: 5},
title: 'New Graph',
});
}
navItemClicked(navItem, evt) {
if (navItem.clickHandler) {
navItem.clickHandler();
......
......@@ -180,7 +180,8 @@ export class DashboardModel {
addPanel(panel) {
panel.id = this.getNextPanelId();
this.panels.push(panel);
this.panels.unshift(new PanelModel(panel));
this.events.emit('panel-added', panel);
}
removePanel(panel, ask?) {
......@@ -282,6 +283,14 @@ export class DashboardModel {
}
}
on(eventName, callback) {
this.events.on(eventName, callback);
}
off(eventName, callback?) {
this.events.off(eventName, callback);
}
cycleGraphTooltip() {
this.graphTooltip = (this.graphTooltip + 1) % 3;
}
......
......@@ -5,7 +5,7 @@
<ul class="gf-tabs">
<li class="gf-tabs-item" ng-repeat="tab in ::['General', 'Links', 'Time picker']">
<a class="gf-tabs-link" ng-click="editor.index = $index" ng-class="{active: editor.index === $index}">
<a class="gf-tabs-link" ng-click="ctrl.editTab = $index" ng-class="{active: ctrl.editTab === $index}">
{{::tab}}
</a>
</li>
......@@ -17,30 +17,30 @@
</div>
<div class="tabbed-view-body">
<div ng-if="editor.index == 0">
<div ng-if="ctrl.editTab == 0">
<div class="gf-form-group section">
<h5 class="section-heading">Details</h5>
<div class="gf-form">
<label class="gf-form-label width-7">Name</label>
<input type="text" class="gf-form-input width-30" ng-model='dashboard.title'></input>
<input type="text" class="gf-form-input width-30" ng-model='ctrl.dashboard.title'></input>
</div>
<div class="gf-form">
<label class="gf-form-label width-7">Description</label>
<input type="text" class="gf-form-input width-30" ng-model='dashboard.description'></input>
<input type="text" class="gf-form-input width-30" ng-model='ctrl.dashboard.description'></input>
</div>
<div class="gf-form">
<label class="gf-form-label width-7">
Tags
<info-popover mode="right-normal">Press enter to add a tag</info-popover>
</label>
<bootstrap-tagsinput ng-model="dashboard.tags" tagclass="label label-tag" placeholder="add tags">
<bootstrap-tagsinput ng-model="ctrl.dashboard.tags" tagclass="label label-tag" placeholder="add tags">
</bootstrap-tagsinput>
</div>
<folder-picker ng-if="!dashboardMeta.isFolder"
initial-title="dashboardMeta.folderTitle"
on-change="onFolderChange($folder)"
<folder-picker ng-if="!ctrl.dashboard.meta.isFolder"
initial-title="ctrl.dashboard.meta.folderTitle"
on-change="ctrl.onFolderChange($folder)"
label-class="width-7">
</folder-picker>
</div>
......@@ -51,19 +51,19 @@
<div class="gf-form">
<label class="gf-form-label width-11">Timezone</label>
<div class="gf-form-select-wrapper">
<select ng-model="dashboard.timezone" class='gf-form-input' ng-options="f.value as f.text for f in [{value: '', text: 'Default'}, {value: 'browser', text: 'Local browser time'},{value: 'utc', text: 'UTC'}]" ng-change="timezoneChanged()"></select>
<select ng-model="ctrl.dashboard.timezone" class='gf-form-input' ng-options="f.value as f.text for f in [{value: '', text: 'Default'}, {value: 'browser', text: 'Local browser time'},{value: 'utc', text: 'UTC'}]" ng-change="timezoneChanged()"></select>
</div>
</div>
<gf-form-switch class="gf-form"
label="Editable"
tooltip="Uncheck, then save and reload to disable all dashboard editing"
checked="dashboard.editable"
checked="ctrl.dashboard.editable"
label-class="width-11">
</gf-form-switch>
<gf-form-switch class="gf-form"
label="Hide Controls"
tooltip="Hide row controls. Shortcut: CTRL+H or CMD+H"
checked="dashboard.hideControls"
checked="ctrl.dashboard.hideControls"
label-class="width-11">
</gf-form-switch>
</div>
......@@ -79,7 +79,7 @@
</info-popover>
</label>
<div class="gf-form-select-wrapper">
<select ng-model="dashboard.graphTooltip" class='gf-form-input' ng-options="f.value as f.text for f in [{value: 0, text: 'Default'}, {value: 1, text: 'Shared crosshair'},{value: 2, text: 'Shared Tooltip'}]"></select>
<select ng-model="ctrl.dashboard.graphTooltip" class='gf-form-input' ng-options="f.value as f.text for f in [{value: 0, text: 'Default'}, {value: 1, text: 'Shared crosshair'},{value: 2, text: 'Shared Tooltip'}]"></select>
</div>
</div>
</div>
......@@ -90,7 +90,7 @@
</div>
<div ng-if="editor.index == 2">
<gf-time-picker-settings dashboard="dashboard"></gf-time-picker-settings>
<gf-time-picker-settings dashboard="ctrl.dashboard"></gf-time-picker-settings>
</div>
</div>
......@@ -178,7 +178,7 @@ export class PanelCtrl {
this.calculatePanelHeight();
this.$timeout(() => {
this.render();
});
}, 100);
}
duplicate() {
......
......@@ -105,9 +105,9 @@ $tight-form-bg: $dark-3;
$tight-form-func-bg: #333;
$tight-form-func-highlight-bg: #444;
$modal-background: $black;
$code-tag-bg: $gray-1;
$code-tag-border: lighten($code-tag-bg, 2%);
$modal-backdrop-bg: $dark-3;
$code-tag-bg: $gray-1;
$code-tag-border: lighten($code-tag-bg, 2%);
// Lists
......
......@@ -112,9 +112,9 @@ $tight-form-bg: $gray-6;
$tight-form-func-bg: $gray-5;
$tight-form-func-highlight-bg: $gray-6;
$modal-background: $body-bg;
$code-tag-bg: $gray-6;
$code-tag-border: darken($code-tag-bg, 3%);
$modal-backdrop-bg: $body-bg;
$code-tag-bg: $gray-6;
$code-tag-border: darken($code-tag-bg, 3%);
// Lists
$grafanaListBackground: $gray-6;
......
......@@ -10,7 +10,7 @@
bottom: 0;
left: 0;
z-index: $zindex-modal-backdrop;
background-color: $black;
background-color: $modal-backdrop-bg;
}
.modal-backdrop,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment