Skip to content

Commit

Permalink
[8.x] [Stateful sidenav] Enable on-prem (#203239) (#203796)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.x`:
- [[Stateful sidenav] Enable on-prem
(#203239)](#203239)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Sébastien
Loix","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-11T13:12:15Z","message":"[Stateful
sidenav] Enable on-prem
(#203239)","sha":"771166bf7f95e95bc1e999919f6a75e26e157d0f","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Feature:Security/Spaces","v9.0.0","Team:SharedUX","backport:prev-minor","Feature:Chrome"],"title":"[Stateful
sidenav] Enable
on-prem","number":203239,"url":"https://github.com/elastic/kibana/pull/203239","mergeCommit":{"message":"[Stateful
sidenav] Enable on-prem
(#203239)","sha":"771166bf7f95e95bc1e999919f6a75e26e157d0f"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203239","number":203239,"mergeCommit":{"message":"[Stateful
sidenav] Enable on-prem
(#203239)","sha":"771166bf7f95e95bc1e999919f6a75e26e157d0f"}}]}]
BACKPORT-->

Co-authored-by: Sébastien Loix <[email protected]>
  • Loading branch information
kibanamachine and sebelga authored Dec 11, 2024
1 parent 5a6fcab commit 16ca90a
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 352 deletions.
1 change: 0 additions & 1 deletion .buildkite/ftr_platform_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ enabled:
- x-pack/test/functional/apps/security/config.ts
- x-pack/test/functional/apps/snapshot_restore/config.ts
- x-pack/test/functional/apps/spaces/config.ts
- x-pack/test/functional/apps/spaces/solution_view_flag_enabled/config.ts
- x-pack/test/functional/apps/status_page/config.ts
- x-pack/test/functional/apps/transform/creation/index_pattern/config.ts
- x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/config.ts
Expand Down
3 changes: 0 additions & 3 deletions x-pack/plugins/spaces/public/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,4 @@ export interface ConfigType {
maxSpaces: number;
allowFeatureVisibility: boolean;
allowSolutionVisibility: boolean;
experimental: {
forceSolutionVisibility: boolean;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ describe('ManagementService', () => {
maxSpaces: 1000,
allowFeatureVisibility: true,
allowSolutionVisibility: true,
experimental: {
forceSolutionVisibility: false,
},
};

describe('#setup', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ const config: ConfigType = {
maxSpaces: 1000,
allowFeatureVisibility: true,
allowSolutionVisibility: true,
experimental: {
forceSolutionVisibility: false,
},
};

const eventTracker = new EventTracker({ reportEvent: jest.fn() });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const SolutionViewTour: FC<Props> = ({ children, solution, isTourOpen, on
onFinish={onFinishTour}
step={1}
stepsTotal={1}
repositionOnScroll
title={i18n.translate('xpack.spaces.navControl.tour.title', {
defaultMessage: 'You chose the {solution} solution view',
values: { solution: solutionLabel },
Expand Down
137 changes: 30 additions & 107 deletions x-pack/plugins/spaces/public/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
import { coreMock } from '@kbn/core/public/mocks';
import { homePluginMock } from '@kbn/home-plugin/public/mocks';
import {
Expand All @@ -20,7 +19,7 @@ describe('Spaces plugin', () => {
it('should register the space selector app when buildFlavor is traditional', () => {
const coreSetup = coreMock.createSetup();
const mockInitializerContext = coreMock.createPluginInitializerContext(
{},
{ allowSolutionVisibility: true },
{ buildFlavor: 'traditional' }
);

Expand All @@ -40,7 +39,7 @@ describe('Spaces plugin', () => {
it('should not register the space selector app when buildFlavor is serverless and maxSpaces is 1', () => {
const coreSetup = coreMock.createSetup();
const mockInitializerContext = coreMock.createPluginInitializerContext(
{ maxSpaces: 1 },
{ maxSpaces: 1, allowSolutionVisibility: true },
{ buildFlavor: 'serverless' }
);

Expand All @@ -60,7 +59,7 @@ describe('Spaces plugin', () => {
it('should register the space selector app when buildFlavor is serverless and and maxSpaces is >1', () => {
const coreSetup = coreMock.createSetup();
const mockInitializerContext = coreMock.createPluginInitializerContext(
{ maxSpaces: 2 },
{ maxSpaces: 2, allowSolutionVisibility: true },
{ buildFlavor: 'serverless' }
);

Expand Down Expand Up @@ -88,7 +87,7 @@ describe('Spaces plugin', () => {
management.sections.section.kibana = mockSection;

const mockInitializerContext = coreMock.createPluginInitializerContext(
{},
{ allowSolutionVisibility: true },
{ buildFlavor: 'traditional' }
);

Expand Down Expand Up @@ -122,7 +121,9 @@ describe('Spaces plugin', () => {

management.sections.section.kibana = mockSection;

const plugin = new SpacesPlugin(coreMock.createPluginInitializerContext({ maxSpaces: 1 }));
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext({ maxSpaces: 1, allowSolutionVisibility: true })
);
plugin.setup(coreSetup, {
management,
home,
Expand Down Expand Up @@ -152,7 +153,9 @@ describe('Spaces plugin', () => {

management.sections.section.kibana = mockSection;

const plugin = new SpacesPlugin(coreMock.createPluginInitializerContext({ maxSpaces: 2 }));
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext({ maxSpaces: 2, allowSolutionVisibility: true })
);
plugin.setup(coreSetup, {
management,
home,
Expand All @@ -179,7 +182,7 @@ describe('Spaces plugin', () => {
const coreStart = coreMock.createStart();

const mockInitializerContext = coreMock.createPluginInitializerContext(
{},
{ allowSolutionVisibility: true },
{ buildFlavor: 'traditional' }
);

Expand All @@ -196,7 +199,7 @@ describe('Spaces plugin', () => {
const coreStart = coreMock.createStart();

const mockInitializerContext = coreMock.createPluginInitializerContext(
{ maxSpaces: 1 },
{ maxSpaces: 1, allowSolutionVisibility: true },
{ buildFlavor: 'serverless' }
);

Expand All @@ -214,7 +217,9 @@ describe('Spaces plugin', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();

const plugin = new SpacesPlugin(coreMock.createPluginInitializerContext({ maxSpaces: 1 }));
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext({ maxSpaces: 1, allowSolutionVisibility: true })
);
const spacesSetup = plugin.setup(coreSetup, {});
const spacesStart = plugin.start(coreStart);

Expand All @@ -226,7 +231,9 @@ describe('Spaces plugin', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();

const plugin = new SpacesPlugin(coreMock.createPluginInitializerContext({ maxSpaces: 1000 }));
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext({ maxSpaces: 1000, allowSolutionVisibility: true })
);
const spacesSetup = plugin.setup(coreSetup, {});
const spacesStart = plugin.start(coreStart);

Expand All @@ -236,129 +243,45 @@ describe('Spaces plugin', () => {
});

describe('isSolutionViewEnabled', () => {
it('when onCloud, not serverless and allowSolutionVisibility is "true"', () => {
it('when allowSolutionVisibility is "true"', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();
const cloud = cloudMock.createSetup();
cloud.isCloudEnabled = true;

const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: true },
{ buildFlavor: 'traditional' }
)
coreMock.createPluginInitializerContext({ allowSolutionVisibility: true })
);
const spacesSetup = plugin.setup(coreSetup, { cloud });
const spacesSetup = plugin.setup(coreSetup, {});
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(true);
expect(spacesStart.isSolutionViewEnabled).toBe(true);
});

it('when not onCloud and allowSolutionVisibility is "true"', () => {
it('when allowSolutionVisibility is "false"', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();

{
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: true }, // it is true but we are not onCloud
{ buildFlavor: 'traditional' }
)
coreMock.createPluginInitializerContext({ allowSolutionVisibility: false })
);
const spacesSetup = plugin.setup(coreSetup, {});
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(false); // so it should be false
expect(spacesStart.isSolutionViewEnabled).toBe(false);
}

{
// unless the forceSolutionVisibility flag is set
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: false, experimental: { forceSolutionVisibility: true } },
{ buildFlavor: 'traditional' }
)
);
const spacesSetup = plugin.setup(coreSetup, {}); // we are not onCloud but forceSolutionVisibility is true
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(true);
expect(spacesStart.isSolutionViewEnabled).toBe(true);
}
});

it('when onCloud, not serverless and allowSolutionVisibility is "false"', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();
const cloud = cloudMock.createSetup();
cloud.isCloudEnabled = true;

{
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: false },
{ buildFlavor: 'traditional' }
)
);
const spacesSetup = plugin.setup(coreSetup, { cloud });
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(false);
expect(spacesStart.isSolutionViewEnabled).toBe(false);
}

{
// unless the forceSolutionVisibility flag is set
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: false, experimental: { forceSolutionVisibility: true } },
{ buildFlavor: 'traditional' }
)
);
const spacesSetup = plugin.setup(coreSetup, { cloud });
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(true);
expect(spacesStart.isSolutionViewEnabled).toBe(true);
}
});

it('when onCloud and serverless', () => {
it('when allowSolutionVisibility is "undefined"', () => {
const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();
const cloud = cloudMock.createSetup();
cloud.isCloudEnabled = true;

{
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: true },
{ buildFlavor: 'serverless' }
)
);
const spacesSetup = plugin.setup(coreSetup, { cloud });
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(false);
expect(spacesStart.isSolutionViewEnabled).toBe(false);
}

{
// unless the forceSolutionVisibility flag is set
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext(
{ allowSolutionVisibility: true, experimental: { forceSolutionVisibility: true } },
{ buildFlavor: 'serverless' }
)
);
const spacesSetup = plugin.setup(coreSetup, { cloud });
const spacesStart = plugin.start(coreStart);

expect(spacesSetup.isSolutionViewEnabled).toBe(true);
expect(spacesStart.isSolutionViewEnabled).toBe(true);
}
const plugin = new SpacesPlugin(
coreMock.createPluginInitializerContext({ allowSolutionVisibility: undefined })
);
expect(() => plugin.setup(coreSetup, {})).toThrowErrorMatchingInlineSnapshot(
`"allowSolutionVisibility has not been set in the Spaces plugin config."`
);
});
});
});
20 changes: 6 additions & 14 deletions x-pack/plugins/spaces/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,11 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
}

public setup(core: CoreSetup<PluginsStart, SpacesPluginStart>, plugins: PluginsSetup) {
const hasOnlyDefaultSpace = this.config.maxSpaces === 1;
const onCloud = plugins.cloud !== undefined && plugins.cloud.isCloudEnabled;
if (this.config.allowSolutionVisibility === undefined) {
throw new Error('allowSolutionVisibility has not been set in the Spaces plugin config.');
}

// We only allow "solution" to be set on cloud environments, not on prem
// unless the forceSolutionVisibility flag is set
const allowSolutionVisibility =
(onCloud && !this.isServerless && this.config.allowSolutionVisibility) ||
Boolean(this.config.experimental?.forceSolutionVisibility);
const hasOnlyDefaultSpace = this.config.maxSpaces === 1;

this.spacesManager = new SpacesManager(core.http);
this.spacesApi = {
Expand All @@ -77,12 +74,7 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
getActiveSpace$: () => this.spacesManager.onActiveSpaceChange$,
getActiveSpace: () => this.spacesManager.getActiveSpace(),
hasOnlyDefaultSpace,
isSolutionViewEnabled: allowSolutionVisibility,
};

this.config = {
...this.config,
allowSolutionVisibility,
isSolutionViewEnabled: this.config.allowSolutionVisibility,
};

registerSpacesEventTypes(core);
Expand Down Expand Up @@ -166,7 +158,7 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart

registerAnalyticsContext(core.analytics, this.spacesManager.onActiveSpaceChange$);

return { hasOnlyDefaultSpace, isSolutionViewEnabled: allowSolutionVisibility };
return { hasOnlyDefaultSpace, isSolutionViewEnabled: this.config.allowSolutionVisibility };
}

public start(core: CoreStart) {
Expand Down
3 changes: 0 additions & 3 deletions x-pack/plugins/spaces/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ export const config: PluginConfigDescriptor = {
maxSpaces: true,
allowFeatureVisibility: true,
allowSolutionVisibility: true,
experimental: {
forceSolutionVisibility: true,
},
},
};

Expand Down
10 changes: 2 additions & 8 deletions x-pack/plugins/spaces/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ describe('Spaces plugin', () => {
"hasOnlyDefaultSpace$": Observable {
"operator": [Function],
"source": Observable {
"operator": [Function],
"source": Observable {
"_subscribe": [Function],
},
"_subscribe": [Function],
},
},
"spacesClient": Object {
Expand Down Expand Up @@ -123,10 +120,7 @@ describe('Spaces plugin', () => {
"hasOnlyDefaultSpace$": Observable {
"operator": [Function],
"source": Observable {
"operator": [Function],
"source": Observable {
"_subscribe": [Function],
},
"_subscribe": [Function],
},
},
"spacesService": Object {
Expand Down
Loading

0 comments on commit 16ca90a

Please sign in to comment.