Merge branch 'feature/workspaces' of github.com:ONLYOFFICE/AppServer into feature/workspaces

This commit is contained in:
Artem Tarasov 2021-03-03 13:01:15 +03:00
commit b97118d72c
33 changed files with 287 additions and 328 deletions

View File

@ -10,7 +10,7 @@ import {
StyledFilterItemContent,
StyledCloseButtonBlock,
} from "../StyledFilterInput";
import GroupSelector from "../../GroupSelector";
import GroupSelector from "people/GroupSelector"; //TODO: Move GroupSelector out of FilterItem
import PeopleSelector from "../../PeopleSelector";
class FilterItem extends React.Component {

View File

@ -1,71 +0,0 @@
/* eslint-disable react/prop-types */
import React from "react";
import { storiesOf } from "@storybook/react";
import { withKnobs, boolean } from "@storybook/addon-knobs/react";
import Section from "../../../.storybook/decorators/section";
import GroupSelector from ".";
import Button from "@appserver/components/button";
//import withReadme from "storybook-readme/with-readme";
//import Readme from "./README.md";
class GroupSelectorExample extends React.Component {
constructor(props) {
super(props);
this.buttonRef = React.createRef();
this.state = {
isOpen: false,
};
}
toggle = () => {
this.setState({
isOpen: !this.state.isOpen,
});
};
onCancel = (e) => {
if (this.buttonRef.current.contains(e.target)) {
console.log("onCancel skipped");
return;
}
console.log("onCancel");
this.toggle();
};
render() {
return (
<div style={{ position: "relative" }}>
<Button
label="Toggle dropdown"
onClick={this.toggle}
ref={this.buttonRef}
/>
<GroupSelector
isOpen={this.state.isOpen}
useFake={true}
isMultiSelect={boolean("isMultiSelect", true)}
onSelect={(data) => {
console.log("onSelect", data);
this.toggle();
}}
onCancel={this.onCancel}
/>
</div>
);
}
}
storiesOf("Components|GroupSelector", module)
.addDecorator(withKnobs)
//.addDecorator(withReadme(Readme))
.addParameters({ options: { addonPanelInRight: false } })
.add("base", () => {
return (
<Section>
<GroupSelectorExample />
</Section>
);
});

View File

@ -1,19 +0,0 @@
import i18n from "i18next";
import en from "./locales/en/translation.json";
import ru from "./locales/ru/translation.json";
import { i18nBaseSettings } from "../../constants";
const newInstance = i18n.createInstance();
const resources = {
en: {
translation: en,
},
ru: {
translation: ru,
},
};
newInstance.init({ ...i18nBaseSettings, resources });
export default newInstance;

View File

@ -1,2 +0,0 @@
import GroupSelector from "./GroupSelector";
export default GroupSelector;

View File

@ -467,11 +467,18 @@ PageLayout.propTypes = {
};
export default inject(({ auth }) => {
const { language, settingsStore } = auth;
const { isTabletView, isArticlePinned, setArticlePinned } = settingsStore;
const { isLoaded, language, settingsStore } = auth;
const {
isHeaderVisible,
isTabletView,
isArticlePinned,
setArticlePinned,
} = settingsStore;
return {
isLoaded,
language,
isTabletView,
isHeaderVisible,
isArticlePinned,
setArticlePinned,
};

View File

@ -2,7 +2,7 @@ import React from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";
import equal from "fast-deep-equal/react";
import { LayoutContextConsumer } from "../../Layout/context";
import { LayoutContextConsumer } from "studio/Layout/context";
import { isMobile } from "react-device-detect";
import { inject, observer } from "mobx-react";

View File

@ -3,7 +3,7 @@ import styled, { css } from "styled-components";
import equal from "fast-deep-equal/react";
import classnames from "classnames";
import PropTypes from "prop-types";
import { LayoutContextConsumer } from "../../Layout/context";
import { LayoutContextConsumer } from "studio/Layout/context";
import { isMobile } from "react-device-detect";
import { tablet, desktop } from "@appserver/components/utils/device";

View File

@ -3,11 +3,7 @@ export { default as PublicRoute } from "./PublicRoute";
export { default as ExternalRedirect } from "./ExternalRedirect";
export { default as Headline } from "./Headline";
export { default as PeopleSelector } from "./PeopleSelector";
export { default as GroupSelector } from "./GroupSelector";
export { default as AdvancedSelector } from "./AdvancedSelector";
export { default as Layout } from "./Layout";
export { default as ScrollToTop } from "./Layout/ScrollToTop";
export * from "./Layout/context";
export { default as PageLayout } from "./PageLayout";
export { default as ErrorContainer } from "./ErrorContainer";
export { default as ErrorBoundary } from "./ErrorBoundary";

View File

@ -43,6 +43,7 @@ const ExpanderDownIconWrapper = ({
isSemitransparent,
dropdownType,
isOpen,
isDisabled,
...props
}) => <ExpanderDownIcon {...props} />;

View File

@ -5,7 +5,7 @@ import Heading from "@appserver/components/heading";
import Aside from "@appserver/components/aside";
import IconButton from "@appserver/components/icon-button";
import { ShareAccessRights } from "@appserver/common/constants";
import GroupSelector from "@appserver/common/components/GroupSelector";
import GroupSelector from "people/GroupSelector";
import { withTranslation } from "react-i18next";
import {
StyledAddGroupsPanel,

View File

@ -119,6 +119,7 @@ var config = {
filename: "remoteEntry.js",
remotes: {
studio: "studio@/remoteEntry.js",
people: "people@/products/people/remoteEntry.js",
},
exposes: {
"./app": "./src/Files.jsx",

View File

@ -62,13 +62,16 @@ const getItems = (data) => {
key={item.key}
icon={
item.root ? (
<StyledDepartmentsGroupIcon size="scale" color="#657077" /* isfill={true} */ /> // TODO: Add isFill prop if need
<StyledDepartmentsGroupIcon
size="scale"
color="#657077" /* isfill={true} */
/> // TODO: Add isFill prop if need
) : (
// <DepartmentsGroupIcon
// size="scale"
// isfill={true}
// color="#657077"
// />
) : (
""
)
}
@ -152,31 +155,34 @@ class ArticleBodyContent extends React.Component {
};
render() {
const { isLoaded, data, selectedKeys, isAdmin } = this.props;
const { isLoaded, data, selectedKeys, isAdmin, isVisitor } = this.props;
//console.log("PeopleTreeMenu", this.props);
return !isLoaded ? (
<Loaders.TreeFolders />
) : (
<StyledTreeMenu
className="people-tree-menu"
checkable={false}
draggable={false}
disabled={false}
multiple={false}
showIcon={true}
defaultExpandAll={true}
switcherIcon={this.switcherIcon}
onSelect={this.onSelectHandler}
selectedKeys={selectedKeys}
isFullFillSelection={false}
gapBetweenNodes="22"
gapBetweenNodesTablet="26"
isEmptyRootNode={getItems(data).length > 0}
isAdmin={isAdmin}
>
{getItems(data)}
</StyledTreeMenu>
return (
!isVisitor &&
(!isLoaded ? (
<Loaders.TreeFolders />
) : (
<StyledTreeMenu
className="people-tree-menu"
checkable={false}
draggable={false}
disabled={false}
multiple={false}
showIcon={true}
defaultExpandAll={true}
switcherIcon={this.switcherIcon}
onSelect={this.onSelectHandler}
selectedKeys={selectedKeys}
isFullFillSelection={false}
gapBetweenNodes="22"
gapBetweenNodesTablet="26"
isEmptyRootNode={getItems(data).length > 0}
isAdmin={isAdmin}
>
{getItems(data)}
</StyledTreeMenu>
))
);
}
}
@ -241,6 +247,7 @@ export default inject(({ auth, peopleStore }) => {
return {
setDocumentTitle: auth.setDocumentTitle,
isLoaded: auth.isLoaded,
isVisitor: auth.userStore.user.isVisitor,
isAdmin: auth.isAdmin,
groups,
data,

View File

@ -3,16 +3,20 @@ import Headline from "@appserver/common/components/Headline";
import Loaders from "@appserver/common/components/Loaders";
import { inject, observer } from "mobx-react";
const ArticleHeaderContent = ({ isLoaded, currentModuleName }) => {
return isLoaded ? (
<Headline type="menu">{currentModuleName}</Headline>
) : (
<Loaders.ArticleHeader />
const ArticleHeaderContent = ({ isVisitor, isLoaded, currentModuleName }) => {
return (
!isVisitor &&
(isLoaded ? (
<Headline type="menu">{currentModuleName}</Headline>
) : (
<Loaders.ArticleHeader />
))
);
};
export default inject(({ auth }) => {
return {
isVisitor: auth.userStore.user.isVisitor,
isLoaded: auth.isLoaded,
currentModuleName: auth.product.title,
};

View File

@ -4,11 +4,12 @@ import { withRouter } from "react-router";
import MainButton from "@appserver/components/main-button";
import DropDownItem from "@appserver/components/drop-down-item";
import { InviteDialog } from "./../../dialogs";
import InviteDialog from "./../../dialogs/InviteDialog/index";
import { withTranslation } from "react-i18next";
import toastr from "@appserver/common/components/Toast";
import toastr from "@appserver/common/components/Toast/toastr";
import Loaders from "@appserver/common/components/Loaders";
import { inject, observer } from "mobx-react";
import config from "../../../../package.json";
class PureArticleMainButtonContent extends React.Component {
constructor(props) {
@ -23,18 +24,18 @@ class PureArticleMainButtonContent extends React.Component {
};
goToEmployeeCreate = () => {
const { history, settings } = this.props;
history.push(`${settings.homepage}/create/user`);
const { history, homepage } = this.props;
history.push(`${homepage}/create/user`);
};
goToGuestCreate = () => {
const { history, settings } = this.props;
history.push(`${settings.homepage}/create/guest`);
const { history, homepage } = this.props;
history.push(`${homepage}/create/guest`);
};
goToGroupCreate = () => {
const { history, settings } = this.props;
history.push(`${settings.homepage}/group/create`);
const { history, homepage } = this.props;
history.push(`${homepage}/group/create`);
};
onNotImplementedClick = (text) => {
@ -46,59 +47,71 @@ class PureArticleMainButtonContent extends React.Component {
render() {
//console.log("People ArticleMainButtonContent render");
const { settings, t, isLoaded } = this.props;
const { userCaption, guestCaption, groupCaption } = settings.customNames;
const {
t,
isLoaded,
isAdmin,
homepage,
userCaption,
guestCaption,
groupCaption,
} = this.props;
const { dialogVisible } = this.state;
return !isLoaded ? (
<Loaders.Rectangle />
) : (
<>
<MainButton isDisabled={false} isDropdown={true} text={t("Actions")}>
<DropDownItem
icon="images/add.employee.react.svg"
label={userCaption}
onClick={this.goToEmployeeCreate}
/>
<DropDownItem
icon="images/add.guest.react.svg"
label={guestCaption}
onClick={this.goToGuestCreate}
/>
<DropDownItem
icon="images/add.department.react.svg"
label={groupCaption}
onClick={this.goToGroupCreate}
/>
<DropDownItem isSeparator />
<DropDownItem
icon="/static/images/invitation.link.react.svg"
label={t("InviteLinkTitle")}
onClick={this.onInvitationDialogClick}
/>
{/* <DropDownItem
return (
isAdmin &&
(!isLoaded ? (
<Loaders.Rectangle />
) : (
<>
<MainButton isDisabled={false} isDropdown={true} text={t("Actions")}>
<DropDownItem
icon="images/add.employee.react.svg"
label={userCaption}
onClick={this.goToEmployeeCreate}
/>
<DropDownItem
icon="images/add.guest.react.svg"
label={guestCaption}
onClick={this.goToGuestCreate}
/>
<DropDownItem
icon="images/add.department.react.svg"
label={groupCaption}
onClick={this.goToGroupCreate}
/>
<DropDownItem isSeparator />
<DropDownItem
icon="/static/images/invitation.link.react.svg"
label={t("InviteLinkTitle")}
onClick={this.onInvitationDialogClick}
/>
{/* <DropDownItem
icon="images/plane.react.svg"
label={t('LblInviteAgain')}
onClick={this.onNotImplementedClick.bind(this, "Invite again action")}
/> */}
{false && (
<DropDownItem
icon="images/import.react.svg"
label={t("ImportPeople")}
onClick={this.onDropDownItemClick.bind(
this,
`${settings.homepage}/import`
)}
{false && (
<DropDownItem
icon="images/import.react.svg"
label={t("ImportPeople")}
onClick={this.onDropDownItemClick.bind(
this,
`${homepage}/import`
)}
/>
)}
</MainButton>
{dialogVisible && (
<InviteDialog
visible={dialogVisible}
onClose={this.onInvitationDialogClick}
onCloseButton={this.onInvitationDialogClick}
/>
)}
</MainButton>
{dialogVisible && (
<InviteDialog
visible={dialogVisible}
onClose={this.onInvitationDialogClick}
onCloseButton={this.onInvitationDialogClick}
/>
)}
</>
</>
))
);
}
}
@ -109,7 +122,9 @@ const ArticleMainButtonContent = withTranslation("Article")(
export default inject(({ auth }) => ({
isAdmin: auth.isAdmin,
settings: auth.settingsStore,
homepage: auth.settingsStore.homepage || config.homepage,
userCaption: auth.settingsStore.customNames.userCaption,
guestCaption: auth.settingsStore.customNames.guestCaption,
groupCaption: auth.settingsStore.customNames.groupCaption,
isLoaded: auth.isLoaded,
language: auth.language,
}))(observer(withRouter(ArticleMainButtonContent)));

View File

@ -0,0 +1,39 @@
import i18n from "i18next";
import Backend from "i18next-http-backend";
import { LANGUAGE } from "@appserver/common/constants";
//import LanguageDetector from "i18next-browser-languagedetector";
// not like to use this?
// have a look at the Quick start guide
// for passing in lng and translations on init
const languages = ["en", "ru"];
const newInstance = i18n.createInstance();
newInstance.use(Backend).init({
lng: localStorage.getItem(LANGUAGE) || "en",
supportedLngs: languages,
whitelist: languages,
fallbackLng: "en",
load: "languageOnly",
//debug: true,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
format: function (value, format) {
if (format === "lowercase") return value.toLowerCase();
return value;
},
},
backend: {
loadPath: `/products/people/locales/{{lng}}/GroupSelector.json`,
},
react: {
useSuspense: false,
},
});
export default newInstance;

View File

@ -1,10 +1,9 @@
import React, { useEffect } from "react";
import React from "react";
import PropTypes from "prop-types";
import { withTranslation } from "react-i18next";
import { I18nextProvider, withTranslation } from "react-i18next";
import i18n from "./i18n";
import AdvancedSelector from "../AdvancedSelector";
import { getGroupList } from "../../api/groups";
import { changeLanguage } from "../../utils";
import AdvancedSelector from "@appserver/common/components/AdvancedSelector";
import { getGroupList } from "@appserver/common/api/groups";
class GroupSelector extends React.Component {
constructor(props) {
@ -15,8 +14,6 @@ class GroupSelector extends React.Component {
}
componentDidMount() {
changeLanguage(i18n);
getGroupList(this.props.useFake)
.then((groups) => this.setState({ options: this.convertGroups(groups) }))
.catch((error) => console.log(error));
@ -157,14 +154,10 @@ GroupSelector.defaultProps = {
withoutAside: false,
};
const ExtendedGroupSelector = withTranslation()(GroupSelector);
const ExtendedGroupSelector = withTranslation("GroupSelector")(GroupSelector);
const GroupSelectorWithI18n = (props) => {
useEffect(() => {
changeLanguage(i18n);
}, []);
return <ExtendedGroupSelector i18n={i18n} {...props} />;
};
export default GroupSelectorWithI18n;
export default (props) => (
<I18nextProvider i18n={i18n}>
<ExtendedGroupSelector {...props} />
</I18nextProvider>
);

View File

@ -40,6 +40,7 @@ const SimpleUserRow = ({
mobilePhone,
options,
userName,
currentUserId,
} = person;
const onContentRowSelect = (checked, user) => {
@ -282,6 +283,7 @@ export default inject(({ auth, peopleStore }, { person }) => {
return {
homepage: auth.settingsStore.homepage,
isAdmin: auth.isAdmin,
currentUserId: auth.userStore.user.id,
checked: peopleStore.selectionStore.selection.some(
(el) => el.id === person.id
),

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";
//import RequestLoader from "@appserver/components/request-loader";
@ -18,72 +18,50 @@ import {
import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
class Home extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.isLoading !== prevProps.isLoading) {
if (this.props.isLoading) {
showLoader();
} else {
hideLoader();
}
}
}
const Home = ({ isLoading }) => {
//console.log("People Home render");
render() {
//console.log("Home render");
const { isLoaded, isAdmin, isHeaderVisible } = this.props;
useEffect(() => {
isLoading ? showLoader() : hideLoader();
}, [isLoading]);
return (
<PageLayout
withBodyScroll={true}
withBodyAutoFocus={!isMobile}
isLoaded={isLoaded}
isHeaderVisible={isHeaderVisible}
>
<PageLayout.ArticleHeader>
<ArticleHeaderContent />
</PageLayout.ArticleHeader>
return (
<PageLayout withBodyScroll withBodyAutoFocus={!isMobile}>
<PageLayout.ArticleHeader>
<ArticleHeaderContent />
</PageLayout.ArticleHeader>
{isAdmin && (
<PageLayout.ArticleMainButton>
<ArticleMainButtonContent />
</PageLayout.ArticleMainButton>
)}
<PageLayout.ArticleMainButton>
<ArticleMainButtonContent />
</PageLayout.ArticleMainButton>
<PageLayout.ArticleBody>
<ArticleBodyContent />
</PageLayout.ArticleBody>
<PageLayout.ArticleBody>
<ArticleBodyContent />
</PageLayout.ArticleBody>
<PageLayout.SectionHeader>
<SectionHeaderContent />
</PageLayout.SectionHeader>
<PageLayout.SectionHeader>
<SectionHeaderContent />
</PageLayout.SectionHeader>
<PageLayout.SectionFilter>
<SectionFilterContent />
</PageLayout.SectionFilter>
<PageLayout.SectionFilter>
<SectionFilterContent />
</PageLayout.SectionFilter>
<PageLayout.SectionBody>
<SectionBodyContent />
</PageLayout.SectionBody>
<PageLayout.SectionBody>
<SectionBodyContent />
</PageLayout.SectionBody>
<PageLayout.SectionPaging>
<SectionPagingContent />
</PageLayout.SectionPaging>
</PageLayout>
);
}
}
Home.propTypes = {
history: PropTypes.object.isRequired,
isLoaded: PropTypes.bool,
isAdmin: PropTypes.bool,
<PageLayout.SectionPaging>
<SectionPagingContent />
</PageLayout.SectionPaging>
</PageLayout>
);
};
export default inject(({ auth, peopleStore }) => ({
isLoaded: auth.isLoaded,
isAdmin: auth.isAdmin,
Home.propTypes = {
isLoading: PropTypes.bool,
};
export default inject(({ peopleStore }) => ({
isLoading: peopleStore.isLoading,
setIsLoading: peopleStore.setIsLoading,
isHeaderVisible: auth.settingsStore.isHeaderVisible,
}))(observer(withRouter(Home)));

View File

@ -87,8 +87,8 @@ const stringFormat = (string, data) =>
class SectionBodyContent extends React.PureComponent {
componentDidMount() {
const { cultures, getPortalCultures, profile, viewer } = this.props;
const isSelf = isMe(viewer, profile.userName);
const { cultures, getPortalCultures, profile, viewer, isSelf } = this.props;
//const isSelf = isMe(viewer, profile.userName);
if (isSelf && !cultures.length) {
getPortalCultures();
}
@ -102,7 +102,15 @@ class SectionBodyContent extends React.PureComponent {
);
render() {
const { profile, cultures, culture, isAdmin, viewer, t } = this.props;
const {
profile,
cultures,
culture,
isAdmin,
viewer,
t,
isSelf,
} = this.props;
const contacts = profile.contacts && getUserContacts(profile.contacts);
const role = getUserRole(profile);
@ -113,7 +121,7 @@ class SectionBodyContent extends React.PureComponent {
createContacts(contacts.social)) ||
null;
const infoContacts = contacts && createContacts(contacts.contact);
const isSelf = isMe(viewer, profile.userName);
//const isSelf = isMe(viewer, profile.userName);
return (
<ProfileWrapper>
@ -194,4 +202,5 @@ export default inject(({ auth, peopleStore }) => ({
profile: peopleStore.targetUserStore.targetUser,
viewer: auth.userStore.user,
isTabletView: auth.settingsStore.isTabletView,
isSelf: peopleStore.targetUserStore.isMe,
}))(observer(withRouter(withTranslation("Profile")(SectionBodyContent))));

View File

@ -7,7 +7,6 @@ import toastr from "@appserver/common/components/Toast";
import { withRouter } from "react-router";
import { withTranslation, Trans } from "react-i18next";
import styled from "styled-components";
import { isMe } from "@appserver/common/utils";
import {
resendUserInvites,
createThumbnailsAvatar,
@ -26,6 +25,7 @@ import {
getUserStatus,
toEmployeeWrapper,
} from "../../../../../helpers/people-helpers";
import Loaders from "@appserver/common/components/Loaders";
const StyledContainer = styled.div`
position: relative;
@ -286,9 +286,9 @@ class SectionHeaderContent extends React.PureComponent {
getUserContextOptions = (user, viewer) => {
let status = "";
const { t, isAdmin } = this.props;
const { t, isAdmin, isMe } = this.props;
if (isAdmin || (!isAdmin && isMe(user, viewer.userName))) {
if (isAdmin || (!isAdmin && isMe)) {
status = getUserStatus(user);
}
@ -311,7 +311,7 @@ class SectionHeaderContent extends React.PureComponent {
label: t("EmailChangeButton"),
onClick: this.toggleChangeEmailDialog,
},
isMe(user, viewer.userName)
isMe
? viewer.isOwner
? {}
: {
@ -360,7 +360,7 @@ class SectionHeaderContent extends React.PureComponent {
label: t("InviteAgainLbl"),
onClick: this.onInviteAgainClick,
},
!isMe(user, viewer.userName) &&
!isMe &&
(user.status === EmployeeStatus.Active
? {
key: "disable",
@ -372,7 +372,7 @@ class SectionHeaderContent extends React.PureComponent {
label: t("EnableUserButton"),
onClick: this.onEnableClick,
}),
isMe(user, viewer.userName) && {
isMe && {
key: "delete-profile",
label: t("DeleteSelfProfile"),
onClick: this.toggleDeleteSelfProfileDialog,
@ -398,14 +398,14 @@ class SectionHeaderContent extends React.PureComponent {
filter,
settings,
history,
isMe,
} = this.props;
const { avatar, visibleAvatarEditor, dialogsVisible } = this.state;
const contextOptions = () => this.getUserContextOptions(profile, viewer);
const IsMe = isMe(viewer, profile.userName);
return (
<StyledContainer
showContextButton={(isAdmin && !profile.isOwner) || IsMe}
showContextButton={(isAdmin && !profile.isOwner) || isMe}
>
<IconButton
iconName="/static/images/arrow.path.react.svg"
@ -420,7 +420,7 @@ class SectionHeaderContent extends React.PureComponent {
{profile.displayName}
{profile.isLDAP && ` (${t("LDAPLbl")})`}
</Headline>
{((isAdmin && !profile.isOwner) || IsMe) && (
{((isAdmin && !profile.isOwner) || isMe) && (
<ContextMenuButton
className="action-button"
directionX="right"
@ -487,16 +487,21 @@ class SectionHeaderContent extends React.PureComponent {
}
}
export default inject(({ auth, peopleStore }) => ({
settings: auth.settingsStore,
isAdmin: auth.isAdmin,
viewer: auth.userStore.user,
filter: peopleStore.filterStore.filter,
setFilter: peopleStore.filterStore.setFilterParams,
updateUserStatus: peopleStore.usersStore.updateUserStatus,
resetProfile: peopleStore.targetUserStore.resetTargetUser,
fetchProfile: peopleStore.targetUserStore.getTargetUser,
profile: peopleStore.targetUserStore.targetUser,
updateProfile: peopleStore.targetUserStore.updateProfile,
getUserPhoto: peopleStore.targetUserStore.getUserPhoto,
}))(observer(withRouter(withTranslation("Profile")(SectionHeaderContent))));
export default inject(({ auth, peopleStore }) => {
console.log(peopleStore.targetUserStore);
return {
settings: auth.settingsStore,
isAdmin: auth.isAdmin,
isLoaded: auth.isLoaded,
viewer: auth.userStore.user,
filter: peopleStore.filterStore.filter,
setFilter: peopleStore.filterStore.setFilterParams,
updateUserStatus: peopleStore.usersStore.updateUserStatus,
resetProfile: peopleStore.targetUserStore.resetTargetUser,
fetchProfile: peopleStore.targetUserStore.getTargetUser,
profile: peopleStore.targetUserStore.targetUser,
isMe: peopleStore.targetUserStore.isMe,
updateProfile: peopleStore.targetUserStore.updateProfile,
getUserPhoto: peopleStore.targetUserStore.getUserPhoto,
};
})(observer(withRouter(withTranslation("Profile")(SectionHeaderContent))));

View File

@ -72,25 +72,21 @@ class Profile extends React.Component {
render() {
//console.log("Profile render");
const { profile, isVisitor, isAdmin, isLoaded } = this.props;
const { profile } = this.props;
return (
<PageLayout withBodyAutoFocus={true} isLoaded={isLoaded}>
{!isVisitor && (
<PageLayout.ArticleHeader>
<ArticleHeaderContent />
</PageLayout.ArticleHeader>
)}
{!isVisitor && isAdmin && (
<PageLayout.ArticleMainButton>
<ArticleMainButtonContent />
</PageLayout.ArticleMainButton>
)}
{!isVisitor && (
<PageLayout.ArticleBody>
<ArticleBodyContent />
</PageLayout.ArticleBody>
)}
<PageLayout withBodyAutoFocus>
<PageLayout.ArticleHeader>
<ArticleHeaderContent />
</PageLayout.ArticleHeader>
<PageLayout.ArticleMainButton>
<ArticleMainButtonContent />
</PageLayout.ArticleMainButton>
<PageLayout.ArticleBody>
<ArticleBodyContent />
</PageLayout.ArticleBody>
<PageLayout.SectionHeader>
{profile ? <SectionHeaderContent /> : <Loaders.SectionHeader />}
@ -107,7 +103,6 @@ class Profile extends React.Component {
Profile.propTypes = {
fetchProfile: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
isLoaded: PropTypes.bool,
match: PropTypes.object.isRequired,
profile: PropTypes.object,
isAdmin: PropTypes.bool,
@ -116,8 +111,6 @@ Profile.propTypes = {
export default inject(({ auth, peopleStore }) => ({
setDocumentTitle: auth.setDocumentTitle,
isVisitor: auth.userStore.user.isVisitor,
isLoaded: auth.isLoaded,
isAdmin: auth.isAdmin,
language: auth.language,
resetProfile: peopleStore.targetUserStore.resetTargetUser,

View File

@ -3,7 +3,7 @@ import equal from "fast-deep-equal/react";
import FieldContainer from "@appserver/components/field-container";
import SelectorAddButton from "@appserver/components/selector-add-button";
import SelectedItem from "@appserver/components/selected-item";
import GroupSelector from "@appserver/common/components/GroupSelector";
import GroupSelector from "../../../../../GroupSelector";
class DepartmentField extends React.Component {
shouldComponentUpdate(nextProps) {

View File

@ -1,5 +1,5 @@
import api from "@appserver/common/api";
import { action, computed, makeObservable, observable } from "mobx";
import { makeAutoObservable } from "mobx";
import store from "studio/store";
const { auth: authStore } = store;
@ -8,17 +8,7 @@ class TargetUserStore {
constructor(peopleStore) {
this.peopleStore = peopleStore;
makeObservable(this, {
targetUser: observable,
getTargetUser: action,
setTargetUser: action,
resetTargetUser: action,
updateProfile: action,
updateCreatedAvatar: action,
updateProfileCulture: action,
getUserPhoto: action,
getDisableProfileType: computed,
});
makeAutoObservable(this);
}
get getDisableProfileType() {
@ -32,17 +22,24 @@ class TargetUserStore {
return res;
}
get isMe() {
return (
this.targetUser &&
this.targetUser.userName === authStore.userStore.user.userName
);
}
getTargetUser = async (userName) => {
if (authStore.userStore.user.userName === userName) {
return (this.targetUser = authStore.userStore.user);
return this.setTargetUser(authStore.userStore.user);
} else {
const user = await api.people.getUser(userName);
return (this.targetUser = user);
return this.setTargetUser(user);
}
};
setTargetUser = (user) => {
return (this.targetUser = user);
this.targetUser = user;
};
resetTargetUser = () => {

View File

@ -119,9 +119,11 @@ var config = {
filename: "remoteEntry.js",
remotes: {
studio: "studio@/remoteEntry.js",
people: "people@/products/people/remoteEntry.js",
},
exposes: {
"./app": "./src/People.jsx",
"./GroupSelector": "./src/components/GroupSelector",
},
shared: {
...deps,

View File

@ -8,8 +8,8 @@ import Box from "@appserver/components/box";
import PrivateRoute from "@appserver/common/components/PrivateRoute";
import PublicRoute from "@appserver/common/components/PublicRoute";
import ErrorBoundary from "@appserver/common/components/ErrorBoundary";
import Layout from "@appserver/common/components/Layout";
import ScrollToTop from "@appserver/common/components/Layout/ScrollToTop";
import Layout from "./components/Layout";
import ScrollToTop from "./components/Layout/ScrollToTop";
import history from "@appserver/common/history";
import toastr from "@appserver/common/components/Toast";
import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader";

View File

@ -12,7 +12,7 @@ import { I18nextProvider, withTranslation } from "react-i18next";
import { withRouter } from "react-router";
import Loaders from "@appserver/common/components/Loaders";
import { LayoutContextConsumer } from "@appserver/common/components/Layout/context";
import { LayoutContextConsumer } from "../Layout/context";
import { isMobile } from "react-device-detect";
import { inject, observer } from "mobx-react";
import i18n from "./i18n";

View File

@ -124,6 +124,8 @@ const config = {
"./Error401": "./src/components/pages/Errors/401",
"./Error403": "./src/components/pages/Errors/403",
"./Error520": "./src/components/pages/Errors/520",
"./Layout": "./src/components/Layout",
"./Layout/context": "./src/components/Layout/context.js",
},
shared: {
...deps,