This commit is contained in:
Daniil Senkiv 2019-11-07 10:15:15 +03:00
commit e04a0bee27
4 changed files with 332 additions and 268 deletions

View File

@ -255,26 +255,6 @@ class ProfileInfo extends React.PureComponent {
> >
{email} {email}
</Link> </Link>
{(isAdmin || isSelf) &&
<IconButtonWrapper title={t('EmailChangeButton')} >
<IconButton
color="#A3A9AE"
size={16}
iconName='AccessEditIcon'
isFill={true}
onClick={this.onEmailChange} />
</IconButtonWrapper>
}
{activationStatus === 2 && (isAdmin || isSelf) &&
<IconButtonWrapper title={t('SendInviteAgain')}>
<IconButton
color="#A3A9AE"
size={16}
iconName='FileActionsConvertIcon'
isFill={true}
onClick={this.onSentInviteAgain.bind(this, id)} />
</IconButtonWrapper>
}
</> </>
</InfoItemValue> </InfoItemValue>
</InfoItem> </InfoItem>

View File

@ -1,6 +1,6 @@
import React, { useCallback } from "react"; import React from "react";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { useTranslation } from 'react-i18next'; import { withTranslation } from 'react-i18next';
import { import {
Text, Text,
Avatar, Avatar,
@ -67,93 +67,90 @@ const createContacts = contacts => {
return styledContacts; return styledContacts;
}; };
const SectionBodyContent = props => { class SectionBodyContent extends React.PureComponent {
const { t } = useTranslation();
const { profile, updateProfileCulture, history, settings, isAdmin, viewer } = props;
const contacts = profile.contacts && getUserContacts(profile.contacts); onEditSubscriptionsClick = () => console.log("Edit subscriptions onClick()");
const role = getUserRole(profile);
const socialContacts = (contacts && contacts.social && contacts.social.length > 0 && createContacts(contacts.social)) || null;
const infoContacts = contacts && createContacts(contacts.contact);
const isSelf = isMe(viewer, profile.userName);
const onEditSubscriptionsClick = useCallback( onEditProfileClick = () => this.props.history.push(`${this.props.settings.homepage}/edit/${this.props.profile.userName}`);
() => console.log("Edit subscriptions onClick()"),
[]
);
const onEditProfileClick = useCallback( render() {
() => history.push(`${settings.homepage}/edit/${profile.userName}`), const { profile, updateProfileCulture, settings, isAdmin, viewer, t } = this.props;
[history, settings.homepage, profile.userName]
);
return ( const contacts = profile.contacts && getUserContacts(profile.contacts);
<ProfileWrapper> const role = getUserRole(profile);
<AvatarWrapper> const socialContacts = (contacts && contacts.social && contacts.social.length > 0 && createContacts(contacts.social)) || null;
<Avatar const infoContacts = contacts && createContacts(contacts.contact);
size="max" const isSelf = isMe(viewer, profile.userName);
role={role}
source={profile.avatarMax} return (
userName={profile.displayName} <ProfileWrapper>
/> <AvatarWrapper>
{(isAdmin || isSelf) && ( <Avatar
<EditButtonWrapper> size="max"
<Button role={role}
size="big" source={profile.avatarMax}
scale={true} userName={profile.displayName}
label={t("EditUserDialogTitle")} />
title={t("EditUserDialogTitle")} {(isAdmin || isSelf) && (
onClick={onEditProfileClick} <EditButtonWrapper>
/>
</EditButtonWrapper>
)}
</AvatarWrapper>
<ProfileInfo profile={profile} updateProfileCulture={updateProfileCulture} isSelf={isSelf} isAdmin={isAdmin} t={t} cultures={settings.cultures} culture={settings.culture} />
{isSelf && (
<ToggleWrapper isSelf={true} >
<ToggleContent label={t('Subscriptions')} isOpen={true} >
<Text.Body as="span">
<Button <Button
size="big" size="big"
label={t('EditSubscriptionsBtn')} scale={true}
primary={true} label={t("EditUserDialogTitle")}
onClick={onEditSubscriptionsClick} title={t("EditUserDialogTitle")}
onClick={this.onEditProfileClick}
/> />
</Text.Body> </EditButtonWrapper>
</ToggleContent> )}
</ToggleWrapper> </AvatarWrapper>
)} <ProfileInfo profile={profile} updateProfileCulture={updateProfileCulture} isSelf={isSelf} isAdmin={isAdmin} t={t} cultures={settings.cultures} culture={settings.culture} />
{profile.notes && ( {isSelf && (
<ToggleWrapper> <ToggleWrapper isSelf={true} >
<ToggleContent label={t('Comments')} isOpen={true} > <ToggleContent label={t('Subscriptions')} isOpen={true} >
<Text.Body as="span">{profile.notes}</Text.Body> <Text.Body as="span">
</ToggleContent> <Button
</ToggleWrapper> size="big"
)} label={t('EditSubscriptionsBtn')}
{profile.contacts && ( primary={true}
<ToggleWrapper isContacts={true} > onClick={this.onEditSubscriptionsClick}
<ToggleContent label={t('ContactInformation')} isOpen={true} > />
<Text.Body as="span">{infoContacts}</Text.Body> </Text.Body>
</ToggleContent> </ToggleContent>
</ToggleWrapper> </ToggleWrapper>
)} )}
{socialContacts && ( {profile.notes && (
<ToggleWrapper isContacts={true} > <ToggleWrapper>
<ToggleContent label={t('SocialProfiles')} isOpen={true} > <ToggleContent label={t('Comments')} isOpen={true} >
<Text.Body as="span">{socialContacts}</Text.Body> <Text.Body as="span">{profile.notes}</Text.Body>
</ToggleContent> </ToggleContent>
</ToggleWrapper> </ToggleWrapper>
)} )}
</ProfileWrapper> {profile.contacts && (
); <ToggleWrapper isContacts={true} >
}; <ToggleContent label={t('ContactInformation')} isOpen={true} >
<Text.Body as="span">{infoContacts}</Text.Body>
</ToggleContent>
</ToggleWrapper>
)}
{socialContacts && (
<ToggleWrapper isContacts={true} >
<ToggleContent label={t('SocialProfiles')} isOpen={true} >
<Text.Body as="span">{socialContacts}</Text.Body>
</ToggleContent>
</ToggleWrapper>
)}
</ProfileWrapper>
);
}
}
function mapStateToProps(state) { const mapStateToProps = state => {
return { return {
settings: state.auth.settings, settings: state.auth.settings,
profile: state.profile.targetUser,
isAdmin: isAdmin(state.auth.user), isAdmin: isAdmin(state.auth.user),
viewer: state.auth.user viewer: state.auth.user
}; };
} }
export default connect(mapStateToProps, { updateProfileCulture })(withRouter(SectionBodyContent)); export default connect(mapStateToProps, { updateProfileCulture })(withRouter(withTranslation()(SectionBodyContent)));

View File

@ -1,7 +1,8 @@
import React, { useCallback, useState } from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { import {
Text, Text,
Link,
IconButton, IconButton,
ContextMenuButton, ContextMenuButton,
toastr, toastr,
@ -13,13 +14,14 @@ import {
} from "asc-web-components"; } from "asc-web-components";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { isAdmin, isMe } from "../../../../../store/auth/selectors"; import { isAdmin, isMe } from "../../../../../store/auth/selectors";
import { getUserStatus } from "../../../../../store/people/selectors"; import { getUserStatus, toEmployeeWrapper } from "../../../../../store/people/selectors";
import { useTranslation } from 'react-i18next'; import { withTranslation } from 'react-i18next';
import { resendUserInvites } from "../../../../../store/services/api"; import { resendUserInvites } from "../../../../../store/services/api";
import { EmployeeStatus } from "../../../../../helpers/constants"; import { EmployeeStatus } from "../../../../../helpers/constants";
import { updateUserStatus } from "../../../../../store/people/actions"; import { updateUserStatus } from "../../../../../store/people/actions";
import { fetchProfile } from '../../../../../store/profile/actions'; import { fetchProfile } from '../../../../../store/profile/actions';
import { import {
sendInstructionsToDelete,
sendInstructionsToChangePassword, sendInstructionsToChangePassword,
sendInstructionsToChangeEmail, sendInstructionsToChangeEmail,
createThumbnailsAvatar, createThumbnailsAvatar,
@ -42,97 +44,128 @@ const Header = styled(Text.ContentHeader)`
} }
`; `;
const SectionHeaderContent = props => { class SectionHeaderContent extends React.PureComponent {
const { profile, history, settings, isAdmin, viewer, updateUserStatus, fetchProfile } = props; constructor(props) {
super(props);
const [newEmailState, setNewEmail] = useState(profile.email); this.state = this.mapPropsToState(props);
const [dialogState, setDialog] = useState( }
{
visible: false,
header: "",
body: "",
buttons: [],
newEmail: profile.email,
});
const [avatarState, setAvatar] = useState(
{
tmpFile: "",
image: profile.avatarDefault ? "data:image/png;base64," + profile.avatarDefault : null,
defaultWidth: 0,
defaultHeight: 0
});
const [avatarEditorState, setAvatarEditorVisible] = useState(false);
const openAvatarEditor = () => { componentDidUpdate(prevProps) {
let avatarDefault = profile.avatarDefault ? "data:image/png;base64," + profile.avatarDefault : null; if (this.props.profile.userName !== prevProps.profile.userName) {
console.log(this.props.profile.userName);
this.setState(this.mapPropsToState(this.props));
}
}
mapPropsToState = props => {
let profile = toEmployeeWrapper(props.profile);
const newState = {
profile: profile,
visibleAvatarEditor: false,
dialog: {
visible: false,
header: "",
body: "",
buttons: [],
newEmail: profile.email,
},
avatar: {
tmpFile: "",
image: profile.avatarDefault ? "data:image/png;base64," + profile.avatarDefault : null,
defaultWidth: 0,
defaultHeight: 0
}
};
return newState;
}
openAvatarEditor = () => {
let avatarDefault = this.state.profile.avatarDefault ? "data:image/png;base64," + this.state.profile.avatarDefault : null;
let _this = this;
if (avatarDefault !== null) { if (avatarDefault !== null) {
let img = new Image(); let img = new Image();
img.onload = function () { img.onload = function () {
setAvatar({ _this.setState({
defaultWidth: img.width, avatar: {
defaultHeight: img.height defaultWidth: img.width,
defaultHeight: img.height
}
}) })
}; };
img.src = avatarDefault; img.src = avatarDefault;
} }
setAvatarEditorVisible(true); this.setState({
visibleAvatarEditor: true,
});
} }
const onLoadFileAvatar = (file) => { onLoadFileAvatar = file => {
let data = new FormData(); let data = new FormData();
let _this = this;
data.append("file", file); data.append("file", file);
data.append("Autosave", false); data.append("Autosave", false);
loadAvatar(profile.id, data) loadAvatar(this.state.profile.id, data)
.then((response) => { .then((response) => {
var img = new Image(); var img = new Image();
img.onload = function () { img.onload = function () {
var stateCopy = Object.assign({}, avatarState); var stateCopy = Object.assign({}, _this.state);
stateCopy = { stateCopy.avatar = {
tmpFile: response.data, tmpFile: response.data,
image: response.data, image: response.data,
defaultWidth: img.width, defaultWidth: img.width,
defaultHeight: img.height defaultHeight: img.height
} }
_this.setState(stateCopy);
setAvatar(stateCopy);
}; };
img.src = response.data; img.src = response.data;
}) })
.catch((error) => toastr.error(error)); .catch((error) => toastr.error(error));
} }
const onSaveAvatar = (isUpdate, result) => { onSaveAvatar = (isUpdate, result) => {
if (isUpdate) { if (isUpdate) {
createThumbnailsAvatar(profile.id, { createThumbnailsAvatar(this.state.profile.id, {
x: Math.round(result.x * avatarState.defaultWidth - result.width / 2), x: Math.round(result.x * this.state.avatar.defaultWidth - result.width / 2),
y: Math.round(result.y * avatarState.defaultHeight - result.height / 2), y: Math.round(result.y * this.state.avatar.defaultHeight - result.height / 2),
width: result.width, width: result.width,
height: result.height, height: result.height,
tmpFile: avatarState.tmpFile tmpFile: this.state.avatar.tmpFile
}) })
.then((response) => { .then((response) => {
setAvatarEditorVisible(false); let stateCopy = Object.assign({}, this.state);
setAvatar({ tmpFile: '' }); stateCopy.visibleAvatarEditor = false;
fetchProfile(profile.id); stateCopy.avatar.tmpFile = '';
stateCopy.profile.avatarMax = response.max + '?_=' + Math.floor(Math.random() * Math.floor(10000));
toastr.success("Success"); toastr.success("Success");
this.setState(stateCopy);
}) })
.catch((error) => toastr.error(error)); .catch((error) => toastr.error(error))
.then(() => this.props.fetchProfile(this.state.profile.id));
} else { } else {
deleteAvatar(profile.id) deleteAvatar(this.state.profile.id)
.then((response) => { .then((response) => {
setAvatarEditorVisible(false); let stateCopy = Object.assign({}, this.state);
fetchProfile(profile.id); stateCopy.visibleAvatarEditor = false;
stateCopy.profile.avatarMax = response.big;
toastr.success("Success"); toastr.success("Success");
this.setState(stateCopy);
}) })
.catch((error) => toastr.error(error)); .catch((error) => toastr.error(error));
} }
} }
const onCloseAvatarEditor = () => setAvatarEditorVisible(false); onCloseAvatarEditor = () => {
this.setState({
visibleAvatarEditor: false,
});
}
const onEmailChange = event => { onEmailChange = event => {
const emailRegex = /.+@.+\..+/; const emailRegex = /.+@.+\..+/;
const newEmail = (event && event.target.value) || newEmailState; const newEmail = (event && event.target.value) || this.state.dialog.newEmail;
const hasError = !emailRegex.test(newEmail); const hasError = !emailRegex.test(newEmail);
const dialog = { const dialog = {
@ -146,7 +179,7 @@ const SectionHeaderContent = props => {
scale={true} scale={true}
isAutoFocussed={true} isAutoFocussed={true}
value={newEmail} value={newEmail}
onChange={onEmailChange} onChange={this.onEmailChange}
hasError={hasError} hasError={hasError}
/> />
</Text.Body> </Text.Body>
@ -157,33 +190,32 @@ const SectionHeaderContent = props => {
label="Send" label="Send"
size="medium" size="medium"
primary={true} primary={true}
onClick={onSendEmailChangeInstructions} onClick={this.onSendEmailChangeInstructions}
isDisabled={hasError} isDisabled={hasError}
/> />
], ],
newEmail: newEmail newEmail: newEmail
}; };
this.setState({ dialog: dialog })
setDialog(dialog);
} }
const onSendEmailChangeInstructions = () => { onSendEmailChangeInstructions = () => {
sendInstructionsToChangeEmail(profile.id, newEmailState) sendInstructionsToChangeEmail(this.state.profile.id, this.state.dialog.newEmail)
.then((res) => { .then((res) => {
toastr.success(res); toastr.success(res);
}) })
.catch((error) => toastr.error(error)) .catch((error) => toastr.error(error))
.finally(onDialogClose); .finally(this.onDialogClose);
} }
const onPasswordChange = () => { onPasswordChange = () => {
const dialog = { const dialog = {
visible: true, visible: true,
header: "Change password", header: "Change password",
body: ( body: (
<Text.Body> <Text.Body>
Send the password change instructions to the <a href={`mailto:${profile.email}`}>{profile.email}</a> email address Send the password change instructions to the <a href={`mailto:${this.state.profile.email}`}>{this.state.profile.email}</a> email address
</Text.Body> </Text.Body>
), ),
buttons: [ buttons: [
<Button <Button
@ -191,70 +223,119 @@ const SectionHeaderContent = props => {
label="Send" label="Send"
size="medium" size="medium"
primary={true} primary={true}
onClick={onSendPasswordChangeInstructions} onClick={this.onSendPasswordChangeInstructions}
/> />
] ]
}; };
this.setState({ dialog: dialog })
setDialog(dialog);
} }
const onSendPasswordChangeInstructions = () => { onSendPasswordChangeInstructions = () => {
sendInstructionsToChangePassword(profile.email) sendInstructionsToChangePassword(this.state.profile.email)
.then((res) => { .then((res) => {
toastr.success(res); toastr.success(res);
}) })
.catch((error) => toastr.error(error)) .catch((error) => toastr.error(error))
.finally(onDialogClose); .finally(this.onDialogClose);
} }
const onDialogClose = () => { onDialogClose = () => {
const dialog = { visible: false, newEmailState: profile.email }; const dialog = { visible: false, newEmail: this.state.profile.email };
setDialog(dialog); this.setState({ dialog: dialog })
} }
const selectedUserIds = new Array(profile.id); onEditClick = () => {
const { history, settings } = this.props;
history.push(`${settings.homepage}/edit/${this.state.profile.userName}`);
}
const onEditClick = () => { onUpdateUserStatus = (status, userId) => {
history.push(`${settings.homepage}/edit/${profile.userName}`); const { fetchProfile, updateUserStatus } = this.props;
};
const onDisableClick = () => { updateUserStatus(status, new Array(userId))
updateUserStatus(EmployeeStatus.Disabled, selectedUserIds) .then(() => fetchProfile(userId));
.then(() => toastr.success(t("SuccessChangeUserStatus"))) }
.then(() => fetchProfile(profile.id));
};
const onEditPhoto = () => { onDisableClick = () => this.onUpdateUserStatus(EmployeeStatus.Disabled, this.state.profile.id);
openAvatarEditor();
};
const onEnableClick = () => { onEnableClick = () => this.onUpdateUserStatus(EmployeeStatus.Active, this.state.profile.id);
updateUserStatus(EmployeeStatus.Active, selectedUserIds)
.then(() => toastr.success(t("SuccessChangeUserStatus")))
.then(() => fetchProfile(profile.id));
};
const onReassignDataClick = user => { onReassignDataClick = user => {
const { history, settings } = props; const { history, settings } = this.props;
history.push(`${settings.homepage}/reassign/${user.userName}`); history.push(`${settings.homepage}/reassign/${user.userName}`);
}; }
const onDeletePersonalDataClick = () => { onDeletePersonalDataClick = () => {
toastr.success("Context action: Delete personal data"); toastr.success("Context action: Delete personal data");
}; }
const onDeleteProfileClick = () => { onDeleteProfileClick = () => {
toastr.success("Context action: Delete profile"); toastr.success("Context action: Delete profile");
}; }
const onInviteAgainClick = () => { onDeleteSelfProfileClick = email => {
resendUserInvites(selectedUserIds) this.setState({
.then(() => toastr.success("The invitation was successfully sent")) dialog: {
visible: true,
header: "Delete profile dialog",
body: (
<Text.Body>
Send the profile deletion instructions to the email address{" "}
<Link type="page" href={`mailto:${email}`} isHovered title={email}>
{email}
</Link>
</Text.Body>
),
buttons: [
<Button
key="OkBtn"
label="Send"
size="medium"
primary={true}
onClick={() => {
const { onLoading } = this.props;
onLoading(true);
sendInstructionsToDelete()
.then(() =>
toastr.success(
<Text.Body>
Instructions to delete your profile has been sent to{" "}
<b>{email}</b> email address
</Text.Body>
)
)
.catch(error => toastr.error(error))
.finally(() => onLoading(false));
this.onDialogClose();
}}
/>,
<Button
key="CancelBtn"
label="Cancel"
size="medium"
primary={false}
onClick={this.onDialogClose}
style={{ marginLeft: "8px" }}
/>
]
}
});
}
onInviteAgainClick = () => {
resendUserInvites(new Array(this.state.profile.id))
.then(() => toastr.success(
<Text.Body>
The email activation instructions have been sent to the{" "}
<b>{this.state.profile.email}</b> email address
</Text.Body>
))
.catch(error => toastr.error(error)); .catch(error => toastr.error(error));
}; }
const getUserContextOptions = (user, viewer, t) => {
getUserContextOptions = (user, viewer) => {
let status = ""; let status = "";
const { t } = this.props;
if (isAdmin || (!isAdmin && isMe(user, viewer.userName))) { if (isAdmin || (!isAdmin && isMe(user, viewer.userName))) {
status = getUserStatus(user); status = getUserStatus(user);
@ -267,22 +348,22 @@ const SectionHeaderContent = props => {
{ {
key: "edit", key: "edit",
label: t('EditUserDialogTitle'), label: t('EditUserDialogTitle'),
onClick: onEditClick onClick: this.onEditClick
}, },
{ {
key: "change-password", key: "change-password",
label: t('PasswordChangeButton'), label: t('PasswordChangeButton'),
onClick: onPasswordChange onClick: this.onPasswordChange
}, },
{ {
key: "change-email", key: "change-email",
label: t('EmailChangeButton'), label: t('EmailChangeButton'),
onClick: onEmailChange onClick: this.onEmailChange
}, },
{ {
key: "edit-photo", key: "edit-photo",
label: t('EditPhoto'), label: t('EditPhoto'),
onClick: onEditPhoto onClick: this.openAvatarEditor
}, },
isMe(user, viewer.userName) isMe(user, viewer.userName)
? viewer.isOwner ? viewer.isOwner
@ -290,12 +371,12 @@ const SectionHeaderContent = props => {
: { : {
key: "delete-profile", key: "delete-profile",
label: t("DeleteSelfProfile"), label: t("DeleteSelfProfile"),
onClick: onDeleteProfileClick onClick: this.onDeleteSelfProfileClick.bind(this, user.email)
} }
: { : {
key: "disable", key: "disable",
label: t("DisableUserButton"), label: t("DisableUserButton"),
onClick: onDisableClick onClick: this.onDisableClick
} }
]; ];
case "disabled": case "disabled":
@ -303,27 +384,27 @@ const SectionHeaderContent = props => {
{ {
key: "enable", key: "enable",
label: t('EnableUserButton'), label: t('EnableUserButton'),
onClick: onEnableClick onClick: this.onEnableClick
}, },
{ {
key: "edit-photo", key: "edit-photo",
label: t('EditPhoto'), label: t('EditPhoto'),
onClick: onEditPhoto onClick: this.openAvatarEditor
}, },
{ {
key: "reassign-data", key: "reassign-data",
label: t('ReassignData'), label: t('ReassignData'),
onClick: onReassignDataClick.bind(this, user) onClick: this.onReassignDataClick.bind(this, user)
}, },
{ {
key: "delete-personal-data", key: "delete-personal-data",
label: t('RemoveData'), label: t('RemoveData'),
onClick: onDeletePersonalDataClick onClick: this.onDeletePersonalDataClick
}, },
{ {
key: "delete-profile", key: "delete-profile",
label: t('DeleteSelfProfile'), label: t('DeleteSelfProfile'),
onClick: onDeleteProfileClick onClick: this.onDeleteProfileClick
} }
]; ];
case "pending": case "pending":
@ -331,103 +412,107 @@ const SectionHeaderContent = props => {
{ {
key: "edit", key: "edit",
label: t('EditButton'), label: t('EditButton'),
onClick: onEditClick onClick: this.onEditClick
}, },
{ {
key: "invite-again", key: "invite-again",
label: t('InviteAgainLbl'), label: t('InviteAgainLbl'),
onClick: onInviteAgainClick onClick: this.onInviteAgainClick
}, },
{ {
key: "edit-photo", key: "edit-photo",
label: t('EditPhoto'), label: t('EditPhoto'),
onClick: onEditPhoto onClick: this.openAvatarEditor
}, },
!isMe(user, viewer.userName) && !isMe(user, viewer.userName) &&
(user.status === EmployeeStatus.Active (user.status === EmployeeStatus.Active
? { ? {
key: "disable", key: "disable",
label: t("DisableUserButton"), label: t("DisableUserButton"),
onClick: onDisableClick onClick: this.onDisableClick
} }
: { : {
key: "enable", key: "enable",
label: t("EnableUserButton"), label: t("EnableUserButton"),
onClick: onEnableClick onClick: this.onEnableClick
}), }),
isMe(user, viewer.userName) && { isMe(user, viewer.userName) && {
key: "delete-profile", key: "delete-profile",
label: t("DeleteSelfProfile"), label: t("DeleteSelfProfile"),
onClick: onDeleteProfileClick onClick: this.onDeleteSelfProfileClick.bind(this, user.email)
} }
]; ];
default: default:
return []; return [];
} }
}
}; goBack = () => {
this.props.history.goBack();
}
const { t } = useTranslation(); render() {
const contextOptions = () => getUserContextOptions(profile, viewer, t); const { profile, isAdmin, viewer, t } = this.props;
const { dialog, avatar, visibleAvatarEditor } = this.state;
const onClick = useCallback(() => { const contextOptions = () => this.getUserContextOptions(profile, viewer);
history.goBack();
}, [history]);
return ( return (
<div style={wrapperStyle}> <div style={wrapperStyle}>
<div style={{ width: "16px" }}> <div style={{ width: "16px" }}>
<IconButton <IconButton
iconName={"ArrowPathIcon"} iconName={"ArrowPathIcon"}
color="#A3A9AE" color="#A3A9AE"
size="16" size="16"
onClick={onClick} onClick={this.goBack}
/>
</div>
<Header truncate={true}>
{profile.displayName}
{profile.isLDAP && ` (${t('LDAPLbl')})`}
</Header>
{((isAdmin && !profile.isOwner) || isMe(viewer, profile.userName)) && (
<ContextMenuButton
directionX="right"
title={t('Actions')}
iconName="VerticalDotsIcon"
size={16}
color="#A3A9AE"
getData={contextOptions}
isDisabled={false}
/>
)}
<ModalDialog
visible={dialog.visible}
headerContent={dialog.header}
bodyContent={dialog.body}
footerContent={dialog.buttons}
onClose={this.onDialogClose}
/>
<AvatarEditor
image={avatar.image}
visible={visibleAvatarEditor}
onClose={this.onCloseAvatarEditor}
onSave={this.onSaveAvatar}
onLoadFile={this.onLoadFileAvatar}
headerLabel={t("editAvatar")}
chooseFileLabel={t("chooseFileLabel")}
unknownTypeError={t("unknownTypeError")}
maxSizeFileError={t("maxSizeFileError")}
unknownError={t("unknownError")}
/> />
</div> </div>
<Header truncate={true}> );
{profile.displayName} }
{profile.isLDAP && ` (${t('LDAPLbl')})`} }
</Header>
{((isAdmin && !profile.isOwner) || isMe(viewer, profile.userName)) && (
<ContextMenuButton
directionX="right"
title={t('Actions')}
iconName="VerticalDotsIcon"
size={16}
color="#A3A9AE"
getData={contextOptions}
isDisabled={false}
/>
)}
<ModalDialog
visible={dialogState.visible}
headerContent={dialogState.header}
bodyContent={dialogState.body}
footerContent={dialogState.buttons}
onClose={onDialogClose}
/>
<AvatarEditor
image={avatarState.image}
visible={avatarEditorState}
onClose={onCloseAvatarEditor}
onSave={onSaveAvatar}
onLoadFile={onLoadFileAvatar}
headerLabel={t("editAvatar")}
chooseFileLabel={t("chooseFileLabel")}
unknownTypeError={t("unknownTypeError")}
maxSizeFileError={t("maxSizeFileError")}
unknownError={t("unknownError")}
/>
</div>
);
};
function mapStateToProps(state) { const mapStateToProps = (state) => {
return { return {
settings: state.auth.settings, settings: state.auth.settings,
profile: state.profile.targetUser,
viewer: state.auth.user, viewer: state.auth.user,
isAdmin: isAdmin(state.auth.user) isAdmin: isAdmin(state.auth.user)
}; };
} }
export default connect(mapStateToProps, { updateUserStatus, fetchProfile })(withRouter(SectionHeaderContent)); export default connect(mapStateToProps, { updateUserStatus, fetchProfile })(withRouter(withTranslation()(SectionHeaderContent)));

View File

@ -20,9 +20,11 @@ class PureProfile extends React.Component {
componentDidMount() { componentDidMount() {
const { match, fetchProfile, t } = this.props; const { match, fetchProfile, t } = this.props;
const { userId } = match.params; const { userId } = match.params;
const queryParams = this.state.queryString.split('&'); const queryParams = this.state.queryString.split('&');
const arrayOfQueryParams = queryParams.map(queryParam => queryParam.split('=')); const arrayOfQueryParams = queryParams.map(queryParam => queryParam.split('='));
const linkParams = Object.fromEntries(arrayOfQueryParams); const linkParams = Object.fromEntries(arrayOfQueryParams);
if (linkParams.email_change && linkParams.email_change === "success"){ if (linkParams.email_change && linkParams.email_change === "success"){
toastr.success(t('ChangeEmailSuccess')); toastr.success(t('ChangeEmailSuccess'));
} }
@ -35,13 +37,13 @@ class PureProfile extends React.Component {
const { userId } = match.params; const { userId } = match.params;
const prevUserId = prevProps.match.params.userId; const prevUserId = prevProps.match.params.userId;
if (userId !== prevUserId) { if (userId !== undefined && userId !== prevUserId) {
fetchProfile(userId); fetchProfile(userId);
} }
} }
render() { render() {
console.log("Profile render") //console.log("Profile render")
const { profile, isVisitor } = this.props; const { profile, isVisitor } = this.props;
@ -52,8 +54,8 @@ class PureProfile extends React.Component {
}; };
const sectionProps = profile ? { const sectionProps = profile ? {
sectionHeaderContent: <SectionHeaderContent profile={profile} />, sectionHeaderContent: <SectionHeaderContent />,
sectionBodyContent: <SectionBodyContent profile={profile} /> sectionBodyContent: <SectionBodyContent />
} : { } : {
sectionBodyContent: <Loader className="pageLoader" type="rombs" size={40} /> sectionBodyContent: <Loader className="pageLoader" type="rombs" size={40} />
}; };