From e3f45546d12794140d688b419ffe60ce102cf77c Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Mon, 27 Nov 2017 11:23:15 +0100 Subject: [PATCH 1/2] migrated viewstatesrv to ts --- public/app/features/dashboard/all.ts | 2 +- public/app/features/dashboard/viewStateSrv.js | 204 ---------------- .../app/features/dashboard/view_state_srv.ts | 217 ++++++++++++++++++ 3 files changed, 218 insertions(+), 205 deletions(-) delete mode 100644 public/app/features/dashboard/viewStateSrv.js create mode 100644 public/app/features/dashboard/view_state_srv.ts diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/all.ts index fd36b52b4d4..b4f1f4e77f0 100644 --- a/public/app/features/dashboard/all.ts +++ b/public/app/features/dashboard/all.ts @@ -9,7 +9,7 @@ import './save_modal'; import './shareModalCtrl'; import './shareSnapshotCtrl'; import './dashboard_srv'; -import './viewStateSrv'; +import './view_state_srv'; import './time_srv'; import './unsavedChangesSrv'; import './unsaved_changes_modal'; diff --git a/public/app/features/dashboard/viewStateSrv.js b/public/app/features/dashboard/viewStateSrv.js deleted file mode 100644 index f7da385ebc9..00000000000 --- a/public/app/features/dashboard/viewStateSrv.js +++ /dev/null @@ -1,204 +0,0 @@ -define([ - 'angular', - 'lodash', - 'jquery', - 'app/core/config' -], -function (angular, _, $, config) { - 'use strict'; - - config = config.default; - var module = angular.module('grafana.services'); - - module.factory('dashboardViewStateSrv', function($location, $timeout, $rootScope) { - - // represents the transient view state - // like fullscreen panel & edit - function DashboardViewState($scope) { - var self = this; - self.state = {}; - self.panelScopes = []; - self.$scope = $scope; - self.dashboard = $scope.dashboard; - - $scope.onAppEvent('$routeUpdate', function() { - var urlState = self.getQueryStringState(); - if (self.needsSync(urlState)) { - self.update(urlState, true); - } - }); - - $scope.onAppEvent('panel-change-view', function(evt, payload) { - self.update(payload); - }); - - $scope.onAppEvent('panel-initialized', function(evt, payload) { - self.registerPanel(payload.scope); - }); - - // this marks changes to location during this digest cycle as not to add history item - // dont want url changes like adding orgId to add browser history - $location.replace(); - this.update(this.getQueryStringState()); - } - - DashboardViewState.prototype.needsSync = function(urlState) { - return _.isEqual(this.state, urlState) === false; - }; - - DashboardViewState.prototype.getQueryStringState = function() { - var state = $location.search(); - state.panelId = parseInt(state.panelId) || null; - state.fullscreen = state.fullscreen ? true : null; - state.edit = (state.edit === "true" || state.edit === true) || null; - state.editview = state.editview || null; - state.orgId = config.bootData.user.orgId; - return state; - }; - - DashboardViewState.prototype.serializeToUrl = function() { - var urlState = _.clone(this.state); - urlState.fullscreen = this.state.fullscreen ? true : null; - urlState.edit = this.state.edit ? true : null; - return urlState; - }; - - DashboardViewState.prototype.update = function(state, fromRouteUpdated) { - // implement toggle logic - if (state.toggle) { - delete state.toggle; - if (this.state.fullscreen && state.fullscreen) { - if (this.state.edit === state.edit) { - state.fullscreen = !state.fullscreen; - } - } - } - - // remember if editStateChanged - this.editStateChanged = state.edit !== this.state.edit; - - _.extend(this.state, state); - this.dashboard.meta.fullscreen = this.state.fullscreen; - - if (!this.state.fullscreen) { - this.state.fullscreen = null; - this.state.edit = null; - // clear panel id unless in solo mode - if (!this.dashboard.meta.soloMode) { - this.state.panelId = null; - } - } - - // if no edit state cleanup tab parm - if (!this.state.edit) { - delete this.state.tab; - } - - // do not update url params if we are here - // from routeUpdated event - if (fromRouteUpdated !== true) { - $location.search(this.serializeToUrl()); - } - - this.syncState(); - }; - - DashboardViewState.prototype.syncState = function() { - if (this.panelScopes.length === 0) { return; } - - if (this.dashboard.meta.fullscreen) { - var panelScope = this.getPanelScope(this.state.panelId); - if (!panelScope) { - return; - } - - if (this.fullscreenPanel) { - // if already fullscreen - if (this.fullscreenPanel === panelScope && this.editStateChanged === false) { - return; - } else { - this.leaveFullscreen(false); - } - } - - if (!panelScope.ctrl.editModeInitiated) { - panelScope.ctrl.initEditMode(); - } - - if (!panelScope.ctrl.fullscreen) { - this.enterFullscreen(panelScope); - } - } else if (this.fullscreenPanel) { - this.leaveFullscreen(true); - } - }; - - DashboardViewState.prototype.getPanelScope = function(id) { - return _.find(this.panelScopes, function(panelScope) { - return panelScope.ctrl.panel.id === id; - }); - }; - - DashboardViewState.prototype.leaveFullscreen = function(render) { - var self = this; - var ctrl = self.fullscreenPanel.ctrl; - - ctrl.editMode = false; - ctrl.fullscreen = false; - - this.dashboard.setViewMode(ctrl.panel, false, false); - this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id}); - - if (!render) { return false;} - - $timeout(function() { - if (self.oldTimeRange !== ctrl.range) { - $rootScope.$broadcast('refresh'); - } else { - $rootScope.$broadcast('render'); - } - delete self.fullscreenPanel; - }); - }; - - DashboardViewState.prototype.enterFullscreen = function(panelScope) { - var ctrl = panelScope.ctrl; - - ctrl.editMode = this.state.edit && this.dashboard.meta.canEdit; - ctrl.fullscreen = true; - - this.oldTimeRange = ctrl.range; - this.fullscreenPanel = panelScope; - - this.dashboard.setViewMode(ctrl.panel, true, ctrl.editMode); - this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id}); - }; - - DashboardViewState.prototype.registerPanel = function(panelScope) { - var self = this; - self.panelScopes.push(panelScope); - - if (!self.dashboard.meta.soloMode) { - if (self.state.panelId === panelScope.ctrl.panel.id) { - if (self.state.edit) { - panelScope.ctrl.editPanel(); - } else { - panelScope.ctrl.viewPanel(); - } - } - } - - var unbind = panelScope.$on('$destroy', function() { - self.panelScopes = _.without(self.panelScopes, panelScope); - unbind(); - }); - }; - - return { - create: function($scope) { - return new DashboardViewState($scope); - } - }; - - }); -}); diff --git a/public/app/features/dashboard/view_state_srv.ts b/public/app/features/dashboard/view_state_srv.ts new file mode 100644 index 00000000000..dec507d2002 --- /dev/null +++ b/public/app/features/dashboard/view_state_srv.ts @@ -0,0 +1,217 @@ +import angular from "angular"; +import _ from "lodash"; +import config from "app/core/config"; + +// represents the transient view state +// like fullscreen panel & edit +export class DashboardViewState { + state: any; + panelScopes: any; + $scope: any; + dashboard: any; + editStateChanged: any; + fullscreenPanel: any; + oldTimeRange: any; + + /** @ngInject */ + constructor($scope, private $location, private $timeout, private $rootScope) { + var self = this; + self.state = {}; + self.panelScopes = []; + self.$scope = $scope; + self.dashboard = $scope.dashboard; + + $scope.onAppEvent("$routeUpdate", function() { + var urlState = self.getQueryStringState(); + if (self.needsSync(urlState)) { + self.update(urlState, true); + } + }); + + $scope.onAppEvent("panel-change-view", function(evt, payload) { + self.update(payload); + }); + + $scope.onAppEvent("panel-initialized", function(evt, payload) { + self.registerPanel(payload.scope); + }); + + // this marks changes to location during this digest cycle as not to add history item + // dont want url changes like adding orgId to add browser history + $location.replace(); + this.update(this.getQueryStringState()); + } + + needsSync(urlState) { + return _.isEqual(this.state, urlState) === false; + } + + getQueryStringState() { + var state = this.$location.search(); + state.panelId = parseInt(state.panelId) || null; + state.fullscreen = state.fullscreen ? true : null; + state.edit = state.edit === "true" || state.edit === true || null; + state.editview = state.editview || null; + state.orgId = config.bootData.user.orgId; + return state; + } + + serializeToUrl() { + var urlState = _.clone(this.state); + urlState.fullscreen = this.state.fullscreen ? true : null; + urlState.edit = this.state.edit ? true : null; + return urlState; + } + + update(state, fromRouteUpdated?) { + // implement toggle logic + if (state.toggle) { + delete state.toggle; + if (this.state.fullscreen && state.fullscreen) { + if (this.state.edit === state.edit) { + state.fullscreen = !state.fullscreen; + } + } + } + + // remember if editStateChanged + this.editStateChanged = state.edit !== this.state.edit; + + _.extend(this.state, state); + this.dashboard.meta.fullscreen = this.state.fullscreen; + + if (!this.state.fullscreen) { + this.state.fullscreen = null; + this.state.edit = null; + // clear panel id unless in solo mode + if (!this.dashboard.meta.soloMode) { + this.state.panelId = null; + } + } + + // if no edit state cleanup tab parm + if (!this.state.edit) { + delete this.state.tab; + } + + // do not update url params if we are here + // from routeUpdated event + if (fromRouteUpdated !== true) { + this.$location.search(this.serializeToUrl()); + } + + this.syncState(); + } + + syncState() { + if (this.panelScopes.length === 0) { + return; + } + + if (this.dashboard.meta.fullscreen) { + var panelScope = this.getPanelScope(this.state.panelId); + if (!panelScope) { + return; + } + + if (this.fullscreenPanel) { + // if already fullscreen + if ( + this.fullscreenPanel === panelScope && + this.editStateChanged === false + ) { + return; + } else { + this.leaveFullscreen(false); + } + } + + if (!panelScope.ctrl.editModeInitiated) { + panelScope.ctrl.initEditMode(); + } + + if (!panelScope.ctrl.fullscreen) { + this.enterFullscreen(panelScope); + } + } else if (this.fullscreenPanel) { + this.leaveFullscreen(true); + } + } + + getPanelScope(id) { + return _.find(this.panelScopes, function(panelScope) { + return panelScope.ctrl.panel.id === id; + }); + } + + leaveFullscreen(render) { + var self = this; + var ctrl = self.fullscreenPanel.ctrl; + + ctrl.editMode = false; + ctrl.fullscreen = false; + + this.dashboard.setViewMode(ctrl.panel, false, false); + this.$scope.appEvent("panel-fullscreen-exit", { panelId: ctrl.panel.id }); + + if (!render) { + return false; + } + + this.$timeout(function() { + if (self.oldTimeRange !== ctrl.range) { + self.$rootScope.$broadcast("refresh"); + } else { + self.$rootScope.$broadcast("render"); + } + delete self.fullscreenPanel; + }); + return true; + } + + enterFullscreen(panelScope) { + var ctrl = panelScope.ctrl; + + ctrl.editMode = this.state.edit && this.dashboard.meta.canEdit; + ctrl.fullscreen = true; + + this.oldTimeRange = ctrl.range; + this.fullscreenPanel = panelScope; + + this.dashboard.setViewMode(ctrl.panel, true, ctrl.editMode); + this.$scope.appEvent("panel-fullscreen-enter", { panelId: ctrl.panel.id }); + } + + registerPanel(panelScope) { + var self = this; + self.panelScopes.push(panelScope); + + if (!self.dashboard.meta.soloMode) { + if (self.state.panelId === panelScope.ctrl.panel.id) { + if (self.state.edit) { + panelScope.ctrl.editPanel(); + } else { + panelScope.ctrl.viewPanel(); + } + } + } + + var unbind = panelScope.$on("$destroy", function() { + self.panelScopes = _.without(self.panelScopes, panelScope); + unbind(); + }); + } +} + +/** @ngInject */ +export function dashboardViewStateSrv($location, $timeout, $rootScope) { + return { + create: function($scope) { + return new DashboardViewState($scope, $location, $timeout, $rootScope); + } + }; +} + +angular + .module("grafana.services") + .factory("dashboardViewStateSrv", dashboardViewStateSrv); From be74957a60316518f53a7fa1d1083aea7ebe0ff5 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Mon, 27 Nov 2017 12:29:20 +0100 Subject: [PATCH 2/2] fixed link i specs-file --- public/app/features/dashboard/specs/viewstate_srv_specs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/dashboard/specs/viewstate_srv_specs.ts b/public/app/features/dashboard/specs/viewstate_srv_specs.ts index 6112f1bd41f..2422406f1ae 100644 --- a/public/app/features/dashboard/specs/viewstate_srv_specs.ts +++ b/public/app/features/dashboard/specs/viewstate_srv_specs.ts @@ -1,5 +1,5 @@ import {describe, beforeEach, it, expect, angularMocks} from 'test/lib/common'; -import 'app/features/dashboard/viewStateSrv'; +import 'app/features/dashboard/view_state_srv'; import config from 'app/core/config'; describe('when updating view state', function() {