[Spaces] Add warning for changes that impact other users (#188728)

This commit is contained in:
Sébastien Loix 2024-07-23 16:06:20 +01:00 committed by GitHub
parent 5d9d92b88e
commit 14770214fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 74 additions and 20 deletions

View file

@ -8,6 +8,7 @@
import {
EuiButton,
EuiButtonEmpty,
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiPageHeader,
@ -63,6 +64,8 @@ interface State {
features: KibanaFeature[];
originalSpace?: Partial<Space>;
showAlteringActiveSpaceDialog: boolean;
haveDisabledFeaturesChanged: boolean;
hasSolutionViewChanged: boolean;
isLoading: boolean;
saveInProgress: boolean;
formError?: {
@ -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);
@ -88,6 +90,8 @@ export class ManageSpacePage extends Component<Props, State> {
},
features: [],
isSolutionNavEnabled: false,
haveDisabledFeaturesChanged: false,
hasSolutionViewChanged: false,
};
}
@ -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));
}
@ -190,6 +219,8 @@ export class ManageSpacePage extends Component<Props, State> {
<EuiSpacer />
{this.getChangeImpactWarning()}
{this.getFormButtons()}
{showAlteringActiveSpaceDialog && (
@ -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',
@ -244,6 +300,7 @@ export class ManageSpacePage extends Component<Props, State> {
);
const saveText = this.editingExistingSpace() ? updateSpaceText : createSpaceText;
return (
<EuiFlexGroup responsive={false}>
<EuiFlexItem grow={false}>
@ -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({
@ -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,
@ -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,

View file

@ -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();