mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
dashfolder: refactor breadcrumbs in PageHeader
Combines title and breadcrumbs in PageHeader instead of having to set title to empty and add it as a breadcrumb.
This commit is contained in:
parent
545d7b9477
commit
21b5ded75b
@ -49,7 +49,7 @@ export class FolderSettings extends React.Component<IContainerProps, any> {
|
||||
const { nav, folder, view } = this.props;
|
||||
|
||||
folder
|
||||
.saveDashboard(this.dashboard, { overwrite: false })
|
||||
.saveFolder(this.dashboard, { overwrite: false })
|
||||
.then(newUrl => {
|
||||
view.updatePathAndQuery(newUrl, '', '');
|
||||
|
||||
@ -96,7 +96,7 @@ export class FolderSettings extends React.Component<IContainerProps, any> {
|
||||
yesText: 'Save & Overwrite',
|
||||
icon: 'fa-warning',
|
||||
onConfirm: () => {
|
||||
this.props.folder.saveDashboard(this.dashboard, { overwrite: true });
|
||||
this.props.folder.saveFolder(this.dashboard, { overwrite: true });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
53
public/app/core/components/PageHeader/PageHeader.jest.tsx
Normal file
53
public/app/core/components/PageHeader/PageHeader.jest.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import PageHeader from './PageHeader';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('PageHeader', () => {
|
||||
let wrapper;
|
||||
|
||||
describe('when the nav tree has a node with a title', () => {
|
||||
beforeAll(() => {
|
||||
const nav = {
|
||||
main: {
|
||||
icon: 'fa fa-folder-open',
|
||||
id: 'node',
|
||||
subTitle: 'node subtitle',
|
||||
url: '',
|
||||
text: 'node',
|
||||
},
|
||||
node: {},
|
||||
};
|
||||
wrapper = shallow(<PageHeader model={nav as any} />);
|
||||
});
|
||||
|
||||
it('should render the title', () => {
|
||||
const title = wrapper.find('.page-header__title');
|
||||
expect(title.text()).toBe('node');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the nav tree has a node with breadcrumbs and a title', () => {
|
||||
beforeAll(() => {
|
||||
const nav = {
|
||||
main: {
|
||||
icon: 'fa fa-folder-open',
|
||||
id: 'child',
|
||||
subTitle: 'child subtitle',
|
||||
url: '',
|
||||
text: 'child',
|
||||
breadcrumbs: [{ title: 'Parent', url: 'parentUrl' }],
|
||||
},
|
||||
node: {},
|
||||
};
|
||||
wrapper = shallow(<PageHeader model={nav as any} />);
|
||||
});
|
||||
|
||||
it('should render the title with breadcrumbs first and then title last', () => {
|
||||
const title = wrapper.find('.page-header__title');
|
||||
expect(title.text()).toBe('Parent / child');
|
||||
|
||||
const parentLink = wrapper.find('.page-header__title > a.text-link');
|
||||
expect(parentLink.prop('href')).toBe('parentUrl');
|
||||
});
|
||||
});
|
||||
});
|
@ -85,7 +85,15 @@ export default class PageHeader extends React.Component<IProps, any> {
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderBreadcrumb(breadcrumbs) {
|
||||
renderTitle(title: string, breadcrumbs: any[]) {
|
||||
if (!title && (!breadcrumbs || breadcrumbs.length === 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!breadcrumbs || breadcrumbs.length === 0) {
|
||||
return <h1 className="page-header__title">{title}</h1>;
|
||||
}
|
||||
|
||||
const breadcrumbsResult = [];
|
||||
for (let i = 0; i < breadcrumbs.length; i++) {
|
||||
const bc = breadcrumbs[i];
|
||||
@ -99,7 +107,9 @@ export default class PageHeader extends React.Component<IProps, any> {
|
||||
breadcrumbsResult.push(<span key={i}> / {bc.title}</span>);
|
||||
}
|
||||
}
|
||||
return breadcrumbsResult;
|
||||
breadcrumbsResult.push(<span key={breadcrumbs.length + 1}> / {title}</span>);
|
||||
|
||||
return <h1 className="page-header__title">{breadcrumbsResult}</h1>;
|
||||
}
|
||||
|
||||
renderHeaderTitle(main) {
|
||||
@ -111,11 +121,7 @@ export default class PageHeader extends React.Component<IProps, any> {
|
||||
</span>
|
||||
|
||||
<div className="page-header__info-block">
|
||||
{main.text && <h1 className="page-header__title">{main.text}</h1>}
|
||||
{main.breadcrumbs &&
|
||||
main.breadcrumbs.length > 0 && (
|
||||
<h1 className="page-header__title">{this.renderBreadcrumb(main.breadcrumbs)}</h1>
|
||||
)}
|
||||
{this.renderTitle(main.text, main.breadcrumbs)}
|
||||
{main.subTitle && <div className="page-header__sub-title">{main.subTitle}</div>}
|
||||
{main.subType && (
|
||||
<div className="page-header__stamps">
|
||||
|
@ -10,8 +10,9 @@ export class InvitedCtrl {
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
text: 'Invite',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: '/login' }, { title: 'Invite' }],
|
||||
breadcrumbs: [{ title: 'Login', url: '/login' }],
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -16,8 +16,9 @@ export class ResetPasswordCtrl {
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
text: 'Reset Password',
|
||||
subTitle: 'Reset your Grafana password',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }, { title: 'Reset Password' }],
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ export class FolderPageLoader {
|
||||
subTitle: 'Manage folder dashboards & permissions',
|
||||
url: '',
|
||||
text: '',
|
||||
breadcrumbs: [{ title: 'Dashboards', url: 'dashboards' }, { title: ' ' }],
|
||||
breadcrumbs: [{ title: 'Dashboards', url: 'dashboards' }],
|
||||
children: [
|
||||
{
|
||||
active: activeChildId === 'manage-folder-dashboards',
|
||||
@ -40,8 +40,7 @@ export class FolderPageLoader {
|
||||
|
||||
return this.backendSrv.getDashboard('db', this.$routeParams.slug).then(result => {
|
||||
const folderTitle = result.dashboard.title;
|
||||
ctrl.navModel.main.text = '';
|
||||
ctrl.navModel.main.breadcrumbs = [{ title: 'Dashboards', url: 'dashboards' }, { title: folderTitle }];
|
||||
ctrl.navModel.main.text = folderTitle;
|
||||
|
||||
const folderUrl = this.createFolderUrl(folderId, result.meta.slug);
|
||||
|
||||
|
@ -32,8 +32,8 @@ export class PluginEditCtrl {
|
||||
img: model.info.logos.large,
|
||||
subTitle: model.info.author.name,
|
||||
url: '',
|
||||
text: '',
|
||||
breadcrumbs: [{ title: 'Plugins', url: 'plugins' }, { title: model.name }],
|
||||
text: model.name,
|
||||
breadcrumbs: [{ title: 'Plugins', url: 'plugins' }],
|
||||
children: [
|
||||
{
|
||||
icon: 'fa fa-fw fa-file-text-o',
|
||||
|
@ -40,8 +40,8 @@ export class AppPageCtrl {
|
||||
img: app.info.logos.large,
|
||||
subTitle: app.name,
|
||||
url: '',
|
||||
text: '',
|
||||
breadcrumbs: [{ title: app.name, url: pluginNav.main.url }, { title: this.page.name }],
|
||||
text: this.page.name,
|
||||
breadcrumbs: [{ title: app.name, url: pluginNav.main.url }],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -25,11 +25,13 @@ export const FolderStore = types
|
||||
});
|
||||
return res;
|
||||
}),
|
||||
|
||||
setTitle: function(originalTitle: string, title: string) {
|
||||
self.folder.title = title;
|
||||
self.folder.hasChanged = originalTitle.toLowerCase() !== title.trim().toLowerCase() && title.trim().length > 0;
|
||||
},
|
||||
saveDashboard: flow(function* saveDashboard(dashboard: any, options: any) {
|
||||
|
||||
saveFolder: flow(function* saveFolder(dashboard: any, options: any) {
|
||||
const backendSrv = getEnv(self).backendSrv;
|
||||
dashboard.title = self.folder.title.trim();
|
||||
|
||||
@ -37,6 +39,7 @@ export const FolderStore = types
|
||||
self.folder.slug = res.slug;
|
||||
return `dashboards/folder/${self.folder.id}/${res.slug}/settings`;
|
||||
}),
|
||||
|
||||
deleteFolder: flow(function* deleteFolder() {
|
||||
const backendSrv = getEnv(self).backendSrv;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user