Merge branch 'feature/files' into feature/avatar-editor-redesign
This commit is contained in:
commit
1129a00d21
@ -1,7 +1,10 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { utils, TreeMenu, TreeNode, Icons, Link } from "asc-web-components";
|
||||
import { selectGroup } from "../../../store/people/actions";
|
||||
import {
|
||||
selectGroup,
|
||||
setIsVisibleDataLossDialog,
|
||||
} from "../../../store/people/actions";
|
||||
import { getSelectedGroup } from "../../../store/people/selectors";
|
||||
import { withTranslation, I18nextProvider } from "react-i18next";
|
||||
import {
|
||||
@ -100,16 +103,25 @@ class ArticleBodyContent extends React.Component {
|
||||
|
||||
return false;
|
||||
}
|
||||
onSelectHandler = (data) => {
|
||||
const { editingForm, setIsVisibleDataLossDialog } = this.props;
|
||||
|
||||
onSelect = (data) => {
|
||||
const { selectGroup } = this.props;
|
||||
|
||||
this.changeTitleDocument(data);
|
||||
selectGroup(
|
||||
data && data.length === 1 && data[0] !== "root" ? data[0] : null
|
||||
);
|
||||
if (editingForm.isEdit) {
|
||||
setIsVisibleDataLossDialog(true, this.onSelect(data));
|
||||
} else {
|
||||
this.onSelect(data)();
|
||||
}
|
||||
};
|
||||
onSelect = (data) => {
|
||||
return () => {
|
||||
const { selectGroup } = this.props;
|
||||
|
||||
this.changeTitleDocument(data);
|
||||
selectGroup(
|
||||
data && data.length === 1 && data[0] !== "root" ? data[0] : null
|
||||
);
|
||||
};
|
||||
};
|
||||
switcherIcon = (obj) => {
|
||||
if (obj.isLeaf) {
|
||||
return null;
|
||||
@ -141,7 +153,7 @@ class ArticleBodyContent extends React.Component {
|
||||
showIcon={true}
|
||||
defaultExpandAll={true}
|
||||
switcherIcon={this.switcherIcon}
|
||||
onSelect={this.onSelect}
|
||||
onSelect={this.onSelectHandler}
|
||||
selectedKeys={selectedKeys}
|
||||
isFullFillSelection={false}
|
||||
gapBetweenNodes="22"
|
||||
@ -220,6 +232,7 @@ function mapStateToProps(state) {
|
||||
const { isLoaded, settings } = state.auth;
|
||||
const { customNames } = settings;
|
||||
const { groupsCaption } = customNames;
|
||||
const { editingForm } = state.people;
|
||||
|
||||
return {
|
||||
data: getTreeGroups(groups, groupsCaption),
|
||||
@ -229,7 +242,11 @@ function mapStateToProps(state) {
|
||||
groups,
|
||||
isAdmin: isAdmin(state),
|
||||
isLoaded,
|
||||
editingForm
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { selectGroup })(BodyContent);
|
||||
export default connect(mapStateToProps, {
|
||||
selectGroup,
|
||||
setIsVisibleDataLossDialog,
|
||||
})(BodyContent);
|
||||
|
@ -0,0 +1,106 @@
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import PropTypes from "prop-types";
|
||||
import { ModalDialog, Button, Text } from "asc-web-components";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { utils } from "asc-web-common";
|
||||
import ModalDialogContainer from "../ModalDialogContainer";
|
||||
import { createI18N } from "../../../helpers/i18n";
|
||||
import {
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
} from "../../../store/people/actions";
|
||||
|
||||
const i18n = createI18N({
|
||||
page: "DataLossWarningDialog",
|
||||
localesPath: "dialogs/DataLossWarningDialog",
|
||||
});
|
||||
|
||||
const { changeLanguage } = utils;
|
||||
|
||||
class DataLossWarningDialogComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
changeLanguage(i18n);
|
||||
}
|
||||
|
||||
onClose = () => {
|
||||
const { setIsVisibleDataLossDialog } = this.props;
|
||||
setIsVisibleDataLossDialog(false);
|
||||
};
|
||||
|
||||
onSubmit = () => {
|
||||
const {
|
||||
onContinue,
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
editingForm,
|
||||
} = this.props;
|
||||
|
||||
setIsVisibleDataLossDialog(false, null);
|
||||
setIsEditingForm(false);
|
||||
|
||||
if (editingForm.callback) {
|
||||
editingForm.callback();
|
||||
} else {
|
||||
onContinue && onContinue();
|
||||
}
|
||||
};
|
||||
render() {
|
||||
const { t, editingForm } = this.props;
|
||||
|
||||
return (
|
||||
<ModalDialogContainer>
|
||||
<ModalDialog
|
||||
visible={editingForm.isVisibleDataLossDialog}
|
||||
onClose={this.onClose}
|
||||
>
|
||||
<ModalDialog.Header>{t("DataLossWarningHeader")}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<Text fontSize="13px">{t("DataLossWarningBody")}</Text>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
key="LeaveForm"
|
||||
label={t("DataLossWarningLeaveBtn")}
|
||||
size="medium"
|
||||
primary={true}
|
||||
onClick={this.onSubmit}
|
||||
/>
|
||||
<Button
|
||||
className="button-dialog"
|
||||
key="StayOnPage"
|
||||
label={t("DataLossWarningCancelBtn")}
|
||||
size="medium"
|
||||
onClick={this.onClose}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
</ModalDialogContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const DataLossWarningDialogTranslated = withTranslation()(
|
||||
DataLossWarningDialogComponent
|
||||
);
|
||||
|
||||
const DataLossWarningDialog = (props) => (
|
||||
<DataLossWarningDialogTranslated i18n={i18n} {...props} />
|
||||
);
|
||||
|
||||
DataLossWarningDialog.propTypes = {
|
||||
editingForm: PropTypes.object.isRequired,
|
||||
onContinue: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
editingForm: state.people.editingForm,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
})(DataLossWarningDialog);
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"DataLossWarningHeader": "Leave the page?",
|
||||
"DataLossWarningBody": "Changes you made may not be saved.",
|
||||
"DataLossWarningLeaveBtn": "Leave",
|
||||
"DataLossWarningCancelBtn": "Cancel"
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"DataLossWarningHeader": "Покинуть страницу?",
|
||||
"DataLossWarningBody": "Внесенные вами изменения могут быть не сохранены.",
|
||||
"DataLossWarningLeaveBtn": "Покинуть",
|
||||
"DataLossWarningCancelBtn": "Отмена"
|
||||
}
|
@ -8,6 +8,7 @@ import InviteDialog from "./InviteDialog";
|
||||
import SendInviteDialog from "./SendInviteDialog";
|
||||
import ChangeUserStatusDialog from "./ChangeUserStatusDialog";
|
||||
import ChangeUserTypeDialog from "./ChangeUserTypeDialog";
|
||||
import DataLossWarningDialog from "./DataLossWarningDialog";
|
||||
|
||||
export {
|
||||
ChangeEmailDialog,
|
||||
@ -19,5 +20,6 @@ export {
|
||||
InviteDialog,
|
||||
SendInviteDialog,
|
||||
ChangeUserStatusDialog,
|
||||
ChangeUserTypeDialog
|
||||
ChangeUserTypeDialog,
|
||||
DataLossWarningDialog,
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
resetGroup,
|
||||
updateGroup,
|
||||
} from "../../../../../store/group/actions";
|
||||
import { selectGroup } from "../../../../../store/people/actions";
|
||||
import { selectGroup, setFilter } from "../../../../../store/people/actions";
|
||||
|
||||
import { GUID_EMPTY } from "../../../../../helpers/constants";
|
||||
import PropTypes from "prop-types";
|
||||
@ -241,10 +241,10 @@ class SectionBodyContent extends React.Component {
|
||||
};
|
||||
|
||||
onCancel = () => {
|
||||
const { history, resetGroup, settings } = this.props;
|
||||
const { resetGroup, filter, setFilter } = this.props;
|
||||
|
||||
resetGroup();
|
||||
history.push(`${settings.homepage}/`);
|
||||
setFilter(filter);
|
||||
};
|
||||
|
||||
onSelectedItemClose = (member) => {
|
||||
@ -490,6 +490,7 @@ function mapStateToProps(state) {
|
||||
groupCaption,
|
||||
me: getCurrentUser(state),
|
||||
currentModuleName,
|
||||
filter: state.people.filter,
|
||||
};
|
||||
}
|
||||
|
||||
@ -498,4 +499,5 @@ export default connect(mapStateToProps, {
|
||||
createGroup,
|
||||
updateGroup,
|
||||
selectGroup,
|
||||
setFilter,
|
||||
})(withRouter(withTranslation()(SectionBodyContent)));
|
||||
|
@ -6,6 +6,7 @@ import { IconButton } from "asc-web-components";
|
||||
import { Headline } from "asc-web-common";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { resetGroup } from "../../../../../store/group/actions";
|
||||
import { setFilter } from "../../../../../store/people/actions";
|
||||
import styled from "styled-components";
|
||||
|
||||
const Wrapper = styled.div`
|
||||
@ -23,7 +24,6 @@ const Wrapper = styled.div`
|
||||
`;
|
||||
|
||||
class SectionHeaderContent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { group, t, groupCaption } = props;
|
||||
@ -32,14 +32,14 @@ class SectionHeaderContent extends React.Component {
|
||||
: t("CustomNewDepartment", { groupCaption });
|
||||
|
||||
this.state = {
|
||||
headerText
|
||||
}
|
||||
headerText,
|
||||
};
|
||||
}
|
||||
onClickBack = () => {
|
||||
const { history, settings, resetGroup } = this.props;
|
||||
const { filter, resetGroup, setFilter } = this.props;
|
||||
|
||||
resetGroup();
|
||||
history.push(settings.homepage);
|
||||
setFilter(filter);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -65,22 +65,22 @@ class SectionHeaderContent extends React.Component {
|
||||
|
||||
SectionHeaderContent.propTypes = {
|
||||
group: PropTypes.object,
|
||||
history: PropTypes.object.isRequired
|
||||
history: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
SectionHeaderContent.defaultProps = {
|
||||
group: null
|
||||
group: null,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
settings: state.auth.settings,
|
||||
group: state.group.targetGroup,
|
||||
groupCaption: state.auth.settings.customNames.groupCaption
|
||||
groupCaption: state.auth.settings.customNames.groupCaption,
|
||||
filter: state.people.filter,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{ resetGroup }
|
||||
)(withTranslation()(withRouter(SectionHeaderContent)));
|
||||
export default connect(mapStateToProps, { resetGroup, setFilter })(
|
||||
withTranslation()(withRouter(SectionHeaderContent))
|
||||
);
|
||||
|
@ -12,7 +12,10 @@ import {
|
||||
toEmployeeWrapper,
|
||||
} from "../../../../../store/people/selectors";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import { updateUserStatus } from "../../../../../store/people/actions";
|
||||
import {
|
||||
updateUserStatus,
|
||||
setFilter,
|
||||
} from "../../../../../store/people/actions";
|
||||
import { updateProfile } from "../../../../../store/profile/actions";
|
||||
import {
|
||||
fetchProfile,
|
||||
@ -390,9 +393,9 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
};
|
||||
|
||||
onClickBack = () => {
|
||||
const { history, settings } = this.props;
|
||||
|
||||
history.push(settings.homepage);
|
||||
const { filter, setFilter } = this.props;
|
||||
setFilter(filter);
|
||||
//history.push(settings.homepage);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -504,4 +507,5 @@ export default connect(mapStateToProps, {
|
||||
updateUserStatus,
|
||||
fetchProfile,
|
||||
updateProfile,
|
||||
setFilter,
|
||||
})(withRouter(withTranslation()(SectionHeaderContent)));
|
||||
|
@ -24,7 +24,7 @@ const { isAdmin, isVisitor, getLanguage } = store.auth.selectors;
|
||||
|
||||
class PureProfile extends React.Component {
|
||||
componentDidMount() {
|
||||
const { match, fetchProfile, t, location } = this.props;
|
||||
const { match, fetchProfile, profile, location, t } = this.props;
|
||||
const { userId } = match.params;
|
||||
|
||||
setDocumentTitle(t("Profile"));
|
||||
@ -39,8 +39,9 @@ class PureProfile extends React.Component {
|
||||
if (linkParams.email_change && linkParams.email_change === "success") {
|
||||
toastr.success(t("ChangeEmailSuccess"));
|
||||
}
|
||||
|
||||
fetchProfile(userId);
|
||||
if (!profile) {
|
||||
fetchProfile(userId);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
|
@ -7,8 +7,7 @@ import {
|
||||
Textarea,
|
||||
AvatarEditor,
|
||||
Text,
|
||||
utils
|
||||
} from "asc-web-components";
|
||||
utils} from "asc-web-components";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import {
|
||||
toEmployeeWrapper,
|
||||
@ -17,13 +16,22 @@ import {
|
||||
getUserContacts,
|
||||
mapGroupsToGroupSelectorOptions,
|
||||
mapGroupSelectorOptionsToGroups,
|
||||
filterGroupSelectorOptions
|
||||
filterGroupSelectorOptions,
|
||||
} from "../../../../../store/people/selectors";
|
||||
import { createProfile } from "../../../../../store/profile/actions";
|
||||
import {
|
||||
createProfile,
|
||||
updateCreatedAvatar,
|
||||
} from "../../../../../store/profile/actions";
|
||||
import {
|
||||
setFilter,
|
||||
updateProfileInUsers,
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
} from "../../../../../store/people/actions";
|
||||
import {
|
||||
MainContainer,
|
||||
AvatarContainer,
|
||||
MainFieldsContainer
|
||||
MainFieldsContainer,
|
||||
} from "./FormFields/Form";
|
||||
import TextField from "./FormFields/TextField";
|
||||
import PasswordField from "./FormFields/PasswordField";
|
||||
@ -33,6 +41,7 @@ import RadioField from "./FormFields/RadioField";
|
||||
import DepartmentField from "./FormFields/DepartmentField";
|
||||
import ContactsField from "./FormFields/ContactsField";
|
||||
import InfoFieldContainer from "./FormFields/InfoFieldContainer";
|
||||
import { DataLossWarningDialog } from "../../../../dialogs";
|
||||
import { api, toastr } from "asc-web-common";
|
||||
import { isMobile } from "react-device-detect";
|
||||
const { createThumbnailsAvatar, loadAvatar } = api.people;
|
||||
@ -50,6 +59,7 @@ class CreateUserForm extends React.Component {
|
||||
this.onBirthdayDateChange = this.onBirthdayDateChange.bind(this);
|
||||
this.onWorkFromDateChange = this.onWorkFromDateChange.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onCancelHandler = this.onCancelHandler.bind(this);
|
||||
|
||||
this.onContactsItemAdd = this.onContactsItemAdd.bind(this);
|
||||
this.onContactsItemTypeChange = this.onContactsItemTypeChange.bind(this);
|
||||
@ -78,15 +88,17 @@ class CreateUserForm extends React.Component {
|
||||
y: this.state.avatar.y,
|
||||
width: this.state.avatar.width,
|
||||
height: this.state.avatar.height,
|
||||
tmpFile: this.state.avatar.tmpFile
|
||||
tmpFile: this.state.avatar.tmpFile,
|
||||
})
|
||||
.then(() => {
|
||||
.then((res) => {
|
||||
this.props.updateCreatedAvatar(res);
|
||||
this.props.updateProfileInUsers();
|
||||
toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
this.props.history.push(
|
||||
`${this.props.settings.homepage}/view/${userName}`
|
||||
);
|
||||
})
|
||||
.catch(error => toastr.error(error));
|
||||
.catch((error) => toastr.error(error));
|
||||
}
|
||||
|
||||
openAvatarEditor() {
|
||||
@ -104,17 +116,19 @@ class CreateUserForm extends React.Component {
|
||||
tmpFile: this.state.avatar.tmpFile,
|
||||
image: this.state.avatar.image,
|
||||
defaultWidth: avatarDefaultSizes[1],
|
||||
defaultHeight: avatarDefaultSizes[2]
|
||||
}
|
||||
defaultHeight: avatarDefaultSizes[2],
|
||||
},
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
visibleAvatarEditor: true
|
||||
visibleAvatarEditor: true,
|
||||
});
|
||||
}
|
||||
|
||||
openAvatarEditorPage() {
|
||||
this.props.history.push(`${this.props.settings.homepage}/edit-avatar/${this.props.profile.userName}`);
|
||||
this.props.history.push(
|
||||
`${this.props.settings.homepage}/edit-avatar/${this.props.profile.userName}`
|
||||
);
|
||||
}
|
||||
|
||||
onLoadFileAvatar(file) {
|
||||
@ -124,21 +138,22 @@ class CreateUserForm extends React.Component {
|
||||
data.append("Autosave", false);
|
||||
|
||||
loadAvatar(0, data)
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
img.onload = function () {
|
||||
var stateCopy = Object.assign({}, _this.state);
|
||||
stateCopy.avatar = {
|
||||
tmpFile: response.data,
|
||||
image: response.data,
|
||||
defaultWidth: img.width,
|
||||
defaultHeight: img.height
|
||||
defaultHeight: img.height,
|
||||
};
|
||||
_this.setState(stateCopy);
|
||||
//if (typeof callback === "function") callback();
|
||||
};
|
||||
img.src = response.data;
|
||||
})
|
||||
.catch(error => toastr.error(error));
|
||||
.catch((error) => toastr.error(error));
|
||||
}
|
||||
|
||||
onSaveAvatar(isUpdate, result, file) {
|
||||
@ -157,6 +172,7 @@ class CreateUserForm extends React.Component {
|
||||
stateCopy.avatar.height = result.height;
|
||||
}
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onCloseAvatarEditor() {
|
||||
@ -164,8 +180,8 @@ class CreateUserForm extends React.Component {
|
||||
visibleAvatarEditor: false,
|
||||
croppedAvatarImage: "",
|
||||
avatar: {
|
||||
tmpFile: ""
|
||||
}
|
||||
tmpFile: "",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -174,17 +190,17 @@ class CreateUserForm extends React.Component {
|
||||
this.setState(this.mapPropsToState(this.props));
|
||||
}
|
||||
|
||||
const isMobileDevice = isMobile || isTablet()
|
||||
const isMobileDevice = isMobile || isTablet();
|
||||
|
||||
if(prevState.isMobile !== isMobileDevice){
|
||||
if (prevState.isMobile !== isMobileDevice) {
|
||||
this.setState({ isMobile: isMobileDevice });
|
||||
}
|
||||
}
|
||||
|
||||
mapPropsToState = props => {
|
||||
mapPropsToState = (props) => {
|
||||
var profile = toEmployeeWrapper({
|
||||
isVisitor: props.match.params.type === "guest",
|
||||
passwordType: "link"
|
||||
passwordType: "link",
|
||||
});
|
||||
var allOptions = mapGroupsToGroupSelectorOptions(props.groups);
|
||||
var selected = mapGroupsToGroupSelectorOptions(profile.groups);
|
||||
@ -196,14 +212,14 @@ class CreateUserForm extends React.Component {
|
||||
firstName: false,
|
||||
lastName: false,
|
||||
email: false,
|
||||
password: false
|
||||
password: false,
|
||||
},
|
||||
profile: profile,
|
||||
selector: {
|
||||
visible: false,
|
||||
allOptions: allOptions,
|
||||
options: [...allOptions],
|
||||
selected: selected
|
||||
selected: selected,
|
||||
},
|
||||
avatar: {
|
||||
tmpFile: "",
|
||||
@ -213,28 +229,35 @@ class CreateUserForm extends React.Component {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
height: 0,
|
||||
},
|
||||
isMobile: isMobile || isTablet
|
||||
isMobile: isMobile || isTablet,
|
||||
};
|
||||
};
|
||||
setIsEdit() {
|
||||
const { editingForm, setIsEditingForm } = this.props;
|
||||
if (!editingForm.isEdit) setIsEditingForm(true);
|
||||
}
|
||||
|
||||
onInputChange(event) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile[event.target.name] = event.target.value;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onBirthdayDateChange(value) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.birthday = value ? value.toJSON() : null;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onWorkFromDateChange(value) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.workFrom = value ? value.toJSON() : null;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
validate() {
|
||||
@ -243,7 +266,7 @@ class CreateUserForm extends React.Component {
|
||||
firstName: !profile.firstName.trim(),
|
||||
lastName: !profile.lastName.trim(),
|
||||
email: stateErrors.email || !profile.email.trim(),
|
||||
password: profile.passwordType === "temp" && !profile.password.trim()
|
||||
password: profile.passwordType === "temp" && !profile.password.trim(),
|
||||
};
|
||||
const hasError =
|
||||
errors.firstName || errors.lastName || errors.email || errors.password;
|
||||
@ -265,7 +288,7 @@ class CreateUserForm extends React.Component {
|
||||
|
||||
this.props
|
||||
.createProfile(this.state.profile)
|
||||
.then(profile => {
|
||||
.then((profile) => {
|
||||
if (this.state.avatar.tmpFile !== "") {
|
||||
this.createAvatar(profile.id, profile.userName);
|
||||
} else {
|
||||
@ -275,14 +298,25 @@ class CreateUserForm extends React.Component {
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
toastr.error(error);
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
}
|
||||
|
||||
onCancelHandler() {
|
||||
const { editingForm, setIsVisibleDataLossDialog } = this.props;
|
||||
|
||||
if (editingForm.isEdit) {
|
||||
setIsVisibleDataLossDialog(true);
|
||||
} else {
|
||||
this.onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.props.history.push(this.props.settings.homepage);
|
||||
const { filter, setFilter } = this.props;
|
||||
setFilter(filter);
|
||||
}
|
||||
|
||||
onContactsItemAdd(item) {
|
||||
@ -290,37 +324,41 @@ class CreateUserForm extends React.Component {
|
||||
stateCopy.profile.contacts.push({
|
||||
id: new Date().getTime().toString(),
|
||||
type: item.value,
|
||||
value: ""
|
||||
value: "",
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemTypeChange(item) {
|
||||
const id = item.key.split("_")[0];
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.contacts.forEach(element => {
|
||||
stateCopy.profile.contacts.forEach((element) => {
|
||||
if (element.id === id) element.type = item.value;
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemTextChange(event) {
|
||||
const id = event.target.name.split("_")[0];
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.contacts.forEach(element => {
|
||||
stateCopy.profile.contacts.forEach((element) => {
|
||||
if (element.id === id) element.value = event.target.value;
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemRemove(event) {
|
||||
const id = event.target.closest(".remove_icon").dataset.for.split("_")[0];
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
const filteredArray = stateCopy.profile.contacts.filter(element => {
|
||||
const filteredArray = stateCopy.profile.contacts.filter((element) => {
|
||||
return element.id !== id;
|
||||
});
|
||||
stateCopy.profile.contacts = filteredArray;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onShowGroupSelector() {
|
||||
@ -350,20 +388,21 @@ class CreateUserForm extends React.Component {
|
||||
stateCopy.selector.selected = selected;
|
||||
stateCopy.selector.visible = false;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onRemoveGroup(id) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.groups = stateCopy.profile.groups.filter(
|
||||
group => group.id !== id
|
||||
(group) => group.id !== id
|
||||
);
|
||||
stateCopy.selector.selected = stateCopy.selector.selected.filter(
|
||||
option => option.key !== id
|
||||
(option) => option.key !== id
|
||||
);
|
||||
this.setState(stateCopy);
|
||||
}
|
||||
|
||||
onValidateEmailField = value =>
|
||||
onValidateEmailField = (value) =>
|
||||
this.setState({ errors: { ...this.state.errors, email: !value.isValid } });
|
||||
|
||||
render() {
|
||||
@ -372,7 +411,7 @@ class CreateUserForm extends React.Component {
|
||||
const {
|
||||
regDateCaption,
|
||||
userPostCaption,
|
||||
groupCaption
|
||||
groupCaption,
|
||||
} = settings.customNames;
|
||||
|
||||
const pattern = getUserContactsPattern();
|
||||
@ -381,6 +420,7 @@ class CreateUserForm extends React.Component {
|
||||
return (
|
||||
<>
|
||||
<MainContainer>
|
||||
<DataLossWarningDialog onContinue={this.onCancel} />
|
||||
<AvatarContainer>
|
||||
<Avatar
|
||||
size="max"
|
||||
@ -388,7 +428,9 @@ class CreateUserForm extends React.Component {
|
||||
editing={true}
|
||||
source={this.state.croppedAvatarImage}
|
||||
editLabel={t("AddButton")}
|
||||
editAction={isMobile ? this.openAvatarEditorPage : this.openAvatarEditor}
|
||||
editAction={
|
||||
isMobile ? this.openAvatarEditorPage : this.openAvatarEditor
|
||||
}
|
||||
/>
|
||||
<AvatarEditor
|
||||
image={this.state.avatar.image}
|
||||
@ -462,7 +504,7 @@ class CreateUserForm extends React.Component {
|
||||
radioValue={profile.passwordType}
|
||||
radioOptions={[
|
||||
{ value: "link", label: t("ActivationLink") },
|
||||
{ value: "temp", label: t("TemporaryPassword") }
|
||||
{ value: "temp", label: t("TemporaryPassword") },
|
||||
]}
|
||||
radioIsDisabled={isLoading}
|
||||
radioOnChange={this.onInputChange}
|
||||
@ -493,7 +535,7 @@ class CreateUserForm extends React.Component {
|
||||
radioValue={profile.sex}
|
||||
radioOptions={[
|
||||
{ value: "male", label: t("MaleSexStatus") },
|
||||
{ value: "female", label: t("FemaleSexStatus") }
|
||||
{ value: "female", label: t("FemaleSexStatus") },
|
||||
]}
|
||||
radioIsDisabled={isLoading}
|
||||
radioOnChange={this.onInputChange}
|
||||
@ -586,7 +628,7 @@ class CreateUserForm extends React.Component {
|
||||
/>
|
||||
<Button
|
||||
label={t("CancelButton")}
|
||||
onClick={this.onCancel}
|
||||
onClick={this.onCancelHandler}
|
||||
isDisabled={isLoading}
|
||||
size="big"
|
||||
style={{ marginLeft: "8px" }}
|
||||
@ -598,16 +640,22 @@ class CreateUserForm extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state) => {
|
||||
const { settings } = state.auth;
|
||||
const { groups, filter, editingForm } = state.people;
|
||||
return {
|
||||
settings: state.auth.settings,
|
||||
groups: state.people.groups
|
||||
settings,
|
||||
groups,
|
||||
filter,
|
||||
editingForm,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
createProfile
|
||||
}
|
||||
)(withRouter(withTranslation()(CreateUserForm)));
|
||||
export default connect(mapStateToProps, {
|
||||
createProfile,
|
||||
updateCreatedAvatar,
|
||||
setFilter,
|
||||
updateProfileInUsers,
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
})(withRouter(withTranslation()(CreateUserForm)));
|
||||
|
@ -8,8 +8,7 @@ import {
|
||||
Text,
|
||||
AvatarEditor,
|
||||
Link,
|
||||
utils,
|
||||
} from "asc-web-components";
|
||||
utils,} from "asc-web-components";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import {
|
||||
toEmployeeWrapper,
|
||||
@ -26,6 +25,12 @@ import {
|
||||
fetchProfile,
|
||||
} from "../../../../../store/profile/actions";
|
||||
import { toggleAvatarEditor } from "../../../../../store/people/actions";
|
||||
import {
|
||||
setFilter,
|
||||
updateProfileInUsers,
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
} from "../../../../../store/people/actions";
|
||||
import {
|
||||
MainContainer,
|
||||
AvatarContainer,
|
||||
@ -39,6 +44,7 @@ import DepartmentField from "./FormFields/DepartmentField";
|
||||
import ContactsField from "./FormFields/ContactsField";
|
||||
import InfoFieldContainer from "./FormFields/InfoFieldContainer";
|
||||
import styled from "styled-components";
|
||||
import { DataLossWarningDialog } from "../../../../dialogs";
|
||||
import { api, toastr } from "asc-web-common";
|
||||
import {
|
||||
ChangeEmailDialog,
|
||||
@ -80,6 +86,7 @@ class UpdateUserForm extends React.Component {
|
||||
this.onBirthdayDateChange = this.onBirthdayDateChange.bind(this);
|
||||
this.onWorkFromDateChange = this.onWorkFromDateChange.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onCancelHandler = this.onCancelHandler.bind(this);
|
||||
|
||||
this.onContactsItemAdd = this.onContactsItemAdd.bind(this);
|
||||
this.onContactsItemTypeChange = this.onContactsItemTypeChange.bind(this);
|
||||
@ -164,8 +171,7 @@ class UpdateUserForm extends React.Component {
|
||||
[dialogsDataset.changeEmail]: false,
|
||||
currentDialog: "",
|
||||
},
|
||||
isMobile: isMobile || isTablet,
|
||||
};
|
||||
isMobile: isMobile || isTablet, };
|
||||
|
||||
//Set unique contacts id
|
||||
const now = new Date().getTime();
|
||||
@ -177,10 +183,16 @@ class UpdateUserForm extends React.Component {
|
||||
return newState;
|
||||
};
|
||||
|
||||
setIsEdit() {
|
||||
const { editingForm, setIsEditingForm } = this.props;
|
||||
if (!editingForm.isEdit) setIsEditingForm(true);
|
||||
}
|
||||
|
||||
onInputChange(event) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile[event.target.name] = event.target.value;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
toggleDialogsVisible = (e) => {
|
||||
@ -200,18 +212,21 @@ class UpdateUserForm extends React.Component {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.isVisitor = event.target.value === "true";
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onBirthdayDateChange(value) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.birthday = value ? value.toJSON() : null;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onWorkFromDateChange(value) {
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile.workFrom = value ? value.toJSON() : null;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
validate() {
|
||||
@ -240,7 +255,7 @@ class UpdateUserForm extends React.Component {
|
||||
this.props
|
||||
.updateProfile(this.state.profile)
|
||||
.then((profile) => {
|
||||
toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
this.props.updateProfileInUsers(profile); toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
this.props.history.push(
|
||||
`${this.props.settings.homepage}/view/${profile.userName}`
|
||||
);
|
||||
@ -250,9 +265,24 @@ class UpdateUserForm extends React.Component {
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
}
|
||||
onCancelHandler() {
|
||||
const { editingForm, setIsVisibleDataLossDialog } = this.props;
|
||||
|
||||
if (editingForm.isEdit) {
|
||||
setIsVisibleDataLossDialog(true);
|
||||
} else {
|
||||
this.onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.props.history.goBack();
|
||||
const { filter, setFilter } = this.props;
|
||||
|
||||
if (document.referrer) {
|
||||
this.props.history.goBack();
|
||||
} else {
|
||||
setFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
onContactsItemAdd(item) {
|
||||
@ -263,6 +293,7 @@ class UpdateUserForm extends React.Component {
|
||||
value: "",
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemTypeChange(item) {
|
||||
@ -272,6 +303,7 @@ class UpdateUserForm extends React.Component {
|
||||
if (element.id === id) element.type = item.value;
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemTextChange(event) {
|
||||
@ -281,6 +313,7 @@ class UpdateUserForm extends React.Component {
|
||||
if (element.id === id) element.value = event.target.value;
|
||||
});
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onContactsItemRemove(event) {
|
||||
@ -291,6 +324,7 @@ class UpdateUserForm extends React.Component {
|
||||
});
|
||||
stateCopy.profile.contacts = filteredArray;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
openAvatarEditor() {
|
||||
@ -337,11 +371,10 @@ class UpdateUserForm extends React.Component {
|
||||
|
||||
data.append("file", file);
|
||||
data.append("Autosave", false);
|
||||
loadAvatar(profile.id, data)
|
||||
loadAvatar(this.state.profile.id, data)
|
||||
.then((response) => {
|
||||
var img = new Image();
|
||||
img.onload = function () {
|
||||
|
||||
_this.setState({ isLoading: false });
|
||||
if (fileData) {
|
||||
fileData.avatar = {
|
||||
@ -349,11 +382,15 @@ class UpdateUserForm extends React.Component {
|
||||
image: response.data,
|
||||
defaultWidth: img.width,
|
||||
defaultHeight: img.height,
|
||||
}
|
||||
if(!fileData.existImage) {
|
||||
_this.onSaveAvatar(fileData.existImage) // saving empty avatar
|
||||
} else{
|
||||
_this.onSaveAvatar(fileData.existImage, fileData.position, fileData.avatar)
|
||||
};
|
||||
if (!fileData.existImage) {
|
||||
_this.onSaveAvatar(fileData.existImage); // saving empty avatar
|
||||
} else {
|
||||
_this.onSaveAvatar(
|
||||
fileData.existImage,
|
||||
fileData.position,
|
||||
fileData.avatar
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -380,9 +417,10 @@ class UpdateUserForm extends React.Component {
|
||||
height: result.height,
|
||||
tmpFile: avatar.tmpFile,
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
this.setState({ isLoading: false });
|
||||
this.setIsEdit();
|
||||
})
|
||||
.catch((error) => {
|
||||
toastr.error(error);
|
||||
@ -390,20 +428,19 @@ class UpdateUserForm extends React.Component {
|
||||
})
|
||||
.then(() => {
|
||||
this.props.updateProfile(this.props.profile);
|
||||
this.setState({ isLoading: false });
|
||||
})
|
||||
.then(() => {
|
||||
this.props.fetchProfile(profile.id);
|
||||
});
|
||||
} else {
|
||||
}); } else {
|
||||
deleteAvatar(profile.id)
|
||||
.then(() => {
|
||||
toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
.then(() => { toastr.success(this.props.t("ChangesSavedSuccessfully"));
|
||||
this.setState({ isLoading: false });
|
||||
this.setIsEdit();
|
||||
})
|
||||
.catch((error) => toastr.error(error))
|
||||
.then(() => this.props.updateProfile(this.props.profile))
|
||||
.then(() => this.props.fetchProfile(profile.id));
|
||||
}
|
||||
.then(() => this.props.fetchProfile(profile.id)); }
|
||||
};
|
||||
|
||||
onCloseAvatarEditor() {
|
||||
@ -439,6 +476,7 @@ class UpdateUserForm extends React.Component {
|
||||
stateCopy.selector.selected = selected;
|
||||
stateCopy.selector.visible = false;
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
onRemoveGroup(id) {
|
||||
@ -450,6 +488,7 @@ class UpdateUserForm extends React.Component {
|
||||
(option) => option.key !== id
|
||||
);
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -551,6 +590,7 @@ class UpdateUserForm extends React.Component {
|
||||
return (
|
||||
<>
|
||||
<MainContainer>
|
||||
<DataLossWarningDialog onContinue={this.onCancel} />
|
||||
<AvatarContainer>
|
||||
<Avatar
|
||||
size="max"
|
||||
@ -779,7 +819,7 @@ class UpdateUserForm extends React.Component {
|
||||
/>
|
||||
<Button
|
||||
label={t("CancelButton")}
|
||||
onClick={this.onCancel}
|
||||
onClick={this.onCancelHandler}
|
||||
isDisabled={isLoading}
|
||||
size="big"
|
||||
style={{ marginLeft: "8px" }}
|
||||
@ -820,11 +860,16 @@ const mapStateToProps = (state) => {
|
||||
profile: state.profile.targetUser,
|
||||
settings: state.auth.settings,
|
||||
groups: state.people.groups,
|
||||
};
|
||||
editingForm: state.people.editingForm,
|
||||
filter: state.people.filter, };
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
updateProfile,
|
||||
fetchProfile,
|
||||
toggleAvatarEditor,
|
||||
})(withRouter(withTranslation()(UpdateUserForm)));
|
||||
updateProfileInUsers,
|
||||
setIsVisibleDataLossDialog,
|
||||
setIsEditingForm,
|
||||
setFilter,
|
||||
toggleAvatarEditor
|
||||
})(withRouter(withTranslation()(UpdateUserForm)));
|
@ -4,9 +4,11 @@ import { connect } from "react-redux";
|
||||
import { withRouter } from "react-router";
|
||||
import { IconButton } from "asc-web-components";
|
||||
import { Headline } from "asc-web-common";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toggleAvatarEditor } from "../../../../../store/people/actions";
|
||||
|
||||
import { useTranslation } from "react-i18next";import {
|
||||
setFilter,
|
||||
setIsVisibleDataLossDialog,
|
||||
toggleAvatarEditor
|
||||
} from "../../../../../store/people/actions";
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -29,10 +31,13 @@ const SectionHeaderContent = (props) => {
|
||||
history,
|
||||
match,
|
||||
settings,
|
||||
filter,
|
||||
editingForm,
|
||||
setFilter,
|
||||
setIsVisibleDataLossDialog,
|
||||
toggleAvatarEditor,
|
||||
avatarEditorIsOpen,
|
||||
} = props;
|
||||
const { userCaption, guestCaption } = settings.customNames;
|
||||
avatarEditorIsOpen
|
||||
} = props; const { userCaption, guestCaption } = settings.customNames;
|
||||
const { type } = match.params;
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -46,14 +51,20 @@ const SectionHeaderContent = (props) => {
|
||||
? `${t("EditUserDialogTitle")} (${profile.displayName})`
|
||||
: "";
|
||||
|
||||
const onClickBackHandler = () => {
|
||||
if (editingForm.isEdit) {
|
||||
setIsVisibleDataLossDialog(true, onClickBack);
|
||||
} else {
|
||||
onClickBack();
|
||||
}
|
||||
};
|
||||
const onClickBack = useCallback(() => {
|
||||
avatarEditorIsOpen
|
||||
? toggleAvatarEditor(false)
|
||||
: !profile
|
||||
? history.push(settings.homepage)
|
||||
: history.push(`/products/people/view/${profile.userName}`);
|
||||
}, [history, profile, settings.homepage, avatarEditorIsOpen]);
|
||||
|
||||
: !profile || !document.referrer
|
||||
? setFilter(filter)
|
||||
: history.goBack();
|
||||
}, [history, profile,setFilter, filter, settings.homepage, avatarEditorIsOpen]);
|
||||
return (
|
||||
<Wrapper>
|
||||
<IconButton
|
||||
@ -62,7 +73,7 @@ const SectionHeaderContent = (props) => {
|
||||
size="17"
|
||||
hoverColor="#657077"
|
||||
isFill={true}
|
||||
onClick={onClickBack}
|
||||
onClick={onClickBackHandler}
|
||||
className="arrow-button"
|
||||
/>
|
||||
<Headline className="header-headline" type="content" truncate={true}>
|
||||
@ -76,10 +87,13 @@ function mapStateToProps(state) {
|
||||
return {
|
||||
profile: state.profile.targetUser,
|
||||
settings: state.auth.settings,
|
||||
avatarEditorIsOpen: state.people.avatarEditorIsOpen,
|
||||
};
|
||||
filter: state.people.filter,
|
||||
editingForm: state.people.editingForm,
|
||||
avatarEditorIsOpen: state.people.avatarEditorIsOpen, };
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { toggleAvatarEditor })(
|
||||
withRouter(SectionHeaderContent)
|
||||
);
|
||||
export default connect(mapStateToProps, {
|
||||
setFilter,
|
||||
setIsVisibleDataLossDialog,
|
||||
toggleAvatarEditor
|
||||
})(withRouter(SectionHeaderContent));
|
@ -14,6 +14,7 @@ import {
|
||||
UpdateUserForm,
|
||||
AvatarEditorPage,} from "./Section";
|
||||
import { fetchProfile } from "../../../store/profile/actions";
|
||||
import { setIsEditingForm } from "../../../store/people/actions";
|
||||
import { I18nextProvider, withTranslation } from "react-i18next";
|
||||
import { createI18N } from "../../../helpers/i18n";
|
||||
import { setDocumentTitle } from "../../../helpers/utils";
|
||||
@ -27,12 +28,14 @@ const { isAdmin } = store.auth.selectors;
|
||||
|
||||
class ProfileAction extends React.Component {
|
||||
componentDidMount() {
|
||||
const { match, fetchProfile, t } = this.props;
|
||||
const { match, fetchProfile, isEdit, setIsEditingForm, t } = this.props;
|
||||
const { userId } = match.params;
|
||||
|
||||
setDocumentTitle(t("ProfileAction"));
|
||||
changeLanguage(i18n);
|
||||
|
||||
if (isEdit) {
|
||||
setIsEditingForm(false);
|
||||
}
|
||||
if (userId) {
|
||||
fetchProfile(userId);
|
||||
}
|
||||
@ -137,10 +140,11 @@ function mapStateToProps(state) {
|
||||
isVisitor: state.auth.user.isVisitor,
|
||||
profile: state.profile.targetUser,
|
||||
isAdmin: isAdmin(state),
|
||||
isEdit: state.people.editingForm.isEdit,
|
||||
avatarEditorIsOpen: state.people.avatarEditorIsOpen,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { fetchProfile })(
|
||||
export default connect(mapStateToProps, { fetchProfile, setIsEditingForm })(
|
||||
ProfileActionContainer
|
||||
);
|
||||
|
@ -9,8 +9,10 @@ import {
|
||||
SORT_BY,
|
||||
SORT_ORDER,
|
||||
PAGE,
|
||||
PAGE_COUNT
|
||||
PAGE_COUNT,
|
||||
} from "../../helpers/constants";
|
||||
import { getUserByUserName } from "../people/selectors";
|
||||
|
||||
const { EmployeeStatus } = constants;
|
||||
const { Filter } = api;
|
||||
|
||||
@ -24,40 +26,42 @@ export const SET_SELECTED = "SET_SELECTED";
|
||||
export const SET_FILTER = "SET_FILTER";
|
||||
export const SELECT_GROUP = "SELECT_GROUP";
|
||||
export const SET_SELECTOR_USERS = "SET_SELECTOR_USERS";
|
||||
export const SET_IS_VISIBLE_DATA_LOSS_DIALOG =
|
||||
"SET_IS_VISIBLE_DATA_LOSS_DIALOG";
|
||||
export const SET_IS_EDITING_FORM = "SET_IS_EDITING_FORM";
|
||||
export const TOGGLE_AVATAR_EDITOR = "TOGGLE_AVATAR_EDITOR"
|
||||
|
||||
export function setUser(user) {
|
||||
return {
|
||||
type: SET_USER,
|
||||
user
|
||||
user,
|
||||
};
|
||||
}
|
||||
|
||||
export function setUsers(users) {
|
||||
return {
|
||||
type: SET_USERS,
|
||||
users
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
export function setGroups(groups) {
|
||||
return {
|
||||
type: SET_GROUPS,
|
||||
groups
|
||||
groups,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSelection(selection) {
|
||||
return {
|
||||
type: SET_SELECTION,
|
||||
selection
|
||||
selection,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSelected(selected) {
|
||||
return {
|
||||
type: SET_SELECTED,
|
||||
selected
|
||||
selected,
|
||||
};
|
||||
}
|
||||
|
||||
@ -76,14 +80,14 @@ export function selectGroup(groupId) {
|
||||
export function selectUser(user) {
|
||||
return {
|
||||
type: SELECT_USER,
|
||||
user
|
||||
user,
|
||||
};
|
||||
}
|
||||
|
||||
export function deselectUser(user) {
|
||||
return {
|
||||
type: DESELECT_USER,
|
||||
user
|
||||
user,
|
||||
};
|
||||
}
|
||||
|
||||
@ -128,7 +132,7 @@ export function setFilterUrl(filter) {
|
||||
|
||||
//const isProfileView = history.location.pathname.includes('/people/view') || history.location.pathname.includes('/people/edit');
|
||||
//if (params.length > 0 && !isProfileView) {
|
||||
history.push(`${config.homepage}/filter?${params.join("&")}`);
|
||||
history.push(`${config.homepage}/filter?${params.join("&")}`);
|
||||
//}
|
||||
}
|
||||
|
||||
@ -136,20 +140,35 @@ export function setFilter(filter) {
|
||||
setFilterUrl(filter);
|
||||
return {
|
||||
type: SET_FILTER,
|
||||
filter
|
||||
filter,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSelectorUsers(users) {
|
||||
return {
|
||||
type: SET_SELECTOR_USERS,
|
||||
users
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
export function setIsVisibleDataLossDialog(isVisible, callback) {
|
||||
return {
|
||||
type: SET_IS_VISIBLE_DATA_LOSS_DIALOG,
|
||||
isVisible,
|
||||
callback,
|
||||
};
|
||||
}
|
||||
|
||||
export function setIsEditingForm(isEdit) {
|
||||
return {
|
||||
type: SET_IS_EDITING_FORM,
|
||||
isEdit,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchSelectorUsers() {
|
||||
return dispatch => {
|
||||
api.people.getSelectorUserList().then(data => {
|
||||
return (dispatch) => {
|
||||
api.people.getSelectorUserList().then((data) => {
|
||||
const users = data.items;
|
||||
return dispatch(setSelectorUsers(users));
|
||||
});
|
||||
@ -157,10 +176,10 @@ export function fetchSelectorUsers() {
|
||||
}
|
||||
|
||||
export function fetchGroups(dispatchFunc = null) {
|
||||
return api.groups.getGroupList().then(groups => {
|
||||
return api.groups.getGroupList().then((groups) => {
|
||||
return dispatchFunc
|
||||
? dispatchFunc(setGroups(groups))
|
||||
: Promise.resolve(dispatch => dispatch(setGroups(groups)));
|
||||
: Promise.resolve((dispatch) => dispatch(setGroups(groups)));
|
||||
});
|
||||
}
|
||||
|
||||
@ -168,21 +187,33 @@ export function fetchPeople(filter, dispatchFunc = null) {
|
||||
return dispatchFunc
|
||||
? fetchPeopleByFilter(dispatchFunc, filter)
|
||||
: (dispatch, getState) => {
|
||||
if (filter) {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
} else {
|
||||
const { people } = getState();
|
||||
const { filter } = people;
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
}
|
||||
};
|
||||
if (filter) {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
} else {
|
||||
const { people } = getState();
|
||||
const { filter } = people;
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function removeUser(userId, filter) {
|
||||
return dispatch => {
|
||||
return api.people.deleteUsers(userId)
|
||||
.then(() => fetchPeople(filter, dispatch))
|
||||
return (dispatch) => {
|
||||
return api.people
|
||||
.deleteUsers(userId)
|
||||
.then(() => fetchPeople(filter, dispatch));
|
||||
};
|
||||
}
|
||||
|
||||
export function updateUserList(dispatch, filter) {
|
||||
let filterData = filter && filter.clone();
|
||||
if (!filterData) {
|
||||
filterData = Filter.getDefault();
|
||||
filterData.employeeStatus = EmployeeStatus.Active;
|
||||
}
|
||||
return api.people.getUserList(filterData).then((data) => {
|
||||
return dispatch(setUsers(data.items));
|
||||
});
|
||||
}
|
||||
|
||||
function fetchPeopleByFilter(dispatch, filter) {
|
||||
@ -193,12 +224,12 @@ function fetchPeopleByFilter(dispatch, filter) {
|
||||
filterData.employeeStatus = EmployeeStatus.Active;
|
||||
}
|
||||
|
||||
return api.people.getUserList(filterData).then(data => {
|
||||
return api.people.getUserList(filterData).then((data) => {
|
||||
filterData.total = data.total;
|
||||
dispatch(setFilter(filterData));
|
||||
dispatch({
|
||||
type: SELECT_GROUP,
|
||||
groupId: filterData.group
|
||||
groupId: filterData.group,
|
||||
});
|
||||
return dispatch(setUsers(data.items));
|
||||
});
|
||||
@ -206,21 +237,20 @@ function fetchPeopleByFilter(dispatch, filter) {
|
||||
|
||||
export function updateUserStatus(status, userIds, isRefetchPeople = false) {
|
||||
return (dispatch, getState) => {
|
||||
return api.people.updateUserStatus(status, userIds)
|
||||
.then(users => {
|
||||
const { people } = getState();
|
||||
const { filter } = people;
|
||||
return isRefetchPeople
|
||||
? fetchPeople(filter, dispatch)
|
||||
: Promise.resolve();
|
||||
});
|
||||
return api.people.updateUserStatus(status, userIds).then((users) => {
|
||||
const { people } = getState();
|
||||
const { filter } = people;
|
||||
return isRefetchPeople
|
||||
? fetchPeople(filter, dispatch)
|
||||
: Promise.resolve();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function updateUserType(type, userIds) {
|
||||
return dispatch => {
|
||||
return api.people.updateUserType(type, userIds).then(users => {
|
||||
users.forEach(user => {
|
||||
return (dispatch) => {
|
||||
return api.people.updateUserType(type, userIds).then((users) => {
|
||||
users.forEach((user) => {
|
||||
dispatch(setUser(user));
|
||||
});
|
||||
});
|
||||
@ -237,3 +267,43 @@ export function resetFilter() {
|
||||
return fetchPeople(newFilter, dispatch);
|
||||
};
|
||||
}
|
||||
|
||||
export function updateProfileInUsers(updatedProfile) {
|
||||
return (dispatch, getState) => {
|
||||
const { people } = getState();
|
||||
const { users } = people;
|
||||
|
||||
if (!users) {
|
||||
return updateUserList(dispatch);
|
||||
}
|
||||
|
||||
if (!updatedProfile) {
|
||||
const { profile } = getState();
|
||||
updatedProfile = profile.targetUser;
|
||||
}
|
||||
|
||||
const { userName } = updatedProfile;
|
||||
const oldProfile = getUserByUserName(users, userName);
|
||||
const newProfile = {};
|
||||
|
||||
for (let key in oldProfile) {
|
||||
if (
|
||||
updatedProfile.hasOwnProperty(key) &&
|
||||
updatedProfile[key] !== oldProfile[key]
|
||||
) {
|
||||
newProfile[key] = updatedProfile[key];
|
||||
} else {
|
||||
newProfile[key] = oldProfile[key];
|
||||
}
|
||||
}
|
||||
|
||||
const updatedUsers = users.map((user) => {
|
||||
if (user.id === newProfile.id) {
|
||||
return newProfile;
|
||||
} else {
|
||||
return user;
|
||||
}
|
||||
});
|
||||
return dispatch(setUsers(updatedUsers));
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
SELECT_GROUP,
|
||||
SET_USER,
|
||||
SET_SELECTOR_USERS,
|
||||
SET_IS_VISIBLE_DATA_LOSS_DIALOG,
|
||||
SET_IS_EDITING_FORM,
|
||||
TOGGLE_AVATAR_EDITOR,
|
||||
} from "./actions";
|
||||
import { isUserSelected, skipUser, getUsersBySelected } from "./selectors";
|
||||
@ -26,7 +28,10 @@ const initialState = {
|
||||
selector: {
|
||||
users: [],
|
||||
},
|
||||
};
|
||||
editingForm: {
|
||||
isEdit: false,
|
||||
isVisibleDataLossDialog: false,
|
||||
},};
|
||||
|
||||
const peopleReducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
@ -79,11 +84,25 @@ const peopleReducer = (state = initialState, action) => {
|
||||
users: action.users,
|
||||
}),
|
||||
});
|
||||
case SET_IS_VISIBLE_DATA_LOSS_DIALOG:
|
||||
return Object.assign({}, state, {
|
||||
editingForm: {
|
||||
...state.editingForm,
|
||||
isVisibleDataLossDialog: action.isVisible,
|
||||
callback: action.callback,
|
||||
},
|
||||
});
|
||||
case SET_IS_EDITING_FORM:
|
||||
return Object.assign({}, state, {
|
||||
editingForm: {
|
||||
...state.editingForm,
|
||||
isEdit: action.isEdit,
|
||||
},
|
||||
});
|
||||
case TOGGLE_AVATAR_EDITOR:
|
||||
return Object.assign({}, state, {
|
||||
avatarEditorIsOpen: action.avatarEditorIsOpen,
|
||||
});
|
||||
default:
|
||||
}); default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { getUserByUserName } from "../people/selectors";
|
||||
import { fetchPeople } from "../people/actions";
|
||||
import { updateUserList } from "../people/actions";
|
||||
import { store, api } from "asc-web-common";
|
||||
const { setCurrentUser } = store.auth.actions;
|
||||
const { isMe } = store.auth.selectors;
|
||||
@ -43,7 +42,6 @@ export function fetchProfile(userName) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function createProfile(profile) {
|
||||
return (dispatch, getState) => {
|
||||
const { people } = getState();
|
||||
@ -58,7 +56,7 @@ export function createProfile(profile) {
|
||||
return dispatch(setProfile(user));
|
||||
})
|
||||
.then(() => {
|
||||
return fetchPeople(filter, dispatch);
|
||||
return updateUserList(dispatch, filter);
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.resolve(result);
|
||||
@ -67,9 +65,7 @@ export function createProfile(profile) {
|
||||
}
|
||||
|
||||
export function updateProfile(profile) {
|
||||
return (dispatch, getState) => {
|
||||
const { people } = getState();
|
||||
const { filter } = people;
|
||||
return (dispatch) => {
|
||||
const member = employeeWrapperToMemberModel(profile);
|
||||
let result;
|
||||
|
||||
@ -79,15 +75,11 @@ export function updateProfile(profile) {
|
||||
result = user;
|
||||
return Promise.resolve(dispatch(setProfile(user)));
|
||||
})
|
||||
.then(() => {
|
||||
return fetchPeople(filter, dispatch);
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.resolve(result);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function updateProfileCulture(id, culture) {
|
||||
return (dispatch) => {
|
||||
return api.people.updateUserCulture(id, culture).then((user) => {
|
||||
@ -100,3 +92,18 @@ export function updateProfileCulture(id, culture) {
|
||||
export function getUserPhoto(id) {
|
||||
return api.people.getUserPhoto(id);
|
||||
}
|
||||
|
||||
export function updateCreatedAvatar(avatar) {
|
||||
return (dispatch, getState) => {
|
||||
const { big, max, medium, small } = avatar;
|
||||
const { profile } = getState();
|
||||
const newProfile = {
|
||||
...profile.targetUser,
|
||||
avatarMax: max,
|
||||
avatarMedium: medium,
|
||||
avatar: big,
|
||||
avatarSmall: small,
|
||||
};
|
||||
return dispatch(setProfile(newProfile));
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "asc-web-common",
|
||||
"version": "1.0.248",
|
||||
"version": "1.0.249",
|
||||
"description": "Ascensio System SIA common components and solutions library",
|
||||
"license": "AGPL-3.0",
|
||||
"files": [
|
||||
|
@ -3,7 +3,7 @@ import styled from "styled-components";
|
||||
|
||||
const StyledMain = styled.main`
|
||||
height: calc(100vh - 56px);
|
||||
/*height: calc(var(--vh, 1vh) * 100 - 56px);*/
|
||||
height: calc(var(--vh, 1vh) * 100 - 56px);
|
||||
width: 100vw;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
|
Loading…
Reference in New Issue
Block a user