From 8574dca081002f36e482b572517d8f05fd44453f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 6 Feb 2019 17:31:52 +0100 Subject: [PATCH] making changes suggested in review and improving typings --- .../dashboard/services/DashboardSrv.ts | 30 +++++++------- .../dashboard/state/DashboardModel.ts | 6 +-- .../app/features/dashboard/state/actions.ts | 7 +--- .../features/dashboard/state/initDashboard.ts | 37 ++++++++++------- public/app/routes/GrafanaCtrl.ts | 11 +++-- public/app/types/dashboard.ts | 41 +++++++++++++++++-- public/app/types/store.ts | 10 +++++ 7 files changed, 97 insertions(+), 45 deletions(-) diff --git a/public/app/features/dashboard/services/DashboardSrv.ts b/public/app/features/dashboard/services/DashboardSrv.ts index 88eb58ad345..4030765a5a3 100644 --- a/public/app/features/dashboard/services/DashboardSrv.ts +++ b/public/app/features/dashboard/services/DashboardSrv.ts @@ -5,7 +5,7 @@ import { DashboardModel } from '../state/DashboardModel'; import { removePanel } from '../utils/panel'; export class DashboardSrv { - dash: DashboardModel; + dashboard: DashboardModel; /** @ngInject */ constructor(private backendSrv, private $rootScope, private $location) { @@ -19,11 +19,11 @@ export class DashboardSrv { } setCurrent(dashboard: DashboardModel) { - this.dash = dashboard; + this.dashboard = dashboard; } getCurrent(): DashboardModel { - return this.dash; + return this.dashboard; } onRemovePanel = (panelId: number) => { @@ -124,10 +124,10 @@ export class DashboardSrv { } postSave(clone, data) { - this.dash.version = data.version; + this.dashboard.version = data.version; // important that these happens before location redirect below - this.$rootScope.appEvent('dashboard-saved', this.dash); + this.$rootScope.appEvent('dashboard-saved', this.dashboard); this.$rootScope.appEvent('alert-success', ['Dashboard saved']); const newUrl = locationUtil.stripBaseFromUrl(data.url); @@ -137,12 +137,12 @@ export class DashboardSrv { this.$location.url(newUrl).replace(); } - return this.dash; + return this.dashboard; } save(clone, options) { options = options || {}; - options.folderId = options.folderId >= 0 ? options.folderId : this.dash.meta.folderId || clone.folderId; + options.folderId = options.folderId >= 0 ? options.folderId : this.dashboard.meta.folderId || clone.folderId; return this.backendSrv .saveDashboard(clone, options) @@ -152,26 +152,26 @@ export class DashboardSrv { saveDashboard(options?, clone?) { if (clone) { - this.setCurrent(this.create(clone, this.dash.meta)); + this.setCurrent(this.create(clone, this.dashboard.meta)); } - if (this.dash.meta.provisioned) { + if (this.dashboard.meta.provisioned) { return this.showDashboardProvisionedModal(); } - if (!this.dash.meta.canSave && options.makeEditable !== true) { + if (!this.dashboard.meta.canSave && options.makeEditable !== true) { return Promise.resolve(); } - if (this.dash.title === 'New dashboard') { + if (this.dashboard.title === 'New dashboard') { return this.showSaveAsModal(); } - if (this.dash.version > 0) { + if (this.dashboard.version > 0) { return this.showSaveModal(); } - return this.save(this.dash.getSaveModelClone(), options); + return this.save(this.dashboard.getSaveModelClone(), options); } saveJSONDashboard(json: string) { @@ -212,8 +212,8 @@ export class DashboardSrv { } return promise.then(res => { - if (this.dash && this.dash.id === dashboardId) { - this.dash.meta.isStarred = res; + if (this.dashboard && this.dashboard.id === dashboardId) { + this.dashboard.meta.isStarred = res; } return res; }); diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index 743eb61f97d..aec6421d12a 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -15,7 +15,7 @@ import sortByKeys from 'app/core/utils/sort_by_keys'; import { PanelModel } from './PanelModel'; import { DashboardMigrator } from './DashboardMigrator'; import { TimeRange } from '@grafana/ui/src'; -import { UrlQueryValue } from 'app/types'; +import { UrlQueryValue, KIOSK_MODE_TV, DashboardMeta } from 'app/types'; export class DashboardModel { id: any; @@ -49,7 +49,7 @@ export class DashboardModel { // repeat process cycles iteration: number; - meta: any; + meta: DashboardMeta; events: Emitter; static nonPersistedProperties: { [str: string]: boolean } = { @@ -887,7 +887,7 @@ export class DashboardModel { } // add back navbar height - if (kioskMode === 'tv') { + if (kioskMode === KIOSK_MODE_TV) { visibleHeight += 55; } diff --git a/public/app/features/dashboard/state/actions.ts b/public/app/features/dashboard/state/actions.ts index c25388bbcb8..50ff004ad48 100644 --- a/public/app/features/dashboard/state/actions.ts +++ b/public/app/features/dashboard/state/actions.ts @@ -1,6 +1,3 @@ -// Libaries -import { ThunkAction } from 'redux-thunk'; - // Services & Utils import { getBackendSrv } from 'app/core/services/backend_srv'; import { actionCreatorFactory, noPayloadActionCreatorFactory } from 'app/core/redux'; @@ -11,7 +8,7 @@ import { loadPluginDashboards } from '../../plugins/state/actions'; import { notifyApp } from 'app/core/actions'; // Types -import { StoreState } from 'app/types'; +import { ThunkResult } from 'app/types'; import { DashboardAcl, DashboardAclDTO, @@ -26,8 +23,6 @@ export const setDashboardLoadingState = actionCreatorFactory('SET_DASHBOARD_MODEL').create(); export const setDashboardLoadingSlow = noPayloadActionCreatorFactory('SET_DASHBOARD_LOADING_SLOW').create(); -export type ThunkResult = ThunkAction; - export function getDashboardPermissions(id: number): ThunkResult { return async dispatch => { const permissions = await getBackendSrv().get(`/api/dashboards/id/${id}/permissions`); diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 2c68435b313..941ac332f3c 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -1,10 +1,8 @@ -// Libraries -import { ThunkDispatch } from 'redux-thunk'; - // Services & Utils import { createErrorNotification } from 'app/core/copy/appNotification'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { DashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { DashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { AnnotationsSrv } from 'app/features/annotations/annotations_srv'; import { VariableSrv } from 'app/features/templating/variable_srv'; @@ -14,14 +12,19 @@ import { KeybindingSrv } from 'app/core/services/keybindingSrv'; import { updateLocation } from 'app/core/actions'; import { notifyApp } from 'app/core/actions'; import locationUtil from 'app/core/utils/location_util'; -import { setDashboardLoadingState, ThunkResult, setDashboardModel, setDashboardLoadingSlow } from './actions'; +import { setDashboardLoadingState, setDashboardModel, setDashboardLoadingSlow } from './actions'; // Types -import { DashboardLoadingState, DashboardRouteInfo, StoreState } from 'app/types'; +import { + DashboardLoadingState, + DashboardRouteInfo, + StoreState, + ThunkDispatch, + ThunkResult, + DashboardDTO, +} from 'app/types'; import { DashboardModel } from './DashboardModel'; -export type Dispatch = ThunkDispatch; - export interface InitDashboardArgs { $injector: any; $scope: any; @@ -33,7 +36,7 @@ export interface InitDashboardArgs { fixUrl: boolean; } -async function redirectToNewUrl(slug: string, dispatch: Dispatch, currentPath: string) { +async function redirectToNewUrl(slug: string, dispatch: ThunkDispatch, currentPath: string) { const res = await getBackendSrv().getDashboardBySlug(slug); if (res) { @@ -49,18 +52,22 @@ async function redirectToNewUrl(slug: string, dispatch: Dispatch, currentPath: s } } -async function fetchDashboard(args: InitDashboardArgs, dispatch: Dispatch, getState: () => StoreState): Promise { +async function fetchDashboard( + args: InitDashboardArgs, + dispatch: ThunkDispatch, + getState: () => StoreState +): Promise { try { switch (args.routeInfo) { case DashboardRouteInfo.Home: { // load home dash - const dashDTO = await getBackendSrv().get('/api/dashboards/home'); + const dashDTO: DashboardDTO = await getBackendSrv().get('/api/dashboards/home'); // if user specified a custom home dashboard redirect to that if (dashDTO.redirectUri) { const newUrl = locationUtil.stripBaseFromUrl(dashDTO.redirectUri); dispatch(updateLocation({ path: newUrl, replace: true })); - return; + return null; } // disable some actions on the default home dashboard @@ -76,8 +83,8 @@ async function fetchDashboard(args: InitDashboardArgs, dispatch: Dispatch, getSt return null; } - const loaderSrv = args.$injector.get('dashboardLoaderSrv'); - const dashDTO = await loaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid); + const loaderSrv: DashboardLoaderSrv = args.$injector.get('dashboardLoaderSrv'); + const dashDTO: DashboardDTO = await loaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid); if (args.fixUrl && dashDTO.meta.url) { // check if the current url is correct (might be old slug) @@ -95,6 +102,8 @@ async function fetchDashboard(args: InitDashboardArgs, dispatch: Dispatch, getSt case DashboardRouteInfo.New: { return getNewDashboardModelData(args.urlFolderId); } + default: + throw { message: 'Unknown route ' + args.routeInfo }; } } catch (err) { dispatch(setDashboardLoadingState(DashboardLoadingState.Error)); @@ -149,7 +158,7 @@ export function initDashboard(args: InitDashboardArgs): ThunkResult { } // add missing orgId query param - const storeState = getState() ; + const storeState = getState(); if (!storeState.location.query.orgId) { dispatch(updateLocation({ query: { orgId: storeState.user.orgId }, partial: true, replace: true })); } diff --git a/public/app/routes/GrafanaCtrl.ts b/public/app/routes/GrafanaCtrl.ts index c2d5dd4d69d..a6d97856e74 100644 --- a/public/app/routes/GrafanaCtrl.ts +++ b/public/app/routes/GrafanaCtrl.ts @@ -1,9 +1,11 @@ -import config from 'app/core/config'; +// Libraries import _ from 'lodash'; import $ from 'jquery'; import Drop from 'tether-drop'; -import { colors } from '@grafana/ui'; +// Utils and servies +import { colors } from '@grafana/ui'; +import config from 'app/core/config'; import coreModule from 'app/core/core_module'; import { profiler } from 'app/core/profiler'; import appEvents from 'app/core/app_events'; @@ -13,6 +15,9 @@ import { DatasourceSrv, setDatasourceSrv } from 'app/features/plugins/datasource import { AngularLoader, setAngularLoader } from 'app/core/services/AngularLoader'; import { configureStore } from 'app/store/configureStore'; +// Types +import { KioskUrlValue } from 'app/types'; + export class GrafanaCtrl { /** @ngInject */ constructor( @@ -67,7 +72,7 @@ export class GrafanaCtrl { } } -function setViewModeBodyClass(body, mode, sidemenuOpen: boolean) { +function setViewModeBodyClass(body, mode: KioskUrlValue, sidemenuOpen: boolean) { body.removeClass('view-mode--tv'); body.removeClass('view-mode--kiosk'); body.removeClass('view-mode--inactive'); diff --git a/public/app/types/dashboard.ts b/public/app/types/dashboard.ts index 39d7e3cba8a..fac8761fa7a 100644 --- a/public/app/types/dashboard.ts +++ b/public/app/types/dashboard.ts @@ -1,10 +1,40 @@ import { DashboardAcl } from './acl'; export interface MutableDashboard { - meta: { - fullscreen: boolean; - isEditing: boolean; - }; + meta: DashboardMeta; +} + +export interface DashboardDTO { + redirectUri?: string; + dashboard: DashboardDataDTO; + meta: DashboardMeta; +} + +export interface DashboardMeta { + canSave?: boolean; + canEdit?: boolean; + canShare?: boolean; + canStar?: boolean; + canAdmin?: boolean; + url?: string; + folderId?: number; + fullscreen?: boolean; + isEditing?: boolean; + canMakeEditable?: boolean; + submenuEnabled?: boolean; + provisioned?: boolean; + focusPanelId?: boolean; + isStarred?: boolean; + showSettings?: boolean; + expires: string; + isSnapshot?: boolean; + folderTitle?: string; + folderUrl?: string; + created?: string; +} + +export interface DashboardDataDTO { + title: string; } export enum DashboardRouteInfo { @@ -22,6 +52,9 @@ export enum DashboardLoadingState { Done = 'Done', } +export const KIOSK_MODE_TV = 'tv'; +export type KioskUrlValue = 'tv' | '1' | true; + export interface DashboardState { model: MutableDashboard | null; loadingState: DashboardLoadingState; diff --git a/public/app/types/store.ts b/public/app/types/store.ts index 78832052e96..72a8cf066f1 100644 --- a/public/app/types/store.ts +++ b/public/app/types/store.ts @@ -1,3 +1,6 @@ +import { ThunkAction, ThunkDispatch as GenericThunkDispatch } from 'redux-thunk'; +import { ActionOf } from 'app/core/redux'; + import { NavIndex } from './navModel'; import { LocationState } from './location'; import { AlertRulesState } from './alerting'; @@ -27,3 +30,10 @@ export interface StoreState { user: UserState; plugins: PluginsState; } + +/* + * Utility type to get strongly types thunks + */ +export type ThunkResult = ThunkAction>; + +export type ThunkDispatch = GenericThunkDispatch;