@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
238 lines (236 loc) • 7.68 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useDispatch } from 'react-redux';
import { defineMessages, useIntl } from 'react-intl';
import React, { useEffect, useMemo, useState } from 'react';
import { disable, enable, fetchRolesBySite, trash, update } from '../../services/users';
import { showSystemNotification } from '../../state/actions/system';
import { showErrorDialog } from '../../state/reducers/dialogs/error';
import { EditUserDialogUI } from './EditUserDialogUI';
import { useSpreadState } from '../../hooks/useSpreadState';
import { useSitesBranch } from '../../hooks/useSitesBranch';
import useUpdateRefs from '../../hooks/useUpdateRefs';
import { isInvalidEmail, validateFieldMinLength } from '../UserManagement/utils';
import { pluckProps } from '../../utils/object';
const translations = defineMessages({
userDeleted: {
id: 'userInfoDialog.userDeleted',
defaultMessage: 'User deleted successfully'
},
userUpdated: {
id: 'userInfoDialog.userUpdated',
defaultMessage: 'User updated successfully'
},
userEnabled: {
id: 'userInfoDialog.userEnabled',
defaultMessage: 'User enabled successfully'
},
userDisabled: {
id: 'userInfoDialog.userDisabled',
defaultMessage: 'User disabled successfully'
}
});
export function EditUserDialogContainer(props) {
var _a, _b;
const {
open,
onClose,
onUserEdited,
passwordRequirementsMinComplexity,
isSubmitting,
onSubmittingAndOrPendingChange
} = props;
const dispatch = useDispatch();
const { formatMessage } = useIntl();
const [user, setUser] = useSpreadState({
id: null,
firstName: '',
lastName: '',
email: '',
username: '',
enabled: false,
externallyManaged: false
});
const [submitOk, setSubmitOk] = useState(false);
const sites = useSitesBranch();
const sitesById = sites.byId;
const mySites = useMemo(() => Object.values(sitesById), [sitesById]);
const [lastSavedUser, setLastSavedUser] = useState(null);
const [rolesBySite, setRolesBySite] = useState({});
const [dirty, setDirty] = useState(false);
const [openResetPassword, setOpenResetPassword] = useState(false);
const fnRefs = useUpdateRefs({ onSubmittingAndOrPendingChange, onUserEdited });
const editMode = !((_a = props.user) === null || _a === void 0 ? void 0 : _a.externallyManaged);
const onInputChange = (value) => {
setDirty(true);
setUser(value);
};
const onCancelForm = () => {
if (lastSavedUser) {
setUser(lastSavedUser);
} else {
setUser(props.user);
}
setDirty(false);
};
const onEnableChange = (value) => {
setUser(value);
if (value.enabled) {
enable(user.username).subscribe({
next() {
dispatch(
showSystemNotification({
message: formatMessage(translations.userEnabled)
})
);
},
error({ response: { response } }) {
dispatch(showErrorDialog({ error: response }));
}
});
} else {
disable(user.username).subscribe({
next() {
dispatch(
showSystemNotification({
message: formatMessage(translations.userDisabled)
})
);
},
error({ response: { response } }) {
dispatch(showErrorDialog({ error: response }));
}
});
}
};
const onSave = () => {
if (!editMode) {
return;
}
onSubmittingAndOrPendingChange({
isSubmitting: true
});
update(pluckProps(user, 'id', 'firstName', 'lastName', 'email', 'enabled')).subscribe({
next() {
dispatch(
showSystemNotification({
message: formatMessage(translations.userUpdated)
})
);
setDirty(false);
setLastSavedUser(user);
fnRefs.current.onUserEdited();
fnRefs.current.onSubmittingAndOrPendingChange({
isSubmitting: false
});
},
error({ response: { response } }) {
dispatch(showErrorDialog({ error: response }));
fnRefs.current.onSubmittingAndOrPendingChange({
isSubmitting: false
});
}
});
};
const onDelete = (username) => {
trash(username).subscribe({
next() {
onClose(null, null);
dispatch(
showSystemNotification({
message: formatMessage(translations.userDeleted)
})
);
fnRefs.current.onUserEdited();
},
error({ response: { response } }) {
dispatch(showErrorDialog({ error: response }));
}
});
};
const onCloseResetPasswordDialog = () => {
setOpenResetPassword(false);
};
const onResetPassword = (value) => {
setOpenResetPassword(value);
};
useEffect(() => {
if (open) {
setUser(props.user);
}
}, [props.user, open, setUser]);
useEffect(() => {
var _a;
if (mySites.length && ((_a = props.user) === null || _a === void 0 ? void 0 : _a.username)) {
fetchRolesBySite(props.user.username, mySites).subscribe((response) => {
setRolesBySite(response);
});
}
}, [mySites, (_b = props.user) === null || _b === void 0 ? void 0 : _b.username]);
const refs = useUpdateRefs({
validateFieldMinLength
});
useEffect(() => {
setSubmitOk(
Boolean(
user.firstName.trim() &&
!validateFieldMinLength('firstName', user.firstName) &&
user.lastName.trim() &&
!validateFieldMinLength('lastName', user.lastName) &&
!isInvalidEmail(user.email)
)
);
}, [user, refs]);
useEffect(() => {
onSubmittingAndOrPendingChange({
hasPendingChanges: dirty
});
}, [dirty, onSubmittingAndOrPendingChange]);
return React.createElement(EditUserDialogUI, {
user: user,
openResetPassword: openResetPassword,
inProgress: isSubmitting,
submitOk: submitOk,
dirty: dirty,
sites: mySites,
rolesBySite: rolesBySite,
passwordRequirementsMinComplexity: passwordRequirementsMinComplexity,
onSave: onSave,
onCloseButtonClick: (e) => onClose(e, null),
onDelete: onDelete,
onCloseResetPasswordDialog: onCloseResetPasswordDialog,
onInputChange: onInputChange,
onEnableChange: onEnableChange,
onCancelForm: onCancelForm,
onResetPassword: onResetPassword
});
}
export default EditUserDialogContainer;