Skip to content

Commit

Permalink
[Spaces] Add warning for changes that impact other users (#188728)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga committed Jul 23, 2024
1 parent 5d9d92b commit 1477021
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import {
EuiButton,
EuiButtonEmpty,
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiPageHeader,
Expand Down Expand Up @@ -63,6 +64,8 @@ interface State {
features: KibanaFeature[];
originalSpace?: Partial<Space>;
showAlteringActiveSpaceDialog: boolean;
haveDisabledFeaturesChanged: boolean;
hasSolutionViewChanged: boolean;
isLoading: boolean;
saveInProgress: boolean;
formError?: {
Expand All @@ -74,7 +77,6 @@ interface State {

export class ManageSpacePage extends Component<Props, State> {
private readonly validator: SpaceValidator;
private initialSpaceState: State['space'] | null = null;

constructor(props: Props) {
super(props);
Expand All @@ -88,6 +90,8 @@ export class ManageSpacePage extends Component<Props, State> {
},
features: [],
isSolutionNavEnabled: false,
haveDisabledFeaturesChanged: false,
hasSolutionViewChanged: false,
};
}

Expand Down Expand Up @@ -118,7 +122,32 @@ export class ManageSpacePage extends Component<Props, State> {
});
}

public async componentDidUpdate(previousProps: Props) {
public async componentDidUpdate(previousProps: Props, prevState: State) {
const { originalSpace, space } = this.state;

if (originalSpace && space) {
let haveDisabledFeaturesChanged = prevState.haveDisabledFeaturesChanged;
if (prevState.space.disabledFeatures !== space.disabledFeatures) {
haveDisabledFeaturesChanged =
space.disabledFeatures?.length !== originalSpace.disabledFeatures?.length ||
difference(space.disabledFeatures, originalSpace.disabledFeatures ?? []).length > 0;
}
const hasSolutionViewChanged =
originalSpace.solution !== undefined
? space.solution !== originalSpace.solution
: !!space.solution && space.solution !== 'classic';

if (
prevState.haveDisabledFeaturesChanged !== haveDisabledFeaturesChanged ||
prevState.hasSolutionViewChanged !== hasSolutionViewChanged
) {
this.setState({
haveDisabledFeaturesChanged,
hasSolutionViewChanged,
});
}
}

if (this.props.spaceId !== previousProps.spaceId && this.props.spaceId) {
await this.loadSpace(this.props.spaceId, Promise.resolve(this.state.features));
}
Expand Down Expand Up @@ -190,6 +219,8 @@ export class ManageSpacePage extends Component<Props, State> {

<EuiSpacer />

{this.getChangeImpactWarning()}

{this.getFormButtons()}

{showAlteringActiveSpaceDialog && (
Expand Down Expand Up @@ -221,6 +252,31 @@ export class ManageSpacePage extends Component<Props, State> {
);
};

public getChangeImpactWarning = () => {
if (!this.editingExistingSpace()) return null;
const { haveDisabledFeaturesChanged, hasSolutionViewChanged } = this.state;
if (!haveDisabledFeaturesChanged && !hasSolutionViewChanged) return null;

return (
<>
<EuiCallOut
color="warning"
iconType="warning"
title={i18n.translate('xpack.spaces.management.manageSpacePage.userImpactWarningTitle', {
defaultMessage: 'Warning',
})}
data-test-subj="userImpactWarning"
>
<FormattedMessage
id="xpack.spaces.management.manageSpacePage.userImpactWarningDescription"
defaultMessage="The changes made will impact all users in the space."
/>
</EuiCallOut>
<EuiSpacer />
</>
);
};

public getFormButtons = () => {
const createSpaceText = i18n.translate(
'xpack.spaces.management.manageSpacePage.createSpaceButton',
Expand All @@ -244,6 +300,7 @@ export class ManageSpacePage extends Component<Props, State> {
);

const saveText = this.editingExistingSpace() ? updateSpaceText : createSpaceText;

return (
<EuiFlexGroup responsive={false}>
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -296,6 +353,7 @@ export class ManageSpacePage extends Component<Props, State> {

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);
if (result.isInvalid) {
this.setState({
Expand All @@ -311,12 +369,6 @@ export class ManageSpacePage extends Component<Props, State> {
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 hasSolutionViewChanged =
this.state.space.solution !== this.initialSpaceState?.solution;

if (editingActiveSpace && (haveDisabledFeaturesChanged || hasSolutionViewChanged)) {
this.setState({
showAlteringActiveSpaceDialog: true,
Expand Down Expand Up @@ -344,19 +396,17 @@ export class ManageSpacePage extends Component<Props, State> {
onLoadSpace(space);
}

this.initialSpaceState = {
...space,
avatarType: space.imageUrl ? 'image' : 'initials',
initials: space.initials || getSpaceInitials(space),
color: space.color || getSpaceColor(space),
customIdentifier: false,
customAvatarInitials:
!!space.initials && getSpaceInitials({ name: space.name }) !== space.initials,
customAvatarColor: !!space.color && getSpaceColor({ name: space.name }) !== space.color,
};

this.setState({
space: { ...this.initialSpaceState },
space: {
...space,
avatarType: space.imageUrl ? 'image' : 'initials',
initials: space.initials || getSpaceInitials(space),
color: space.color || getSpaceColor(space),
customIdentifier: false,
customAvatarInitials:
!!space.initials && getSpaceInitials({ name: space.name }) !== space.initials,
customAvatarColor: !!space.color && getSpaceColor({ name: space.name }) !== space.color,
},
features,
originalSpace: space,
isLoading: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.common.navigateToUrl('management', 'kibana/spaces/edit/default', {
shouldUseHashForSubUrl: false,
});

await testSubjects.missingOrFail('userImpactWarning');
await PageObjects.spaceSelector.changeSolutionView('classic');
await testSubjects.existOrFail('userImpactWarning'); // Warn that the change will impact other users

await PageObjects.spaceSelector.clickSaveSpaceCreation();
await PageObjects.spaceSelector.confirmModal();

Expand Down

0 comments on commit 1477021

Please sign in to comment.