From f80f8887220ce89353117a2773ea0fd78bf83264 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 08:30:39 -0400 Subject: [PATCH 01/42] shimming NP for spaces client-side plugin --- x-pack/legacy/plugins/spaces/index.ts | 37 +------- .../spaces/public/hacks/init_np_plugin.ts | 15 ++++ x-pack/legacy/plugins/spaces/public/index.ts | 11 +++ .../legacy/plugins/spaces/public/lib/index.ts | 2 +- .../spaces/public/lib/spaces_manager.mock.ts | 1 + .../spaces/public/lib/spaces_manager.ts | 85 ++++++++++++------- .../legacy/plugins/spaces/public/plugin.tsx | 23 +++++ .../confirm_delete_modal.test.tsx.snap | 22 ----- .../components/confirm_delete_modal.test.tsx | 13 --- .../components/confirm_delete_modal.tsx | 23 +++-- .../edit_space/delete_spaces_button.test.tsx | 7 -- .../edit_space/delete_spaces_button.tsx | 9 +- .../edit_space/manage_space_page.test.tsx | 31 ++----- .../edit_space/manage_space_page.tsx | 33 ++++--- .../public/views/management/page_routes.tsx | 31 +++---- .../spaces_grid/spaces_grid_page.tsx | 9 +- .../spaces_grid/spaces_grid_pages.test.tsx | 18 +--- .../nav_control_popover.test.tsx.snap | 13 +-- .../spaces/public/views/nav_control/index.ts | 4 +- .../public/views/nav_control/nav_control.tsx | 82 ++++++------------ .../nav_control/nav_control_popover.test.tsx | 17 ++-- .../views/nav_control/nav_control_popover.tsx | 27 ++---- .../space_selector.test.tsx.snap | 16 +--- .../public/views/space_selector/index.tsx | 18 ++-- .../space_selector/space_selector.test.tsx | 36 +------- .../views/space_selector/space_selector.tsx | 16 ++-- .../api/__fixtures__/create_test_handler.ts | 2 +- .../server/routes/api/v1/spaces.test.ts | 30 +++++++ .../spaces/server/routes/api/v1/spaces.ts | 32 +++++++ 29 files changed, 292 insertions(+), 371 deletions(-) create mode 100644 x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts create mode 100644 x-pack/legacy/plugins/spaces/public/index.ts create mode 100644 x-pack/legacy/plugins/spaces/public/plugin.tsx diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index 4b6b238d20136..82df69091ab88 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -11,9 +11,6 @@ import { createOptionalPlugin } from '../../server/lib/optional_plugin'; // @ts-ignore import { AuditLogger } from '../../server/lib/audit_logger'; import mappings from './mappings.json'; -import { wrapError } from './server/lib/errors'; -import { getActiveSpace } from './server/lib/get_active_space'; -import { getSpaceSelectorUrl } from './server/lib/get_space_selector_url'; import { migrateToKibana660 } from './server/lib/migrations'; import { plugin } from './server/new_platform'; import { @@ -51,7 +48,6 @@ export const spaces = (kibana: Record) => }, uiExports: { - chromeNavControls: ['plugins/spaces/views/nav_control'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), managementSections: ['plugins/spaces/views/management'], apps: [ @@ -63,7 +59,7 @@ export const spaces = (kibana: Record) => hidden: true, }, ], - hacks: [], + hacks: ['plugins/spaces/hacks/init_np_plugin'], mappings, migrations: { space: { @@ -76,37 +72,6 @@ export const spaces = (kibana: Record) => }, }, home: ['plugins/spaces/register_feature'], - injectDefaultVars(server: any) { - return { - spaces: [], - activeSpace: null, - spaceSelectorURL: getSpaceSelectorUrl(server.config()), - }; - }, - async replaceInjectedVars( - vars: Record, - request: Record, - server: Record - ) { - const spacesClient = await server.plugins.spaces.getScopedSpacesClient(request); - try { - vars.activeSpace = { - valid: true, - space: await getActiveSpace( - spacesClient, - request.getBasePath(), - server.config().get('server.basePath') - ), - }; - } catch (e) { - vars.activeSpace = { - valid: false, - error: wrapError(e).output.payload, - }; - } - - return vars; - }, }, async init(server: Server) { diff --git a/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts b/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts new file mode 100644 index 0000000000000..b634ce73353d2 --- /dev/null +++ b/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { npSetup, npStart } from 'ui/new_platform'; +import { plugin } from '../index'; +import { Plugin } from '../plugin'; + +const spacesPlugin: Plugin = plugin({}); + +export const waitForSpacesNPInit = spacesPlugin + .start(npStart.core) + .then(() => spacesPlugin.setup(npSetup.core)); diff --git a/x-pack/legacy/plugins/spaces/public/index.ts b/x-pack/legacy/plugins/spaces/public/index.ts new file mode 100644 index 0000000000000..226f399b3b02f --- /dev/null +++ b/x-pack/legacy/plugins/spaces/public/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { PluginInitializerContext } from 'src/core/public'; +import { Plugin } from './plugin'; + +export const plugin = (initializerContext: PluginInitializerContext) => { + return new Plugin(initializerContext); +}; diff --git a/x-pack/legacy/plugins/spaces/public/lib/index.ts b/x-pack/legacy/plugins/spaces/public/lib/index.ts index 538dd77e053f5..243f85509c55c 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/index.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { SpacesManager } from './spaces_manager'; +export { SpacesManager, initSpacesManager, getSpacesManager } from './spaces_manager'; diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts index 7d4fb1b90fe11..80ed765121da2 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts @@ -10,6 +10,7 @@ function createSpacesManagerMock() { return ({ getSpaces: jest.fn().mockResolvedValue([]), getSpace: jest.fn().mockResolvedValue(undefined), + getActiveSpace: jest.fn().mockResolvedValue(undefined), createSpace: jest.fn().mockResolvedValue(undefined), updateSpace: jest.fn().mockResolvedValue(undefined), deleteSpace: jest.fn().mockResolvedValue(undefined), diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index cd2939f83e20b..48e97182691c6 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -4,58 +4,85 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { toastNotifications } from 'ui/notify'; import { EventEmitter } from 'events'; -import { kfetch } from 'ui/kfetch'; +import { NotificationsSetup, HttpSetup } from 'src/core/public'; import { Space } from '../../common/model/space'; +let spacesManager: SpacesManager | undefined; +export const initSpacesManager = ( + spaceSelectorUrl: string, + http: HttpSetup, + notifications: NotificationsSetup +) => { + if (spacesManager) { + throw new Error('SpacesManager has already been initialized!'); + } + spacesManager = new SpacesManager(spaceSelectorUrl, http, notifications); + return spacesManager; +}; + +export const getSpacesManager = () => { + if (!spacesManager) { + throw new Error('SpacesManager has not been initialized yet'); + } + + return spacesManager; +}; + export class SpacesManager extends EventEmitter { - private spaceSelectorURL: string; + private activeSpace: Space | undefined; - constructor(spaceSelectorURL: string) { + constructor( + private readonly spaceSelectorURL: string, + private readonly http: HttpSetup, + private readonly notifications: NotificationsSetup + ) { super(); - this.spaceSelectorURL = spaceSelectorURL; } public async getSpaces(): Promise { - return await kfetch({ pathname: '/api/spaces/space' }); + return await this.http.get('/api/spaces/space'); } public async getSpace(id: string): Promise { - return await kfetch({ pathname: `/api/spaces/space/${encodeURIComponent(id)}` }); + return await this.http.get(`/api/spaces/space/${encodeURIComponent(id)}`); + } + + public async getActiveSpace(): Promise { + if (!this.activeSpace) { + this.activeSpace = (await this.http.get('/api/spaces/v1/activeSpace')) as Space; + } + return this.activeSpace; } public async createSpace(space: Space) { - return await kfetch({ - pathname: `/api/spaces/space`, - method: 'POST', - body: JSON.stringify(space), - }); + return this.http + .post(`/api/spaces/space`, { + body: JSON.stringify(space), + }) + .then(() => this.requestRefresh()); } public async updateSpace(space: Space) { - return await kfetch({ - pathname: `/api/spaces/space/${encodeURIComponent(space.id)}`, - query: { - overwrite: true, - }, - method: 'PUT', - body: JSON.stringify(space), - }); + return this.http + .put(`/api/spaces/space/${encodeURIComponent(space.id)}`, { + query: { + overwrite: true, + }, + body: JSON.stringify(space), + }) + .then(() => this.requestRefresh()); } public async deleteSpace(space: Space) { - return await kfetch({ - pathname: `/api/spaces/space/${encodeURIComponent(space.id)}`, - method: 'DELETE', - }); + return this.http + .delete(`/api/spaces/space/${encodeURIComponent(space.id)}`) + .then(() => this.requestRefresh()); } public async changeSelectedSpace(space: Space) { - await kfetch({ - pathname: `/api/spaces/v1/space/${encodeURIComponent(space.id)}/select`, - method: 'POST', - }) + await this.http + .post(`/api/spaces/v1/space/${encodeURIComponent(space.id)}/select`) .then(response => { if (response.location) { window.location = response.location; @@ -75,7 +102,7 @@ export class SpacesManager extends EventEmitter { } public _displayError() { - toastNotifications.addDanger({ + this.notifications.toasts.addDanger({ title: i18n.translate('xpack.spaces.spacesManager.unableToChangeSpaceWarningTitle', { defaultMessage: 'Unable to change your Space', }), diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx new file mode 100644 index 0000000000000..6a9862c039fbd --- /dev/null +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginInitializerContext, CoreSetup, CoreStart } from 'src/core/public'; +import { initSpacesManager } from './lib'; +import { initSpacesNavControl } from './views/nav_control'; + +export class Plugin { + // @ts-ignore + constructor(private readonly initializerContext: PluginInitializerContext) {} + + public async start(core: CoreStart) { + const { spaceSelectorUrl } = await core.http.get('/api/spaces/v1/npStart'); + const spacesManager = initSpacesManager(spaceSelectorUrl, core.http, core.notifications); + + initSpacesNavControl(spacesManager, core); + } + + public async setup(core: CoreSetup) {} +} diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap index b3a491749f5a4..cae21995f9ab1 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap @@ -63,28 +63,6 @@ exports[`ConfirmDeleteModal renders as expected 1`] = ` value="" /> - - - - ( - - My Space - - ) - , - } - } - /> - - diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx index b34b52cd48c7a..a2245a2236707 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx @@ -6,7 +6,6 @@ import React from 'react'; import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { SpacesNavState } from '../../nav_control'; import { ConfirmDeleteModal } from './confirm_delete_modal'; import { spacesManagerMock } from '../../../lib/mocks'; @@ -20,11 +19,6 @@ describe('ConfirmDeleteModal', () => { const spacesManager = spacesManagerMock.create(); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; - const onCancel = jest.fn(); const onConfirm = jest.fn(); @@ -33,7 +27,6 @@ describe('ConfirmDeleteModal', () => { { const spacesManager = spacesManagerMock.create(); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; - const onCancel = jest.fn(); const onConfirm = jest.fn(); @@ -63,7 +51,6 @@ describe('ConfirmDeleteModal', () => { void; onConfirm: () => void; intl: InjectedIntl; @@ -41,6 +39,7 @@ interface State { confirmSpaceName: string; error: boolean | null; deleteInProgress: boolean; + isDeletingCurrentSpace: boolean; } class ConfirmDeleteModalUI extends Component { @@ -48,13 +47,23 @@ class ConfirmDeleteModalUI extends Component { confirmSpaceName: '', error: null, deleteInProgress: false, + isDeletingCurrentSpace: false, }; + public componentWillMount() { + isCurrentSpace(this.props.space, this.props.spacesManager).then(result => { + this.setState({ + isDeletingCurrentSpace: result, + }); + }); + } + public render() { - const { space, spacesNavState, onCancel, intl } = this.props; + const { space, onCancel, intl } = this.props; + const { isDeletingCurrentSpace } = this.state; let warning = null; - if (isDeletingCurrentSpace(space, spacesNavState)) { + if (isDeletingCurrentSpace) { const name = ( ({space.name}) @@ -182,7 +191,7 @@ class ConfirmDeleteModalUI extends Component { private onConfirm = async () => { if (this.state.confirmSpaceName === this.props.space.name) { - const needsRedirect = isDeletingCurrentSpace(this.props.space, this.props.spacesNavState); + const needsRedirect = this.state.isDeletingCurrentSpace; const spacesManager = this.props.spacesManager; this.setState({ @@ -206,8 +215,8 @@ class ConfirmDeleteModalUI extends Component { }; } -function isDeletingCurrentSpace(space: Space, spacesNavState: SpacesNavState) { - return space.id === spacesNavState.getActiveSpace().id; +async function isCurrentSpace(space: Space, spacesManager: SpacesManager) { + return space.id === (await spacesManager.getActiveSpace()).id; } export const ConfirmDeleteModal = injectI18n(ConfirmDeleteModalUI); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.test.tsx index 4a7f419bde82c..8f1f022038346 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.test.tsx @@ -6,7 +6,6 @@ import React from 'react'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { SpacesNavState } from '../../nav_control'; import { DeleteSpacesButton } from './delete_spaces_button'; import { spacesManagerMock } from '../../../lib/mocks'; @@ -20,16 +19,10 @@ describe('DeleteSpacesButton', () => { it('renders as expected', () => { const spacesManager = spacesManagerMock.create(); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; - const wrapper = shallowWithIntl( diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.tsx index 7f3dd0aea485e..216dd7c41f124 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/delete_spaces_button.tsx @@ -6,7 +6,6 @@ import { EuiButton, EuiButtonIcon, EuiButtonIconProps } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { SpacesNavState } from 'plugins/spaces/views/nav_control'; import React, { Component, Fragment } from 'react'; // @ts-ignore import { toastNotifications } from 'ui/notify'; @@ -18,7 +17,6 @@ interface Props { style?: 'button' | 'icon'; space: Space; spacesManager: SpacesManager; - spacesNavState: SpacesNavState; onDelete: () => void; intl: InjectedIntl; } @@ -81,12 +79,11 @@ class DeleteSpacesButtonUI extends Component { return null; } - const { spacesNavState, spacesManager } = this.props; + const { spacesManager } = this.props; return ( { this.setState({ @@ -99,7 +96,7 @@ class DeleteSpacesButtonUI extends Component { }; public deleteSpaces = async () => { - const { spacesManager, space, spacesNavState, intl } = this.props; + const { spacesManager, space, intl } = this.props; try { await spacesManager.deleteSpace(space); @@ -139,8 +136,6 @@ class DeleteSpacesButtonUI extends Component { if (this.props.onDelete) { this.props.onDelete(); } - - spacesNavState.refreshSpacesList(); }; } diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx index bf0e995858839..a6ff71ddba019 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx @@ -11,7 +11,6 @@ import { EuiButton, EuiLink, EuiSwitch } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { SpacesNavState } from '../../nav_control'; import { ConfirmAlterActiveSpaceModal } from './confirm_alter_active_space_modal'; import { ManageSpacePage } from './manage_space_page'; import { SectionPanel } from './section_panel'; @@ -27,18 +26,10 @@ describe('ManageSpacePage', () => { it('allows a space to be created', async () => { const spacesManager = spacesManagerMock.create(); spacesManager.createSpace = jest.fn(spacesManager.createSpace); - - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); const wrapper = mountWithIntl( - + ); await waitForDataLoad(wrapper); @@ -73,16 +64,12 @@ describe('ManageSpacePage', () => { initials: 'AB', disabledFeatures: [], }); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; const wrapper = mountWithIntl( ); @@ -119,16 +106,12 @@ describe('ManageSpacePage', () => { initials: 'AB', disabledFeatures: [], }); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; const wrapper = mountWithIntl( ); @@ -174,16 +157,12 @@ describe('ManageSpacePage', () => { initials: 'AB', disabledFeatures: [], }); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); - const spacesNavState: SpacesNavState = { - getActiveSpace: () => space, - refreshSpacesList: jest.fn(), - }; const wrapper = mountWithIntl( ); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx index 2ee860744fdda..804c1d73d8be7 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx @@ -16,7 +16,6 @@ import { } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import _ from 'lodash'; -import { SpacesNavState } from 'plugins/spaces/views/nav_control'; import React, { Component, Fragment } from 'react'; import { capabilities } from 'ui/capabilities'; import { Breadcrumb } from 'ui/chrome'; @@ -39,7 +38,6 @@ import { ReservedSpaceBadge } from './reserved_space_badge'; interface Props { spacesManager: SpacesManager; spaceId?: string; - spacesNavState: SpacesNavState; intl: InjectedIntl; setBreadcrumbs?: (breadcrumbs: Breadcrumb[]) => void; } @@ -269,7 +267,6 @@ class ManageSpacePageUI extends Component { data-test-subj="delete-space-button" space={this.state.space as Space} spacesManager={this.props.spacesManager} - spacesNavState={this.props.spacesNavState} onDelete={this.backToSpacesList} /> @@ -298,27 +295,30 @@ class ManageSpacePageUI extends Component { } if (this.editingExistingSpace()) { - const { spacesNavState } = this.props; + const { spacesManager } = this.props; const originalSpace: Space = this.state.originalSpace as Space; const space: Space = this.state.space as Space; - const editingActiveSpace = spacesNavState.getActiveSpace().id === originalSpace.id; + spacesManager.getActiveSpace().then(activeSpace => { + const editingActiveSpace = activeSpace.id === originalSpace.id; - const haveDisabledFeaturesChanged = - space.disabledFeatures.length !== originalSpace.disabledFeatures.length || - _.difference(space.disabledFeatures, originalSpace.disabledFeatures).length > 0; + const haveDisabledFeaturesChanged = + space.disabledFeatures.length !== originalSpace.disabledFeatures.length || + _.difference(space.disabledFeatures, originalSpace.disabledFeatures).length > 0; - if (editingActiveSpace && haveDisabledFeaturesChanged) { - this.setState({ - showAlteringActiveSpaceDialog: true, - }); + if (editingActiveSpace && haveDisabledFeaturesChanged) { + this.setState({ + showAlteringActiveSpaceDialog: true, + }); - return; - } + return; + } + this.performSave(); + }); + } else { + this.performSave(); } - - this.performSave(); }; private performSave = (requireRefresh = false) => { @@ -356,7 +356,6 @@ class ManageSpacePageUI extends Component { action .then(() => { - this.props.spacesNavState.refreshSpacesList(); toastNotifications.addSuccess( intl.formatMessage( { diff --git a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx index d38c5c1998b3a..2a8c2a41531e7 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx @@ -5,32 +5,34 @@ */ // @ts-ignore import template from 'plugins/spaces/views/management/template.html'; -import { SpacesNavState } from 'plugins/spaces/views/nav_control'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import 'ui/autoload/styles'; import { I18nContext } from 'ui/i18n'; // @ts-ignore import routes from 'ui/routes'; -import { SpacesManager } from '../../lib/spaces_manager'; +import { getSpacesManager } from '../../lib/spaces_manager'; import { ManageSpacePage } from './edit_space'; import { getCreateBreadcrumbs, getEditBreadcrumbs, getListBreadcrumbs } from './lib'; import { SpacesGridPage } from './spaces_grid'; + +import { waitForSpacesNPInit } from '../../hacks/init_np_plugin'; + const reactRootNodeId = 'manageSpacesReactRoot'; routes.when('/management/spaces/list', { template, k7Breadcrumbs: getListBreadcrumbs, requireUICapability: 'management.kibana.spaces', - controller($scope: any, spacesNavState: SpacesNavState, spaceSelectorURL: string) { + controller($scope: any) { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); - const spacesManager = new SpacesManager(spaceSelectorURL); + await waitForSpacesNPInit; render( - + , domNode ); @@ -49,15 +51,15 @@ routes.when('/management/spaces/create', { template, k7Breadcrumbs: getCreateBreadcrumbs, requireUICapability: 'management.kibana.spaces', - controller($scope: any, spacesNavState: SpacesNavState, spaceSelectorURL: string) { + controller($scope: any) { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); - const spacesManager = new SpacesManager(spaceSelectorURL); + await waitForSpacesNPInit; render( - + , domNode ); @@ -80,26 +82,19 @@ routes.when('/management/spaces/edit/:spaceId', { template, k7Breadcrumbs: () => getEditBreadcrumbs(), requireUICapability: 'management.kibana.spaces', - controller( - $scope: any, - $route: any, - chrome: any, - spacesNavState: SpacesNavState, - spaceSelectorURL: string - ) { + controller($scope: any, $route: any, chrome: any) { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); const { spaceId } = $route.current.params; - const spacesManager = new SpacesManager(spaceSelectorURL); + await waitForSpacesNPInit; render( { chrome.breadcrumbs.set(breadcrumbs); }} diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx index 803b786b2a5b6..e572230f2cfc0 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx @@ -30,7 +30,6 @@ import { Space } from '../../../../common/model/space'; import { SpaceAvatar } from '../../../components'; import { getSpacesFeatureDescription } from '../../../lib/constants'; import { SpacesManager } from '../../../lib/spaces_manager'; -import { SpacesNavState } from '../../nav_control'; import { ConfirmDeleteModal } from '../components/confirm_delete_modal'; import { SecureSpaceMessage } from '../components/secure_space_message'; import { UnauthorizedPrompt } from '../components/unauthorized_prompt'; @@ -38,7 +37,6 @@ import { getEnabledFeatures } from '../lib/feature_utils'; interface Props { spacesManager: SpacesManager; - spacesNavState: SpacesNavState; intl: InjectedIntl; } @@ -158,12 +156,11 @@ class SpacesGridPageUI extends Component { return null; } - const { spacesNavState, spacesManager } = this.props; + const { spacesManager } = this.props; return ( { this.setState({ @@ -177,7 +174,7 @@ class SpacesGridPageUI extends Component { public deleteSpace = async () => { const { intl } = this.props; - const { spacesManager, spacesNavState } = this.props; + const { spacesManager } = this.props; const space = this.state.selectedSpace; @@ -220,8 +217,6 @@ class SpacesGridPageUI extends Component { ); toastNotifications.addSuccess(message); - - spacesNavState.refreshSpacesList(); }; public loadGrid = async () => { diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx index a59ad8084de22..c8ae846adb9e7 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx @@ -11,7 +11,6 @@ import React from 'react'; import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { SpaceAvatar } from '../../../components'; import { spacesManagerMock } from '../../../lib/mocks'; -import { SpacesNavState } from '../../nav_control'; import { SpacesGridPage } from './spaces_grid_page'; const spaces = [ @@ -36,11 +35,6 @@ const spaces = [ }, ]; -const spacesNavState: SpacesNavState = { - getActiveSpace: () => spaces[0], - refreshSpacesList: jest.fn(), -}; - const spacesManager = spacesManagerMock.create(); spacesManager.getSpaces = jest.fn().mockResolvedValue(spaces); @@ -48,22 +42,14 @@ describe('SpacesGridPage', () => { it('renders as expected', () => { expect( shallowWithIntl( - + ) ).toMatchSnapshot(); }); it('renders the list of spaces', async () => { const wrapper = mountWithIntl( - + ); // allow spacesManager to load spaces diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap index fdebc42496002..a1288f3b9ae28 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap @@ -6,20 +6,13 @@ exports[`NavControlPopover renders without crashing 1`] = ` button={ } - linkTitle="foo" + linkTitle="loading" spaceSelectorShown={false} toggleSpaceSelector={[Function]} /> diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/index.ts b/x-pack/legacy/plugins/spaces/public/views/nav_control/index.ts index 541c79a8fd4a3..649aeee9eab9e 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/index.ts +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/index.ts @@ -4,6 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import './nav_control'; - -export { SpacesNavState } from './nav_control'; +export { initSpacesNavControl } from './nav_control'; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx index ad2ae08374708..3ecb6662e7d63 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx @@ -5,69 +5,37 @@ */ import { SpacesManager } from 'plugins/spaces/lib/spaces_manager'; -// @ts-ignore -import template from 'plugins/spaces/views/nav_control/nav_control.html'; import { NavControlPopover } from 'plugins/spaces/views/nav_control/nav_control_popover'; // @ts-ignore import { Path } from 'plugins/xpack_main/services/path'; import React from 'react'; import ReactDOM from 'react-dom'; -import { I18nContext } from 'ui/i18n'; -// @ts-ignore -import { uiModules } from 'ui/modules'; -import { - chromeHeaderNavControlsRegistry, - NavControlSide, -} from 'ui/registry/chrome_header_nav_controls'; -// @ts-ignore -import { Space } from '../../../common/model/space'; +import { CoreStart } from 'src/core/public'; import { SpacesHeaderNavButton } from './components/spaces_header_nav_button'; -const module = uiModules.get('spaces_nav', ['kibana']); - -export interface SpacesNavState { - getActiveSpace: () => Space; - refreshSpacesList: () => void; -} - -let spacesManager: SpacesManager; - -module.service('spacesNavState', (activeSpace: any) => { - return { - getActiveSpace: () => { - return activeSpace.space; - }, - refreshSpacesList: () => { - if (spacesManager) { - spacesManager.requestRefresh(); +export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreStart) { + const I18nContext = core.i18n.Context; + core.chrome.navControls.registerLeft({ + order: 1000, + mount(targetDomElement: HTMLElement) { + if (Path.isUnauthenticated()) { + return () => null; } - }, - } as SpacesNavState; -}); - -chromeHeaderNavControlsRegistry.register((chrome: any, activeSpace: any) => ({ - name: 'spaces', - order: 1000, - side: NavControlSide.Left, - render(el: HTMLElement) { - if (Path.isUnauthenticated()) { - return; - } - - const spaceSelectorURL = chrome.getInjected('spaceSelectorURL'); - spacesManager = new SpacesManager(spaceSelectorURL); - - ReactDOM.render( - - - , - el - ); - }, -})); + ReactDOM.render( + + + , + targetDomElement + ); + + return () => { + ReactDOM.unmountComponentAtNode(targetDomElement); + }; + }, + }); +} diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx index c30433fb3bf08..666126e1355a6 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx @@ -13,16 +13,10 @@ import { NavControlPopover } from './nav_control_popover'; describe('NavControlPopover', () => { it('renders without crashing', () => { - const activeSpace = { - space: { id: '', name: 'foo', disabledFeatures: [] }, - valid: true, - }; - const spacesManager = spacesManagerMock.create(); const wrapper = shallow( { }); it('renders a SpaceAvatar with the active space', async () => { - const activeSpace = { - space: { id: 'foo-space', name: 'foo', disabledFeatures: [] }, - valid: true, - }; - const spacesManager = spacesManagerMock.create(); spacesManager.getSpaces = jest.fn().mockResolvedValue([ { @@ -50,10 +39,14 @@ describe('NavControlPopover', () => { disabledFeatures: [], }, ]); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue({ + id: 'foo-space', + name: 'foo', + disabledFeatures: [], + }); const wrapper = mount( ; } @@ -37,7 +32,7 @@ export class NavControlPopover extends Component { this.state = { showSpaceSelector: false, loading: false, - activeSpace: props.activeSpace.space, + activeSpace: null, spaces: [], }; } @@ -91,24 +86,20 @@ export class NavControlPopover extends Component { } private async loadSpaces() { - const { spacesManager, activeSpace } = this.props; + const { spacesManager } = this.props; this.setState({ loading: true, }); - const spaces = await spacesManager.getSpaces(); - - // Update the active space definition, if it changed since the last load operation - let activeSpaceEntry: Space | null = activeSpace.space; - - if (activeSpace.valid) { - activeSpaceEntry = spaces.find(space => space.id === this.props.activeSpace.space.id) || null; - } + const [activeSpace, spaces] = await Promise.all([ + spacesManager.getActiveSpace(), + spacesManager.getSpaces(), + ]); this.setState({ spaces, - activeSpace: activeSpaceEntry, + activeSpace, loading: false, }); } @@ -118,8 +109,8 @@ export class NavControlPopover extends Component { if (!activeSpace) { return this.getButton( - , - 'error' + , + 'loading' ); } diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/__snapshots__/space_selector.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/space_selector/__snapshots__/space_selector.test.tsx.snap index 84ed864c36231..1516157188cc6 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/__snapshots__/space_selector.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/__snapshots__/space_selector.test.tsx.snap @@ -62,21 +62,9 @@ exports[`it renders without crashing 1`] = ` - - - - - diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx index 935e79e73517e..c731454bbb351 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SpacesManager } from 'plugins/spaces/lib/spaces_manager'; +import { getSpacesManager } from 'plugins/spaces/lib/spaces_manager'; // @ts-ignore import template from 'plugins/spaces/views/space_selector/space_selector.html'; import 'ui/autoload/styles'; @@ -15,20 +15,20 @@ import { uiModules } from 'ui/modules'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { Space } from '../../../common/model/space'; import { SpaceSelector } from './space_selector'; +import { waitForSpacesNPInit } from '../../hacks/init_np_plugin'; + const module = uiModules.get('spaces_selector', []); -module.controller( - 'spacesSelectorController', - ($scope: any, spaces: Space[], spaceSelectorURL: string) => { +module.controller('spacesSelectorController', ($scope: any) => { + $scope.$$postDigest(async () => { const domNode = document.getElementById('spaceSelectorRoot'); - const spacesManager = new SpacesManager(spaceSelectorURL); + await waitForSpacesNPInit; render( - + , domNode ); @@ -39,7 +39,7 @@ module.controller( unmountComponentAtNode(domNode); } }); - } -); + }); +}); chrome.setVisible(false).setRootTemplate(template); diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.test.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.test.tsx index 78779e38713db..829312061ca98 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.test.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { renderWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import { Space } from '../../../common/model/space'; import { spacesManagerMock } from '../../lib/mocks'; import { SpaceSelector } from './space_selector'; @@ -19,42 +19,12 @@ function getSpacesManager(spaces: Space[] = []) { test('it renders without crashing', () => { const spacesManager = getSpacesManager(); const component = shallowWithIntl( - + ); expect(component).toMatchSnapshot(); }); -test('it uses the spaces on props, when provided', () => { - const spacesManager = getSpacesManager(); - - const spaces = [ - { - id: 'space-1', - name: 'Space 1', - description: 'This is the first space', - disabledFeatures: [], - }, - ]; - - const component = renderWithIntl( - - ); - - return Promise.resolve().then(() => { - expect(component.find('.spaceCard')).toHaveLength(1); - expect(spacesManager.getSpaces).toHaveBeenCalledTimes(0); - }); -}); - -test('it queries for spaces when not provided on props', () => { +test('it queries for spaces when loaded', () => { const spaces = [ { id: 'space-1', diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx index 776e5f848296f..2b91649c3a1f4 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx @@ -16,6 +16,7 @@ import { EuiSpacer, EuiText, EuiTitle, + EuiLoadingSpinner, } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import { SpacesManager } from 'plugins/spaces/lib'; @@ -25,7 +26,6 @@ import { Space } from '../../../common/model/space'; import { SpaceCards } from '../components/space_cards'; interface Props { - spaces?: Space[]; spacesManager: SpacesManager; intl: InjectedIntl; } @@ -47,10 +47,6 @@ class SpaceSelectorUI extends Component { spaces: [], }; - if (Array.isArray(props.spaces)) { - state.spaces = [...props.spaces]; - } - this.state = state; } @@ -130,9 +126,13 @@ class SpaceSelectorUI extends Component { - + {this.state.loading && } + + {!this.state.loading && ( + + )} - {filteredSpaces.length === 0 && ( + {!this.state.loading && filteredSpaces.length === 0 && ( { public getSearchField = () => { const { intl } = this.props; - if (!this.props.spaces || this.props.spaces.length < SPACE_SEARCH_COUNT_THRESHOLD) { + if (!this.state.spaces || this.state.spaces.length < SPACE_SEARCH_COUNT_THRESHOLD) { return null; } return ( diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts b/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts index f84194160971d..e7607a9a14e04 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts @@ -182,7 +182,7 @@ export function createTestHandler( initApiFn({ http: ({ - server, + ...httpServiceMock.createSetupContract(), route: server.route.bind(server), } as unknown) as SpacesHttpServiceSetup, routePreCheckLicenseFn: pre, diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts index 4d9952f4ab3dc..2f21e338dad96 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts @@ -41,6 +41,36 @@ describe('Spaces API', () => { await Promise.all(teardowns.splice(0).map(fn => fn())); }); + test('GET /npStart should return the space selector URL', async () => { + const { response } = await request('GET', '/api/spaces/v1/npStart', { + expectSpacesClientCall: false, + }); + + const { statusCode, payload } = response; + + expect(statusCode).toEqual(200); + + const result = JSON.parse(payload); + expect(result).toEqual({ + spaceSelectorUrl: '/', + }); + }); + + test('GET /activeSpace should return the active space', async () => { + const { response } = await request('GET', '/api/spaces/v1/activeSpace'); + + const { statusCode, payload } = response; + + expect(statusCode).toEqual(200); + + const result = JSON.parse(payload); + expect(result).toEqual({ + id: 'default', + name: 'Default Space', + _reserved: true, + }); + }); + test('POST space/{id}/select should respond with the new space location', async () => { const { response } = await request('POST', '/api/spaces/v1/space/a-space/select'); diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.ts b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.ts index 8765bd635a45a..c79827978a5b2 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.ts @@ -5,16 +5,48 @@ */ import Boom from 'boom'; +import { Legacy } from 'kibana'; import { Space } from '../../../../common/model/space'; import { wrapError } from '../../../lib/errors'; import { SpacesClient } from '../../../lib/spaces_client'; import { addSpaceIdToPath } from '../../../lib/spaces_url_parser'; import { getSpaceById } from '../../lib'; import { InternalRouteDeps } from '.'; +import { getActiveSpace } from '../../../lib/get_active_space'; +import { getSpaceSelectorUrl } from '../../../lib/get_space_selector_url'; export function initInternalSpacesApi(deps: InternalRouteDeps) { const { http, config, spacesService, savedObjects, routePreCheckLicenseFn } = deps; + http.route({ + method: 'GET', + path: '/api/spaces/v1/activeSpace', + async handler(request: Legacy.Request) { + const spacesClient: SpacesClient = await spacesService.scopedClient(request); + return await getActiveSpace( + spacesClient, + http.basePath.get(request), + config.get('server.basePath') + ); + }, + options: { + pre: [routePreCheckLicenseFn], + }, + }); + + http.route({ + method: 'GET', + path: '/api/spaces/v1/npStart', + async handler() { + return { + spaceSelectorUrl: getSpaceSelectorUrl(config), + }; + }, + options: { + pre: [routePreCheckLicenseFn], + }, + }); + http.route({ method: 'POST', path: '/api/spaces/v1/space/{id}/select', From 452d592b598cfa511afd207ac2d790ea23bfcccc Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 08:58:40 -0400 Subject: [PATCH 02/42] refresh active space in nav control when updated --- x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts | 4 ++-- .../spaces/public/views/nav_control/nav_control_popover.tsx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index 48e97182691c6..6b41afbcb62d0 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -48,8 +48,8 @@ export class SpacesManager extends EventEmitter { return await this.http.get(`/api/spaces/space/${encodeURIComponent(id)}`); } - public async getActiveSpace(): Promise { - if (!this.activeSpace) { + public async getActiveSpace(forceRefresh: boolean = false): Promise { + if (!this.activeSpace || forceRefresh) { this.activeSpace = (await this.http.get('/api/spaces/v1/activeSpace')) as Space; } return this.activeSpace; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx index dca9e843021ed..5f0284401e977 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx @@ -42,7 +42,7 @@ export class NavControlPopover extends Component { if (this.props.spacesManager) { this.props.spacesManager.on('request_refresh', () => { - this.loadSpaces(); + this.loadSpaces(true); }); } } @@ -85,7 +85,7 @@ export class NavControlPopover extends Component { ); } - private async loadSpaces() { + private async loadSpaces(refreshActiveSpace: boolean = false) { const { spacesManager } = this.props; this.setState({ @@ -93,7 +93,7 @@ export class NavControlPopover extends Component { }); const [activeSpace, spaces] = await Promise.all([ - spacesManager.getActiveSpace(), + spacesManager.getActiveSpace(refreshActiveSpace), spacesManager.getSpaces(), ]); From b41073c9192b7446679b90a27fcd9843e3bf1b8e Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 11:04:55 -0400 Subject: [PATCH 03/42] fix advanced settings screen --- .../advanced_settings_subtitle.test.tsx.snap | 29 ---------- .../advanced_settings_subtitle.test.tsx | 17 ++++-- .../advanced_settings_subtitle.tsx | 54 +++++++++++-------- .../advanced_settings_title.test.tsx.snap | 45 ---------------- .../advanced_settings_title.test.tsx | 15 ++++-- .../advanced_settings_title.tsx | 48 ++++++++++------- .../spaces/public/views/management/index.tsx | 13 +++-- .../public/components/telemetry_form.js | 1 - .../public/views/management/management.js | 6 +-- 9 files changed, 98 insertions(+), 130 deletions(-) delete mode 100644 x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap delete mode 100644 x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_title/__snapshots__/advanced_settings_title.test.tsx.snap diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap deleted file mode 100644 index 69d1011de3c55..0000000000000 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AdvancedSettingsSubtitle renders as expected 1`] = ` - - - - - My Space - , - } - } - /> -
{ spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); const wrapper = mountWithIntl( - + ); await waitForDataLoad(wrapper); @@ -71,6 +80,12 @@ describe('ManageSpacePage', () => { spaceId={'existing-space'} spacesManager={spacesManager} intl={null as any} + capabilities={{ + navLinks: {}, + management: {}, + catalogue: {}, + spaces: { manage: false }, + }} /> ); @@ -113,6 +128,12 @@ describe('ManageSpacePage', () => { spaceId={'my-space'} spacesManager={spacesManager} intl={null as any} + capabilities={{ + navLinks: {}, + management: {}, + catalogue: {}, + spaces: { manage: false }, + }} /> ); @@ -164,6 +185,12 @@ describe('ManageSpacePage', () => { spaceId={'my-space'} spacesManager={spacesManager} intl={null as any} + capabilities={{ + navLinks: {}, + management: {}, + catalogue: {}, + spaces: { manage: false }, + }} /> ); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx index 804c1d73d8be7..76b6db8c70783 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.tsx @@ -17,10 +17,10 @@ import { import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import _ from 'lodash'; import React, { Component, Fragment } from 'react'; -import { capabilities } from 'ui/capabilities'; import { Breadcrumb } from 'ui/chrome'; import { kfetch } from 'ui/kfetch'; import { toastNotifications } from 'ui/notify'; +import { Capabilities } from 'src/core/public'; import { Feature } from '../../../../../xpack_main/types'; import { isReservedSpace } from '../../../../common'; import { Space } from '../../../../common/model/space'; @@ -40,6 +40,7 @@ interface Props { spaceId?: string; intl: InjectedIntl; setBreadcrumbs?: (breadcrumbs: Breadcrumb[]) => void; + capabilities: Capabilities; } interface State { @@ -71,7 +72,7 @@ class ManageSpacePageUI extends Component { } public async componentDidMount() { - if (!capabilities.get().spaces.manage) { + if (!this.props.capabilities.spaces.manage) { return; } @@ -137,7 +138,7 @@ class ManageSpacePageUI extends Component { ); public getForm = () => { - if (!capabilities.get().spaces.manage) { + if (!this.props.capabilities.spaces.manage) { return ; } @@ -171,7 +172,7 @@ class ManageSpacePageUI extends Component { @@ -214,7 +215,7 @@ class ManageSpacePageUI extends Component { public maybeGetSecureSpacesMessage = () => { if (this.editingExistingSpace()) { - return ; + return ; } return null; }; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx index 2a8c2a41531e7..1a0ed7811bd18 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx @@ -11,6 +11,7 @@ import 'ui/autoload/styles'; import { I18nContext } from 'ui/i18n'; // @ts-ignore import routes from 'ui/routes'; +import { npStart } from 'ui/new_platform'; import { getSpacesManager } from '../../lib/spaces_manager'; import { ManageSpacePage } from './edit_space'; import { getCreateBreadcrumbs, getEditBreadcrumbs, getListBreadcrumbs } from './lib'; @@ -32,7 +33,10 @@ routes.when('/management/spaces/list', { render( - + , domNode ); @@ -59,7 +63,10 @@ routes.when('/management/spaces/create', { render( - + , domNode ); @@ -82,7 +89,7 @@ routes.when('/management/spaces/edit/:spaceId', { template, k7Breadcrumbs: () => getEditBreadcrumbs(), requireUICapability: 'management.kibana.spaces', - controller($scope: any, $route: any, chrome: any) { + controller($scope: any, $route: any) { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); @@ -95,9 +102,8 @@ routes.when('/management/spaces/edit/:spaceId', { { - chrome.breadcrumbs.set(breadcrumbs); - }} + setBreadcrumbs={npStart.core.chrome.setBreadcrumbs} + capabilities={npStart.core.application.capabilities} /> , domNode diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap index cfe14ea07b010..d820773dcdfa1 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap @@ -128,7 +128,18 @@ exports[`SpacesGridPage renders as expected 1`] = ` sorting={false} /> - + `; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx index e572230f2cfc0..d34b7fd9a01b9 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx @@ -19,10 +19,10 @@ import { EuiTitle, } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { capabilities } from 'ui/capabilities'; import { kfetch } from 'ui/kfetch'; // @ts-ignore import { toastNotifications } from 'ui/notify'; +import { Capabilities } from 'src/core/public'; import { Feature } from '../../../../../xpack_main/types'; import { isReservedSpace } from '../../../../common'; import { DEFAULT_SPACE_ID } from '../../../../common/constants'; @@ -38,6 +38,7 @@ import { getEnabledFeatures } from '../lib/feature_utils'; interface Props { spacesManager: SpacesManager; intl: InjectedIntl; + capabilities: Capabilities; } interface State { @@ -63,7 +64,7 @@ class SpacesGridPageUI extends Component { } public componentDidMount() { - if (capabilities.get().spaces.manage) { + if (this.props.capabilities.spaces.manage) { this.loadGrid(); } } @@ -72,7 +73,7 @@ class SpacesGridPageUI extends Component { return ( {this.getPageContent()} - + {this.getConfirmDeleteModal()} ); @@ -81,7 +82,7 @@ class SpacesGridPageUI extends Component { public getPageContent() { const { intl } = this.props; - if (!capabilities.get().spaces.manage) { + if (!this.props.capabilities.spaces.manage) { return ; } diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx index c8ae846adb9e7..42e1b2bd50a81 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx @@ -42,14 +42,32 @@ describe('SpacesGridPage', () => { it('renders as expected', () => { expect( shallowWithIntl( - + ) ).toMatchSnapshot(); }); it('renders the list of spaces', async () => { const wrapper = mountWithIntl( - + ); // allow spacesManager to load spaces diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap index a1288f3b9ae28..1d704161397c5 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap @@ -28,6 +28,16 @@ exports[`NavControlPopover renders without crashing 1`] = ` withTitle={true} > diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/__snapshots__/spaces_description.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/__snapshots__/spaces_description.test.tsx.snap index 8cce2a376746a..079dab701cc1d 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/__snapshots__/spaces_description.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/__snapshots__/spaces_description.test.tsx.snap @@ -19,6 +19,16 @@ exports[`SpacesDescription renders without crashing 1`] = ` key="manageSpacesButton" > { it('renders without crashing', () => { - expect(shallow()).toMatchSnapshot(); + expect( + shallow( + + ) + ).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_description.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_description.tsx index fe071dba25467..c083b1fc96cff 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_description.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_description.tsx @@ -6,11 +6,13 @@ import { EuiContextMenuPanel, EuiText } from '@elastic/eui'; import React, { SFC } from 'react'; +import { Capabilities } from 'src/core/public'; import { ManageSpacesButton } from '../../../components'; import { getSpacesFeatureDescription } from '../../../lib/constants'; interface Props { onManageSpacesClick: () => void; + capabilities: Capabilities; } export const SpacesDescription: SFC = (props: Props) => { @@ -29,6 +31,7 @@ export const SpacesDescription: SFC = (props: Props) => { size="s" style={{ width: `100%` }} onClick={props.onManageSpacesClick} + capabilities={props.capabilities} /> diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx index 76a47ca738627..5db0c03d466cf 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx @@ -7,6 +7,7 @@ import { EuiContextMenuItem, EuiContextMenuPanel, EuiFieldSearch, EuiText } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React, { Component } from 'react'; +import { Capabilities } from 'src/core/public'; import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../../common/constants'; import { Space } from '../../../../common/model/space'; import { ManageSpacesButton, SpaceAvatar } from '../../../components'; @@ -16,6 +17,7 @@ interface Props { onSelectSpace: (space: Space) => void; onManageSpacesClick: () => void; intl: InjectedIntl; + capabilities: Capabilities; } interface State { @@ -151,6 +153,7 @@ class SpacesMenuUI extends Component { className="spcMenu__manageButton" size="s" onClick={this.props.onManageSpacesClick} + capabilities={this.props.capabilities} /> ); }; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx index 3ecb6662e7d63..5ff3571e169c0 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx @@ -28,6 +28,7 @@ export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreSta spacesManager={spacesManager} anchorPosition="downLeft" buttonClass={SpacesHeaderNavButton} + capabilities={core.application.capabilities} /> , targetDomElement diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx index 666126e1355a6..633ca44356cb9 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx @@ -20,6 +20,7 @@ describe('NavControlPopover', () => { spacesManager={spacesManager} anchorPosition={'downRight'} buttonClass={SpacesHeaderNavButton} + capabilities={{ navLinks: {}, management: {}, catalogue: {}, spaces: { manage: true } }} /> ); expect(wrapper).toMatchSnapshot(); @@ -50,6 +51,7 @@ describe('NavControlPopover', () => { spacesManager={spacesManager} anchorPosition={'rightCenter'} buttonClass={SpacesHeaderNavButton} + capabilities={{ navLinks: {}, management: {}, catalogue: {}, spaces: { manage: true } }} /> ); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx index 5f0284401e977..62a69252f1cd7 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx @@ -6,6 +6,7 @@ import { EuiAvatar, EuiPopover, PopoverAnchorPosition } from '@elastic/eui'; import React, { Component, ComponentClass } from 'react'; +import { Capabilities } from 'src/core/public'; import { Space } from '../../../common/model/space'; import { SpaceAvatar } from '../../components'; import { SpacesManager } from '../../lib/spaces_manager'; @@ -17,6 +18,7 @@ interface Props { spacesManager: SpacesManager; anchorPosition: PopoverAnchorPosition; buttonClass: ComponentClass; + capabilities: Capabilities; } interface State { @@ -55,13 +57,19 @@ export class NavControlPopover extends Component { let element: React.ReactNode; if (this.state.spaces.length < 2) { - element = ; + element = ( + + ); } else { element = ( ); } diff --git a/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts b/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts index fb9c8a85a4e2e..45d1266a0de4f 100644 --- a/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts +++ b/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UICapabilities } from 'ui/capabilities'; import { Feature } from '../../../xpack_main/types'; import { Space } from '../../common/model/space'; import { toggleUICapabilities } from './toggle_ui_capabilities'; +import { Capabilities } from 'src/core/public'; const features: Feature[] = [ { @@ -58,7 +58,7 @@ const features: Feature[] = [ }, ]; -const buildUiCapabilities = () => +const buildCapabilities = () => Object.freeze({ navLinks: { feature1: true, @@ -89,7 +89,7 @@ const buildUiCapabilities = () => foo: true, bar: true, }, - }) as UICapabilities; + }) as Capabilities; describe('toggleUiCapabilities', () => { it('does not toggle capabilities when the space has no disabled features', () => { @@ -99,9 +99,9 @@ describe('toggleUiCapabilities', () => { disabledFeatures: [], }; - const uiCapabilities: UICapabilities = buildUiCapabilities(); - const result = toggleUICapabilities(features, uiCapabilities, space); - expect(result).toEqual(buildUiCapabilities()); + const capabilities: Capabilities = buildCapabilities(); + const result = toggleUICapabilities(features, capabilities, space); + expect(result).toEqual(buildCapabilities()); }); it('ignores unknown disabledFeatures', () => { @@ -111,9 +111,9 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['i-do-not-exist'], }; - const uiCapabilities: UICapabilities = buildUiCapabilities(); - const result = toggleUICapabilities(features, uiCapabilities, space); - expect(result).toEqual(buildUiCapabilities()); + const capabilities: Capabilities = buildCapabilities(); + const result = toggleUICapabilities(features, capabilities, space); + expect(result).toEqual(buildCapabilities()); }); it('disables the corresponding navLink, catalogue, management sections, and all capability flags for disabled features', () => { @@ -123,10 +123,10 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['feature_2'], }; - const uiCapabilities: UICapabilities = buildUiCapabilities(); - const result = toggleUICapabilities(features, uiCapabilities, space); + const capabilities: Capabilities = buildCapabilities(); + const result = toggleUICapabilities(features, capabilities, space); - const expectedCapabilities = buildUiCapabilities(); + const expectedCapabilities = buildCapabilities(); expectedCapabilities.navLinks.feature2 = false; expectedCapabilities.catalogue.feature2Entry = false; @@ -144,10 +144,10 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['feature_1', 'feature_2', 'feature_3'], }; - const uiCapabilities: UICapabilities = buildUiCapabilities(); - const result = toggleUICapabilities(features, uiCapabilities, space); + const capabilities: Capabilities = buildCapabilities(); + const result = toggleUICapabilities(features, capabilities, space); - const expectedCapabilities = buildUiCapabilities(); + const expectedCapabilities = buildCapabilities(); expectedCapabilities.feature_1.bar = false; expectedCapabilities.feature_1.foo = false; diff --git a/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.ts b/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.ts index 4cec018959ab3..1cdb8df5c9169 100644 --- a/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.ts +++ b/x-pack/legacy/plugins/spaces/server/lib/toggle_ui_capabilities.ts @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ import _ from 'lodash'; -import { UICapabilities } from 'ui/capabilities'; +import { Capabilities } from 'src/core/public'; import { Feature } from '../../../xpack_main/types'; import { Space } from '../../common/model/space'; export function toggleUICapabilities( features: Feature[], - uiCapabilities: UICapabilities, + capabilities: Capabilities, activeSpace: Space ) { - const clonedCapabilities = _.cloneDeep(uiCapabilities); + const clonedCapabilities = _.cloneDeep(capabilities); toggleDisabledFeatures(features, clonedCapabilities, activeSpace); @@ -22,7 +22,7 @@ export function toggleUICapabilities( function toggleDisabledFeatures( features: Feature[], - uiCapabilities: UICapabilities, + capabilities: Capabilities, activeSpace: Space ) { const disabledFeatureKeys: string[] = activeSpace.disabledFeatures; @@ -31,9 +31,9 @@ function toggleDisabledFeatures( .map(key => features.find(feature => feature.id === key)) .filter(feature => typeof feature !== 'undefined') as Feature[]; - const navLinks: Record = uiCapabilities.navLinks; - const catalogueEntries: Record = uiCapabilities.catalogue; - const managementItems: Record> = uiCapabilities.management; + const navLinks: Record = capabilities.navLinks; + const catalogueEntries: Record = capabilities.catalogue; + const managementItems: Record> = capabilities.management; for (const feature of disabledFeatures) { // Disable associated navLink, if one exists @@ -61,8 +61,8 @@ function toggleDisabledFeatures( }); // Disable "sub features" that match the disabled feature - if (uiCapabilities.hasOwnProperty(feature.id)) { - const capability = uiCapabilities[feature.id]; + if (capabilities.hasOwnProperty(feature.id)) { + const capability = capabilities[feature.id]; Object.keys(capability).forEach(featureKey => { capability[featureKey] = false; }); From aed3888906ca5bc996b85942675670e447875271 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 14:49:10 -0400 Subject: [PATCH 08/42] fix tests --- .../management/edit_space/manage_space_page.test.tsx | 9 ++++----- .../management/spaces_grid/spaces_grid_pages.test.tsx | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx index 151d54d0138ea..3e96c36558c58 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx @@ -6,7 +6,6 @@ jest.mock('ui/kfetch', () => ({ kfetch: () => Promise.resolve([{ id: 'feature-1', name: 'feature 1' }]), })); -import '../../../__mocks__/ui_capabilities'; import { EuiButton, EuiLink, EuiSwitch } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; import React from 'react'; @@ -36,7 +35,7 @@ describe('ManageSpacePage', () => { navLinks: {}, management: {}, catalogue: {}, - spaces: { manage: false }, + spaces: { manage: true }, }} /> ); @@ -84,7 +83,7 @@ describe('ManageSpacePage', () => { navLinks: {}, management: {}, catalogue: {}, - spaces: { manage: false }, + spaces: { manage: true }, }} /> ); @@ -132,7 +131,7 @@ describe('ManageSpacePage', () => { navLinks: {}, management: {}, catalogue: {}, - spaces: { manage: false }, + spaces: { manage: true }, }} /> ); @@ -189,7 +188,7 @@ describe('ManageSpacePage', () => { navLinks: {}, management: {}, catalogue: {}, - spaces: { manage: false }, + spaces: { manage: true }, }} /> ); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx index 42e1b2bd50a81..7d04693ac41b1 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx @@ -6,7 +6,6 @@ jest.mock('ui/kfetch', () => ({ kfetch: () => Promise.resolve([]), })); -import '../../../__mocks__/ui_capabilities'; import React from 'react'; import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { SpaceAvatar } from '../../../components'; From 2aa3b71ab5d431368c406be92f974a18963d2904 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 15:42:42 -0400 Subject: [PATCH 09/42] implement NP plugin interface --- x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts | 4 ++-- x-pack/legacy/plugins/spaces/public/index.ts | 4 ++-- x-pack/legacy/plugins/spaces/public/plugin.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts b/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts index b634ce73353d2..fca2a4b3adf9d 100644 --- a/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts +++ b/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts @@ -6,9 +6,9 @@ import { npSetup, npStart } from 'ui/new_platform'; import { plugin } from '../index'; -import { Plugin } from '../plugin'; +import { SpacesPlugin } from '../plugin'; -const spacesPlugin: Plugin = plugin({}); +const spacesPlugin: SpacesPlugin = plugin({}); export const waitForSpacesNPInit = spacesPlugin .start(npStart.core) diff --git a/x-pack/legacy/plugins/spaces/public/index.ts b/x-pack/legacy/plugins/spaces/public/index.ts index 226f399b3b02f..ddd02aeebc5f8 100644 --- a/x-pack/legacy/plugins/spaces/public/index.ts +++ b/x-pack/legacy/plugins/spaces/public/index.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { PluginInitializerContext } from 'src/core/public'; -import { Plugin } from './plugin'; +import { SpacesPlugin } from './plugin'; export const plugin = (initializerContext: PluginInitializerContext) => { - return new Plugin(initializerContext); + return new SpacesPlugin(initializerContext); }; diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 6a9862c039fbd..27d08f77588bd 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, CoreSetup, CoreStart } from 'src/core/public'; +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { initSpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; -export class Plugin { +export class SpacesPlugin implements Plugin<{}, {}> { // @ts-ignore constructor(private readonly initializerContext: PluginInitializerContext) {} From b039a99275a71e8aa9bf8ab7c11a7e0455c84040 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 16:17:19 -0400 Subject: [PATCH 10/42] remove hack in favor of convention in migration guide --- x-pack/legacy/plugins/spaces/index.ts | 2 +- .../{hacks/init_np_plugin.ts => legacy.ts} | 9 ++++---- .../legacy/plugins/spaces/public/lib/index.ts | 2 +- .../spaces/public/lib/spaces_manager.ts | 21 ------------------- .../legacy/plugins/spaces/public/plugin.tsx | 18 ++++++++++++---- .../spaces/public/views/management/index.tsx | 7 +++---- .../public/views/management/page_routes.tsx | 15 +++++++------ .../public/views/space_selector/index.tsx | 7 +++---- 8 files changed, 33 insertions(+), 48 deletions(-) rename x-pack/legacy/plugins/spaces/public/{hacks/init_np_plugin.ts => legacy.ts} (63%) diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index 82df69091ab88..82fd441c2a2d5 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -59,7 +59,7 @@ export const spaces = (kibana: Record) => hidden: true, }, ], - hacks: ['plugins/spaces/hacks/init_np_plugin'], + hacks: [], mappings, migrations: { space: { diff --git a/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts similarity index 63% rename from x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts rename to x-pack/legacy/plugins/spaces/public/legacy.ts index fca2a4b3adf9d..f2e7fd98e763e 100644 --- a/x-pack/legacy/plugins/spaces/public/hacks/init_np_plugin.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -5,11 +5,10 @@ */ import { npSetup, npStart } from 'ui/new_platform'; -import { plugin } from '../index'; -import { SpacesPlugin } from '../plugin'; +import { plugin } from './index'; +import { SpacesPlugin } from './plugin'; const spacesPlugin: SpacesPlugin = plugin({}); -export const waitForSpacesNPInit = spacesPlugin - .start(npStart.core) - .then(() => spacesPlugin.setup(npSetup.core)); +export const setup = spacesPlugin.setup(npSetup.core); +export const start = spacesPlugin.start(npStart.core); diff --git a/x-pack/legacy/plugins/spaces/public/lib/index.ts b/x-pack/legacy/plugins/spaces/public/lib/index.ts index 243f85509c55c..538dd77e053f5 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/index.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { SpacesManager, initSpacesManager, getSpacesManager } from './spaces_manager'; +export { SpacesManager } from './spaces_manager'; diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index 6b41afbcb62d0..c335e8ea197d3 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -8,27 +8,6 @@ import { EventEmitter } from 'events'; import { NotificationsSetup, HttpSetup } from 'src/core/public'; import { Space } from '../../common/model/space'; -let spacesManager: SpacesManager | undefined; -export const initSpacesManager = ( - spaceSelectorUrl: string, - http: HttpSetup, - notifications: NotificationsSetup -) => { - if (spacesManager) { - throw new Error('SpacesManager has already been initialized!'); - } - spacesManager = new SpacesManager(spaceSelectorUrl, http, notifications); - return spacesManager; -}; - -export const getSpacesManager = () => { - if (!spacesManager) { - throw new Error('SpacesManager has not been initialized yet'); - } - - return spacesManager; -}; - export class SpacesManager extends EventEmitter { private activeSpace: Space | undefined; diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 27d08f77588bd..9bbd828f17881 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -5,18 +5,28 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { initSpacesManager } from './lib'; +import { SpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; -export class SpacesPlugin implements Plugin<{}, {}> { +export interface SpacesPluginStart { + spacesManager: SpacesManager; +} + +export class SpacesPlugin implements Plugin<{}, SpacesPluginStart> { + private spacesManager: SpacesManager | undefined; + // @ts-ignore constructor(private readonly initializerContext: PluginInitializerContext) {} public async start(core: CoreStart) { const { spaceSelectorUrl } = await core.http.get('/api/spaces/v1/npStart'); - const spacesManager = initSpacesManager(spaceSelectorUrl, core.http, core.notifications); + this.spacesManager = new SpacesManager(spaceSelectorUrl, core.http, core.notifications); + + initSpacesNavControl(this.spacesManager, core); - initSpacesNavControl(spacesManager, core); + return { + spacesManager: this.spacesManager, + }; } public async setup(core: CoreSetup) {} diff --git a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx index 16f00d1ccb74b..1fe117b2ebd8f 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx @@ -15,10 +15,9 @@ import { } from 'ui/management'; // @ts-ignore import routes from 'ui/routes'; -import { getSpacesManager } from 'plugins/spaces/lib'; import { AdvancedSettingsSubtitle } from './components/advanced_settings_subtitle'; import { AdvancedSettingsTitle } from './components/advanced_settings_title'; -import { waitForSpacesNPInit } from '../../hacks/init_np_plugin'; +import { start as spacesNPStart } from '../../legacy'; const MANAGE_SPACES_KEY = 'spaces'; @@ -48,8 +47,8 @@ routes.defaults(/\/management/, { } const getActiveSpace = async () => { - await waitForSpacesNPInit; - return getSpacesManager().getActiveSpace(); + const { spacesManager } = await spacesNPStart; + return spacesManager.getActiveSpace(); }; const PageTitle = () => ; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx index 1a0ed7811bd18..b23453fcc091c 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx @@ -12,12 +12,11 @@ import { I18nContext } from 'ui/i18n'; // @ts-ignore import routes from 'ui/routes'; import { npStart } from 'ui/new_platform'; -import { getSpacesManager } from '../../lib/spaces_manager'; import { ManageSpacePage } from './edit_space'; import { getCreateBreadcrumbs, getEditBreadcrumbs, getListBreadcrumbs } from './lib'; import { SpacesGridPage } from './spaces_grid'; -import { waitForSpacesNPInit } from '../../hacks/init_np_plugin'; +import { start as spacesNPStart } from '../../legacy'; const reactRootNodeId = 'manageSpacesReactRoot'; @@ -29,12 +28,12 @@ routes.when('/management/spaces/list', { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); - await waitForSpacesNPInit; + const { spacesManager } = await spacesNPStart; render( , @@ -59,12 +58,12 @@ routes.when('/management/spaces/create', { $scope.$$postDigest(async () => { const domNode = document.getElementById(reactRootNodeId); - await waitForSpacesNPInit; + const { spacesManager } = await spacesNPStart; render( , @@ -95,13 +94,13 @@ routes.when('/management/spaces/edit/:spaceId', { const { spaceId } = $route.current.params; - await waitForSpacesNPInit; + const { spacesManager } = await spacesNPStart; render( diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx index c731454bbb351..6af31c39e5f0a 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getSpacesManager } from 'plugins/spaces/lib/spaces_manager'; // @ts-ignore import template from 'plugins/spaces/views/space_selector/space_selector.html'; import 'ui/autoload/styles'; @@ -17,18 +16,18 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { SpaceSelector } from './space_selector'; -import { waitForSpacesNPInit } from '../../hacks/init_np_plugin'; +import { start as spacesNPStart } from '../../legacy'; const module = uiModules.get('spaces_selector', []); module.controller('spacesSelectorController', ($scope: any) => { $scope.$$postDigest(async () => { const domNode = document.getElementById('spaceSelectorRoot'); - await waitForSpacesNPInit; + const { spacesManager } = await spacesNPStart; render( - + , domNode ); From 8c161f23f2762feb9284efc15980032d4184e45e Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 11 Jul 2019 16:31:59 -0400 Subject: [PATCH 11/42] shim feature catalogue registration --- x-pack/legacy/plugins/spaces/index.ts | 2 +- x-pack/legacy/plugins/spaces/public/legacy.ts | 13 +++++++++++-- x-pack/legacy/plugins/spaces/public/plugin.tsx | 13 +++++++++++-- .../plugins/spaces/public/register_feature.ts | 10 ++++------ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index 82fd441c2a2d5..d2b2899e76d25 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -71,7 +71,7 @@ export const spaces = (kibana: Record) => isNamespaceAgnostic: true, }, }, - home: ['plugins/spaces/register_feature'], + home: ['plugins/spaces/legacy'], }, async init(server: Server) { diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index f2e7fd98e763e..6c0b064a59da5 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -5,10 +5,19 @@ */ import { npSetup, npStart } from 'ui/new_platform'; +import { FeatureCatalogueRegistryProvider } from 'ui/registry/feature_catalogue'; import { plugin } from './index'; -import { SpacesPlugin } from './plugin'; +import { SpacesPlugin, PluginsSetup } from './plugin'; const spacesPlugin: SpacesPlugin = plugin({}); +const plugins: PluginsSetup = { + kibana: { + registerCatalogueFeature: fn => { + FeatureCatalogueRegistryProvider.register(fn); + }, + }, +}; + export const setup = spacesPlugin.setup(npSetup.core); -export const start = spacesPlugin.start(npStart.core); +export const start = spacesPlugin.start(npStart.core, plugins); diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 9bbd828f17881..8d43a6d0dc594 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -5,24 +5,33 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; +import { FeatureCatalogueRegistryFunction } from 'ui/registry/feature_catalogue'; import { SpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; +import { createSpacesFeatureCatalogueEntry } from './register_feature'; export interface SpacesPluginStart { spacesManager: SpacesManager; } -export class SpacesPlugin implements Plugin<{}, SpacesPluginStart> { +export interface PluginsSetup { + kibana: { + registerCatalogueFeature: (fn: FeatureCatalogueRegistryFunction) => void; + }; +} + +export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> { private spacesManager: SpacesManager | undefined; // @ts-ignore constructor(private readonly initializerContext: PluginInitializerContext) {} - public async start(core: CoreStart) { + public async start(core: CoreStart, plugins: PluginsSetup) { const { spaceSelectorUrl } = await core.http.get('/api/spaces/v1/npStart'); this.spacesManager = new SpacesManager(spaceSelectorUrl, core.http, core.notifications); initSpacesNavControl(this.spacesManager, core); + plugins.kibana.registerCatalogueFeature(createSpacesFeatureCatalogueEntry); return { spacesManager: this.spacesManager, diff --git a/x-pack/legacy/plugins/spaces/public/register_feature.ts b/x-pack/legacy/plugins/spaces/public/register_feature.ts index c8ebfd8db5686..9981a542ccd6e 100644 --- a/x-pack/legacy/plugins/spaces/public/register_feature.ts +++ b/x-pack/legacy/plugins/spaces/public/register_feature.ts @@ -4,18 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { FeatureCatalogueCategory, - FeatureCatalogueRegistryProvider, - // @ts-ignore + FeatureCatalogueRegistryFunction, } from 'ui/registry/feature_catalogue'; import { getSpacesFeatureDescription } from './lib/constants'; -FeatureCatalogueRegistryProvider.register(() => { +export const createSpacesFeatureCatalogueEntry: FeatureCatalogueRegistryFunction = i18n => { return { id: 'spaces', - title: i18n.translate('xpack.spaces.spacesTitle', { + title: i18n('xpack.spaces.spacesTitle', { defaultMessage: 'Spaces', }), description: getSpacesFeatureDescription(), @@ -24,4 +22,4 @@ FeatureCatalogueRegistryProvider.register(() => { showOnHomePage: true, category: FeatureCatalogueCategory.ADMIN, }; -}); +}; From 3a010f18b465d1f26d353466f58c915d776d93c7 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Fri, 12 Jul 2019 09:56:56 -0400 Subject: [PATCH 12/42] streamline nav control, and handle async loading more gracefully --- .../nav_control_popover.test.tsx.snap | 29 +++++++------ .../components/spaces_header_nav_button.tsx | 29 ------------- .../nav_control/components/spaces_menu.tsx | 23 ++++++++-- .../public/views/nav_control/nav_control.tsx | 2 - .../nav_control/nav_control_popover.test.tsx | 3 -- .../views/nav_control/nav_control_popover.tsx | 42 +++++++++++-------- 6 files changed, 61 insertions(+), 67 deletions(-) delete mode 100644 x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_header_nav_button.tsx diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap index 1d704161397c5..9dee693769e58 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap @@ -4,18 +4,18 @@ exports[`NavControlPopover renders without crashing 1`] = ` - } - linkTitle="loading" - spaceSelectorShown={false} - toggleSpaceSelector={[Function]} - /> + + + } closePopover={[Function]} data-test-subj="spacesNavSelector" @@ -27,7 +27,7 @@ exports[`NavControlPopover renders without crashing 1`] = ` repositionOnScroll={true} withTitle={true} > - `; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_header_nav_button.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_header_nav_button.tsx deleted file mode 100644 index 45bb79ee749ee..0000000000000 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_header_nav_button.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - // @ts-ignore - EuiHeaderSectionItemButton, -} from '@elastic/eui'; -import React, { Component } from 'react'; -import { ButtonProps } from '../types'; - -export class SpacesHeaderNavButton extends Component { - public render() { - return ( - - {this.props.linkIcon} - - ); - } -} diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx index 5db0c03d466cf..7a21b1e26c6c0 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiContextMenuItem, EuiContextMenuPanel, EuiFieldSearch, EuiText } from '@elastic/eui'; +import { + EuiContextMenuItem, + EuiContextMenuPanel, + EuiFieldSearch, + EuiText, + EuiLoadingContent, +} from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React, { Component } from 'react'; import { Capabilities } from 'src/core/public'; @@ -14,6 +20,7 @@ import { ManageSpacesButton, SpaceAvatar } from '../../../components'; interface Props { spaces: Space[]; + isLoading: boolean; onSelectSpace: (space: Space) => void; onManageSpacesClick: () => void; intl: InjectedIntl; @@ -32,10 +39,12 @@ class SpacesMenuUI extends Component { }; public render() { - const { intl } = this.props; + const { intl, isLoading } = this.props; const { searchTerm } = this.state; - const items = this.getVisibleSpaces(searchTerm).map(this.renderSpaceMenuItem); + const items = isLoading + ? [1, 2, 3].map(this.rendePlaceholderMenuItem) + : this.getVisibleSpaces(searchTerm).map(this.renderSpaceMenuItem); const panelProps = { className: 'spcMenu', @@ -178,6 +187,14 @@ class SpacesMenuUI extends Component { ); }; + + private rendePlaceholderMenuItem = (key: string | number): JSX.Element => { + return ( + null}> + + + ); + }; } export const SpacesMenu = injectI18n(SpacesMenuUI); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx index 5ff3571e169c0..2646618bf0c6b 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx @@ -11,7 +11,6 @@ import { Path } from 'plugins/xpack_main/services/path'; import React from 'react'; import ReactDOM from 'react-dom'; import { CoreStart } from 'src/core/public'; -import { SpacesHeaderNavButton } from './components/spaces_header_nav_button'; export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreStart) { const I18nContext = core.i18n.Context; @@ -27,7 +26,6 @@ export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreSta , diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx index 633ca44356cb9..de0945d006a4a 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx @@ -8,7 +8,6 @@ import { mount, shallow } from 'enzyme'; import React from 'react'; import { SpaceAvatar } from '../../components'; import { spacesManagerMock } from '../../lib/mocks'; -import { SpacesHeaderNavButton } from './components/spaces_header_nav_button'; import { NavControlPopover } from './nav_control_popover'; describe('NavControlPopover', () => { @@ -19,7 +18,6 @@ describe('NavControlPopover', () => { ); @@ -50,7 +48,6 @@ describe('NavControlPopover', () => { ); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx index 62a69252f1cd7..d716bc3d65834 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx @@ -4,20 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiAvatar, EuiPopover, PopoverAnchorPosition } from '@elastic/eui'; -import React, { Component, ComponentClass } from 'react'; +import { + EuiPopover, + PopoverAnchorPosition, + EuiLoadingSpinner, + // @ts-ignore + EuiHeaderSectionItemButton, +} from '@elastic/eui'; +import React, { Component } from 'react'; import { Capabilities } from 'src/core/public'; import { Space } from '../../../common/model/space'; import { SpaceAvatar } from '../../components'; import { SpacesManager } from '../../lib/spaces_manager'; import { SpacesDescription } from './components/spaces_description'; import { SpacesMenu } from './components/spaces_menu'; -import { ButtonProps } from './types'; interface Props { spacesManager: SpacesManager; anchorPosition: PopoverAnchorPosition; - buttonClass: ComponentClass; capabilities: Capabilities; } @@ -56,7 +60,7 @@ export class NavControlPopover extends Component { } let element: React.ReactNode; - if (this.state.spaces.length < 2) { + if (!this.state.loading && this.state.spaces.length < 2) { element = ( { element = ( { } return ( - // @ts-ignore repositionOnScroll doesn't exist on EuiPopover { private async loadSpaces(refreshActiveSpace: boolean = false) { const { spacesManager } = this.props; + if (this.state.loading) { + return; + } + this.setState({ loading: true, }); @@ -116,10 +124,7 @@ export class NavControlPopover extends Component { const { activeSpace } = this.state; if (!activeSpace) { - return this.getButton( - , - 'loading' - ); + return this.getButton(, 'loading'); } return this.getButton( @@ -129,14 +134,17 @@ export class NavControlPopover extends Component { }; private getButton = (linkIcon: JSX.Element, linkTitle: string) => { - const Button = this.props.buttonClass; return ( - + + {linkIcon} + ); }; From a3e1e598b1d7cb10eeef9e4db92a65267e4037d2 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Fri, 2 Aug 2019 17:43:23 -0400 Subject: [PATCH 13/42] adding opaqueId --- x-pack/legacy/plugins/spaces/public/legacy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 6c0b064a59da5..9f6f16d848156 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -9,7 +9,7 @@ import { FeatureCatalogueRegistryProvider } from 'ui/registry/feature_catalogue' import { plugin } from './index'; import { SpacesPlugin, PluginsSetup } from './plugin'; -const spacesPlugin: SpacesPlugin = plugin({}); +const spacesPlugin: SpacesPlugin = plugin({ opaqueId: Symbol('spaces plugin') }); const plugins: PluginsSetup = { kibana: { From 8df1838d8571f9df33f06107237eab10f0b97f20 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Fri, 23 Aug 2019 15:44:55 -0400 Subject: [PATCH 14/42] fixes from merge --- .../copy_to_space_flyout.test.tsx | 13 ++++++++----- .../spaces/public/views/management/index.tsx | 1 - 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/copy_saved_objects_to_space/copy_to_space_flyout.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/copy_saved_objects_to_space/copy_to_space_flyout.test.tsx index 9e8f1e7c1a6f4..002ec70ca4bf3 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/copy_saved_objects_to_space/copy_to_space_flyout.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/copy_saved_objects_to_space/copy_to_space_flyout.test.tsx @@ -27,6 +27,13 @@ const setup = async (opts: SetupOpts = {}) => { const onClose = jest.fn(); const mockSpacesManager = spacesManagerMock.create(); + + mockSpacesManager.getActiveSpace.mockResolvedValue({ + id: 'my-active-space', + name: 'my active space', + disabledFeatures: [], + }); + mockSpacesManager.getSpaces.mockResolvedValue( opts.mockSpaces || [ { @@ -73,11 +80,6 @@ const setup = async (opts: SetupOpts = {}) => { @@ -86,6 +88,7 @@ const setup = async (opts: SetupOpts = {}) => { if (!opts.returnBeforeSpacesLoad) { // Wait for spaces manager to complete and flyout to rerender await Promise.resolve(); + await Promise.resolve(); wrapper.update(); } diff --git a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx index 96873a2b5cf5b..95f90f8f50a19 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx @@ -15,7 +15,6 @@ import { import { SavedObjectsManagementActionRegistry } from 'ui/management/saved_objects_management'; // @ts-ignore import routes from 'ui/routes'; -import { SpacesManager } from '../../lib'; import { AdvancedSettingsSubtitle } from './components/advanced_settings_subtitle'; import { AdvancedSettingsTitle } from './components/advanced_settings_title'; import { start as spacesNPStart } from '../../legacy'; From 6517a60c1cbfdef6e6508f16b1d42fc8910c82ac Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 19 Sep 2019 16:09:14 -0400 Subject: [PATCH 15/42] fix merge from master --- .../confirm_delete_modal.test.tsx.snap | 23 ------------------- .../edit_space/manage_space_page.test.tsx | 1 - .../spaces_grid_pages.test.tsx.snap | 13 +---------- .../spaces_grid/spaces_grid_pages.test.tsx | 1 - .../spaces/server/new_platform/plugin.ts | 1 + .../server/routes/api/v1/spaces.test.ts | 2 +- 6 files changed, 3 insertions(+), 38 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap index d202df26b572f..47fc5c63a66f2 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/__snapshots__/confirm_delete_modal.test.tsx.snap @@ -64,29 +64,6 @@ exports[`ConfirmDeleteModal renders as expected 1`] = ` value="" /> - - - - - ( - - My Space - - ) - , - } - } - /> - - diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx index 617c7e9adb90b..b0f2179267235 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx @@ -6,7 +6,6 @@ jest.mock('ui/kfetch', () => ({ kfetch: () => Promise.resolve([{ id: 'feature-1', name: 'feature 1' }]), })); -import '../../../__mocks__/ui_capabilities'; import '../../../__mocks__/xpack_info'; import { EuiButton, EuiLink, EuiSwitch } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap index a3f6449d7bc4a..fcf0e992b2be2 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap @@ -124,18 +124,7 @@ exports[`SpacesGridPage renders as expected 1`] = ` sorting={false} /> - + `; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx index 573ce8cc63d38..4add607707b24 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_pages.test.tsx @@ -6,7 +6,6 @@ jest.mock('ui/kfetch', () => ({ kfetch: () => Promise.resolve([]), })); -import '../../../__mocks__/ui_capabilities'; import '../../../__mocks__/xpack_info'; import React from 'react'; import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; diff --git a/x-pack/legacy/plugins/spaces/server/new_platform/plugin.ts b/x-pack/legacy/plugins/spaces/server/new_platform/plugin.ts index 382227a4f1cec..bea620f6e464c 100644 --- a/x-pack/legacy/plugins/spaces/server/new_platform/plugin.ts +++ b/x-pack/legacy/plugins/spaces/server/new_platform/plugin.ts @@ -183,6 +183,7 @@ export class Plugin { getLegacyAPI: this.getLegacyAPI, spacesService, xpackMain: xpackMainPlugin, + http: core.http, }); initExternalSpacesApi({ diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts index 2f21e338dad96..ee10e4d241dd7 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/v1/spaces.test.ts @@ -52,7 +52,7 @@ describe('Spaces API', () => { const result = JSON.parse(payload); expect(result).toEqual({ - spaceSelectorUrl: '/', + spaceSelectorUrl: '/spaces/space_selector', }); }); From 3acca4535c0a2bdde830922613a2924462d8d97d Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 8 Oct 2019 15:20:35 -0400 Subject: [PATCH 16/42] fixing merge from master --- x-pack/legacy/plugins/spaces/index.ts | 5 +++++ .../plugins/spaces/public/lib/spaces_manager.ts | 11 +++-------- x-pack/legacy/plugins/spaces/public/plugin.tsx | 4 ++-- .../api/__fixtures__/create_test_handler.ts | 1 - .../spaces/server/routes/api/external/get.ts | 15 +++++++++++++++ 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index c619236f8a19a..564452da6601f 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -80,6 +80,11 @@ export const spaces = (kibana: Record) => }, }, home: ['plugins/spaces/legacy'], + injectDefaultVars(server: Server) { + return { + serverBasePath: server.config().get('server.basePath'), + }; + }, }, async init(server: Server) { diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index ca45fda0fe99f..fb232a53c66b1 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { EventEmitter } from 'events'; -import { NotificationsSetup, HttpSetup } from 'src/core/public'; +import { HttpSetup } from 'src/core/public'; import { SavedObjectsManagementRecord } from 'ui/management/saved_objects_management'; import { Space } from '../../common/model/space'; import { GetSpacePurpose } from '../../common/model/types'; @@ -16,11 +15,7 @@ import { addSpaceIdToPath } from '../../common'; export class SpacesManager extends EventEmitter { private activeSpace: Space | undefined; - constructor( - private readonly spaceSelectorURL: string, - private readonly http: HttpSetup, - private readonly notifications: NotificationsSetup - ) { + constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { super(); } @@ -34,7 +29,7 @@ export class SpacesManager extends EventEmitter { public async getActiveSpace(forceRefresh: boolean = false): Promise { if (!this.activeSpace || forceRefresh) { - this.activeSpace = (await this.http.get('/api/spaces/v1/activeSpace')) as Space; + this.activeSpace = (await this.http.get('/api/spaces/_active_space')) as Space; } return this.activeSpace; } diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 8d43a6d0dc594..ee2803c7579e1 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -27,8 +27,8 @@ export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> constructor(private readonly initializerContext: PluginInitializerContext) {} public async start(core: CoreStart, plugins: PluginsSetup) { - const { spaceSelectorUrl } = await core.http.get('/api/spaces/v1/npStart'); - this.spacesManager = new SpacesManager(spaceSelectorUrl, core.http, core.notifications); + const serverBasePath = core.injectedMetadata.getInjectedVar('serverBasePath') as string; + this.spacesManager = new SpacesManager(serverBasePath, core.http); initSpacesNavControl(this.spacesManager, core); plugins.kibana.registerCatalogueFeature(createSpacesFeatureCatalogueEntry); diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts b/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts index 2ddcff020cebe..405a3dd34e7fc 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/__fixtures__/create_test_handler.ts @@ -256,7 +256,6 @@ export function createTestHandler(initApiFn: (deps: ExternalRouteDeps) => void) spacesService, log, legacyRouter: server.route.bind(server), - http: coreSetupMock.http, }); teardowns.push(() => server.stop()); diff --git a/x-pack/legacy/plugins/spaces/server/routes/api/external/get.ts b/x-pack/legacy/plugins/spaces/server/routes/api/external/get.ts index 310cef5c1069e..ce3528f144955 100644 --- a/x-pack/legacy/plugins/spaces/server/routes/api/external/get.ts +++ b/x-pack/legacy/plugins/spaces/server/routes/api/external/get.ts @@ -16,6 +16,21 @@ import { ExternalRouteDeps, ExternalRouteRequestFacade } from '.'; export function initGetSpacesApi(deps: ExternalRouteDeps) { const { legacyRouter, log, spacesService, savedObjects, routePreCheckLicenseFn } = deps; + legacyRouter({ + method: 'GET', + path: '/api/spaces/_active_space', + async handler(request: ExternalRouteRequestFacade) { + try { + return spacesService.getActiveSpace(request); + } catch (error) { + return wrapError(error); + } + }, + options: { + pre: [routePreCheckLicenseFn], + }, + }); + legacyRouter({ method: 'GET', path: '/api/spaces/space', From 444dbb634a246c5474052064c42c03a606b07810 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 28 Oct 2019 15:06:06 -0400 Subject: [PATCH 17/42] move _active_space route to NP --- x-pack/legacy/plugins/spaces/index.ts | 2 - x-pack/legacy/plugins/spaces/public/legacy.ts | 5 +- .../spaces/public/lib/spaces_manager.ts | 2 +- .../server/lib/toggle_ui_capabilities.test.ts | 1 - x-pack/plugins/spaces/server/plugin.ts | 7 ++ .../api/internal/get_active_space.test.ts | 61 ++++++++++++++++++ .../routes/api/internal/get_active_space.ts | 28 ++++++++ .../server/routes/api/internal/index.ts | 18 ++++++ x-pack/test/api_integration/apis/index.js | 36 +++++------ .../apis/spaces/get_active_space.ts | 64 +++++++++++++++++++ .../test/api_integration/apis/spaces/index.ts | 1 + 11 files changed, 202 insertions(+), 23 deletions(-) create mode 100644 x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts create mode 100644 x-pack/plugins/spaces/server/routes/api/internal/get_active_space.ts create mode 100644 x-pack/plugins/spaces/server/routes/api/internal/index.ts create mode 100644 x-pack/test/api_integration/apis/spaces/get_active_space.ts diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index 6bbeba771d93d..b2cf6b4982f85 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -7,14 +7,12 @@ import { resolve } from 'path'; import KbnServer, { Server } from 'src/legacy/server/kbn_server'; import { Legacy } from 'kibana'; -import { KibanaRequest } from '../../../../src/core/server'; import { SpacesServiceSetup } from '../../../plugins/spaces/server/spaces_service/spaces_service'; import { SpacesPluginSetup } from '../../../plugins/spaces/server'; import { createOptionalPlugin } from '../../server/lib/optional_plugin'; // @ts-ignore import { AuditLogger } from '../../server/lib/audit_logger'; import mappings from './mappings.json'; -import { wrapError } from './server/lib/errors'; import { migrateToKibana660 } from './server/lib/migrations'; import { SecurityPlugin } from '../security'; // @ts-ignore diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 9f6f16d848156..88e4ab411cf1a 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -9,7 +9,10 @@ import { FeatureCatalogueRegistryProvider } from 'ui/registry/feature_catalogue' import { plugin } from './index'; import { SpacesPlugin, PluginsSetup } from './plugin'; -const spacesPlugin: SpacesPlugin = plugin({ opaqueId: Symbol('spaces plugin') }); +const spacesPlugin: SpacesPlugin = plugin({ + opaqueId: Symbol('spaces plugin'), + env: null as any, +}); const plugins: PluginsSetup = { kibana: { diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index 05aa4c9334bcc..1aeb204bb1bc3 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -29,7 +29,7 @@ export class SpacesManager extends EventEmitter { public async getActiveSpace(forceRefresh: boolean = false): Promise { if (!this.activeSpace || forceRefresh) { - this.activeSpace = (await this.http.get('/api/spaces/_active_space')) as Space; + this.activeSpace = (await this.http.get('/internal/spaces/_active_space')) as Space; } return this.activeSpace; } diff --git a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts index ab737b30edcf8..f7d0e16babc33 100644 --- a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts +++ b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UICapabilities } from 'ui/capabilities'; import { Feature } from '../../../../plugins/features/server'; import { Space } from '../../common/model/space'; import { toggleUICapabilities } from './toggle_ui_capabilities'; diff --git a/x-pack/plugins/spaces/server/plugin.ts b/x-pack/plugins/spaces/server/plugin.ts index 4b071baaa7e2c..ca90f373a7ae7 100644 --- a/x-pack/plugins/spaces/server/plugin.ts +++ b/x-pack/plugins/spaces/server/plugin.ts @@ -32,6 +32,7 @@ import { ConfigType } from './config'; import { toggleUICapabilities } from './lib/toggle_ui_capabilities'; import { initSpacesRequestInterceptors } from './lib/request_interceptors'; import { initExternalSpacesApi } from './routes/api/external'; +import { initInternalSpacesApi } from './routes/api/internal'; /** * Describes a set of APIs that is available in the legacy platform only and required by this plugin @@ -129,6 +130,12 @@ export class Plugin { spacesService, }); + const internalRouter = core.http.createRouter(); + initInternalSpacesApi({ + internalRouter, + spacesService, + }); + initSpacesRequestInterceptors({ http: core.http, log: this.log, diff --git a/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts new file mode 100644 index 0000000000000..33e50239470c7 --- /dev/null +++ b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import * as Rx from 'rxjs'; +import { createLegacyAPI, mockRouteContextWithInvalidLicense } from '../__fixtures__'; +import { CoreSetup, IRouter, kibanaResponseFactory } from 'src/core/server'; +import { httpServiceMock, httpServerMock, elasticsearchServiceMock } from 'src/core/server/mocks'; +import { SpacesService } from '../../../spaces_service'; +import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; +import { SpacesAuditLogger } from '../../../lib/audit_logger'; +import { spacesConfig } from '../../../lib/__fixtures__'; +import { initGetActiveSpaceApi } from './get_active_space'; + +describe('GET /internal/spaces/_active_space', () => { + const setup = async () => { + const httpService = httpServiceMock.createSetupContract(); + const router = httpService.createRouter('') as jest.Mocked; + + const legacyAPI = createLegacyAPI(); + + const service = new SpacesService(null as any, () => legacyAPI); + const spacesService = await service.setup({ + http: (httpService as unknown) as CoreSetup['http'], + elasticsearch: elasticsearchServiceMock.createSetupContract(), + getSecurity: () => + createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + getSpacesAuditLogger: () => ({} as SpacesAuditLogger), + config$: Rx.of(spacesConfig), + }); + + initGetActiveSpaceApi({ + internalRouter: router, + spacesService, + }); + + return { + routeHandler: router.get.mock.calls[0][1], + }; + }; + + it(`returns http/403 when the license is invalid`, async () => { + const { routeHandler } = await setup(); + + const request = httpServerMock.createKibanaRequest({ + method: 'get', + }); + + const response = await routeHandler( + mockRouteContextWithInvalidLicense, + request, + kibanaResponseFactory + ); + + expect(response.status).toEqual(403); + expect(response.payload).toEqual({ + message: 'License is invalid for spaces', + }); + }); +}); diff --git a/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.ts b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.ts new file mode 100644 index 0000000000000..fa9dafa526da8 --- /dev/null +++ b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { wrapError } from '../../../lib/errors'; +import { InternalRouteDeps } from '.'; +import { createLicensedRouteHandler } from '../../lib'; + +export function initGetActiveSpaceApi(deps: InternalRouteDeps) { + const { internalRouter, spacesService } = deps; + + internalRouter.get( + { + path: '/internal/spaces/_active_space', + validate: false, + }, + createLicensedRouteHandler(async (context, request, response) => { + try { + const space = await spacesService.getActiveSpace(request); + return response.ok({ body: space }); + } catch (error) { + return response.customError(wrapError(error)); + } + }) + ); +} diff --git a/x-pack/plugins/spaces/server/routes/api/internal/index.ts b/x-pack/plugins/spaces/server/routes/api/internal/index.ts new file mode 100644 index 0000000000000..12ce50f228bfc --- /dev/null +++ b/x-pack/plugins/spaces/server/routes/api/internal/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IRouter } from 'src/core/server'; +import { SpacesServiceSetup } from '../../../spaces_service/spaces_service'; +import { initGetActiveSpaceApi } from './get_active_space'; + +export interface InternalRouteDeps { + internalRouter: IRouter; + spacesService: SpacesServiceSetup; +} + +export function initInternalSpacesApi(deps: InternalRouteDeps) { + initGetActiveSpaceApi(deps); +} diff --git a/x-pack/test/api_integration/apis/index.js b/x-pack/test/api_integration/apis/index.js index 86ef445899039..eca0c860a216c 100644 --- a/x-pack/test/api_integration/apis/index.js +++ b/x-pack/test/api_integration/apis/index.js @@ -8,24 +8,24 @@ export default function ({ loadTestFile }) { describe('apis', function () { this.tags('ciGroup6'); - loadTestFile(require.resolve('./es')); - loadTestFile(require.resolve('./security')); + // loadTestFile(require.resolve('./es')); + // loadTestFile(require.resolve('./security')); loadTestFile(require.resolve('./spaces')); - loadTestFile(require.resolve('./monitoring')); - loadTestFile(require.resolve('./xpack_main')); - loadTestFile(require.resolve('./features')); - loadTestFile(require.resolve('./telemetry')); - loadTestFile(require.resolve('./logstash')); - loadTestFile(require.resolve('./kibana')); - loadTestFile(require.resolve('./infra')); - loadTestFile(require.resolve('./beats')); - loadTestFile(require.resolve('./console')); - loadTestFile(require.resolve('./management')); - loadTestFile(require.resolve('./uptime')); - loadTestFile(require.resolve('./maps')); - loadTestFile(require.resolve('./apm')); - loadTestFile(require.resolve('./siem')); - loadTestFile(require.resolve('./short_urls')); - loadTestFile(require.resolve('./lens')); + // loadTestFile(require.resolve('./monitoring')); + // loadTestFile(require.resolve('./xpack_main')); + // loadTestFile(require.resolve('./features')); + // loadTestFile(require.resolve('./telemetry')); + // loadTestFile(require.resolve('./logstash')); + // loadTestFile(require.resolve('./kibana')); + // loadTestFile(require.resolve('./infra')); + // loadTestFile(require.resolve('./beats')); + // loadTestFile(require.resolve('./console')); + // loadTestFile(require.resolve('./management')); + // loadTestFile(require.resolve('./uptime')); + // loadTestFile(require.resolve('./maps')); + // loadTestFile(require.resolve('./apm')); + // loadTestFile(require.resolve('./siem')); + // loadTestFile(require.resolve('./short_urls')); + // loadTestFile(require.resolve('./lens')); }); } diff --git a/x-pack/test/api_integration/apis/spaces/get_active_space.ts b/x-pack/test/api_integration/apis/spaces/get_active_space.ts new file mode 100644 index 0000000000000..995bd834552ac --- /dev/null +++ b/x-pack/test/api_integration/apis/spaces/get_active_space.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const spacesService = getService('spaces'); + + describe('GET /internal/spaces/_active_space', () => { + before(async () => { + await spacesService.create({ + id: 'foo-space', + name: 'Foo Space', + disabledFeatures: ['timelion'], + color: '#AABBCC', + }); + }); + + after(async () => { + await spacesService.delete('foo-space'); + }); + + it('returns the default space', async () => { + await supertest + .get('/internal/spaces/_active_space') + .set('kbn-xsrf', 'xxx') + .expect(200, { + id: 'default', + name: 'Default', + description: 'This is your default space!', + color: '#00bfb3', + disabledFeatures: [], + _reserved: true, + }); + }); + + it('returns the foo space', async () => { + await supertest + .get('/s/foo-space/internal/spaces/_active_space') + .set('kbn-xsrf', 'xxx') + .expect(200, { + id: 'foo-space', + name: 'Foo Space', + disabledFeatures: ['timelion'], + color: '#AABBCC', + }); + }); + + it('returns 404 when the space is not found', async () => { + await supertest + .get('/s/not-found-space/internal/spaces/_active_space') + .set('kbn-xsrf', 'xxx') + .expect(404, { + statusCode: 404, + error: 'Not Found', + message: 'Saved object [space/not-found-space] not found', + }); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/spaces/index.ts b/x-pack/test/api_integration/apis/spaces/index.ts index adcf70d032e0f..94734a35fa73a 100644 --- a/x-pack/test/api_integration/apis/spaces/index.ts +++ b/x-pack/test/api_integration/apis/spaces/index.ts @@ -9,6 +9,7 @@ export default function({ loadTestFile }: FtrProviderContext) { describe('spaces', function() { this.tags('ciGroup6'); + loadTestFile(require.resolve('./get_active_space')); loadTestFile(require.resolve('./saved_objects')); loadTestFile(require.resolve('./space_attributes')); }); From 13cc9ae6614ff8438544d83aff5ea756d9573944 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 28 Oct 2019 15:20:54 -0400 Subject: [PATCH 18/42] moving to the NP feature catalogue registry --- ..._feature.ts => create_feature_catalogue_entry.ts} | 9 +++++---- x-pack/legacy/plugins/spaces/public/legacy.ts | 7 +------ x-pack/legacy/plugins/spaces/public/plugin.tsx | 12 ++++++------ 3 files changed, 12 insertions(+), 16 deletions(-) rename x-pack/legacy/plugins/spaces/public/{register_feature.ts => create_feature_catalogue_entry.ts} (70%) diff --git a/x-pack/legacy/plugins/spaces/public/register_feature.ts b/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts similarity index 70% rename from x-pack/legacy/plugins/spaces/public/register_feature.ts rename to x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts index 9981a542ccd6e..c26fac5d4b772 100644 --- a/x-pack/legacy/plugins/spaces/public/register_feature.ts +++ b/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts @@ -4,16 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; import { + FeatureCatalogueEntry, FeatureCatalogueCategory, - FeatureCatalogueRegistryFunction, -} from 'ui/registry/feature_catalogue'; +} from '../../../../../src/plugins/feature_catalogue/public'; import { getSpacesFeatureDescription } from './lib/constants'; -export const createSpacesFeatureCatalogueEntry: FeatureCatalogueRegistryFunction = i18n => { +export const createSpacesFeatureCatalogueEntry = (): FeatureCatalogueEntry => { return { id: 'spaces', - title: i18n('xpack.spaces.spacesTitle', { + title: i18n.translate('xpack.spaces.spacesTitle', { defaultMessage: 'Spaces', }), description: getSpacesFeatureDescription(), diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 88e4ab411cf1a..3d71b228b94ce 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -5,7 +5,6 @@ */ import { npSetup, npStart } from 'ui/new_platform'; -import { FeatureCatalogueRegistryProvider } from 'ui/registry/feature_catalogue'; import { plugin } from './index'; import { SpacesPlugin, PluginsSetup } from './plugin'; @@ -15,11 +14,7 @@ const spacesPlugin: SpacesPlugin = plugin({ }); const plugins: PluginsSetup = { - kibana: { - registerCatalogueFeature: fn => { - FeatureCatalogueRegistryProvider.register(fn); - }, - }, + feature_catalogue: npSetup.plugins.feature_catalogue, }; export const setup = spacesPlugin.setup(npSetup.core); diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index ee2803c7579e1..5b95593eb63da 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -5,19 +5,17 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { FeatureCatalogueRegistryFunction } from 'ui/registry/feature_catalogue'; +import { FeatureCatalogueSetup } from 'src/plugins/feature_catalogue/public'; import { SpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; -import { createSpacesFeatureCatalogueEntry } from './register_feature'; +import { createSpacesFeatureCatalogueEntry } from './create_feature_catalogue_entry'; export interface SpacesPluginStart { spacesManager: SpacesManager; } export interface PluginsSetup { - kibana: { - registerCatalogueFeature: (fn: FeatureCatalogueRegistryFunction) => void; - }; + feature_catalogue?: FeatureCatalogueSetup; } export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> { @@ -31,7 +29,9 @@ export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> this.spacesManager = new SpacesManager(serverBasePath, core.http); initSpacesNavControl(this.spacesManager, core); - plugins.kibana.registerCatalogueFeature(createSpacesFeatureCatalogueEntry); + if (plugins.feature_catalogue) { + plugins.feature_catalogue.register(createSpacesFeatureCatalogueEntry()); + } return { spacesManager: this.spacesManager, From 1b505036ecb946c068b407e9f1339b778c7543e1 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 28 Oct 2019 15:29:25 -0400 Subject: [PATCH 19/42] moving setup to setup phase --- x-pack/legacy/plugins/spaces/public/legacy.ts | 4 ++-- x-pack/legacy/plugins/spaces/public/plugin.tsx | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 3d71b228b94ce..65e4003ca5169 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -17,5 +17,5 @@ const plugins: PluginsSetup = { feature_catalogue: npSetup.plugins.feature_catalogue, }; -export const setup = spacesPlugin.setup(npSetup.core); -export const start = spacesPlugin.start(npStart.core, plugins); +export const setup = spacesPlugin.setup(npSetup.core, plugins); +export const start = spacesPlugin.start(npStart.core); diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 5b95593eb63da..0c861a9884032 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -21,22 +21,22 @@ export interface PluginsSetup { export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> { private spacesManager: SpacesManager | undefined; - // @ts-ignore - constructor(private readonly initializerContext: PluginInitializerContext) {} + constructor(initializerContext: PluginInitializerContext) {} - public async start(core: CoreStart, plugins: PluginsSetup) { + public async start(core: CoreStart) { const serverBasePath = core.injectedMetadata.getInjectedVar('serverBasePath') as string; this.spacesManager = new SpacesManager(serverBasePath, core.http); initSpacesNavControl(this.spacesManager, core); - if (plugins.feature_catalogue) { - plugins.feature_catalogue.register(createSpacesFeatureCatalogueEntry()); - } return { spacesManager: this.spacesManager, }; } - public async setup(core: CoreSetup) {} + public async setup(core: CoreSetup, plugins: PluginsSetup) { + if (plugins.feature_catalogue) { + plugins.feature_catalogue.register(createSpacesFeatureCatalogueEntry()); + } + } } From 6f123b649a24e47cb6b66df2f70637e019ea6021 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 29 Oct 2019 06:56:19 -0400 Subject: [PATCH 20/42] optimizing active space retrieval --- x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index 1aeb204bb1bc3..d1af8a5014020 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -13,7 +13,7 @@ import { ENTER_SPACE_PATH } from '../../common/constants'; import { addSpaceIdToPath } from '../../../../../plugins/spaces/common'; export class SpacesManager extends EventEmitter { - private activeSpace: Space | undefined; + private activeSpace: Promise | undefined; constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { super(); @@ -29,7 +29,7 @@ export class SpacesManager extends EventEmitter { public async getActiveSpace(forceRefresh: boolean = false): Promise { if (!this.activeSpace || forceRefresh) { - this.activeSpace = (await this.http.get('/internal/spaces/_active_space')) as Space; + this.activeSpace = this.http.get('/internal/spaces/_active_space') as Promise; } return this.activeSpace; } From 6192de10d2492d5e5781f7e28ba99f343d93c60f Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 29 Oct 2019 06:56:44 -0400 Subject: [PATCH 21/42] reverting test isolation change --- x-pack/test/api_integration/apis/index.js | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/x-pack/test/api_integration/apis/index.js b/x-pack/test/api_integration/apis/index.js index eca0c860a216c..86ef445899039 100644 --- a/x-pack/test/api_integration/apis/index.js +++ b/x-pack/test/api_integration/apis/index.js @@ -8,24 +8,24 @@ export default function ({ loadTestFile }) { describe('apis', function () { this.tags('ciGroup6'); - // loadTestFile(require.resolve('./es')); - // loadTestFile(require.resolve('./security')); + loadTestFile(require.resolve('./es')); + loadTestFile(require.resolve('./security')); loadTestFile(require.resolve('./spaces')); - // loadTestFile(require.resolve('./monitoring')); - // loadTestFile(require.resolve('./xpack_main')); - // loadTestFile(require.resolve('./features')); - // loadTestFile(require.resolve('./telemetry')); - // loadTestFile(require.resolve('./logstash')); - // loadTestFile(require.resolve('./kibana')); - // loadTestFile(require.resolve('./infra')); - // loadTestFile(require.resolve('./beats')); - // loadTestFile(require.resolve('./console')); - // loadTestFile(require.resolve('./management')); - // loadTestFile(require.resolve('./uptime')); - // loadTestFile(require.resolve('./maps')); - // loadTestFile(require.resolve('./apm')); - // loadTestFile(require.resolve('./siem')); - // loadTestFile(require.resolve('./short_urls')); - // loadTestFile(require.resolve('./lens')); + loadTestFile(require.resolve('./monitoring')); + loadTestFile(require.resolve('./xpack_main')); + loadTestFile(require.resolve('./features')); + loadTestFile(require.resolve('./telemetry')); + loadTestFile(require.resolve('./logstash')); + loadTestFile(require.resolve('./kibana')); + loadTestFile(require.resolve('./infra')); + loadTestFile(require.resolve('./beats')); + loadTestFile(require.resolve('./console')); + loadTestFile(require.resolve('./management')); + loadTestFile(require.resolve('./uptime')); + loadTestFile(require.resolve('./maps')); + loadTestFile(require.resolve('./apm')); + loadTestFile(require.resolve('./siem')); + loadTestFile(require.resolve('./short_urls')); + loadTestFile(require.resolve('./lens')); }); } From 86bc36df0d4ca5cb184bdc62e84af1e180ee4172 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:07:57 -0400 Subject: [PATCH 22/42] Apply suggestions from code review Co-Authored-By: Aleh Zasypkin --- x-pack/legacy/plugins/spaces/public/plugin.tsx | 5 ++--- .../public/views/nav_control/components/spaces_menu.tsx | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 0c861a9884032..728a4771cf19a 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -18,10 +18,9 @@ export interface PluginsSetup { feature_catalogue?: FeatureCatalogueSetup; } -export class SpacesPlugin implements Plugin<{}, SpacesPluginStart, PluginsSetup> { - private spacesManager: SpacesManager | undefined; +export class SpacesPlugin implements Plugin { + private spacesManager?: SpacesManager; - constructor(initializerContext: PluginInitializerContext) {} public async start(core: CoreStart) { const serverBasePath = core.injectedMetadata.getInjectedVar('serverBasePath') as string; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx index 7a21b1e26c6c0..8b92481e98f5c 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx @@ -43,7 +43,7 @@ class SpacesMenuUI extends Component { const { searchTerm } = this.state; const items = isLoading - ? [1, 2, 3].map(this.rendePlaceholderMenuItem) + ? [1, 2, 3].map(this.renderPlaceholderMenuItem) : this.getVisibleSpaces(searchTerm).map(this.renderSpaceMenuItem); const panelProps = { @@ -188,9 +188,9 @@ class SpacesMenuUI extends Component { ); }; - private rendePlaceholderMenuItem = (key: string | number): JSX.Element => { + private renderPlaceholderMenuItem = (key: string | number): JSX.Element => { return ( - null}> + ); From 0d1d28369154c96c57a541afbaf4ddb4d2bc049e Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:13:08 -0400 Subject: [PATCH 23/42] removing unnecessary PluginInitializerContext --- x-pack/legacy/plugins/spaces/public/index.ts | 5 ++--- x-pack/legacy/plugins/spaces/public/legacy.ts | 5 +---- x-pack/legacy/plugins/spaces/public/plugin.tsx | 3 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/index.ts b/x-pack/legacy/plugins/spaces/public/index.ts index ddd02aeebc5f8..9233aae9fb12f 100644 --- a/x-pack/legacy/plugins/spaces/public/index.ts +++ b/x-pack/legacy/plugins/spaces/public/index.ts @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext } from 'src/core/public'; import { SpacesPlugin } from './plugin'; -export const plugin = (initializerContext: PluginInitializerContext) => { - return new SpacesPlugin(initializerContext); +export const plugin = () => { + return new SpacesPlugin(); }; diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 65e4003ca5169..604d7e218faab 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -8,10 +8,7 @@ import { npSetup, npStart } from 'ui/new_platform'; import { plugin } from './index'; import { SpacesPlugin, PluginsSetup } from './plugin'; -const spacesPlugin: SpacesPlugin = plugin({ - opaqueId: Symbol('spaces plugin'), - env: null as any, -}); +const spacesPlugin: SpacesPlugin = plugin(); const plugins: PluginsSetup = { feature_catalogue: npSetup.plugins.feature_catalogue, diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 728a4771cf19a..dd6182dcea462 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; +import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { FeatureCatalogueSetup } from 'src/plugins/feature_catalogue/public'; import { SpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; @@ -21,7 +21,6 @@ export interface PluginsSetup { export class SpacesPlugin implements Plugin { private spacesManager?: SpacesManager; - public async start(core: CoreStart) { const serverBasePath = core.injectedMetadata.getInjectedVar('serverBasePath') as string; this.spacesManager = new SpacesManager(serverBasePath, core.http); From c849fdefcb416ca8374a7dadb538b8af71c23490 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:13:35 -0400 Subject: [PATCH 24/42] updating advanced settings subtitle --- .../advanced_settings_subtitle.test.tsx | 1 + .../advanced_settings_subtitle/advanced_settings_subtitle.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.test.tsx index 4609f18f9d5a5..49f5233db44e2 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.test.tsx @@ -20,6 +20,7 @@ describe('AdvancedSettingsSubtitle', () => { Promise.resolve(space)} /> ); + // Wait for active space to resolve before requesting the component to update await Promise.resolve(); await Promise.resolve(); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.tsx index c30139990add2..433f8a8ccf0a2 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_subtitle/advanced_settings_subtitle.tsx @@ -18,7 +18,7 @@ export const AdvancedSettingsSubtitle = (props: Props) => { useEffect(() => { props.getActiveSpace().then(space => setActiveSpace(space)); - }, []); + }, [props]); if (!activeSpace) return null; From e4c0e439e8aa11189f2e39a13af01ff8c6369712 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:22:10 -0400 Subject: [PATCH 25/42] using NP anonymousPaths service --- .../plugins/spaces/public/views/nav_control/nav_control.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx index 2646618bf0c6b..2dce77e40af62 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx @@ -6,8 +6,6 @@ import { SpacesManager } from 'plugins/spaces/lib/spaces_manager'; import { NavControlPopover } from 'plugins/spaces/views/nav_control/nav_control_popover'; -// @ts-ignore -import { Path } from 'plugins/xpack_main/services/path'; import React from 'react'; import ReactDOM from 'react-dom'; import { CoreStart } from 'src/core/public'; @@ -17,7 +15,7 @@ export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreSta core.chrome.navControls.registerLeft({ order: 1000, mount(targetDomElement: HTMLElement) { - if (Path.isUnauthenticated()) { + if (core.http.anonymousPaths.isAnonymous(window.location.pathname)) { return () => null; } From 03e93da1d9c1c07d728c693cea585b8fa234da1f Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:25:00 -0400 Subject: [PATCH 26/42] additional nav_control_popover cleanup --- .../spaces/public/views/nav_control/nav_control_popover.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx index d716bc3d65834..a2a48dd074fb9 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx @@ -8,7 +8,6 @@ import { EuiPopover, PopoverAnchorPosition, EuiLoadingSpinner, - // @ts-ignore EuiHeaderSectionItemButton, } from '@elastic/eui'; import React, { Component } from 'react'; @@ -48,7 +47,7 @@ export class NavControlPopover extends Component { if (this.props.spacesManager) { this.props.spacesManager.on('request_refresh', () => { - this.loadSpaces(true); + this.loadSpaces({ refreshActiveSpace: true }); }); } } @@ -97,7 +96,7 @@ export class NavControlPopover extends Component { ); } - private async loadSpaces(refreshActiveSpace: boolean = false) { + private async loadSpaces({ refreshActiveSpace = false } = {}) { const { spacesManager } = this.props; if (this.state.loading) { From 7d151908ec4284e2d3b55d3b00738e9294d555a5 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 08:43:06 -0400 Subject: [PATCH 27/42] additional cleanup --- .../plugins/spaces/public/lib/spaces_manager.ts | 2 +- .../public/views/space_selector/space_selector.tsx | 4 +--- .../server/lib/toggle_ui_capabilities.test.ts | 8 ++++---- .../spaces/server/lib/toggle_ui_capabilities.ts | 14 +++++++------- .../routes/api/internal/get_active_space.test.ts | 4 ++-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index d1af8a5014020..802feada3497b 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -13,7 +13,7 @@ import { ENTER_SPACE_PATH } from '../../common/constants'; import { addSpaceIdToPath } from '../../../../../plugins/spaces/common'; export class SpacesManager extends EventEmitter { - private activeSpace: Promise | undefined; + private activeSpace?: Promise; constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { super(); diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx index 2b91649c3a1f4..d665752b3c8a6 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/space_selector.tsx @@ -41,13 +41,11 @@ class SpaceSelectorUI extends Component { constructor(props: Props) { super(props); - const state: State = { + this.state = { loading: false, searchTerm: '', spaces: [], }; - - this.state = state; } public setHeaderRef = (ref: HTMLElement | null) => { diff --git a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts index f7d0e16babc33..b92922def2eb8 100644 --- a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts +++ b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.test.ts @@ -99,7 +99,7 @@ describe('toggleUiCapabilities', () => { disabledFeatures: [], }; - const capabilities: Capabilities = buildCapabilities(); + const capabilities = buildCapabilities(); const result = toggleUICapabilities(features, capabilities, space); expect(result).toEqual(buildCapabilities()); }); @@ -111,7 +111,7 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['i-do-not-exist'], }; - const capabilities: Capabilities = buildCapabilities(); + const capabilities = buildCapabilities(); const result = toggleUICapabilities(features, capabilities, space); expect(result).toEqual(buildCapabilities()); }); @@ -123,7 +123,7 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['feature_2'], }; - const capabilities: Capabilities = buildCapabilities(); + const capabilities = buildCapabilities(); const result = toggleUICapabilities(features, capabilities, space); const expectedCapabilities = buildCapabilities(); @@ -144,7 +144,7 @@ describe('toggleUiCapabilities', () => { disabledFeatures: ['feature_1', 'feature_2', 'feature_3'], }; - const capabilities: Capabilities = buildCapabilities(); + const capabilities = buildCapabilities(); const result = toggleUICapabilities(features, capabilities, space); const expectedCapabilities = buildCapabilities(); diff --git a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.ts b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.ts index 65055bc695af2..2de84ec05017b 100644 --- a/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.ts +++ b/x-pack/plugins/spaces/server/lib/toggle_ui_capabilities.ts @@ -25,15 +25,15 @@ function toggleDisabledFeatures( capabilities: UICapabilities, activeSpace: Space ) { - const disabledFeatureKeys: string[] = activeSpace.disabledFeatures; + const disabledFeatureKeys = activeSpace.disabledFeatures; - const disabledFeatures: Feature[] = disabledFeatureKeys + const disabledFeatures = disabledFeatureKeys .map(key => features.find(feature => feature.id === key)) .filter(feature => typeof feature !== 'undefined') as Feature[]; - const navLinks: Record = capabilities.navLinks; - const catalogueEntries: Record = capabilities.catalogue; - const managementItems: Record> = capabilities.management; + const navLinks = capabilities.navLinks; + const catalogueEntries = capabilities.catalogue; + const managementItems = capabilities.management; for (const feature of disabledFeatures) { // Disable associated navLink, if one exists @@ -42,13 +42,13 @@ function toggleDisabledFeatures( } // Disable associated catalogue entries - const privilegeCatalogueEntries: string[] = feature.catalogue || []; + const privilegeCatalogueEntries = feature.catalogue || []; privilegeCatalogueEntries.forEach(catalogueEntryId => { catalogueEntries[catalogueEntryId] = false; }); // Disable associated management items - const privilegeManagementSections: Record = feature.management || {}; + const privilegeManagementSections = feature.management || {}; Object.entries(privilegeManagementSections).forEach(([sectionId, sectionItems]) => { sectionItems.forEach(item => { if ( diff --git a/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts index 33e50239470c7..83353602e9b76 100644 --- a/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/internal/get_active_space.test.ts @@ -5,7 +5,7 @@ */ import * as Rx from 'rxjs'; import { createLegacyAPI, mockRouteContextWithInvalidLicense } from '../__fixtures__'; -import { CoreSetup, IRouter, kibanaResponseFactory } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory } from 'src/core/server'; import { httpServiceMock, httpServerMock, elasticsearchServiceMock } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; @@ -16,7 +16,7 @@ import { initGetActiveSpaceApi } from './get_active_space'; describe('GET /internal/spaces/_active_space', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpServiceMock.createRouter(); const legacyAPI = createLegacyAPI(); From c3cb211a52ee512e6d2e9d6852d20efdae83f9cc Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 10:49:56 -0400 Subject: [PATCH 28/42] testing out onActiveSpaceChange$ property --- .../spaces/public/lib/spaces_manager.mock.ts | 5 +- .../spaces/public/lib/spaces_manager.ts | 58 ++++++++++--------- .../nav_control_popover.test.tsx.snap | 5 +- .../nav_control/nav_control_popover.test.tsx | 25 ++++---- .../views/nav_control/nav_control_popover.tsx | 29 ++++++---- 5 files changed, 67 insertions(+), 55 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts index b8cee9635aae5..a6a882c730b63 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +import { of, Observable } from 'rxjs'; + function createSpacesManagerMock() { return { + onActiveSpaceChange$: of(undefined) as Observable, getSpaces: jest.fn().mockResolvedValue([]), getSpace: jest.fn().mockResolvedValue(undefined), getActiveSpace: jest.fn().mockResolvedValue(undefined), @@ -15,8 +18,6 @@ function createSpacesManagerMock() { copySavedObjects: jest.fn().mockResolvedValue(undefined), resolveCopySavedObjectsErrors: jest.fn().mockResolvedValue(undefined), redirectToSpaceSelector: jest.fn().mockResolvedValue(undefined), - requestRefresh: jest.fn(), - on: jest.fn(), }; } diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index 802feada3497b..c431df961d6fd 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -3,7 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { EventEmitter } from 'events'; +import { Observable, BehaviorSubject } from 'rxjs'; +import { skipWhile } from 'rxjs/operators'; import { HttpSetup } from 'src/core/public'; import { SavedObjectsManagementRecord } from 'ui/management/saved_objects_management'; import { Space } from '../../common/model/space'; @@ -12,11 +13,15 @@ import { CopySavedObjectsToSpaceResponse } from './copy_saved_objects_to_space/t import { ENTER_SPACE_PATH } from '../../common/constants'; import { addSpaceIdToPath } from '../../../../../plugins/spaces/common'; -export class SpacesManager extends EventEmitter { - private activeSpace?: Promise; +export class SpacesManager { + private activeSpace$: BehaviorSubject = new BehaviorSubject(null); + + public readonly onActiveSpaceChange$: Observable; constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { - super(); + this.onActiveSpaceChange$ = this.activeSpace$.asObservable().pipe(skipWhile(v => !v)); + + this.refreshActiveSpace(); } public async getSpaces(purpose?: GetSpacePurpose): Promise { @@ -27,36 +32,36 @@ export class SpacesManager extends EventEmitter { return await this.http.get(`/api/spaces/space/${encodeURIComponent(id)}`); } - public async getActiveSpace(forceRefresh: boolean = false): Promise { - if (!this.activeSpace || forceRefresh) { - this.activeSpace = this.http.get('/internal/spaces/_active_space') as Promise; + public getActiveSpace({ forceRefresh = false } = {}) { + if (!forceRefresh && this.activeSpace$.value) { + return Promise.resolve(this.activeSpace$.value); } - return this.activeSpace; + return this.http.get('/internal/spaces/_active_space') as Promise; } public async createSpace(space: Space) { - return this.http - .post(`/api/spaces/space`, { - body: JSON.stringify(space), - }) - .then(() => this.requestRefresh()); + await this.http.post(`/api/spaces/space`, { + body: JSON.stringify(space), + }); } public async updateSpace(space: Space) { - return this.http - .put(`/api/spaces/space/${encodeURIComponent(space.id)}`, { - query: { - overwrite: true, - }, - body: JSON.stringify(space), - }) - .then(() => this.requestRefresh()); + await this.http.put(`/api/spaces/space/${encodeURIComponent(space.id)}`, { + query: { + overwrite: true, + }, + body: JSON.stringify(space), + }); + + const activeSpaceId = (await this.getActiveSpace()).id; + + if (space.id === activeSpaceId) { + this.refreshActiveSpace(); + } } public async deleteSpace(space: Space) { - return this.http - .delete(`/api/spaces/space/${encodeURIComponent(space.id)}`) - .then(() => this.requestRefresh()); + await this.http.delete(`/api/spaces/space/${encodeURIComponent(space.id)}`); } public async copySavedObjects( @@ -97,7 +102,8 @@ export class SpacesManager extends EventEmitter { window.location.href = `${this.serverBasePath}/spaces/space_selector`; } - public async requestRefresh() { - this.emit('request_refresh'); + private async refreshActiveSpace() { + const activeSpace = await this.getActiveSpace({ forceRefresh: true }); + this.activeSpace$.next(activeSpace); } } diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap index 408ebd659c001..5cad4e794cfda 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/__snapshots__/nav_control_popover.test.tsx.snap @@ -28,7 +28,7 @@ exports[`NavControlPopover renders without crashing 1`] = ` repositionOnScroll={true} withTitle={true} > - `; diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx index b4a80ffda44ed..a04f28242f984 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.test.tsx @@ -4,12 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { mount, shallow } from 'enzyme'; +import * as Rx from 'rxjs'; +import { shallow } from 'enzyme'; import React from 'react'; import { SpaceAvatar } from '../../components'; import { spacesManagerMock } from '../../lib/mocks'; import { SpacesManager } from '../../lib'; import { NavControlPopover } from './nav_control_popover'; +import { EuiHeaderSectionItemButton } from '@elastic/eui'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; describe('NavControlPopover', () => { it('renders without crashing', () => { @@ -39,13 +42,13 @@ describe('NavControlPopover', () => { disabledFeatures: [], }, ]); - spacesManager.getActiveSpace = jest.fn().mockResolvedValue({ + spacesManager.onActiveSpaceChange$ = Rx.of({ id: 'foo-space', name: 'foo', disabledFeatures: [], }); - const wrapper = mount( + const wrapper = mountWithIntl( { /> ); - return new Promise(resolve => { - setTimeout(() => { - expect(wrapper.state().spaces).toHaveLength(2); - wrapper.update(); - expect(wrapper.find(SpaceAvatar)).toHaveLength(1); - resolve(); - }, 20); - }); + wrapper.find(EuiHeaderSectionItemButton).simulate('click'); + + // Wait for `getSpaces` promise to resolve + await Promise.resolve(); + await Promise.resolve(); + wrapper.update(); + + expect(wrapper.find(SpaceAvatar)).toHaveLength(3); }); }); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx index a2a48dd074fb9..98ce64715f325 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control_popover.tsx @@ -12,6 +12,7 @@ import { } from '@elastic/eui'; import React, { Component } from 'react'; import { Capabilities } from 'src/core/public'; +import { Subscription } from 'rxjs'; import { Space } from '../../../common/model/space'; import { SpaceAvatar } from '../../components'; import { SpacesManager } from '../../lib/spaces_manager'; @@ -32,6 +33,8 @@ interface State { } export class NavControlPopover extends Component { + private activeSpace$?: Subscription; + constructor(props: Props) { super(props); this.state = { @@ -42,13 +45,19 @@ export class NavControlPopover extends Component { }; } - public componentDidMount() { - this.loadSpaces(); + public componentWillMount() { + this.activeSpace$ = this.props.spacesManager.onActiveSpaceChange$.subscribe({ + next: activeSpace => { + this.setState({ + activeSpace, + }); + }, + }); + } - if (this.props.spacesManager) { - this.props.spacesManager.on('request_refresh', () => { - this.loadSpaces({ refreshActiveSpace: true }); - }); + public componentWillUnmount() { + if (this.activeSpace$) { + this.activeSpace$.unsubscribe(); } } @@ -96,7 +105,7 @@ export class NavControlPopover extends Component { ); } - private async loadSpaces({ refreshActiveSpace = false } = {}) { + private async loadSpaces() { const { spacesManager } = this.props; if (this.state.loading) { @@ -107,14 +116,10 @@ export class NavControlPopover extends Component { loading: true, }); - const [activeSpace, spaces] = await Promise.all([ - spacesManager.getActiveSpace(refreshActiveSpace), - spacesManager.getSpaces(), - ]); + const spaces = await spacesManager.getSpaces(); this.setState({ spaces, - activeSpace, loading: false, }); } From 6cf91d421d7dc35c280efd279319120c16e96bcc Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 11:27:38 -0400 Subject: [PATCH 29/42] make the linter happy --- .../advanced_settings_title/advanced_settings_title.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_title/advanced_settings_title.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_title/advanced_settings_title.tsx index 588503ce13084..af6fa42cce07b 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_title/advanced_settings_title.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/advanced_settings_title/advanced_settings_title.tsx @@ -19,7 +19,7 @@ export const AdvancedSettingsTitle = (props: Props) => { useEffect(() => { props.getActiveSpace().then(space => setActiveSpace(space)); - }, []); + }, [props]); if (!activeSpace) return null; From 8146ddb43a8ecc28679b193077fc3dbd69d5a769 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 31 Oct 2019 12:13:19 -0400 Subject: [PATCH 30/42] make the type checker happy --- x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts index a6a882c730b63..69c6f7a452fdd 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.mock.ts @@ -5,10 +5,11 @@ */ import { of, Observable } from 'rxjs'; +import { Space } from '../../common/model/space'; function createSpacesManagerMock() { return { - onActiveSpaceChange$: of(undefined) as Observable, + onActiveSpaceChange$: (of(undefined) as unknown) as Observable, getSpaces: jest.fn().mockResolvedValue([]), getSpace: jest.fn().mockResolvedValue(undefined), getActiveSpace: jest.fn().mockResolvedValue(undefined), From ebd31476e771d9dbf27ff2d51f710a343cdcb968 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 20 Nov 2019 11:19:22 -0500 Subject: [PATCH 31/42] fixing types --- .../spaces/public/create_feature_catalogue_entry.ts | 2 +- x-pack/legacy/plugins/spaces/public/legacy.ts | 2 +- x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts | 4 +++- x-pack/legacy/plugins/spaces/public/plugin.tsx | 8 ++++---- .../server/routes/api/internal/get_active_space.test.ts | 4 +--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts b/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts index c26fac5d4b772..1f41bb89d7707 100644 --- a/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts +++ b/x-pack/legacy/plugins/spaces/public/create_feature_catalogue_entry.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { FeatureCatalogueEntry, FeatureCatalogueCategory, -} from '../../../../../src/plugins/feature_catalogue/public'; +} from '../../../../../src/plugins/home/public'; import { getSpacesFeatureDescription } from './lib/constants'; export const createSpacesFeatureCatalogueEntry = (): FeatureCatalogueEntry => { diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index 604d7e218faab..a2a9d8f302a9e 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -11,7 +11,7 @@ import { SpacesPlugin, PluginsSetup } from './plugin'; const spacesPlugin: SpacesPlugin = plugin(); const plugins: PluginsSetup = { - feature_catalogue: npSetup.plugins.feature_catalogue, + home: npSetup.plugins.home, }; export const setup = spacesPlugin.setup(npSetup.core, plugins); diff --git a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts index c431df961d6fd..77beefd3fd767 100644 --- a/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts +++ b/x-pack/legacy/plugins/spaces/public/lib/spaces_manager.ts @@ -19,7 +19,9 @@ export class SpacesManager { public readonly onActiveSpaceChange$: Observable; constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { - this.onActiveSpaceChange$ = this.activeSpace$.asObservable().pipe(skipWhile(v => !v)); + this.onActiveSpaceChange$ = this.activeSpace$ + .asObservable() + .pipe(skipWhile((v: Space | null) => v == null)) as Observable; this.refreshActiveSpace(); } diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index dd6182dcea462..27e213bf55851 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -5,7 +5,7 @@ */ import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { FeatureCatalogueSetup } from 'src/plugins/feature_catalogue/public'; +import { HomePublicPluginSetup } from 'src/plugins/home/public'; import { SpacesManager } from './lib'; import { initSpacesNavControl } from './views/nav_control'; import { createSpacesFeatureCatalogueEntry } from './create_feature_catalogue_entry'; @@ -15,7 +15,7 @@ export interface SpacesPluginStart { } export interface PluginsSetup { - feature_catalogue?: FeatureCatalogueSetup; + home?: HomePublicPluginSetup; } export class SpacesPlugin implements Plugin { @@ -33,8 +33,8 @@ export class SpacesPlugin implements Plugin { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: null, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); From 54f8ce796e7b30805b871d5c348d9f6d8cf7b17b Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 9 Dec 2019 09:03:46 -0500 Subject: [PATCH 32/42] fix merge from master --- x-pack/plugins/spaces/server/plugin.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/spaces/server/plugin.ts b/x-pack/plugins/spaces/server/plugin.ts index 10a3f649bca62..8630fa875c905 100644 --- a/x-pack/plugins/spaces/server/plugin.ts +++ b/x-pack/plugins/spaces/server/plugin.ts @@ -32,7 +32,6 @@ import { toggleUICapabilities } from './lib/toggle_ui_capabilities'; import { initSpacesRequestInterceptors } from './lib/request_interceptors'; import { initExternalSpacesApi } from './routes/api/external'; import { initInternalSpacesApi } from './routes/api/internal'; -import { HomeServerPluginSetup } from '../../../../src/plugins/home/server'; /** * Describes a set of APIs that is available in the legacy platform only and required by this plugin From f6249ff8608cead627b9daea75e9a3a8bf53a120 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 9 Dec 2019 11:11:26 -0500 Subject: [PATCH 33/42] spaces LP init should run on all pages, not just the kibana app --- x-pack/legacy/plugins/spaces/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index a47a1e96622f0..b93e8ab0f2dda 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -57,7 +57,7 @@ export const spaces = (kibana: Record) => hidden: true, }, ], - hacks: [], + hacks: ['plugins/spaces/legacy'], mappings, migrations: { space: { @@ -70,7 +70,7 @@ export const spaces = (kibana: Record) => hidden: true, }, }, - home: ['plugins/spaces/legacy'], + home: [], injectDefaultVars(server: Server) { return { serverBasePath: server.config().get('server.basePath'), From b27c7b7f41d58d7d10af217501cf0030a4390944 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 9 Dec 2019 12:55:37 -0500 Subject: [PATCH 34/42] address nits --- x-pack/legacy/plugins/spaces/public/legacy.ts | 2 +- .../public/views/nav_control/components/spaces_menu.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/legacy.ts b/x-pack/legacy/plugins/spaces/public/legacy.ts index a2a9d8f302a9e..99419206093e9 100644 --- a/x-pack/legacy/plugins/spaces/public/legacy.ts +++ b/x-pack/legacy/plugins/spaces/public/legacy.ts @@ -5,7 +5,7 @@ */ import { npSetup, npStart } from 'ui/new_platform'; -import { plugin } from './index'; +import { plugin } from '.'; import { SpacesPlugin, PluginsSetup } from './plugin'; const spacesPlugin: SpacesPlugin = plugin(); diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx index 8b92481e98f5c..9a26f6802abdf 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/components/spaces_menu.tsx @@ -12,7 +12,7 @@ import { EuiLoadingContent, } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import React, { Component } from 'react'; +import React, { Component, ReactElement } from 'react'; import { Capabilities } from 'src/core/public'; import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../../common/constants'; import { Space } from '../../../../common/model/space'; @@ -87,7 +87,7 @@ class SpacesMenuUI extends Component { return filteredSpaces; }; - private renderSpacesListPanel = (items: JSX.Element[], searchTerm: string) => { + private renderSpacesListPanel = (items: ReactElement[], searchTerm: string) => { if (items.length === 0) { return ( From eb2714beff9ef11ea119ebb512a20ef98abc9ff8 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 9 Dec 2019 12:56:04 -0500 Subject: [PATCH 35/42] fix infra/logs, and the spaces disabled scenario --- .../infra/public/utils/use_kibana_space_id.ts | 20 +++++++++++++------ .../legacy/plugins/spaces/public/plugin.tsx | 11 ++++++---- .../public/views/nav_control/nav_control.tsx | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts index 4642f7fd26f21..50917800b01ee 100644 --- a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts +++ b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts @@ -8,22 +8,30 @@ import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { useKibanaInjectedVar } from './use_kibana_injected_var'; +import { useState, useEffect } from 'react'; +import { start as spacesPluginStart } from '../../../spaces/public/legacy'; +import { Space } from '../../../../../plugins/spaces/common/model/space'; export const useKibanaSpaceId = (): string => { - const activeSpace = useKibanaInjectedVar('activeSpace'); + const [activeSpace, setActiveSpace] = useState(); + + useEffect(() => { + spacesPluginStart.then(({ spacesManager }) => { + if (spacesManager) { + spacesManager.getActiveSpace().then(space => setActiveSpace(space)); + } + }); + }, []); return pipe( activeSpaceRT.decode(activeSpace), fold( () => 'default', - decodedActiveSpace => decodedActiveSpace.space.id + decodedActiveSpace => decodedActiveSpace.id ) ); }; const activeSpaceRT = rt.type({ - space: rt.type({ - id: rt.string, - }), + id: rt.string, }); diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index 27e213bf55851..cb55962378613 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -11,7 +11,7 @@ import { initSpacesNavControl } from './views/nav_control'; import { createSpacesFeatureCatalogueEntry } from './create_feature_catalogue_entry'; export interface SpacesPluginStart { - spacesManager: SpacesManager; + spacesManager: SpacesManager | null; } export interface PluginsSetup { @@ -19,13 +19,16 @@ export interface PluginsSetup { } export class SpacesPlugin implements Plugin { - private spacesManager?: SpacesManager; + private spacesManager: SpacesManager | null = null; public async start(core: CoreStart) { const serverBasePath = core.injectedMetadata.getInjectedVar('serverBasePath') as string; - this.spacesManager = new SpacesManager(serverBasePath, core.http); + const spacesEnabled = core.injectedMetadata.getInjectedVar('spacesEnabled') as boolean; - initSpacesNavControl(this.spacesManager, core); + if (spacesEnabled) { + this.spacesManager = new SpacesManager(serverBasePath, core.http); + initSpacesNavControl(this.spacesManager, core); + } return { spacesManager: this.spacesManager, diff --git a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx index 2dce77e40af62..0df077e0d2da0 100644 --- a/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/nav_control/nav_control.tsx @@ -5,10 +5,10 @@ */ import { SpacesManager } from 'plugins/spaces/lib/spaces_manager'; -import { NavControlPopover } from 'plugins/spaces/views/nav_control/nav_control_popover'; import React from 'react'; import ReactDOM from 'react-dom'; import { CoreStart } from 'src/core/public'; +import { NavControlPopover } from './nav_control_popover'; export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreStart) { const I18nContext = core.i18n.Context; From 1871ef7da24c8f1c02246030ee25f66989aea315 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Mon, 9 Dec 2019 13:10:57 -0500 Subject: [PATCH 36/42] fix typescript errors --- .../legacy/plugins/spaces/public/views/management/index.tsx | 4 ++-- .../plugins/spaces/public/views/management/page_routes.tsx | 6 +++--- .../plugins/spaces/public/views/space_selector/index.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx index 063542a38355a..bf33273c614d6 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/index.tsx @@ -49,7 +49,7 @@ routes.defaults(/\/management/, { // Customize Saved Objects Management spacesNPStart.then(({ spacesManager }) => { - const action = new CopyToSpaceSavedObjectsManagementAction(spacesManager); + const action = new CopyToSpaceSavedObjectsManagementAction(spacesManager!); // This route resolve function executes any time the management screen is loaded, and we want to ensure // that this action is only registered once. if (!managementSetup.savedObjects.registry.has(action.id)) { @@ -59,7 +59,7 @@ routes.defaults(/\/management/, { const getActiveSpace = async () => { const { spacesManager } = await spacesNPStart; - return spacesManager.getActiveSpace(); + return spacesManager!.getActiveSpace(); }; const PageTitle = () => ; diff --git a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx index e18a10f9cce50..d8fd0298df2fc 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/page_routes.tsx @@ -32,7 +32,7 @@ routes.when('/management/spaces/list', { render( , @@ -62,7 +62,7 @@ routes.when('/management/spaces/create', { render( , @@ -99,7 +99,7 @@ routes.when('/management/spaces/edit/:spaceId', { diff --git a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx index b7607a87a9c98..c520c2683c965 100644 --- a/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/space_selector/index.tsx @@ -26,7 +26,7 @@ module.controller('spacesSelectorController', ($scope: any) => { render( - + , domNode ); From d771522adb41e5a3735028afeb5f3f4ca231b702 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 10 Dec 2019 16:14:17 -0500 Subject: [PATCH 37/42] revert changes to infra plugin --- .../infra/public/utils/use_kibana_space_id.ts | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts index 50917800b01ee..4642f7fd26f21 100644 --- a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts +++ b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts @@ -8,30 +8,22 @@ import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { useState, useEffect } from 'react'; -import { start as spacesPluginStart } from '../../../spaces/public/legacy'; -import { Space } from '../../../../../plugins/spaces/common/model/space'; +import { useKibanaInjectedVar } from './use_kibana_injected_var'; export const useKibanaSpaceId = (): string => { - const [activeSpace, setActiveSpace] = useState(); - - useEffect(() => { - spacesPluginStart.then(({ spacesManager }) => { - if (spacesManager) { - spacesManager.getActiveSpace().then(space => setActiveSpace(space)); - } - }); - }, []); + const activeSpace = useKibanaInjectedVar('activeSpace'); return pipe( activeSpaceRT.decode(activeSpace), fold( () => 'default', - decodedActiveSpace => decodedActiveSpace.id + decodedActiveSpace => decodedActiveSpace.space.id ) ); }; const activeSpaceRT = rt.type({ - id: rt.string, + space: rt.type({ + id: rt.string, + }), }); From 0186d5f528f798b1ccc67ac488ae2de37cc05f15 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 10 Dec 2019 16:24:17 -0500 Subject: [PATCH 38/42] reintroducing activeSpace injected var for legacy plugins --- .../infra/public/utils/use_kibana_space_id.ts | 1 + x-pack/legacy/plugins/spaces/index.ts | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts index 4642f7fd26f21..52c896feef1a2 100644 --- a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts +++ b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts @@ -11,6 +11,7 @@ import * as rt from 'io-ts'; import { useKibanaInjectedVar } from './use_kibana_injected_var'; export const useKibanaSpaceId = (): string => { + // NOTICE: use of `activeSpace` is deprecated and will not be made available in the New Platform. const activeSpace = useKibanaInjectedVar('activeSpace'); return pipe( diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index b93e8ab0f2dda..ebcfe512c89f6 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -7,11 +7,13 @@ import { resolve } from 'path'; import KbnServer, { Server } from 'src/legacy/server/kbn_server'; import { Legacy } from 'kibana'; +import { KibanaRequest } from '../../../../src/core/server'; import { SpacesServiceSetup } from '../../../plugins/spaces/server/spaces_service/spaces_service'; import { SpacesPluginSetup } from '../../../plugins/spaces/server'; // @ts-ignore import { AuditLogger } from '../../server/lib/audit_logger'; import mappings from './mappings.json'; +import { wrapError } from './server/lib/errors'; import { migrateToKibana660 } from './server/lib/migrations'; // @ts-ignore import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize'; @@ -76,6 +78,35 @@ export const spaces = (kibana: Record) => serverBasePath: server.config().get('server.basePath'), }; }, + async replaceInjectedVars( + vars: Record, + request: Legacy.Request, + server: Server + ) { + // NOTICE: use of `activeSpace` is deprecated and will not be made available in the New Platform. + // Known usages: + // - x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts + const spacesPlugin = server.newPlatform.setup.plugins.spaces as SpacesPluginSetup; + if (!spacesPlugin) { + throw new Error('New Platform XPack Spaces plugin is not available.'); + } + const kibanaRequest = KibanaRequest.from(request); + const spaceId = spacesPlugin.spacesService.getSpaceId(kibanaRequest); + const spacesClient = await spacesPlugin.spacesService.scopedClient(kibanaRequest); + try { + vars.activeSpace = { + valid: true, + space: await spacesClient.get(spaceId), + }; + } catch (e) { + vars.activeSpace = { + valid: false, + error: wrapError(e).output.payload, + }; + } + + return vars; + }, }, async init(server: Server) { From 5b2c16a42912846312966c22ecf93e8bb541b302 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 11 Dec 2019 07:41:30 -0500 Subject: [PATCH 39/42] fixing react deprecation warning and unhandled promise rejection --- .../views/management/components/confirm_delete_modal.test.tsx | 2 ++ .../public/views/management/components/confirm_delete_modal.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx index db1bebe1dd0ce..f0ab2c99ac2e2 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.test.tsx @@ -19,6 +19,7 @@ describe('ConfirmDeleteModal', () => { }; const spacesManager = spacesManagerMock.create(); + spacesManager.getActiveSpace.mockResolvedValue(space); const onCancel = jest.fn(); const onConfirm = jest.fn(); @@ -44,6 +45,7 @@ describe('ConfirmDeleteModal', () => { }; const spacesManager = spacesManagerMock.create(); + spacesManager.getActiveSpace.mockResolvedValue(space); const onCancel = jest.fn(); const onConfirm = jest.fn(); diff --git a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.tsx b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.tsx index 36d419f5f467a..0c76cb4a828fe 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/components/confirm_delete_modal.tsx @@ -51,7 +51,7 @@ class ConfirmDeleteModalUI extends Component { isDeletingCurrentSpace: false, }; - public componentWillMount() { + public componentDidMount() { isCurrentSpace(this.props.space, this.props.spacesManager).then(result => { this.setState({ isDeletingCurrentSpace: result, From e29437b996f2f09b797807ad1926a62781e0d38c Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 11 Dec 2019 09:20:09 -0500 Subject: [PATCH 40/42] restore activeSpace default var --- x-pack/legacy/plugins/spaces/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index ebcfe512c89f6..edea4ae7d5c5b 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -76,6 +76,7 @@ export const spaces = (kibana: Record) => injectDefaultVars(server: Server) { return { serverBasePath: server.config().get('server.basePath'), + activeSpace: null, }; }, async replaceInjectedVars( From 2ff6cb88228533c628f816899e79e305b438083c Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Fri, 13 Dec 2019 13:40:12 -0500 Subject: [PATCH 41/42] spaces does not need to check its own enabled status --- x-pack/legacy/plugins/spaces/public/plugin.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/spaces/public/plugin.tsx b/x-pack/legacy/plugins/spaces/public/plugin.tsx index cb55962378613..4e070c3cee3df 100644 --- a/x-pack/legacy/plugins/spaces/public/plugin.tsx +++ b/x-pack/legacy/plugins/spaces/public/plugin.tsx @@ -23,12 +23,9 @@ export class SpacesPlugin implements Plugin Date: Fri, 13 Dec 2019 14:19:22 -0500 Subject: [PATCH 42/42] fix from merge --- .../public/views/management/spaces_grid/spaces_grid_page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx index 11a4a588095de..9fa03b1a9b74a 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.tsx @@ -20,8 +20,8 @@ import { } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import { kfetch } from 'ui/kfetch'; -// @ts-ignore import { toastNotifications } from 'ui/notify'; +import { Capabilities } from 'src/core/public'; import { Feature } from '../../../../../../../plugins/features/public'; import { isReservedSpace } from '../../../../common'; import { DEFAULT_SPACE_ID } from '../../../../common/constants';