From 22e36117c41caa757cdcf962e5c2c065f21bbc0b Mon Sep 17 00:00:00 2001 From: Jeramy Soucy Date: Thu, 3 Oct 2024 13:03:25 +0200 Subject: [PATCH] Removes visible features column from spaces grid when in serverless (#194438) Closes #194403 ## Summary Removes the 'Features visible' column from the Spaces management page grid when in serverless. ### Tests - x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx ### Manual tesing - Start ES & Kibana in serverless mode, with a `xpack.spaces.maxSpaces` setting > 1 - Navigate to spaces management page and verify that the 'Features visible' column is not present - Start ES & Kibana in stateful mode - Navigate to spaces management page and verify that the 'Features visible' column is present --- .../management/management_service.test.ts | 3 + .../public/management/management_service.tsx | 3 + .../spaces_grid/spaces_grid_page.test.tsx | 79 +++++++++++++++++++ .../spaces_grid/spaces_grid_page.tsx | 4 +- .../management/spaces_management_app.test.tsx | 4 +- .../management/spaces_management_app.tsx | 3 + x-pack/plugins/spaces/public/plugin.tsx | 1 + 7 files changed, 95 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/spaces/public/management/management_service.test.ts b/x-pack/plugins/spaces/public/management/management_service.test.ts index 40a61397e286f..d1d7fe8d160a9 100644 --- a/x-pack/plugins/spaces/public/management/management_service.test.ts +++ b/x-pack/plugins/spaces/public/management/management_service.test.ts @@ -50,6 +50,7 @@ describe('ManagementService', () => { getRolesAPIClient: getRolesAPIClientMock, getPrivilegesAPIClient: jest.fn(), eventTracker, + isServerless: false, }); expect(mockKibanaSection.registerApp).toHaveBeenCalledTimes(1); @@ -73,6 +74,7 @@ describe('ManagementService', () => { getRolesAPIClient: getRolesAPIClientMock, getPrivilegesAPIClient: jest.fn(), eventTracker, + isServerless: false, }); }); }); @@ -97,6 +99,7 @@ describe('ManagementService', () => { getRolesAPIClient: jest.fn(), getPrivilegesAPIClient: jest.fn(), eventTracker, + isServerless: false, }); service.stop(); diff --git a/x-pack/plugins/spaces/public/management/management_service.tsx b/x-pack/plugins/spaces/public/management/management_service.tsx index 0379189e192c3..ba66229323bc8 100644 --- a/x-pack/plugins/spaces/public/management/management_service.tsx +++ b/x-pack/plugins/spaces/public/management/management_service.tsx @@ -28,6 +28,7 @@ interface SetupDeps { eventTracker: EventTracker; getPrivilegesAPIClient: () => Promise; logger: Logger; + isServerless: boolean; } export class ManagementService { @@ -42,6 +43,7 @@ export class ManagementService { getRolesAPIClient, eventTracker, getPrivilegesAPIClient, + isServerless, }: SetupDeps) { this.registeredSpacesManagementApp = management.sections.section.kibana.registerApp( spacesManagementApp.create({ @@ -52,6 +54,7 @@ export class ManagementService { getRolesAPIClient, eventTracker, getPrivilegesAPIClient, + isServerless, }) ); } diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx index c8707f8959f0c..abb184bcb4382 100644 --- a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx @@ -60,6 +60,7 @@ featuresStart.getFeatures.mockResolvedValue([ const spacesGridCommonProps = { serverBasePath: '', maxSpaces: 1000, + isServerless: false, }; describe('SpacesGridPage', () => { @@ -326,6 +327,7 @@ describe('SpacesGridPage', () => { maxSpaces={1} allowSolutionVisibility serverBasePath={spacesGridCommonProps.serverBasePath} + isServerless={false} /> ); @@ -410,4 +412,81 @@ describe('SpacesGridPage', () => { title: 'Error loading spaces', }); }); + + it(`renders the 'Features visible' column when not serverless`, async () => { + const httpStart = httpServiceMock.createStartContract(); + httpStart.get.mockResolvedValue([]); + + const error = new Error('something awful happened'); + + const notifications = notificationServiceMock.createStartContract(); + + const wrapper = shallowWithIntl( + Promise.reject(error)} + notifications={notifications} + getUrlForApp={getUrlForApp} + history={history} + capabilities={{ + navLinks: {}, + management: {}, + catalogue: {}, + spaces: { manage: true }, + }} + allowSolutionVisibility + {...spacesGridCommonProps} + /> + ); + + // allow spacesManager to load spaces and lazy-load SpaceAvatar + await act(async () => {}); + wrapper.update(); + + expect(wrapper.find('EuiInMemoryTable').prop('columns')).toContainEqual( + expect.objectContaining({ + field: 'disabledFeatures', + name: 'Features visible', + }) + ); + }); + + it(`does not render the 'Features visible' column when serverless`, async () => { + const httpStart = httpServiceMock.createStartContract(); + httpStart.get.mockResolvedValue([]); + + const error = new Error('something awful happened'); + + const notifications = notificationServiceMock.createStartContract(); + + const wrapper = shallowWithIntl( + Promise.reject(error)} + notifications={notifications} + getUrlForApp={getUrlForApp} + history={history} + capabilities={{ + navLinks: {}, + management: {}, + catalogue: {}, + spaces: { manage: true }, + }} + allowSolutionVisibility + {...spacesGridCommonProps} + isServerless={true} + /> + ); + + // allow spacesManager to load spaces and lazy-load SpaceAvatar + await act(async () => {}); + wrapper.update(); + + expect(wrapper.find('EuiInMemoryTable').prop('columns')).not.toContainEqual( + expect.objectContaining({ + field: 'disabledFeatures', + name: 'Features visible', + }) + ); + }); }); diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx index 462b65f327ebc..3049fb00d8977 100644 --- a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx @@ -63,6 +63,7 @@ interface Props { getUrlForApp: ApplicationStart['getUrlForApp']; maxSpaces: number; allowSolutionVisibility: boolean; + isServerless: boolean; } interface State { @@ -335,7 +336,8 @@ export class SpacesGridPage extends Component { }, ]; - const shouldShowFeaturesColumn = !activeSolution || activeSolution === SOLUTION_VIEW_CLASSIC; + const shouldShowFeaturesColumn = + !this.props.isServerless && (!activeSolution || activeSolution === SOLUTION_VIEW_CLASSIC); if (shouldShowFeaturesColumn) { config.push({ field: 'disabledFeatures', diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx index a04335613e59b..ffafe432a5a3b 100644 --- a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx @@ -78,6 +78,7 @@ async function mountApp(basePath: string, pathname: string, spaceId?: string) { getRolesAPIClient: jest.fn(), getPrivilegesAPIClient: jest.fn(), eventTracker, + isServerless: false, }) .mount({ basePath, @@ -102,6 +103,7 @@ describe('spacesManagementApp', () => { getRolesAPIClient: jest.fn(), getPrivilegesAPIClient: jest.fn(), eventTracker, + isServerless: false, }) ).toMatchInlineSnapshot(` Object { @@ -126,7 +128,7 @@ describe('spacesManagementApp', () => { css="You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)." data-test-subj="kbnRedirectAppLink" > - Spaces Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"serverBasePath":"","history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}},"maxSpaces":1000,"allowSolutionVisibility":true} + Spaces Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"serverBasePath":"","history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}},"maxSpaces":1000,"allowSolutionVisibility":true,"isServerless":false} `); diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx index fa74316779a7e..7ad85d0ef7c52 100644 --- a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx @@ -36,6 +36,7 @@ interface CreateParams { getRolesAPIClient: () => Promise; eventTracker: EventTracker; getPrivilegesAPIClient: () => Promise; + isServerless: boolean; } export const spacesManagementApp = Object.freeze({ @@ -48,6 +49,7 @@ export const spacesManagementApp = Object.freeze({ eventTracker, getRolesAPIClient, getPrivilegesAPIClient, + isServerless, }: CreateParams) { const title = i18n.translate('xpack.spaces.displayName', { defaultMessage: 'Spaces', @@ -92,6 +94,7 @@ export const spacesManagementApp = Object.freeze({ getUrlForApp={application.getUrlForApp} maxSpaces={config.maxSpaces} allowSolutionVisibility={config.allowSolutionVisibility} + isServerless={isServerless} /> ); }; diff --git a/x-pack/plugins/spaces/public/plugin.tsx b/x-pack/plugins/spaces/public/plugin.tsx index 86196333c0883..8450aaff32657 100644 --- a/x-pack/plugins/spaces/public/plugin.tsx +++ b/x-pack/plugins/spaces/public/plugin.tsx @@ -129,6 +129,7 @@ export class SpacesPlugin implements Plugin