Implement k7Breadcrumbs in Kibana mangement routes (#26503) (#26577)

* [chrome/breadcrumbs] don't clear the breadcrumbs on redirect routes

* [ui/topNav/breadcrumbs] don't set k7 breadcrumbs

* [management] implement k7Breadcrumbs in kibana mangement routes

* Avoid title case

* [chrome/breadcrumbs] protect against times where route did not match anything

* [chrome] only load route is available

* move breadcrumb modules into new location

* fix i18n message id

* Update reference to renamed variable

Co-Authored-By: spalger <email@spalger.com>

* simplify redirectTo and avoid mutable var

* fix eslint issues
This commit is contained in:
Spencer 2018-12-03 16:40:30 -08:00 committed by GitHub
parent 43183614b0
commit 5c1dbd74cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 248 additions and 34 deletions

View file

@ -24,14 +24,17 @@ import uiRoutes from 'ui/routes';
import { uiModules } from 'ui/modules';
import appTemplate from './app.html';
import landingTemplate from './landing.html';
import { management } from 'ui/management';
import { management, MANAGEMENT_BREADCRUMB } from 'ui/management';
import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
import { timefilter } from 'ui/timefilter';
import 'ui/kbn_top_nav';
uiRoutes
.when('/management', {
template: landingTemplate
template: landingTemplate,
k7Breadcrumbs: () => [
MANAGEMENT_BREADCRUMB
]
});
uiRoutes

View file

@ -0,0 +1,67 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { MANAGEMENT_BREADCRUMB } from 'ui/management';
import { i18n } from '@kbn/i18n';
export function getCreateBreadcrumbs() {
return [
MANAGEMENT_BREADCRUMB,
{
text: i18n.translate('kbn.management.indexPatterns.createBreadcrumb', {
defaultMessage: 'Create index pattern'
}),
href: '#/management/kibana/objects'
}
];
}
export function getEditBreadcrumbs($route) {
const { indexPattern } = $route.current.locals;
return [
MANAGEMENT_BREADCRUMB,
{
text: indexPattern.title,
href: `#/management/kibana/indices/${indexPattern.id}`
}
];
}
export function getEditFieldBreadcrumbs($route) {
const { fieldName } = $route.current.params;
return [
...getEditBreadcrumbs($route),
{
text: fieldName
}
];
}
export function getCreateFieldBreadcrumbs($route) {
return [
...getEditBreadcrumbs($route),
{
text: i18n.translate('kbn.management.indexPatterns.createFieldBreadcrumb', {
defaultMessage: 'Create field'
})
}
];
}

View file

@ -22,11 +22,13 @@ import uiRoutes from 'ui/routes';
import angularTemplate from './angular_template.html';
import 'ui/index_patterns';
import { IndexPatternCreationFactory } from 'ui/management/index_pattern_creation';
import { getCreateBreadcrumbs } from '../breadcrumbs';
import { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } from './render';
uiRoutes.when('/management/kibana/index', {
template: angularTemplate,
k7Breadcrumbs: getCreateBreadcrumbs,
controller: function ($scope, $injector) {
// Wait for the directives to execute
const kbnUrl = $injector.get('kbnUrl');

View file

@ -22,7 +22,9 @@ import { RegistryFieldFormatEditorsProvider } from 'ui/registry/field_format_edi
import { KbnUrlProvider } from 'ui/url';
import uiRoutes from 'ui/routes';
import { toastNotifications } from 'ui/notify';
import template from './create_edit_field.html';
import { getEditFieldBreadcrumbs, getCreateFieldBreadcrumbs } from '../../breadcrumbs';
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
@ -69,8 +71,14 @@ const destroyFieldEditor = () => {
};
uiRoutes
.when('/management/kibana/indices/:indexPatternId/field/:fieldName*', { mode: 'edit' })
.when('/management/kibana/indices/:indexPatternId/create-field/', { mode: 'create' })
.when('/management/kibana/indices/:indexPatternId/field/:fieldName*', {
mode: 'edit',
k7Breadcrumbs: getEditFieldBreadcrumbs
})
.when('/management/kibana/indices/:indexPatternId/create-field/', {
mode: 'create',
k7Breadcrumbs: getCreateFieldBreadcrumbs
})
.defaults(/management\/kibana\/indices\/[^\/]+\/(field|create-field)(\/|$)/, {
template,
mapBreadcrumbs($route, breadcrumbs) {

View file

@ -35,6 +35,9 @@ import { IndexedFieldsTable } from './indexed_fields_table';
import { ScriptedFieldsTable } from './scripted_fields_table';
import { I18nProvider } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import chrome from 'ui/chrome';
import { getEditBreadcrumbs } from '../breadcrumbs';
const REACT_SOURCE_FILTERS_DOM_ELEMENT_ID = 'reactSourceFiltersTable';
const REACT_INDEXED_FIELDS_DOM_ELEMENT_ID = 'reactIndexedFieldsTable';
@ -156,28 +159,25 @@ function destroyIndexedFieldsTable() {
uiRoutes
.when('/management/kibana/indices/:indexPatternId', {
template,
k7Breadcrumbs: getEditBreadcrumbs,
resolve: {
indexPattern: function ($route, redirectWhenMissing, indexPatterns) {
return indexPatterns
.get($route.current.params.indexPatternId)
.catch(redirectWhenMissing('/management/kibana/index'));
}
}
},
});
uiRoutes
.when('/management/kibana/indices', {
resolve: {
redirect: function ($location, config) {
const defaultIndex = config.get('defaultIndex');
let path = '/management/kibana/index';
if (defaultIndex) {
path = `/management/kibana/indices/${defaultIndex}`;
}
$location.path(path).replace();
redirectTo() {
const defaultIndex = chrome.getUiSettingsClient().get('defaultIndex');
if (defaultIndex) {
return `/management/kibana/indices/${defaultIndex}`;
}
return '/management/kibana/index';
}
});

View file

@ -78,12 +78,7 @@ const indexPatternsResolutions = {
// add a dependency to all of the subsection routes
uiRoutes
.defaults(/management\/kibana\/indices/, {
resolve: indexPatternsResolutions
});
uiRoutes
.defaults(/management\/kibana\/index/, {
.defaults(/management\/kibana\/(indices|index)/, {
resolve: indexPatternsResolutions
});

View file

@ -30,6 +30,8 @@ import { ObjectsTable } from './components/objects_table';
import { getInAppUrl } from './lib/get_in_app_url';
import { I18nProvider } from '@kbn/i18n/react';
import { getIndexBreadcrumbs } from './breadcrumbs';
const REACT_OBJECTS_TABLE_DOM_ELEMENT_ID = 'reactSavedObjectsTable';
function updateObjectsTable($scope, $injector) {
@ -91,8 +93,13 @@ function destroyObjectsTable() {
}
uiRoutes
.when('/management/kibana/objects', { template: objectIndexHTML })
.when('/management/kibana/objects/:service', { redirectTo: '/management/kibana/objects' });
.when('/management/kibana/objects', {
template: objectIndexHTML,
k7Breadcrumbs: getIndexBreadcrumbs
})
.when('/management/kibana/objects/:service', {
redirectTo: '/management/kibana/objects'
});
uiModules.get('apps/management')
.directive('kbnManagementObjects', function () {

View file

@ -30,11 +30,14 @@ import { castEsToKbnFieldTypeName } from '../../../../../../../utils';
import { SavedObjectsClientProvider } from 'ui/saved_objects';
import { isNumeric } from 'ui/utils/numeric';
import { getViewBreadcrumbs } from './breadcrumbs';
const location = 'SavedObject view';
uiRoutes
.when('/management/kibana/objects/:service/:id', {
template: objectViewHTML
template: objectViewHTML,
k7Breadcrumbs: getViewBreadcrumbs
});
uiModules.get('apps/management')

View file

@ -0,0 +1,50 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { MANAGEMENT_BREADCRUMB } from 'ui/management';
import { i18n } from '@kbn/i18n';
import { savedObjectManagementRegistry } from '../../saved_object_registry';
export function getIndexBreadcrumbs() {
return [
MANAGEMENT_BREADCRUMB,
{
text: i18n.translate('kbn.management.savedObjects.indexBreadcrumb', {
defaultMessage: 'Saved objects'
}),
href: '#/management/kibana/objects'
}
];
}
export function getViewBreadcrumbs($routeParams, $injector) {
const serviceObj = savedObjectManagementRegistry.get($routeParams.service);
const service = $injector.get(serviceObj.service);
return [
...getIndexBreadcrumbs(),
{
text: i18n.translate('kbn.management.savedObjects.editBreadcrumb', {
defaultMessage: 'Edit {savedObjectType}',
values: { savedObjectType: service.type }
})
}
];
}

View file

@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { MANAGEMENT_BREADCRUMB } from 'ui/management';
import { i18n } from '@kbn/i18n';
export function getBreadcrumbs() {
return [
MANAGEMENT_BREADCRUMB,
{
text: i18n.translate('kbn.management.settings.breadcrumb', {
defaultMessage: 'Advanced settings',
})
}
];
}

View file

@ -27,6 +27,7 @@ import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { AdvancedSettings } from './advanced_settings';
import { i18n } from '@kbn/i18n';
import { getBreadcrumbs } from './breadcrumbs';
const REACT_ADVANCED_SETTINGS_DOM_ELEMENT_ID = 'reactAdvancedSettings';
@ -54,7 +55,8 @@ function destroyAdvancedSettings() {
uiRoutes
.when('/management/kibana/settings/:setting?', {
template: indexTemplate
template: indexTemplate,
k7Breadcrumbs: getBreadcrumbs
});
uiModules.get('apps/management')

View file

@ -17,8 +17,11 @@
* under the License.
*/
import { IRootScopeService } from 'angular';
// @ts-ignore
import { uiModules } from 'ui/modules';
import { fatalError } from 'ui/notify/fatal_error';
import { Breadcrumb, ChromeStartContract } from '../../../../core/public/chrome';
export { Breadcrumb };
@ -46,13 +49,13 @@ export function initBreadcrumbsApi(
) {
// A flag used to determine if we should automatically
// clear the breadcrumbs between angular route changes.
let shouldClear = false;
let breadcrumbSetSinceRouteChange = false;
// reset shouldClear any time the breadcrumbs change, even
// reset breadcrumbSetSinceRouteChange any time the breadcrumbs change, even
// if it was done directly through the new platform
newPlatformChrome.getBreadcrumbs$().subscribe({
next() {
shouldClear = false;
breadcrumbSetSinceRouteChange = true;
},
});
@ -70,14 +73,31 @@ export function initBreadcrumbsApi(
// bootstraps and lets us integrate with the angular router so that we can
// automatically clear the breadcrumbs if we switch to a Kibana app that
// does not use breadcrumbs correctly
internals.$setupBreadcrumbsAutoClear = ($rootScope: any) => {
internals.$setupBreadcrumbsAutoClear = ($rootScope: IRootScopeService, $injector: any) => {
const uiSettings = chrome.getUiSettingsClient();
const $route = $injector.has('$route') ? $injector.get('$route') : {};
$rootScope.$on('$routeChangeStart', () => {
shouldClear = true;
breadcrumbSetSinceRouteChange = false;
});
$rootScope.$on('$routeChangeSuccess', () => {
if (shouldClear) {
const current = $route.current || {};
if (breadcrumbSetSinceRouteChange || (current.$$route && current.$$route.redirectTo)) {
return;
}
const k7BreadcrumbsProvider = current.k7Breadcrumbs;
if (!k7BreadcrumbsProvider || !uiSettings.get('k7design')) {
newPlatformChrome.setBreadcrumbs([]);
return;
}
try {
chrome.breadcrumbs.set($injector.invoke(k7BreadcrumbsProvider));
} catch (error) {
fatalError(error);
}
});
};

View file

@ -20,7 +20,6 @@
import breadCrumbsTemplate from './bread_crumbs.html';
import { uiModules } from '../../modules';
import uiRouter from '../../routes';
import chrome from '../../chrome';
const module = uiModules.get('kibana');
@ -78,8 +77,6 @@ module.directive('breadCrumbs', function () {
if ($scope.pageTitle) {
newBreadcrumbs.push({ text: $scope.pageTitle });
}
chrome.breadcrumbs.set(newBreadcrumbs);
});
}
};

View file

@ -0,0 +1,27 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { i18n } from '@kbn/i18n';
export const MANAGEMENT_BREADCRUMB = Object.freeze({
text: i18n.translate('common.ui.management.breadcrumb', {
defaultMessage: 'Management'
}),
href: '#/management'
});

View file

@ -27,3 +27,4 @@ export {
} from '../../../legacy/core_plugins/kibana/public/management/sections/settings/components/component_registry';
export { Field } from '../../../legacy/core_plugins/kibana/public/management/sections/settings/components/field/field';
export { management } from './sections_register';
export { MANAGEMENT_BREADCRUMB } from './breadcrumbs';