Commit ae768193 by Torkel Ödegaard

Now handles all dashbord routes

parent 21746807
......@@ -8,12 +8,13 @@ export const initialState: LocationState = {
path: '',
query: {},
routeParams: {},
replace: false,
};
export const locationReducer = (state = initialState, action: Action): LocationState => {
switch (action.type) {
case CoreActionTypes.UpdateLocation: {
const { path, routeParams } = action.payload;
const { path, routeParams, replace } = action.payload;
let query = action.payload.query || state.query;
if (action.payload.partial) {
......@@ -26,6 +27,7 @@ export const locationReducer = (state = initialState, action: Action): LocationS
path: path || state.path,
query: { ...query },
routeParams: routeParams || state.routeParams,
replace: replace === true,
};
}
}
......
......@@ -46,6 +46,10 @@ export class BridgeSrv {
if (angularUrl !== url) {
this.$timeout(() => {
this.$location.url(url);
// some state changes should not trigger new browser history
if (state.location.replace) {
this.$location.replace();
}
});
console.log('store updating angular $location.url', url);
}
......
......@@ -22,9 +22,8 @@ import { updateLocation } from 'app/core/actions';
import { notifyApp } from 'app/core/actions';
// Types
import { StoreState } from 'app/types';
import { StoreState, DashboardLoadingState, DashboardRouteInfo } from 'app/types';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { DashboardLoadingState } from 'app/types/dashboard';
interface Props {
urlUid?: string;
......@@ -32,8 +31,10 @@ interface Props {
urlType?: string;
editview?: string;
urlPanelId?: string;
urlFolderId?: string;
$scope: any;
$injector: any;
routeInfo: DashboardRouteInfo;
urlEdit: boolean;
urlFullscreen: boolean;
loadingState: DashboardLoadingState;
......@@ -66,6 +67,8 @@ export class DashboardPage extends PureComponent<Props, State> {
urlSlug: this.props.urlSlug,
urlUid: this.props.urlUid,
urlType: this.props.urlType,
urlFolderId: this.props.urlFolderId,
routeInfo: this.props.routeInfo,
});
}
......@@ -208,6 +211,7 @@ const mapStateToProps = (state: StoreState) => ({
urlType: state.location.routeParams.type,
editview: state.location.query.editview,
urlPanelId: state.location.query.panelId,
urlFolderId: state.location.query.folderId,
urlFullscreen: state.location.query.fullscreen === true,
urlEdit: state.location.query.edit === true,
loadingState: state.dashboard.loadingState,
......
......@@ -23,10 +23,10 @@ export class DashboardViewStateSrv {
self.dashboard = $scope.dashboard;
$scope.onAppEvent('$routeUpdate', () => {
const urlState = self.getQueryStringState();
if (self.needsSync(urlState)) {
self.update(urlState, true);
}
// const urlState = self.getQueryStringState();
// if (self.needsSync(urlState)) {
// self.update(urlState, true);
// }
});
$scope.onAppEvent('panel-change-view', (evt, payload) => {
......@@ -35,8 +35,8 @@ export class DashboardViewStateSrv {
// this marks changes to location during this digest cycle as not to add history item
// don't want url changes like adding orgId to add browser history
$location.replace();
this.update(this.getQueryStringState());
// $location.replace();
// this.update(this.getQueryStringState());
}
needsSync(urlState) {
......
......@@ -15,7 +15,7 @@ import { setDashboardLoadingState, ThunkResult, setDashboardModel } from './acti
import { removePanel } from '../utils/panel';
// Types
import { DashboardLoadingState } from 'app/types/dashboard';
import { DashboardLoadingState, DashboardRouteInfo } from 'app/types';
import { DashboardModel } from './DashboardModel';
export interface InitDashboardArgs {
......@@ -24,6 +24,8 @@ export interface InitDashboardArgs {
urlUid?: string;
urlSlug?: string;
urlType?: string;
urlFolderId: string;
routeInfo: string;
}
async function redirectToNewUrl(slug: string, dispatch: any) {
......@@ -35,36 +37,67 @@ async function redirectToNewUrl(slug: string, dispatch: any) {
}
}
export function initDashboard({ $injector, $scope, urlUid, urlSlug, urlType }: InitDashboardArgs): ThunkResult<void> {
return async dispatch => {
// handle old urls with no uid
if (!urlUid && urlSlug && !urlType) {
redirectToNewUrl(urlSlug, dispatch);
return;
}
export function initDashboard({
$injector,
$scope,
urlUid,
urlSlug,
urlType,
urlFolderId,
routeInfo,
}: InitDashboardArgs): ThunkResult<void> {
return async (dispatch, getState) => {
let dashDTO = null;
// set fetching state
dispatch(setDashboardLoadingState(DashboardLoadingState.Fetching));
try {
// if no uid or slug, load home dashboard
if (!urlUid && !urlSlug) {
dashDTO = await getBackendSrv().get('/api/dashboards/home');
if (dashDTO.redirectUri) {
const newUrl = locationUtil.stripBaseFromUrl(dashDTO.redirectUri);
dispatch(updateLocation({ path: newUrl }));
switch (routeInfo) {
// handle old urls with no uid
case DashboardRouteInfo.Old: {
redirectToNewUrl(urlSlug, dispatch);
return;
} else {
}
case DashboardRouteInfo.Home: {
// load home dash
dashDTO = 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;
}
// disable some actions on the default home dashboard
dashDTO.meta.canSave = false;
dashDTO.meta.canShare = false;
dashDTO.meta.canStar = false;
break;
}
case DashboardRouteInfo.Normal: {
const loaderSrv = $injector.get('dashboardLoaderSrv');
dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
// check if the current url is correct (might be old slug)
const dashboardUrl = locationUtil.stripBaseFromUrl(dashDTO.meta.url);
const currentPath = getState().location.path;
console.log('loading dashboard: currentPath', currentPath);
console.log('loading dashboard: dashboardUrl', dashboardUrl);
if (dashboardUrl !== currentPath) {
// replace url to not create additional history items and then return so that initDashboard below isn't executed multiple times.
dispatch(updateLocation({path: dashboardUrl, partial: true, replace: true}));
return;
}
break;
}
case DashboardRouteInfo.New: {
dashDTO = getNewDashboardModelData(urlFolderId);
break;
}
} else {
const loaderSrv = $injector.get('dashboardLoaderSrv');
dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
}
} catch (err) {
dispatch(setDashboardLoadingState(DashboardLoadingState.Error));
......@@ -136,3 +169,30 @@ export function initDashboard({ $injector, $scope, urlUid, urlSlug, urlType }: I
dispatch(setDashboardModel(dashboard));
};
}
function getNewDashboardModelData(urlFolderId?: string): any {
const data = {
meta: {
canStar: false,
canShare: false,
isNew: true,
folderId: 0,
},
dashboard: {
title: 'New dashboard',
panels: [
{
type: 'add-panel',
gridPos: { x: 0, y: 0, w: 12, h: 9 },
title: 'Panel Title',
},
],
},
};
if (urlFolderId) {
data.meta.folderId = parseInt(urlFolderId, 10);
}
return data;
}
......@@ -44,6 +44,7 @@ export function reactContainer(
$injector: $injector,
$rootScope: $rootScope,
$scope: scope,
routeInfo: $route.current.$$route.routeInfo,
};
ReactDOM.render(WrapInProvider(store, component, props), elem[0]);
......
......@@ -2,6 +2,7 @@ import './dashboard_loaders';
import './ReactContainer';
import { applyRouteRegistrationHandlers } from './registry';
// Pages
import ServerStats from 'app/features/admin/ServerStats';
import AlertRuleList from 'app/features/alerting/AlertRuleList';
import TeamPages from 'app/features/teams/TeamPages';
......@@ -23,6 +24,9 @@ import SoloPanelPage from '../features/dashboard/containers/SoloPanelPage';
import DashboardPage from '../features/dashboard/containers/DashboardPage';
import config from 'app/core/config';
// Types
import { DashboardRouteInfo } from 'app/types';
/** @ngInject */
export function setupAngularRoutes($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
......@@ -31,6 +35,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/', {
template: '<react-container />',
pageClass: 'page-dashboard',
routeInfo: DashboardRouteInfo.Home,
reloadOnSearch: false,
resolve: {
component: () => DashboardPage,
......@@ -39,6 +44,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/d/:uid/:slug', {
template: '<react-container />',
pageClass: 'page-dashboard',
routeInfo: DashboardRouteInfo.Normal,
reloadOnSearch: false,
resolve: {
component: () => DashboardPage,
......@@ -48,6 +54,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
template: '<react-container />',
pageClass: 'page-dashboard',
reloadOnSearch: false,
routeInfo: DashboardRouteInfo.Normal,
resolve: {
component: () => DashboardPage,
},
......@@ -55,6 +62,16 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/dashboard/:type/:slug', {
template: '<react-container />',
pageClass: 'page-dashboard',
routeInfo: DashboardRouteInfo.Old,
reloadOnSearch: false,
resolve: {
component: () => DashboardPage,
},
})
.when('/dashboard/new', {
template: '<react-container />',
pageClass: 'page-dashboard',
routeInfo: DashboardRouteInfo.New,
reloadOnSearch: false,
resolve: {
component: () => DashboardPage,
......@@ -63,6 +80,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/d-solo/:uid/:slug', {
template: '<react-container />',
pageClass: 'dashboard-solo',
routeInfo: DashboardRouteInfo.Normal,
resolve: {
component: () => SoloPanelPage,
},
......@@ -70,16 +88,11 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/dashboard-solo/:type/:slug', {
template: '<react-container />',
pageClass: 'dashboard-solo',
routeInfo: DashboardRouteInfo.Old,
resolve: {
component: () => SoloPanelPage,
},
})
.when('/dashboard/new', {
templateUrl: 'public/app/partials/dashboard.html',
controller: 'NewDashboardCtrl',
reloadOnSearch: false,
pageClass: 'page-dashboard',
})
.when('/dashboard/import', {
templateUrl: 'public/app/features/manage-dashboards/partials/dashboard_import.html',
controller: DashboardImportCtrl,
......
......@@ -7,9 +7,16 @@ export interface MutableDashboard {
};
}
export enum DashboardRouteInfo {
Old = 'old-dashboard',
Home = 'home-dashboard',
New = 'new-dashboard',
Normal = 'normal-dashboard',
}
export enum DashboardLoadingState {
NotStarted = 'Not started',
Fetching = 'Fetching',
Fetching = 'Fetching',
Initializing = 'Initializing',
Error = 'Error',
Done = 'Done',
......
......@@ -3,6 +3,10 @@ export interface LocationUpdate {
query?: UrlQueryMap;
routeParams?: UrlQueryMap;
partial?: boolean;
/*
* If true this will replace url state (ie cause no new browser history)
*/
replace?: boolean;
}
export interface LocationState {
......@@ -10,6 +14,7 @@ export interface LocationState {
path: string;
query: UrlQueryMap;
routeParams: UrlQueryMap;
replace: boolean;
}
export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[];
......
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