diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx
index f169395688de1..ac60902920fa9 100644
--- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx
+++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx
@@ -98,6 +98,8 @@ describe('ManageSpacePage', () => {
nameInput.simulate('change', { target: { value: 'New Space Name' } });
descriptionInput.simulate('change', { target: { value: 'some description' } });
+ updateSpace(wrapper, false, 'oblt');
+
const createButton = wrapper.find('button[data-test-subj="save-space-button"]');
createButton.simulate('click');
await Promise.resolve();
@@ -110,9 +112,78 @@ describe('ManageSpacePage', () => {
color: '#AA6556',
imageUrl: '',
disabledFeatures: [],
+ solution: 'oblt',
});
});
+ it('validates the form (name, initials, solution view...)', async () => {
+ const spacesManager = spacesManagerMock.create();
+ spacesManager.createSpace = jest.fn(spacesManager.createSpace);
+ spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space);
+
+ const wrapper = mountWithIntl(
+
+ );
+
+ await waitFor(() => {
+ wrapper.update();
+ expect(wrapper.find('input[name="name"]')).toHaveLength(1);
+ });
+
+ const createButton = wrapper.find('button[data-test-subj="save-space-button"]');
+ createButton.simulate('click');
+ await Promise.resolve();
+
+ {
+ const errors = wrapper.find('.euiFormErrorText').map((node) => node.text());
+ expect(errors).toEqual([
+ 'Enter a name.',
+ 'Enter a URL identifier.',
+ 'Enter initials.',
+ 'Select one solution.',
+ ]);
+
+ expect(spacesManager.createSpace).not.toHaveBeenCalled();
+
+ const nameInput = wrapper.find('input[name="name"]');
+ nameInput.simulate('change', { target: { value: 'New Space Name' } });
+ }
+
+ createButton.simulate('click');
+ await Promise.resolve();
+
+ {
+ const errors = wrapper.find('.euiFormErrorText').map((node) => node.text());
+ expect(errors).toEqual(['Select one solution.']); // requires solution view to be set
+ }
+
+ updateSpace(wrapper, false, 'oblt');
+
+ createButton.simulate('click');
+ await Promise.resolve();
+
+ {
+ const errors = wrapper.find('.euiFormErrorText').map((node) => node.text());
+ expect(errors).toEqual([]); // no more errors
+ }
+
+ expect(spacesManager.createSpace).toHaveBeenCalled();
+ });
+
it('shows solution view select when visible', async () => {
const spacesManager = spacesManagerMock.create();
spacesManager.createSpace = jest.fn(spacesManager.createSpace);
diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx
index cb81ae9304260..4f45b55fb1630 100644
--- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx
+++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx
@@ -206,6 +206,8 @@ export class ManageSpacePage extends Component {
{
const originalSpace: Space = this.state.originalSpace as Space;
const space: Space = this.state.space as Space;
const { haveDisabledFeaturesChanged, hasSolutionViewChanged } = this.state;
- const result = this.validator.validateForSave(space);
+ const result = this.validator.validateForSave(
+ space,
+ this.editingExistingSpace(),
+ this.props.allowSolutionVisibility
+ );
if (result.isInvalid) {
this.setState({
formError: result,
diff --git a/x-pack/plugins/spaces/public/management/edit_space/solution_view/solution_view.tsx b/x-pack/plugins/spaces/public/management/edit_space/solution_view/solution_view.tsx
index 608454a75600b..9d7ca7140956c 100644
--- a/x-pack/plugins/spaces/public/management/edit_space/solution_view/solution_view.tsx
+++ b/x-pack/plugins/spaces/public/management/edit_space/solution_view/solution_view.tsx
@@ -24,6 +24,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { Space } from '../../../../common';
+import type { SpaceValidator } from '../../lib';
import { SectionPanel } from '../section_panel';
type SolutionView = Space['solution'];
@@ -98,10 +99,18 @@ const getOptions = ({ size }: EuiThemeComputed): Array;
onChange: (space: Partial) => void;
+ isEditing: boolean;
+ validator: SpaceValidator;
sectionTitle?: string;
}
-export const SolutionView: FunctionComponent = ({ space, onChange, sectionTitle }) => {
+export const SolutionView: FunctionComponent = ({
+ space,
+ onChange,
+ validator,
+ isEditing,
+ sectionTitle,
+}) => {
const { euiTheme } = useEuiTheme();
return (
@@ -132,6 +141,7 @@ export const SolutionView: FunctionComponent = ({ space, onChange, sectio
defaultMessage: 'Solution view',
})}
fullWidth
+ {...validator.validateSolutionView(space, isEditing)}
>
= ({ space, onChange, sectio
onChange={(solution) => {
onChange({ ...space, solution });
}}
+ placeholder={i18n.translate(
+ 'xpack.spaces.management.navigation.solutionViewDefaultValue',
+ {
+ defaultMessage: 'Classic (Default)',
+ }
+ )}
+ isInvalid={validator.validateSolutionView(space, isEditing).isInvalid}
/>
diff --git a/x-pack/plugins/spaces/public/management/lib/validate_space.ts b/x-pack/plugins/spaces/public/management/lib/validate_space.ts
index a93d627f6e159..9a9ae0cbe98fd 100644
--- a/x-pack/plugins/spaces/public/management/lib/validate_space.ts
+++ b/x-pack/plugins/spaces/public/management/lib/validate_space.ts
@@ -169,11 +169,31 @@ export class SpaceValidator {
return valid();
}
+ public validateSolutionView(
+ space: FormValues,
+ isEditing: boolean,
+ allowSolutionVisibility = true
+ ) {
+ if (!this.shouldValidate || isEditing || !allowSolutionVisibility) {
+ return valid();
+ }
+
+ if (!space.solution) {
+ return invalid(
+ i18n.translate('xpack.spaces.management.validateSpace.requiredSolutionViewErrorMessage', {
+ defaultMessage: 'Select one solution.',
+ })
+ );
+ }
+
+ return valid();
+ }
+
public validateEnabledFeatures(space: FormValues) {
return valid();
}
- public validateForSave(space: FormValues) {
+ public validateForSave(space: FormValues, isEditing: boolean, allowSolutionVisibility: boolean) {
const { isInvalid: isNameInvalid } = this.validateSpaceName(space);
const { isInvalid: isDescriptionInvalid } = this.validateSpaceDescription(space);
const { isInvalid: isIdentifierInvalid } = this.validateURLIdentifier(space);
@@ -181,6 +201,11 @@ export class SpaceValidator {
const { isInvalid: isAvatarColorInvalid } = this.validateAvatarColor(space);
const { isInvalid: isAvatarImageInvalid } = this.validateAvatarImage(space);
const { isInvalid: areFeaturesInvalid } = this.validateEnabledFeatures(space);
+ const { isInvalid: isSolutionViewInvalid } = this.validateSolutionView(
+ space,
+ isEditing,
+ allowSolutionVisibility
+ );
if (
isNameInvalid ||
@@ -189,7 +214,8 @@ export class SpaceValidator {
isAvatarInitialsInvalid ||
isAvatarColorInvalid ||
isAvatarImageInvalid ||
- areFeaturesInvalid
+ areFeaturesInvalid ||
+ isSolutionViewInvalid
) {
return invalid();
}