mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip: progress
This commit is contained in:
@@ -16,6 +16,7 @@ export interface Props {
|
|||||||
editview: string;
|
editview: string;
|
||||||
isEditing: boolean;
|
isEditing: boolean;
|
||||||
isFullscreen: boolean;
|
isFullscreen: boolean;
|
||||||
|
$injector: any;
|
||||||
updateLocation: typeof updateLocation;
|
updateLocation: typeof updateLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,13 +26,29 @@ export class DashNav extends PureComponent<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onAddPanel = () => {};
|
onAddPanel = () => {};
|
||||||
|
|
||||||
|
onClose = () => {
|
||||||
|
this.props.updateLocation({
|
||||||
|
query: { editview: null, panelId: null, edit: null, fullscreen: null },
|
||||||
|
partial: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onOpenSettings = () => {
|
onOpenSettings = () => {
|
||||||
this.props.updateLocation({
|
this.props.updateLocation({
|
||||||
query: {
|
query: { editview: 'settings' },
|
||||||
editview: 'settings',
|
|
||||||
},
|
|
||||||
partial: true,
|
partial: true,
|
||||||
})
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onStarDashboard = () => {
|
||||||
|
const { $injector, dashboard } = this.props;
|
||||||
|
const dashboardSrv = $injector.get('dashboardSrv');
|
||||||
|
|
||||||
|
dashboardSrv.starDashboard(dashboard.id, dashboard.meta.isStarred).then(newState => {
|
||||||
|
dashboard.meta.isStarred = newState;
|
||||||
|
this.forceUpdate();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderLoadingState() {
|
renderLoadingState() {
|
||||||
@@ -48,15 +65,16 @@ export class DashNav extends PureComponent<Props> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { dashboard } = this.props;
|
const { dashboard, isFullscreen, editview } = this.props;
|
||||||
|
|
||||||
if (!dashboard) {
|
if (!dashboard) {
|
||||||
return this.renderLoadingState();
|
return this.renderLoadingState();
|
||||||
}
|
}
|
||||||
|
|
||||||
const haveFolder = dashboard.meta.folderId > 0;
|
const haveFolder = dashboard.meta.folderId > 0;
|
||||||
const { canEdit, canSave, folderTitle, showSettings } = dashboard.meta;
|
const { canEdit, canStar, canSave, folderTitle, showSettings, isStarred } = dashboard.meta;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="navbar">
|
<div className="navbar">
|
||||||
@@ -95,10 +113,18 @@ export class DashNav extends PureComponent<Props> {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{canStar && (
|
||||||
|
<button
|
||||||
|
className="btn navbar-button navbar-button--star"
|
||||||
|
onClick={this.onStarDashboard}
|
||||||
|
title="Mark as favorite"
|
||||||
|
>
|
||||||
|
{isStarred && <i className="fa fa-star" />}
|
||||||
|
{!isStarred && <i className="fa fa-star-o" />}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
{
|
{
|
||||||
// <button class="btn navbar-button navbar-button--star" ng-show="::ctrl.dashboard.meta.canStar" ng-click="ctrl.starDashboard()" bs-tooltip="'Mark as favorite'" data-placement="bottom">
|
|
||||||
// <i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}"></i>
|
|
||||||
// </button>
|
|
||||||
//
|
//
|
||||||
// <button class="btn navbar-button navbar-button--share" ng-show="::ctrl.dashboard.meta.canShare" ng-click="ctrl.shareDashboard(0)" bs-tooltip="'Share dashboard'" data-placement="bottom">
|
// <button class="btn navbar-button navbar-button--share" ng-show="::ctrl.dashboard.meta.canShare" ng-click="ctrl.shareDashboard(0)" bs-tooltip="'Share dashboard'" data-placement="bottom">
|
||||||
// <i class="fa fa-share-square-o"></i></a>
|
// <i class="fa fa-share-square-o"></i></a>
|
||||||
@@ -125,23 +151,28 @@ export class DashNav extends PureComponent<Props> {
|
|||||||
//
|
//
|
||||||
// <gf-time-picker class="gf-timepicker-nav" dashboard="ctrl.dashboard" ng-if="!ctrl.dashboard.timepicker.hidden"></gf-time-picker>
|
// <gf-time-picker class="gf-timepicker-nav" dashboard="ctrl.dashboard" ng-if="!ctrl.dashboard.timepicker.hidden"></gf-time-picker>
|
||||||
//
|
//
|
||||||
// <div class="navbar-buttons navbar-buttons--close">
|
|
||||||
// <button class="btn navbar-button navbar-button--primary" ng-click="ctrl.close()" bs-tooltip="'Back to dashboard'" data-placement="bottom">
|
|
||||||
// <i class="fa fa-reply"></i>
|
|
||||||
// </button>
|
|
||||||
// </div>
|
|
||||||
}
|
}
|
||||||
|
{(isFullscreen || editview) && (
|
||||||
|
<div className="navbar-buttons navbar-buttons--close">
|
||||||
|
<button
|
||||||
|
className="btn navbar-button navbar-button--primary"
|
||||||
|
onClick={this.onClose}
|
||||||
|
title="Back to dashboard"
|
||||||
|
>
|
||||||
|
<i className="fa fa-reply" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = () => ({
|
const mapStateToProps = () => ({});
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
updateLocation
|
updateLocation,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(DashNav);
|
export default connect(mapStateToProps, mapDispatchToProps)(DashNav);
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ export class DashboardPage extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
this.props.initDashboard({
|
this.props.initDashboard({
|
||||||
injector: this.props.$injector,
|
$injector: this.props.$injector,
|
||||||
scope: this.props.$scope,
|
$scope: this.props.$scope,
|
||||||
urlSlug: this.props.urlSlug,
|
urlSlug: this.props.urlSlug,
|
||||||
urlUid: this.props.urlUid,
|
urlUid: this.props.urlUid,
|
||||||
urlType: this.props.urlType,
|
urlType: this.props.urlType,
|
||||||
@@ -123,7 +123,7 @@ export class DashboardPage extends PureComponent<Props, State> {
|
|||||||
fullscreen: null,
|
fullscreen: null,
|
||||||
panelId: null,
|
panelId: null,
|
||||||
},
|
},
|
||||||
partial: true
|
partial: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ export class DashboardPage extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard, editview } = this.props;
|
const { dashboard, editview, $injector } = this.props;
|
||||||
const { isSettingsOpening, isEditing, isFullscreen } = this.state;
|
const { isSettingsOpening, isEditing, isFullscreen } = this.state;
|
||||||
|
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
@@ -173,7 +173,13 @@ export class DashboardPage extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
<DashNav dashboard={dashboard} isEditing={isEditing} isFullscreen={isFullscreen} editview={editview} />
|
<DashNav
|
||||||
|
dashboard={dashboard}
|
||||||
|
isEditing={isEditing}
|
||||||
|
isFullscreen={isFullscreen}
|
||||||
|
editview={editview}
|
||||||
|
$injector={$injector}
|
||||||
|
/>
|
||||||
{!dashboard && this.renderLoadingState()}
|
{!dashboard && this.renderLoadingState()}
|
||||||
{dashboard && this.renderDashboard()}
|
{dashboard && this.renderDashboard()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// Libaries
|
// Libaries
|
||||||
import { StoreState } from 'app/types';
|
|
||||||
import { ThunkAction } from 'redux-thunk';
|
import { ThunkAction } from 'redux-thunk';
|
||||||
|
|
||||||
// Services & Utils
|
// Services & Utils
|
||||||
@@ -13,6 +12,7 @@ import { loadPluginDashboards } from '../../plugins/state/actions';
|
|||||||
import { notifyApp } from 'app/core/actions';
|
import { notifyApp } from 'app/core/actions';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
import { StoreState } from 'app/types';
|
||||||
import {
|
import {
|
||||||
DashboardAcl,
|
DashboardAcl,
|
||||||
DashboardAclDTO,
|
DashboardAclDTO,
|
||||||
@@ -27,7 +27,6 @@ export const setDashboardLoadingState = actionCreatorFactory<DashboardLoadingSta
|
|||||||
export const setDashboardModel = actionCreatorFactory<MutableDashboard>('SET_DASHBOARD_MODEL').create();
|
export const setDashboardModel = actionCreatorFactory<MutableDashboard>('SET_DASHBOARD_MODEL').create();
|
||||||
|
|
||||||
export type Action = ActionOf<DashboardAclDTO[]>;
|
export type Action = ActionOf<DashboardAclDTO[]>;
|
||||||
|
|
||||||
export type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>;
|
export type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>;
|
||||||
|
|
||||||
export function getDashboardPermissions(id: number): ThunkResult<void> {
|
export function getDashboardPermissions(id: number): ThunkResult<void> {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Services & Utils
|
// Services & Utils
|
||||||
import { createErrorNotification } from 'app/core/copy/appNotification';
|
import { createErrorNotification } from 'app/core/copy/appNotification';
|
||||||
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import { updateLocation } from 'app/core/actions';
|
import { updateLocation } from 'app/core/actions';
|
||||||
@@ -12,24 +13,53 @@ import { DashboardLoadingState } from 'app/types/dashboard';
|
|||||||
import { DashboardModel } from './DashboardModel';
|
import { DashboardModel } from './DashboardModel';
|
||||||
|
|
||||||
export interface InitDashboardArgs {
|
export interface InitDashboardArgs {
|
||||||
injector: any;
|
$injector: any;
|
||||||
scope: any;
|
$scope: any;
|
||||||
urlUid?: string;
|
urlUid?: string;
|
||||||
urlSlug?: string;
|
urlSlug?: string;
|
||||||
urlType?: string;
|
urlType?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initDashboard({ injector, scope, urlUid, urlSlug, urlType }: InitDashboardArgs): ThunkResult<void> {
|
async function redirectToNewUrl(slug: string, dispatch: any) {
|
||||||
return async dispatch => {
|
const res = await getBackendSrv().getDashboardBySlug(slug);
|
||||||
const loaderSrv = injector.get('dashboardLoaderSrv');
|
|
||||||
|
|
||||||
dispatch(setDashboardLoadingState(DashboardLoadingState.Fetching));
|
if (res) {
|
||||||
|
const url = locationUtil.stripBaseFromUrl(res.meta.url.replace('/d/', '/d-solo/'));
|
||||||
|
dispatch(updateLocation(url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initDashboard({ $injector, $scope, urlUid, urlSlug, urlType }: InitDashboardArgs): ThunkResult<void> {
|
||||||
|
return async dispatch => {
|
||||||
|
// handle old urls with no uid
|
||||||
|
if (!urlUid && urlSlug) {
|
||||||
|
redirectToNewUrl(urlSlug, dispatch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let dashDTO = null;
|
let dashDTO = null;
|
||||||
|
|
||||||
|
// set fetching state
|
||||||
|
dispatch(setDashboardLoadingState(DashboardLoadingState.Fetching));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// fetch dashboard from api
|
// 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 }));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
dashDTO.meta.canSave = false;
|
||||||
|
dashDTO.meta.canShare = false;
|
||||||
|
dashDTO.meta.canStar = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const loaderSrv = $injector.get('dashboardLoaderSrv');
|
||||||
dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
|
dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dispatch(setDashboardLoadingState(DashboardLoadingState.Error));
|
dispatch(setDashboardLoadingState(DashboardLoadingState.Error));
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -50,13 +80,13 @@ export function initDashboard({ injector, scope, urlUid, urlSlug, urlType }: Ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
// init services
|
// init services
|
||||||
injector.get('timeSrv').init(dashboard);
|
$injector.get('timeSrv').init(dashboard);
|
||||||
injector.get('annotationsSrv').init(dashboard);
|
$injector.get('annotationsSrv').init(dashboard);
|
||||||
|
|
||||||
// template values service needs to initialize completely before
|
// template values service needs to initialize completely before
|
||||||
// the rest of the dashboard can load
|
// the rest of the dashboard can load
|
||||||
try {
|
try {
|
||||||
await injector.get('variableSrv').init(dashboard);
|
await $injector.get('variableSrv').init(dashboard);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dispatch(notifyApp(createErrorNotification('Templating init failed', err.toString())));
|
dispatch(notifyApp(createErrorNotification('Templating init failed', err.toString())));
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -68,11 +98,11 @@ export function initDashboard({ injector, scope, urlUid, urlSlug, urlType }: Ini
|
|||||||
dashboard.autoFitPanels(window.innerHeight);
|
dashboard.autoFitPanels(window.innerHeight);
|
||||||
|
|
||||||
// init unsaved changes tracking
|
// init unsaved changes tracking
|
||||||
injector.get('unsavedChangesSrv').init(dashboard, scope);
|
$injector.get('unsavedChangesSrv').init(dashboard, $scope);
|
||||||
|
|
||||||
scope.dashboard = dashboard;
|
$scope.dashboard = dashboard;
|
||||||
injector.get('dashboardViewStateSrv').create(scope);
|
$injector.get('dashboardViewStateSrv').create($scope);
|
||||||
injector.get('keybindingSrv').setupDashboardBindings(scope, dashboard);
|
$injector.get('keybindingSrv').setupDashboardBindings($scope, dashboard);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dispatch(notifyApp(createErrorNotification('Dashboard init failed', err.toString())));
|
dispatch(notifyApp(createErrorNotification('Dashboard init failed', err.toString())));
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
|
|
||||||
$routeProvider
|
$routeProvider
|
||||||
.when('/', {
|
.when('/', {
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
template: '<react-container />',
|
||||||
controller: 'LoadDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
pageClass: 'page-dashboard',
|
pageClass: 'page-dashboard',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
resolve: {
|
||||||
|
component: () => DashboardPage,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.when('/d/:uid/:slug', {
|
.when('/d/:uid/:slug', {
|
||||||
template: '<react-container />',
|
template: '<react-container />',
|
||||||
@@ -43,16 +45,20 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.when('/d/:uid', {
|
.when('/d/:uid', {
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
template: '<react-container />',
|
||||||
controller: 'LoadDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
pageClass: 'page-dashboard',
|
pageClass: 'page-dashboard',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
resolve: {
|
||||||
|
component: () => DashboardPage,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.when('/dashboard/:type/:slug', {
|
.when('/dashboard/:type/:slug', {
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
template: '<react-container />',
|
||||||
controller: 'LoadDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
pageClass: 'page-dashboard',
|
pageClass: 'page-dashboard',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
resolve: {
|
||||||
|
component: () => DashboardPage,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.when('/d-solo/:uid/:slug', {
|
.when('/d-solo/:uid/:slug', {
|
||||||
template: '<react-container />',
|
template: '<react-container />',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export interface MutableDashboard {
|
|||||||
meta: {
|
meta: {
|
||||||
fullscreen: boolean;
|
fullscreen: boolean;
|
||||||
isEditing: boolean;
|
isEditing: boolean;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DashboardLoadingState {
|
export enum DashboardLoadingState {
|
||||||
|
|||||||
Reference in New Issue
Block a user