Web:People:Profile: add support dark-theme
This commit is contained in:
parent
0dbf805f8b
commit
bc62c12e9e
@ -1,22 +1,23 @@
|
||||
import React from "react";
|
||||
import { Trans, withTranslation } from "react-i18next";
|
||||
import Text from "@appserver/components/text";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import Link from "@appserver/components/link";
|
||||
import ComboBox from "@appserver/components/combobox";
|
||||
import HelpButton from "@appserver/components/help-button";
|
||||
import styled from "styled-components";
|
||||
import { resendUserInvites } from "@appserver/common/api/people";
|
||||
import toastr from "studio/toastr";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { showLoader, hideLoader } from "@appserver/common/utils";
|
||||
import { withRouter } from "react-router";
|
||||
import { AppServerConfig } from "@appserver/common/constants";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import withCultureNames from "@appserver/common/hoc/withCultureNames";
|
||||
import config from "../../../../../../package.json";
|
||||
import NoUserSelect from "@appserver/components/utils/commonStyles";
|
||||
import React from 'react';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
import Text from '@appserver/components/text';
|
||||
import { Base } from '@appserver/components/themes';
|
||||
import IconButton from '@appserver/components/icon-button';
|
||||
import Link from '@appserver/components/link';
|
||||
import ComboBox from '@appserver/components/combobox';
|
||||
import HelpButton from '@appserver/components/help-button';
|
||||
import styled from 'styled-components';
|
||||
import { resendUserInvites } from '@appserver/common/api/people';
|
||||
import toastr from 'studio/toastr';
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { showLoader, hideLoader } from '@appserver/common/utils';
|
||||
import { withRouter } from 'react-router';
|
||||
import { AppServerConfig } from '@appserver/common/constants';
|
||||
import { combineUrl } from '@appserver/common/utils';
|
||||
import withCultureNames from '@appserver/common/hoc/withCultureNames';
|
||||
import config from '../../../../../../package.json';
|
||||
import NoUserSelect from '@appserver/components/utils/commonStyles';
|
||||
|
||||
const InfoContainer = styled.div`
|
||||
margin-bottom: 24px;
|
||||
@ -41,9 +42,11 @@ const InfoItemLabel = styled.div`
|
||||
}
|
||||
|
||||
white-space: nowrap;
|
||||
color: #83888d;
|
||||
color: ${(props) => props.theme.profileInfo.color};
|
||||
`;
|
||||
|
||||
InfoItemLabel.defaultProps = { theme: Base };
|
||||
|
||||
const InfoItemValue = styled.div`
|
||||
width: 260px;
|
||||
word-break: break-word;
|
||||
@ -115,11 +118,7 @@ class ProfileInfo extends React.PureComponent {
|
||||
|
||||
const urlFilter = newFilter.toUrlParams();
|
||||
|
||||
const url = combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`/filter?${urlFilter}`
|
||||
);
|
||||
const url = combineUrl(AppServerConfig.proxyURL, config.homepage, `/filter?${urlFilter}`);
|
||||
history.push(url);
|
||||
|
||||
fetchPeople(newFilter).finally(() => setIsLoading(false));
|
||||
@ -134,11 +133,10 @@ class ProfileInfo extends React.PureComponent {
|
||||
fontSize="13px"
|
||||
isHovered={true}
|
||||
data-id={department.id}
|
||||
onClick={this.onGroupClick}
|
||||
>
|
||||
onClick={this.onGroupClick}>
|
||||
{department.name}
|
||||
</Link>
|
||||
{departments.length - 1 !== index ? ", " : ""}
|
||||
{departments.length - 1 !== index ? ', ' : ''}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
@ -149,19 +147,17 @@ class ProfileInfo extends React.PureComponent {
|
||||
onSentInviteAgain = (id) => {
|
||||
const { t } = this.props;
|
||||
resendUserInvites(new Array(id))
|
||||
.then(() => toastr.success(t("Translations:SuccessSentInvitation")))
|
||||
.catch((error) =>
|
||||
toastr.error(error && error.message ? error.message : error)
|
||||
);
|
||||
.then(() => toastr.success(t('Translations:SuccessSentInvitation')))
|
||||
.catch((error) => toastr.error(error && error.message ? error.message : error));
|
||||
};
|
||||
|
||||
onEmailClick = (e) => {
|
||||
const email = e.currentTarget.dataset.email;
|
||||
if (e.target.title) window.open("mailto:" + email);
|
||||
if (e.target.title) window.open('mailto:' + email);
|
||||
};
|
||||
|
||||
onLanguageSelect = (language) => {
|
||||
console.log("onLanguageSelect", language);
|
||||
console.log('onLanguageSelect', language);
|
||||
const {
|
||||
profile,
|
||||
updateProfileCulture,
|
||||
@ -234,30 +230,27 @@ class ProfileInfo extends React.PureComponent {
|
||||
const birthDayDate = new Date(birthday).toLocaleDateString(language);
|
||||
|
||||
const formatedSex =
|
||||
(sex === "male" && t("Translations:MaleSexStatus")) ||
|
||||
t("Translations:FemaleSexStatus");
|
||||
(sex === 'male' && t('Translations:MaleSexStatus')) || t('Translations:FemaleSexStatus');
|
||||
|
||||
const formatedDepartments =
|
||||
department && this.getFormattedDepartments(groups);
|
||||
const formatedDepartments = department && this.getFormattedDepartments(groups);
|
||||
|
||||
const supportEmail = "documentation@onlyoffice.com";
|
||||
const supportEmail = 'documentation@onlyoffice.com';
|
||||
|
||||
const tooltipLanguage = (
|
||||
<Text fontSize="13px">
|
||||
<Trans t={t} i18nKey="NotFoundLanguage" ns="Common">
|
||||
"In case you cannot find your language in the list of the available
|
||||
ones, feel free to write to us at
|
||||
"In case you cannot find your language in the list of the available ones, feel free to
|
||||
write to us at
|
||||
<Link href={`mailto:${supportEmail}`} isHovered={true}>
|
||||
{{ supportEmail }}
|
||||
</Link>
|
||||
to take part in the translation and get up to 1 year free of charge."
|
||||
</Trans>{" "}
|
||||
</Trans>{' '}
|
||||
<Link
|
||||
isHovered={true}
|
||||
href="https://helpcenter.onlyoffice.com/ru/guides/become-translator.aspx"
|
||||
target="_blank"
|
||||
>
|
||||
{t("Common:LearnMore")}
|
||||
target="_blank">
|
||||
{t('Common:LearnMore')}
|
||||
</Link>
|
||||
</Text>
|
||||
);
|
||||
@ -266,20 +259,17 @@ class ProfileInfo extends React.PureComponent {
|
||||
<InfoContainer>
|
||||
{!personal && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Common:Type")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Common:Type')}:</InfoItemLabel>
|
||||
<InfoItemValue>{type}</InfoItemValue>
|
||||
</InfoItem>
|
||||
)}
|
||||
{email && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Common:Email")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Common:Email')}:</InfoItemLabel>
|
||||
<InfoItemValue>
|
||||
<>
|
||||
{activationStatus === 2 && (isAdmin || isSelf) && (
|
||||
<IconButtonWrapper
|
||||
isBefore={true}
|
||||
title={t("Translations:PendingTitle")}
|
||||
>
|
||||
<IconButtonWrapper isBefore={true} title={t('Translations:PendingTitle')}>
|
||||
<IconButton
|
||||
color="#C96C27"
|
||||
size={16}
|
||||
@ -295,8 +285,7 @@ class ProfileInfo extends React.PureComponent {
|
||||
isHovered={true}
|
||||
title={email}
|
||||
data-email={email}
|
||||
onClick={this.onEmailClick}
|
||||
>
|
||||
onClick={this.onEmailClick}>
|
||||
{email}
|
||||
</Link>
|
||||
</>
|
||||
@ -305,19 +294,19 @@ class ProfileInfo extends React.PureComponent {
|
||||
)}
|
||||
{mobilePhone && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("PhoneLbl")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('PhoneLbl')}:</InfoItemLabel>
|
||||
<InfoItemValue>{mobilePhone}</InfoItemValue>
|
||||
</InfoItem>
|
||||
)}
|
||||
{sex && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Translations:Sex")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Translations:Sex')}:</InfoItemLabel>
|
||||
<InfoItemValue>{formatedSex}</InfoItemValue>
|
||||
</InfoItem>
|
||||
)}
|
||||
{birthday && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Translations:Birthdate")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Translations:Birthdate')}:</InfoItemLabel>
|
||||
<InfoItemValue>{birthDayDate}</InfoItemValue>
|
||||
</InfoItem>
|
||||
)}
|
||||
@ -335,7 +324,7 @@ class ProfileInfo extends React.PureComponent {
|
||||
)}
|
||||
{location && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Translations:Location")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Translations:Location')}:</InfoItemLabel>
|
||||
<InfoItemValue>{location}</InfoItemValue>
|
||||
</InfoItem>
|
||||
)}
|
||||
@ -347,7 +336,7 @@ class ProfileInfo extends React.PureComponent {
|
||||
)}
|
||||
{isSelf && (
|
||||
<InfoItem>
|
||||
<InfoItemLabel>{t("Common:Language")}:</InfoItemLabel>
|
||||
<InfoItemLabel>{t('Common:Language')}:</InfoItemLabel>
|
||||
<InfoItemValue>
|
||||
{cultureNames && selectedLanguage ? (
|
||||
<>
|
||||
@ -368,7 +357,7 @@ class ProfileInfo extends React.PureComponent {
|
||||
offsetLeft={50}
|
||||
offsetRight={0}
|
||||
tooltipContent={tooltipLanguage}
|
||||
helpButtonHeaderContent={t("Common:Language")}
|
||||
helpButtonHeaderContent={t('Common:Language')}
|
||||
className="help-icon"
|
||||
/>
|
||||
</>
|
||||
@ -394,12 +383,7 @@ export default withRouter(
|
||||
userCaption,
|
||||
guestCaption,
|
||||
} = customNames;
|
||||
const {
|
||||
usersStore,
|
||||
filterStore,
|
||||
loadingStore,
|
||||
targetUserStore,
|
||||
} = peopleStore;
|
||||
const { usersStore, filterStore, loadingStore, targetUserStore } = peopleStore;
|
||||
const { getUsersList: fetchPeople } = usersStore;
|
||||
const { filter } = filterStore;
|
||||
const { setIsLoading, isLoading } = loadingStore;
|
||||
@ -419,10 +403,6 @@ export default withRouter(
|
||||
personal: auth.settingsStore.personal,
|
||||
};
|
||||
})(
|
||||
observer(
|
||||
withTranslation(["Profile", "Common", "Translations"])(
|
||||
withCultureNames(ProfileInfo)
|
||||
)
|
||||
)
|
||||
)
|
||||
observer(withTranslation(['Profile', 'Common', 'Translations'])(withCultureNames(ProfileInfo))),
|
||||
),
|
||||
);
|
||||
|
@ -1,40 +1,30 @@
|
||||
import Avatar from "@appserver/components/avatar";
|
||||
import Button from "@appserver/components/button";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import Text from "@appserver/components/text";
|
||||
import SocialButton from "@appserver/components/social-button";
|
||||
import FacebookButton from "@appserver/components/facebook-button";
|
||||
import ToggleContent from "@appserver/components/toggle-content";
|
||||
import Link from "@appserver/components/link";
|
||||
import ProfileInfo from "./ProfileInfo/ProfileInfo";
|
||||
import toastr from "studio/toastr";
|
||||
import React from "react";
|
||||
import {
|
||||
combineUrl,
|
||||
isMe,
|
||||
getProviderTranslation,
|
||||
} from "@appserver/common/utils";
|
||||
import styled from "styled-components";
|
||||
import Avatar from '@appserver/components/avatar';
|
||||
import Button from '@appserver/components/button';
|
||||
import IconButton from '@appserver/components/icon-button';
|
||||
import Text from '@appserver/components/text';
|
||||
import SocialButton from '@appserver/components/social-button';
|
||||
import FacebookButton from '@appserver/components/facebook-button';
|
||||
import ToggleContent from '@appserver/components/toggle-content';
|
||||
import Link from '@appserver/components/link';
|
||||
import ProfileInfo from './ProfileInfo/ProfileInfo';
|
||||
import toastr from 'studio/toastr';
|
||||
import React from 'react';
|
||||
import { combineUrl, isMe, getProviderTranslation } from '@appserver/common/utils';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { withRouter } from "react-router";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
getUserContacts,
|
||||
getUserRole,
|
||||
} from "../../../../helpers/people-helpers";
|
||||
import config from "../../../../../package.json";
|
||||
import { AppServerConfig, providersData } from "@appserver/common/constants";
|
||||
import { unlinkOAuth, linkOAuth } from "@appserver/common/api/people";
|
||||
import { getAuthProviders } from "@appserver/common/api/settings";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import {
|
||||
ResetApplicationDialog,
|
||||
BackupCodesDialog,
|
||||
} from "../../../../components/dialogs";
|
||||
import { withRouter } from 'react-router';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { getUserContacts, getUserRole } from '../../../../helpers/people-helpers';
|
||||
import config from '../../../../../package.json';
|
||||
import { AppServerConfig, providersData } from '@appserver/common/constants';
|
||||
import { unlinkOAuth, linkOAuth } from '@appserver/common/api/people';
|
||||
import { getAuthProviders } from '@appserver/common/api/settings';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { ResetApplicationDialog, BackupCodesDialog } from '../../../../components/dialogs';
|
||||
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import withLoader from "../../../../HOCs/withLoader";
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import withLoader from '../../../../HOCs/withLoader';
|
||||
|
||||
const ProfileWrapper = styled.div`
|
||||
display: flex;
|
||||
@ -98,7 +88,7 @@ const ProviderButtonsWrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const createContacts = (contacts) => {
|
||||
const createContacts = (contacts, theme) => {
|
||||
const styledContacts = contacts.map((contact, index) => {
|
||||
let url = null;
|
||||
if (contact.link && contact.link.length > 0) {
|
||||
@ -108,7 +98,7 @@ const createContacts = (contacts) => {
|
||||
<ContactWrapper key={index}>
|
||||
<IconButton
|
||||
className="icon-button"
|
||||
color="#333333"
|
||||
color={theme ? theme.profileInfo.iconButtonColor : '#333333'}
|
||||
size={16}
|
||||
iconName={contact.icon}
|
||||
isFill={true}
|
||||
@ -123,8 +113,7 @@ const createContacts = (contacts) => {
|
||||
return styledContacts;
|
||||
};
|
||||
|
||||
const stringFormat = (string, data) =>
|
||||
string.replace(/\{(\d+)\}/g, (m, n) => data[n] || m);
|
||||
const stringFormat = (string, data) => string.replace(/\{(\d+)\}/g, (m, n) => data[n] || m);
|
||||
|
||||
class SectionBodyContent extends React.PureComponent {
|
||||
constructor(props) {
|
||||
@ -166,34 +155,23 @@ class SectionBodyContent extends React.PureComponent {
|
||||
const type = await getTfaType();
|
||||
this.setState({ tfa: type });
|
||||
|
||||
if (type && type !== "none") {
|
||||
if (type && type !== 'none') {
|
||||
const codes = await getBackupCodes();
|
||||
setBackupCodes(codes);
|
||||
}
|
||||
window.loginCallback = this.loginCallback;
|
||||
}
|
||||
|
||||
onEditSubscriptionsClick = () => console.log("Edit subscriptions onClick()");
|
||||
onEditSubscriptionsClick = () => console.log('Edit subscriptions onClick()');
|
||||
|
||||
onEditProfileClick = () => {
|
||||
const {
|
||||
isMy,
|
||||
avatarMax,
|
||||
setAvatarMax,
|
||||
history,
|
||||
profile,
|
||||
setIsEditTargetUser,
|
||||
} = this.props;
|
||||
const { isMy, avatarMax, setAvatarMax, history, profile, setIsEditTargetUser } = this.props;
|
||||
|
||||
avatarMax && setAvatarMax(null);
|
||||
setIsEditTargetUser(true);
|
||||
const editUrl = isMy
|
||||
? combineUrl(AppServerConfig.proxyURL, `/my?action=edit`)
|
||||
: combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`/edit/${profile.userName}`
|
||||
);
|
||||
: combineUrl(AppServerConfig.proxyURL, config.homepage, `/edit/${profile.userName}`);
|
||||
|
||||
history.push(editUrl);
|
||||
};
|
||||
@ -212,7 +190,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
linkOAuth(profile).then((resp) => {
|
||||
getAuthProviders().then((providers) => {
|
||||
setProviders(providers);
|
||||
toastr.success(t("ProviderSuccessfullyConnected"));
|
||||
toastr.success(t('ProviderSuccessfullyConnected'));
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -222,7 +200,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
unlinkOAuth(providerName).then(() => {
|
||||
getAuthProviders().then((providers) => {
|
||||
setProviders(providers);
|
||||
toastr.success(t("ProviderSuccessfullyDisconnected"));
|
||||
toastr.success(t('ProviderSuccessfullyDisconnected'));
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -234,17 +212,17 @@ class SectionBodyContent extends React.PureComponent {
|
||||
try {
|
||||
const tokenGetterWin = window.open(
|
||||
link,
|
||||
"login",
|
||||
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no"
|
||||
'login',
|
||||
'width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no',
|
||||
);
|
||||
|
||||
getOAuthToken(tokenGetterWin).then((code) => {
|
||||
const token = window.btoa(
|
||||
JSON.stringify({
|
||||
auth: providerName,
|
||||
mode: "popup",
|
||||
callback: "loginCallback",
|
||||
})
|
||||
mode: 'popup',
|
||||
callback: 'loginCallback',
|
||||
}),
|
||||
);
|
||||
|
||||
tokenGetterWin.location.href = getLoginLink(token, code);
|
||||
@ -255,7 +233,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
};
|
||||
|
||||
providerButtons = () => {
|
||||
const { t, providers } = this.props;
|
||||
const { t, providers, theme } = this.props;
|
||||
|
||||
const providerButtons =
|
||||
providers &&
|
||||
@ -267,7 +245,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
return (
|
||||
<React.Fragment key={`${item.provider}ProviderItem`}>
|
||||
<div>
|
||||
{item.provider === "facebook" ? (
|
||||
{item.provider === 'facebook' ? (
|
||||
<FacebookButton
|
||||
noHover={true}
|
||||
iconName={icon}
|
||||
@ -289,22 +267,20 @@ class SectionBodyContent extends React.PureComponent {
|
||||
<div>
|
||||
<Link
|
||||
type="action"
|
||||
color="A3A9AE"
|
||||
color={theme.profileInfo.linkColor}
|
||||
onClick={(e) => this.unlinkAccount(item.provider, e)}
|
||||
isHovered={true}
|
||||
>
|
||||
{t("Disconnect")}
|
||||
isHovered={true}>
|
||||
{t('Disconnect')}
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<Link
|
||||
type="action"
|
||||
color="A3A9AE"
|
||||
color={theme.profileInfo.linkColor}
|
||||
onClick={(e) => this.linkAccount(item.provider, item.url, e)}
|
||||
isHovered={true}
|
||||
>
|
||||
{t("Connect")}
|
||||
isHovered={true}>
|
||||
{t('Connect')}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
@ -341,6 +317,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
providers,
|
||||
backupCodes,
|
||||
personal,
|
||||
theme,
|
||||
} = this.props;
|
||||
const contacts = profile.contacts && getUserContacts(profile.contacts);
|
||||
const role = getUserRole(profile);
|
||||
@ -348,9 +325,9 @@ class SectionBodyContent extends React.PureComponent {
|
||||
(contacts &&
|
||||
contacts.social &&
|
||||
contacts.social.length > 0 &&
|
||||
createContacts(contacts.social)) ||
|
||||
createContacts(contacts.social, theme)) ||
|
||||
null;
|
||||
const infoContacts = contacts && createContacts(contacts.contact);
|
||||
const infoContacts = contacts && createContacts(contacts.contact, theme);
|
||||
//const isSelf = isMe(viewer, profile.userName);
|
||||
|
||||
let backupCodesCount = 0;
|
||||
@ -377,8 +354,8 @@ class SectionBodyContent extends React.PureComponent {
|
||||
<Button
|
||||
size="big"
|
||||
scale={true}
|
||||
label={t("EditUser")}
|
||||
title={t("EditUser")}
|
||||
label={t('EditUser')}
|
||||
title={t('EditUser')}
|
||||
onClick={this.onEditProfileClick}
|
||||
/>
|
||||
</EditButtonWrapper>
|
||||
@ -395,20 +372,18 @@ class SectionBodyContent extends React.PureComponent {
|
||||
|
||||
{!personal && isSelf && this.oauthDataExists() && (
|
||||
<ToggleWrapper>
|
||||
<ToggleContent label={t("LoginSettings")} isOpen={true}>
|
||||
<ProviderButtonsWrapper>
|
||||
{this.providerButtons()}
|
||||
</ProviderButtonsWrapper>
|
||||
<ToggleContent label={t('LoginSettings')} isOpen={true}>
|
||||
<ProviderButtonsWrapper>{this.providerButtons()}</ProviderButtonsWrapper>
|
||||
</ToggleContent>
|
||||
</ToggleWrapper>
|
||||
)}
|
||||
{!personal && isSelf && false && (
|
||||
<ToggleWrapper isSelf={true}>
|
||||
<ToggleContent label={t("Subscriptions")} isOpen={true}>
|
||||
<ToggleContent label={t('Subscriptions')} isOpen={true}>
|
||||
<Text as="span">
|
||||
<Button
|
||||
size="big"
|
||||
label={t("EditSubscriptionsBtn")}
|
||||
label={t('EditSubscriptionsBtn')}
|
||||
primary={true}
|
||||
onClick={this.onEditSubscriptionsClick}
|
||||
/>
|
||||
@ -416,32 +391,30 @@ class SectionBodyContent extends React.PureComponent {
|
||||
</ToggleContent>
|
||||
</ToggleWrapper>
|
||||
)}
|
||||
{isSelf && tfa && tfa !== "none" && (
|
||||
{isSelf && tfa && tfa !== 'none' && (
|
||||
<ToggleWrapper>
|
||||
<ToggleContent label={t("TfaLoginSettings")} isOpen={true}>
|
||||
<Text as="span">{t("TwoFactorDescription")}</Text>
|
||||
<ToggleContent label={t('TfaLoginSettings')} isOpen={true}>
|
||||
<Text as="span">{t('TwoFactorDescription')}</Text>
|
||||
<LinkActionWrapper>
|
||||
<Link
|
||||
type="action"
|
||||
isHovered={true}
|
||||
className="link-action-reset"
|
||||
isBold={true}
|
||||
onClick={this.toggleResetAppDialogVisible}
|
||||
>
|
||||
{t("Common:ResetApplication")}
|
||||
onClick={this.toggleResetAppDialogVisible}>
|
||||
{t('Common:ResetApplication')}
|
||||
</Link>
|
||||
<Link
|
||||
type="action"
|
||||
isHovered={true}
|
||||
className="link-action-backup"
|
||||
isBold={true}
|
||||
onClick={this.toggleBackupCodesDialogVisible}
|
||||
>
|
||||
{t("ShowBackupCodes")}
|
||||
onClick={this.toggleBackupCodesDialogVisible}>
|
||||
{t('ShowBackupCodes')}
|
||||
</Link>
|
||||
|
||||
<Link color="#A3A9AE" noHover={true}>
|
||||
({backupCodesCount} {t("CountCodesRemaining")})
|
||||
<Link color={theme.profileInfo.linkColor} noHover={true}>
|
||||
({backupCodesCount} {t('CountCodesRemaining')})
|
||||
</Link>
|
||||
</LinkActionWrapper>
|
||||
</ToggleContent>
|
||||
@ -450,24 +423,21 @@ class SectionBodyContent extends React.PureComponent {
|
||||
|
||||
{profile.notes && (
|
||||
<ToggleWrapper>
|
||||
<ToggleContent label={t("Translations:Comments")} isOpen={true}>
|
||||
<ToggleContent label={t('Translations:Comments')} isOpen={true}>
|
||||
<Text as="span">{profile.notes}</Text>
|
||||
</ToggleContent>
|
||||
</ToggleWrapper>
|
||||
)}
|
||||
{profile.contacts && (
|
||||
<ToggleWrapper isContacts={true}>
|
||||
<ToggleContent label={t("ContactInformation")} isOpen={true}>
|
||||
<ToggleContent label={t('ContactInformation')} isOpen={true}>
|
||||
<Text as="span">{infoContacts}</Text>
|
||||
</ToggleContent>
|
||||
</ToggleWrapper>
|
||||
)}
|
||||
{socialContacts && (
|
||||
<ToggleWrapper isContacts={true}>
|
||||
<ToggleContent
|
||||
label={t("Translations:SocialProfiles")}
|
||||
isOpen={true}
|
||||
>
|
||||
<ToggleContent label={t('Translations:SocialProfiles')} isOpen={true}>
|
||||
<Text as="span">{socialContacts}</Text>
|
||||
</ToggleContent>
|
||||
</ToggleWrapper>
|
||||
@ -498,13 +468,9 @@ export default withRouter(
|
||||
inject(({ auth, peopleStore }) => {
|
||||
const { isAdmin, userStore, settingsStore, tfaStore } = auth;
|
||||
const { user: viewer } = userStore;
|
||||
const { isTabletView, getOAuthToken, getLoginLink } = settingsStore;
|
||||
const { isTabletView, getOAuthToken, getLoginLink, theme } = settingsStore;
|
||||
const { targetUserStore, avatarEditorStore, usersStore } = peopleStore;
|
||||
const {
|
||||
targetUser: profile,
|
||||
isMe: isSelf,
|
||||
setIsEditTargetUser,
|
||||
} = targetUserStore;
|
||||
const { targetUser: profile, isMe: isSelf, setIsEditTargetUser } = targetUserStore;
|
||||
const { avatarMax, setAvatarMax } = avatarEditorStore;
|
||||
const { providers, setProviders } = usersStore;
|
||||
const {
|
||||
@ -536,12 +502,13 @@ export default withRouter(
|
||||
setBackupCodes,
|
||||
setIsEditTargetUser,
|
||||
personal: auth.settingsStore.personal,
|
||||
theme,
|
||||
};
|
||||
})(
|
||||
observer(
|
||||
withTranslation(["Profile", "Common", "Translations"])(
|
||||
withLoader(SectionBodyContent)(<Loaders.ProfileView />)
|
||||
)
|
||||
)
|
||||
)
|
||||
withTranslation(['Profile', 'Common', 'Translations'])(
|
||||
withLoader(SectionBodyContent)(<Loaders.ProfileView />),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1,47 +1,43 @@
|
||||
import React from "react";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import ContextMenuButton from "@appserver/components/context-menu-button";
|
||||
import AvatarEditor from "@appserver/components/avatar-editor";
|
||||
import Headline from "@appserver/common/components/Headline";
|
||||
import toastr from "studio/toastr";
|
||||
import { withRouter } from "react-router";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import React from 'react';
|
||||
import IconButton from '@appserver/components/icon-button';
|
||||
import ContextMenuButton from '@appserver/components/context-menu-button';
|
||||
import AvatarEditor from '@appserver/components/avatar-editor';
|
||||
import Headline from '@appserver/common/components/Headline';
|
||||
import toastr from 'studio/toastr';
|
||||
import { withRouter } from 'react-router';
|
||||
import { withTranslation, Trans } from 'react-i18next';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
resendUserInvites,
|
||||
createThumbnailsAvatar,
|
||||
loadAvatar,
|
||||
deleteAvatar,
|
||||
} from "@appserver/common/api/people";
|
||||
import { AppServerConfig, EmployeeStatus } from "@appserver/common/constants";
|
||||
} from '@appserver/common/api/people';
|
||||
import { AppServerConfig, EmployeeStatus } from '@appserver/common/constants';
|
||||
import {
|
||||
DeleteSelfProfileDialog,
|
||||
ChangePasswordDialog,
|
||||
ChangeEmailDialog,
|
||||
DeleteProfileEverDialog,
|
||||
} from "../../../../components/dialogs";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
getUserStatus,
|
||||
toEmployeeWrapper,
|
||||
} from "../../../../helpers/people-helpers";
|
||||
import config from "../../../../../package.json";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
} from '../../../../components/dialogs';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { getUserStatus, toEmployeeWrapper } from '../../../../helpers/people-helpers';
|
||||
import config from '../../../../../package.json';
|
||||
import { combineUrl } from '@appserver/common/utils';
|
||||
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import withLoader from "../../../../HOCs/withLoader";
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import withLoader from '../../../../HOCs/withLoader';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
position: relative;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: ${(props) =>
|
||||
props.showContextButton ? "auto auto auto 1fr" : "auto 1fr"};
|
||||
props.showContextButton ? 'auto auto auto 1fr' : 'auto 1fr'};
|
||||
align-items: center;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
grid-template-columns: ${(props) =>
|
||||
props.showContextButton ? "auto 1fr auto" : "auto 1fr"};
|
||||
grid-template-columns: ${(props) => (props.showContextButton ? 'auto 1fr auto' : 'auto 1fr')};
|
||||
}
|
||||
|
||||
.action-button {
|
||||
@ -78,10 +74,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!this.props.profile && !prevProps.profile) return;
|
||||
if (
|
||||
!prevProps.profile ||
|
||||
this.props.profile.userName !== prevProps.profile.userName
|
||||
) {
|
||||
if (!prevProps.profile || this.props.profile.userName !== prevProps.profile.userName) {
|
||||
this.setState(this.mapPropsToState(this.props));
|
||||
}
|
||||
}
|
||||
@ -93,7 +86,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
profile: profile,
|
||||
visibleAvatarEditor: false,
|
||||
avatar: {
|
||||
tmpFile: "",
|
||||
tmpFile: '',
|
||||
image: null,
|
||||
defaultWidth: 0,
|
||||
defaultHeight: 0,
|
||||
@ -120,7 +113,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
defaultWidth: avatarDefaultSizes[1],
|
||||
defaultHeight: avatarDefaultSizes[2],
|
||||
image: userPhotoData.original
|
||||
? userPhotoData.original.indexOf("default_user_photo") !== -1
|
||||
? userPhotoData.original.indexOf('default_user_photo') !== -1
|
||||
? null
|
||||
: userPhotoData.original
|
||||
: null,
|
||||
@ -145,8 +138,8 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
onLoadFileAvatar = (file, callback) => {
|
||||
let data = new FormData();
|
||||
let _this = this;
|
||||
data.append("file", file);
|
||||
data.append("Autosave", false);
|
||||
data.append('file', file);
|
||||
data.append('Autosave', false);
|
||||
loadAvatar(this.state.profile.id, data)
|
||||
.then((response) => {
|
||||
if (!response.success && response.message) {
|
||||
@ -162,7 +155,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
defaultHeight: img.height,
|
||||
};
|
||||
_this.setState(stateCopy);
|
||||
if (typeof callback === "function") callback();
|
||||
if (typeof callback === 'function') callback();
|
||||
};
|
||||
img.src = response.data;
|
||||
})
|
||||
@ -172,12 +165,8 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
onSaveAvatar = (isUpdate, result) => {
|
||||
if (isUpdate) {
|
||||
createThumbnailsAvatar(this.state.profile.id, {
|
||||
x: Math.round(
|
||||
result.x * this.state.avatar.defaultWidth - result.width / 2
|
||||
),
|
||||
y: Math.round(
|
||||
result.y * this.state.avatar.defaultHeight - result.height / 2
|
||||
),
|
||||
x: Math.round(result.x * this.state.avatar.defaultWidth - result.width / 2),
|
||||
y: Math.round(result.y * this.state.avatar.defaultHeight - result.height / 2),
|
||||
width: result.width,
|
||||
height: result.height,
|
||||
tmpFile: this.state.avatar.tmpFile,
|
||||
@ -185,12 +174,10 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
.then((response) => {
|
||||
let stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.visibleAvatarEditor = false;
|
||||
stateCopy.avatar.tmpFile = "";
|
||||
stateCopy.avatar.tmpFile = '';
|
||||
stateCopy.profile.avatarMax =
|
||||
response.max +
|
||||
"?_=" +
|
||||
Math.floor(Math.random() * Math.floor(10000));
|
||||
toastr.success(this.props.t("ChangesApplied"));
|
||||
response.max + '?_=' + Math.floor(Math.random() * Math.floor(10000));
|
||||
toastr.success(this.props.t('ChangesApplied'));
|
||||
this.setState(stateCopy);
|
||||
})
|
||||
.catch((error) => toastr.error(error))
|
||||
@ -202,7 +189,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
let stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.visibleAvatarEditor = false;
|
||||
stateCopy.profile.avatarMax = response.big;
|
||||
toastr.success(this.props.t("ChangesApplied"));
|
||||
toastr.success(this.props.t('ChangesApplied'));
|
||||
this.setState(stateCopy);
|
||||
})
|
||||
.catch((error) => toastr.error(error));
|
||||
@ -239,7 +226,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
: combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`/edit/${this.state.profile.userName}`
|
||||
`/edit/${this.state.profile.userName}`,
|
||||
);
|
||||
|
||||
history.push(editUrl);
|
||||
@ -251,29 +238,23 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
updateUserStatus(status, new Array(userId))
|
||||
.then(() => this.props.updateProfile(this.props.profile))
|
||||
.then(() => fetchProfile(userId))
|
||||
.then(() => toastr.success(t("Translations:SuccessChangeUserStatus")))
|
||||
.then(() => toastr.success(t('Translations:SuccessChangeUserStatus')))
|
||||
.catch((error) => toastr.error(error));
|
||||
};
|
||||
|
||||
onDisableClick = () =>
|
||||
this.onUpdateUserStatus(EmployeeStatus.Disabled, this.state.profile.id);
|
||||
onDisableClick = () => this.onUpdateUserStatus(EmployeeStatus.Disabled, this.state.profile.id);
|
||||
|
||||
onEnableClick = () =>
|
||||
this.onUpdateUserStatus(EmployeeStatus.Active, this.state.profile.id);
|
||||
onEnableClick = () => this.onUpdateUserStatus(EmployeeStatus.Active, this.state.profile.id);
|
||||
|
||||
onReassignDataClick = (user) => {
|
||||
const { history } = this.props;
|
||||
history.push(
|
||||
combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`/reassign/${user.userName}`
|
||||
)
|
||||
combineUrl(AppServerConfig.proxyURL, config.homepage, `/reassign/${user.userName}`),
|
||||
);
|
||||
};
|
||||
|
||||
onDeletePersonalDataClick = () => {
|
||||
console.log("Context action: Delete personal data");
|
||||
console.log('Context action: Delete personal data');
|
||||
};
|
||||
|
||||
toggleDeleteProfileEverDialog = () =>
|
||||
@ -300,18 +281,17 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
<Trans
|
||||
i18nKey="MessageEmailActivationInstuctionsSentOnEmail"
|
||||
ns="Profile"
|
||||
t={this.props.t}
|
||||
>
|
||||
t={this.props.t}>
|
||||
The email activation instructions have been sent to the
|
||||
<strong>{{ email: this.state.profile.email }}</strong> email address
|
||||
</Trans>
|
||||
)
|
||||
</Trans>,
|
||||
),
|
||||
)
|
||||
.catch((error) => toastr.error(error));
|
||||
};
|
||||
|
||||
getUserContextOptions = (user, viewer) => {
|
||||
let status = "";
|
||||
let status = '';
|
||||
const { t, isAdmin, isMe } = this.props;
|
||||
|
||||
if (isAdmin || (!isAdmin && isMe)) {
|
||||
@ -319,88 +299,88 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case "normal":
|
||||
case "unknown":
|
||||
case 'normal':
|
||||
case 'unknown':
|
||||
return [
|
||||
{
|
||||
key: "edit",
|
||||
label: t("EditUser"),
|
||||
key: 'edit',
|
||||
label: t('EditUser'),
|
||||
onClick: this.onEditClick,
|
||||
},
|
||||
{
|
||||
key: "change-password",
|
||||
label: t("Translations:PasswordChangeButton"),
|
||||
key: 'change-password',
|
||||
label: t('Translations:PasswordChangeButton'),
|
||||
onClick: this.toggleChangePasswordDialog,
|
||||
},
|
||||
{
|
||||
key: "change-email",
|
||||
label: t("Translations:EmailChangeButton"),
|
||||
key: 'change-email',
|
||||
label: t('Translations:EmailChangeButton'),
|
||||
onClick: this.toggleChangeEmailDialog,
|
||||
},
|
||||
isMe
|
||||
? viewer.isOwner
|
||||
? {}
|
||||
: {
|
||||
key: "delete-profile",
|
||||
label: t("Translations:DeleteSelfProfile"),
|
||||
key: 'delete-profile',
|
||||
label: t('Translations:DeleteSelfProfile'),
|
||||
onClick: this.toggleDeleteSelfProfileDialog,
|
||||
}
|
||||
: {
|
||||
key: "disable",
|
||||
label: t("Translations:DisableUserButton"),
|
||||
key: 'disable',
|
||||
label: t('Translations:DisableUserButton'),
|
||||
onClick: this.onDisableClick,
|
||||
},
|
||||
];
|
||||
case "disabled":
|
||||
case 'disabled':
|
||||
return [
|
||||
{
|
||||
key: "enable",
|
||||
label: t("Translations:EnableUserButton"),
|
||||
key: 'enable',
|
||||
label: t('Translations:EnableUserButton'),
|
||||
onClick: this.onEnableClick,
|
||||
},
|
||||
{
|
||||
key: "reassign-data",
|
||||
label: t("Translations:ReassignData"),
|
||||
key: 'reassign-data',
|
||||
label: t('Translations:ReassignData'),
|
||||
onClick: this.onReassignDataClick.bind(this, user),
|
||||
},
|
||||
{
|
||||
key: "delete-personal-data",
|
||||
label: t("Translations:RemoveData"),
|
||||
key: 'delete-personal-data',
|
||||
label: t('Translations:RemoveData'),
|
||||
onClick: this.onDeletePersonalDataClick,
|
||||
},
|
||||
{
|
||||
key: "delete-profile",
|
||||
label: t("Translations:DeleteSelfProfile"),
|
||||
key: 'delete-profile',
|
||||
label: t('Translations:DeleteSelfProfile'),
|
||||
onClick: this.toggleDeleteProfileEverDialog,
|
||||
},
|
||||
];
|
||||
case "pending":
|
||||
case 'pending':
|
||||
return [
|
||||
{
|
||||
key: "edit",
|
||||
label: t("Common:EditButton"),
|
||||
key: 'edit',
|
||||
label: t('Common:EditButton'),
|
||||
onClick: this.onEditClick,
|
||||
},
|
||||
{
|
||||
key: "invite-again",
|
||||
label: t("InviteAgainLbl"),
|
||||
key: 'invite-again',
|
||||
label: t('InviteAgainLbl'),
|
||||
onClick: this.onInviteAgainClick,
|
||||
},
|
||||
!isMe &&
|
||||
(user.status === EmployeeStatus.Active
|
||||
? {
|
||||
key: "disable",
|
||||
label: t("Translations:DisableUserButton"),
|
||||
key: 'disable',
|
||||
label: t('Translations:DisableUserButton'),
|
||||
onClick: this.onDisableClick,
|
||||
}
|
||||
: {
|
||||
key: "enable",
|
||||
label: t("Translations:EnableUserButton"),
|
||||
key: 'enable',
|
||||
label: t('Translations:EnableUserButton'),
|
||||
onClick: this.onEnableClick,
|
||||
}),
|
||||
isMe && {
|
||||
key: "delete-profile",
|
||||
label: t("Translations:DeleteSelfProfile"),
|
||||
key: 'delete-profile',
|
||||
label: t('Translations:DeleteSelfProfile'),
|
||||
onClick: this.toggleDeleteSelfProfileDialog,
|
||||
},
|
||||
];
|
||||
@ -419,11 +399,7 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
resetProfile();
|
||||
|
||||
const url = filter.toUrlParams();
|
||||
const backUrl = combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`filter?/${url}`
|
||||
);
|
||||
const backUrl = combineUrl(AppServerConfig.proxyURL, config.homepage, `filter?/${url}`);
|
||||
|
||||
history.push(backUrl, url);
|
||||
setFilter(filter);
|
||||
@ -436,14 +412,10 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
const contextOptions = () => this.getUserContextOptions(profile, viewer);
|
||||
|
||||
return (
|
||||
<StyledContainer
|
||||
showContextButton={(isAdmin && !profile.isOwner) || isMe}
|
||||
>
|
||||
<StyledContainer showContextButton={(isAdmin && !profile.isOwner) || isMe}>
|
||||
<IconButton
|
||||
iconName="/static/images/arrow.path.react.svg"
|
||||
color="#A3A9AE"
|
||||
size="17"
|
||||
hoverColor="#657077"
|
||||
isFill={true}
|
||||
onClick={this.onClickBack}
|
||||
className="arrow-button"
|
||||
@ -451,16 +423,15 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
|
||||
<Headline className="header-headline" type="content" truncate={true}>
|
||||
{profile.displayName}
|
||||
{profile.isLDAP && ` (${t("Translations:LDAPLbl")})`}
|
||||
{profile.isLDAP && ` (${t('Translations:LDAPLbl')})`}
|
||||
</Headline>
|
||||
{((isAdmin && !profile.isOwner) || isMe) && (
|
||||
<ContextMenuButton
|
||||
className="action-button"
|
||||
directionX="right"
|
||||
title={t("Common:Actions")}
|
||||
title={t('Common:Actions')}
|
||||
iconName="/static/images/vertical-dots.react.svg"
|
||||
size={17}
|
||||
color="#A3A9AE"
|
||||
getData={contextOptions}
|
||||
isDisabled={false}
|
||||
/>
|
||||
@ -472,13 +443,13 @@ class SectionHeaderContent extends React.PureComponent {
|
||||
onClose={this.onCloseAvatarEditor}
|
||||
onSave={this.onSaveAvatar}
|
||||
onLoadFile={this.onLoadFileAvatar}
|
||||
headerLabel={t("Common:EditAvatar")}
|
||||
selectNewPhotoLabel={t("Translations:selectNewPhotoLabel")}
|
||||
orDropFileHereLabel={t("Translations:orDropFileHereLabel")}
|
||||
unknownTypeError={t("Translations:ErrorUnknownFileImageType")}
|
||||
maxSizeFileError={t("Translations:maxSizeFileError")}
|
||||
unknownError={t("Common:Error")}
|
||||
saveButtonLabel={t("Common:SaveButton")}
|
||||
headerLabel={t('Common:EditAvatar')}
|
||||
selectNewPhotoLabel={t('Translations:selectNewPhotoLabel')}
|
||||
orDropFileHereLabel={t('Translations:orDropFileHereLabel')}
|
||||
unknownTypeError={t('Translations:ErrorUnknownFileImageType')}
|
||||
maxSizeFileError={t('Translations:maxSizeFileError')}
|
||||
unknownError={t('Common:Error')}
|
||||
saveButtonLabel={t('Common:SaveButton')}
|
||||
/>
|
||||
|
||||
{dialogsVisible.deleteSelfProfile && (
|
||||
@ -538,9 +509,9 @@ export default withRouter(
|
||||
};
|
||||
})(
|
||||
observer(
|
||||
withTranslation(["Profile", "Common", "Translations"])(
|
||||
withLoader(SectionHeaderContent)(<Loaders.SectionHeader />)
|
||||
)
|
||||
)
|
||||
)
|
||||
withTranslation(['Profile', 'Common', 'Translations'])(
|
||||
withLoader(SectionHeaderContent)(<Loaders.SectionHeader />),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user