diff --git a/packages/asc-web-common/components/PrivateRoute/index.js b/packages/asc-web-common/components/PrivateRoute/index.js index 3f84852bc0..547f5645fd 100644 --- a/packages/asc-web-common/components/PrivateRoute/index.js +++ b/packages/asc-web-common/components/PrivateRoute/index.js @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { Redirect, Route } from "react-router-dom"; //import Loader from "@appserver/components/loader"; -import PageLayout from "../PageLayout"; +//import PageLayout from "../PageLayout"; // import Error401 from "studio/Error401"; // import Error404 from "studio/Error404"; import AppLoader from "../AppLoader"; @@ -22,11 +22,12 @@ const PrivateRoute = ({ component: Component, ...rest }) => { computedMatch, setModuleInfo, modules, - homepage, + currentProductId, wizardCompleted, } = rest; - const { userId } = computedMatch.params; + const { params, path } = computedMatch; + const { userId } = params; const renderComponent = (props) => { if (isLoaded && !isAuthenticated) { @@ -101,21 +102,30 @@ const PrivateRoute = ({ component: Component, ...rest }) => { }; useEffect(() => { - const currentModule = modules.find((m) => { - if ( - computedMatch.path !== "/" && - m.link.indexOf(computedMatch.path) !== -1 - ) { - return true; - } - }); + if (!isLoaded) return; - if (currentModule && homepage !== computedMatch.path) { - const { id } = currentModule; + let currentModule; - setModuleInfo(currentModule.origLink || currentModule.link, id); + if (path === "" || path === "/") { + currentModule = { + id: "home", + origLink: "/", + }; + } else if (path.startsWith("/my")) { + currentModule = { + id: "f4d98afd-d336-4332-8778-3c6945c81ea0", + origLink: "/products/people", + }; + } else { + currentModule = modules.find((m) => m.link.startsWith(path)); } - }, [computedMatch.path]); + + if (!currentModule) return; + + const { id, origLink, link } = currentModule; + + setModuleInfo(origLink || link, id); + }, [path, modules, isLoaded]); //console.log("PrivateRoute render", rest); return ; @@ -131,9 +141,8 @@ export default inject(({ auth }) => { moduleStore, } = auth; const { user } = userStore; - const { setModuleInfo, homepage } = settingsStore; const { modules } = moduleStore; - const { wizardCompleted } = settingsStore; + const { setModuleInfo, wizardCompleted } = settingsStore; return { modules, @@ -142,8 +151,6 @@ export default inject(({ auth }) => { isAdmin, isLoaded, setModuleInfo, - homepage, wizardCompleted, - //getUser: store.userStore.getCurrentUser, }; })(observer(PrivateRoute)); diff --git a/products/ASC.Files/Client/src/custom.scss b/packages/asc-web-common/custom.scss similarity index 93% rename from products/ASC.Files/Client/src/custom.scss rename to packages/asc-web-common/custom.scss index 1808172681..06957785ca 100644 --- a/products/ASC.Files/Client/src/custom.scss +++ b/packages/asc-web-common/custom.scss @@ -31,3 +31,12 @@ body.drag-cursor * { 6 6, auto !important; } + +body.desktop { + user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + mozuserselect: none; +} diff --git a/packages/asc-web-common/store/SettingsStore.js b/packages/asc-web-common/store/SettingsStore.js index 9b0334fe9b..2c3abd4ce1 100644 --- a/packages/asc-web-common/store/SettingsStore.js +++ b/packages/asc-web-common/store/SettingsStore.js @@ -212,7 +212,11 @@ class SettingsStore { }; setModuleInfo = (homepage, productId) => { - if (this.homepage == homepage) return; + if (this.homepage === homepage || this.currentProductId === productId) + return; + + console.log(`setModuleInfo('${homepage}', '${productId}')`); + this.homepage = homepage; this.setCurrentProductId(productId); @@ -223,7 +227,9 @@ class SettingsStore { ? homepage : `${homepage}/` : "/"; + console.log("SET base URL", baseUrl); + baseElm[0].setAttribute("href", baseUrl); } }; diff --git a/products/ASC.CRM/Client/src/App.js b/products/ASC.CRM/Client/src/App.js index 4ed936eff8..c3a3323af5 100644 --- a/products/ASC.CRM/Client/src/App.js +++ b/products/ASC.CRM/Client/src/App.js @@ -1,7 +1,15 @@ //import "./wdyr"; import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; -const App = () => ; +const App = () => { + return ( + + + + ); +}; export default App; diff --git a/products/ASC.CRM/Client/src/Crm.jsx b/products/ASC.CRM/Client/src/Crm.jsx index 9e20192faf..38158ad9a3 100644 --- a/products/ASC.CRM/Client/src/Crm.jsx +++ b/products/ASC.CRM/Client/src/Crm.jsx @@ -8,7 +8,6 @@ import PrivateRoute from "@appserver/common/components/PrivateRoute"; import AppLoader from "@appserver/common/components/AppLoader"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import config from "../package.json"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import Home from "./pages/Home"; diff --git a/products/ASC.CRM/Client/src/custom.scss b/products/ASC.CRM/Client/src/custom.scss deleted file mode 100644 index 835034402f..0000000000 --- a/products/ASC.CRM/Client/src/custom.scss +++ /dev/null @@ -1,27 +0,0 @@ -// Override default variables before the import -$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - position: relative; - - .pageLoader { - position: absolute; - left: calc(50% - 20px); - top: 35%; - } -} - -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} diff --git a/products/ASC.Calendar/Client/src/App.js b/products/ASC.Calendar/Client/src/App.js index 4ed936eff8..c3a3323af5 100644 --- a/products/ASC.Calendar/Client/src/App.js +++ b/products/ASC.Calendar/Client/src/App.js @@ -1,7 +1,15 @@ //import "./wdyr"; import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; -const App = () => ; +const App = () => { + return ( + + + + ); +}; export default App; diff --git a/products/ASC.Calendar/Client/src/Calendar.jsx b/products/ASC.Calendar/Client/src/Calendar.jsx index e263f51971..46a8b767fa 100644 --- a/products/ASC.Calendar/Client/src/Calendar.jsx +++ b/products/ASC.Calendar/Client/src/Calendar.jsx @@ -8,7 +8,6 @@ import PrivateRoute from "@appserver/common/components/PrivateRoute"; import AppLoader from "@appserver/common/components/AppLoader"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import config from "../package.json"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import Home from "./pages/Home"; diff --git a/products/ASC.Calendar/Client/src/custom.scss b/products/ASC.Calendar/Client/src/custom.scss deleted file mode 100644 index 835034402f..0000000000 --- a/products/ASC.Calendar/Client/src/custom.scss +++ /dev/null @@ -1,27 +0,0 @@ -// Override default variables before the import -$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - position: relative; - - .pageLoader { - position: absolute; - left: calc(50% - 20px); - top: 35%; - } -} - -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} diff --git a/products/ASC.Files/Client/src/App.js b/products/ASC.Files/Client/src/App.js index e8b1b01e21..c3a3323af5 100644 --- a/products/ASC.Files/Client/src/App.js +++ b/products/ASC.Files/Client/src/App.js @@ -1,9 +1,15 @@ +//import "./wdyr"; import React from "react"; import Shell from "studio/shell"; -//import "./wdyr"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; const App = () => { - return ; + return ( + + + + ); }; export default App; diff --git a/products/ASC.Files/Client/src/Files.jsx b/products/ASC.Files/Client/src/Files.jsx index 82b3c9db14..be992d2863 100644 --- a/products/ASC.Files/Client/src/Files.jsx +++ b/products/ASC.Files/Client/src/Files.jsx @@ -8,7 +8,6 @@ import AppLoader from "@appserver/common/components/AppLoader"; import toastr from "studio/toastr"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import stores from "./store/index"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import { regDesktop } from "@appserver/common/desktop"; diff --git a/products/ASC.Files/Client/src/index.js b/products/ASC.Files/Client/src/index.js index ddab4af63b..50599f7ad8 100644 --- a/products/ASC.Files/Client/src/index.js +++ b/products/ASC.Files/Client/src/index.js @@ -1,48 +1 @@ import("./bootstrap"); - -//import "./wdyr"; - -// import React from "react"; -// import ReactDOM from "react-dom"; -// import "./custom.scss"; -// import App from "./App"; - -// import * as serviceWorker from "./serviceWorker"; -// import { ErrorBoundary, store as commonStore } from "asc-web-common"; -// import { Provider as MobxProvider } from "mobx-react"; -// import filesStore from "./store/FilesStore"; -// import settingsStore from "./store/SettingsStore"; -// import mediaViewerDataStore from "./store/MediaViewerDataStore"; -// import formatsStore from "./store/FormatsStore"; -// import versionHistoryStore from "./store/VersionHistoryStore"; -// import uploadDataStore from "./store/UploadDataStore"; -// import dialogsStore from "./store/DialogsStore"; -// import treeFoldersStore from "./store/TreeFoldersStore"; -// import selectedFolderStore from "./store/SelectedFolderStore"; - -// const { authStore } = commonStore; - -// ReactDOM.render( -// -// -// -// -// , -// document.getElementById("root") -// ); - -// // If you want your app to work offline and load faster, you can change -// // unregister() to register() below. Note this comes with some pitfalls. -// // Learn more about service workers: https://bit.ly/CRA-PWA -// serviceWorker.register(); diff --git a/products/ASC.Mail/Client/src/App.js b/products/ASC.Mail/Client/src/App.js index 4ed936eff8..c3a3323af5 100644 --- a/products/ASC.Mail/Client/src/App.js +++ b/products/ASC.Mail/Client/src/App.js @@ -1,7 +1,15 @@ //import "./wdyr"; import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; -const App = () => ; +const App = () => { + return ( + + + + ); +}; export default App; diff --git a/products/ASC.Mail/Client/src/Mail.jsx b/products/ASC.Mail/Client/src/Mail.jsx index 9c97ea245d..a848f9b135 100644 --- a/products/ASC.Mail/Client/src/Mail.jsx +++ b/products/ASC.Mail/Client/src/Mail.jsx @@ -8,7 +8,6 @@ import PrivateRoute from "@appserver/common/components/PrivateRoute"; import AppLoader from "@appserver/common/components/AppLoader"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import config from "../package.json"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import Home from "./pages/Home"; diff --git a/products/ASC.Mail/Client/src/custom.scss b/products/ASC.Mail/Client/src/custom.scss deleted file mode 100644 index 835034402f..0000000000 --- a/products/ASC.Mail/Client/src/custom.scss +++ /dev/null @@ -1,27 +0,0 @@ -// Override default variables before the import -$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - position: relative; - - .pageLoader { - position: absolute; - left: calc(50% - 20px); - top: 35%; - } -} - -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} diff --git a/products/ASC.People/Client/src/App.js b/products/ASC.People/Client/src/App.js index 4ed936eff8..c3a3323af5 100644 --- a/products/ASC.People/Client/src/App.js +++ b/products/ASC.People/Client/src/App.js @@ -1,7 +1,15 @@ //import "./wdyr"; import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; -const App = () => ; +const App = () => { + return ( + + + + ); +}; export default App; diff --git a/products/ASC.People/Client/src/People.jsx b/products/ASC.People/Client/src/People.jsx index 17f2bc67a6..ddda188949 100644 --- a/products/ASC.People/Client/src/People.jsx +++ b/products/ASC.People/Client/src/People.jsx @@ -8,7 +8,6 @@ import PrivateRoute from "@appserver/common/components/PrivateRoute"; import AppLoader from "@appserver/common/components/AppLoader"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import config from "../package.json"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import Home from "./pages/Home"; diff --git a/products/ASC.People/Client/src/custom.scss b/products/ASC.People/Client/src/custom.scss deleted file mode 100644 index 835034402f..0000000000 --- a/products/ASC.People/Client/src/custom.scss +++ /dev/null @@ -1,27 +0,0 @@ -// Override default variables before the import -$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - position: relative; - - .pageLoader { - position: absolute; - left: calc(50% - 20px); - top: 35%; - } -} - -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} diff --git a/products/ASC.People/Client/src/index.js b/products/ASC.People/Client/src/index.js index 29f89d9f02..50599f7ad8 100644 --- a/products/ASC.People/Client/src/index.js +++ b/products/ASC.People/Client/src/index.js @@ -1,27 +1 @@ import("./bootstrap"); - -// import React from "react"; -// import ReactDOM from "react-dom"; -// import { Provider } from "react-redux"; -// import store from "./store/store"; -// import * as serviceWorker from "./serviceWorker"; -// import { ErrorBoundary, store as commonStore } from "asc-web-common"; -// import { Provider as MobxProvider } from "mobx-react"; -// import PeopleStore from "./store/PeopleStore"; - -// const { authStore } = commonStore; -// const peopleStore = new PeopleStore(); - -// ReactDOM.render( -// -// -// -// -// , -// document.getElementById("root") -// ); - -// // If you want your app to work offline and load faster, you can change -// // unregister() to register() below. Note this comes with some pitfalls. -// // Learn more about service workers: https://bit.ly/CRA-PWA -// serviceWorker.register(); diff --git a/products/ASC.People/Client/src/pages/My/i18n.js b/products/ASC.People/Client/src/pages/My/i18n.js new file mode 100644 index 0000000000..cb8ee13847 --- /dev/null +++ b/products/ASC.People/Client/src/pages/My/i18n.js @@ -0,0 +1,40 @@ +import i18n from "i18next"; +import Backend from "i18next-http-backend"; +import { LANGUAGE } from "@appserver/common/constants"; +import config from "../../../package.json"; +const homepage = config.homepage; + +//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 newInstance = i18n.createInstance(); + +newInstance.use(Backend).init({ + lng: localStorage.getItem(LANGUAGE) || "en", + 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: `${homepage}/locales/{{lng}}/{{ns}}.json`, + }, + + ns: ["Profile", "ProfileAction"], + defaultNS: "Profile", + + react: { + useSuspense: false, + }, +}); + +export default newInstance; diff --git a/products/ASC.People/Client/src/pages/My/index.js b/products/ASC.People/Client/src/pages/My/index.js new file mode 100644 index 0000000000..3ad51dc3d1 --- /dev/null +++ b/products/ASC.People/Client/src/pages/My/index.js @@ -0,0 +1,117 @@ +import React from "react"; +import MyProfileI18n from "./i18n"; +import PeopleStore from "../../store/PeopleStore"; + +import PropTypes from "prop-types"; +import PageLayout from "@appserver/common/components/PageLayout"; +import toastr from "studio/toastr"; +import Loaders from "@appserver/common/components/Loaders"; +import { withRouter } from "react-router"; + +import { Provider as PeopleProvider, inject, observer } from "mobx-react"; +import { I18nextProvider, withTranslation } from "react-i18next"; +import { + SectionBodyContent as ViewBodyContent, + SectionHeaderContent as ViewHeaderContent, +} from "../Profile/Section"; +import { SectionHeaderContent as EditHeaderContent } from "../ProfileAction/Section"; +import EditBodyContent from "../ProfileAction/Section/Body"; + +class My extends React.Component { + componentDidMount() { + const { fetchProfile, profile, location, t, setDocumentTitle } = this.props; + + setDocumentTitle(t("Profile")); + + this.documentElement = document.getElementsByClassName("hidingHeader"); + const queryString = ((location && location.search) || "").slice(1); + const queryParams = queryString.split("&"); + const arrayOfQueryParams = queryParams.map((queryParam) => + queryParam.split("=") + ); + const linkParams = Object.fromEntries(arrayOfQueryParams); + + if (linkParams.email_change && linkParams.email_change === "success") { + toastr.success(t("ChangeEmailSuccess")); + } + if (!profile) { + fetchProfile("@self"); + } + + if (!profile && this.documentElement) { + for (var i = 0; i < this.documentElement.length; i++) { + this.documentElement[i].style.transition = "none"; + } + } + } + + componentWillUnmount() { + this.props.resetProfile(); + } + + render() { + const { profile, tReady, location } = this.props; + + const isEdit = (location && location.search === "?action=edit") || false; + + //console.log("My Profile render", this.props, isEdit); + + return ( + + + {profile && tReady ? ( + isEdit ? ( + + ) : ( + + ) + ) : ( + + )} + + + + {profile && tReady ? ( + isEdit ? ( + + ) : ( + + ) + ) : ( + + )} + + + ); + } +} + +My.propTypes = { + fetchProfile: PropTypes.func.isRequired, + history: PropTypes.object.isRequired, + match: PropTypes.object.isRequired, + profile: PropTypes.object, + language: PropTypes.string, +}; + +const MyProfile = withRouter( + inject(({ auth, peopleStore }) => ({ + setDocumentTitle: auth.setDocumentTitle, + language: auth.language, + resetProfile: peopleStore.targetUserStore.resetTargetUser, + fetchProfile: peopleStore.targetUserStore.getTargetUser, + profile: peopleStore.targetUserStore.targetUser, + }))(withTranslation(["Profile", "ProfileAction"])(observer(My))) +); + +const peopleStore = new PeopleStore(); + +export default ({ i18n, ...rest }) => { + return ( + + + + + + ); +}; diff --git a/products/ASC.People/Client/src/pages/Profile/Section/Body/index.js b/products/ASC.People/Client/src/pages/Profile/Section/Body/index.js index 9287dd6acb..cab9bc74b1 100644 --- a/products/ASC.People/Client/src/pages/Profile/Section/Body/index.js +++ b/products/ASC.People/Client/src/pages/Profile/Section/Body/index.js @@ -129,15 +129,19 @@ class SectionBodyContent extends React.PureComponent { onEditSubscriptionsClick = () => console.log("Edit subscriptions onClick()"); onEditProfileClick = () => { - this.props.avatarMax && this.props.setAvatarMax(null); + const { isMy, avatarMax, setAvatarMax, history, profile } = this.props; - this.props.history.push( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/edit/${this.props.profile.userName}` - ) - ); + avatarMax && setAvatarMax(null); + + const editUrl = isMy + ? combineUrl(AppServerConfig.proxyURL, `/my?action=edit`) + : combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/edit/${profile.userName}` + ); + + history.push(editUrl); }; loginCallback = (profile) => { diff --git a/products/ASC.People/Client/src/pages/Profile/Section/Header/index.js b/products/ASC.People/Client/src/pages/Profile/Section/Header/index.js index f5a02a4118..eb8e945e28 100644 --- a/products/ASC.People/Client/src/pages/Profile/Section/Header/index.js +++ b/products/ASC.People/Client/src/pages/Profile/Section/Header/index.js @@ -223,14 +223,17 @@ class SectionHeaderContent extends React.PureComponent { }); onEditClick = () => { - const { history } = this.props; - history.push( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/edit/${this.state.profile.userName}` - ) - ); + const { history, isMy } = this.props; + + const editUrl = isMy + ? combineUrl(AppServerConfig.proxyURL, `/my?action=edit`) + : combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/edit/${this.state.profile.userName}` + ); + + history.push(editUrl); }; onUpdateUserStatus = (status, userId) => { @@ -398,9 +401,13 @@ class SectionHeaderContent extends React.PureComponent { }; onClickBack = () => { - const { filter, setFilter, history, resetProfile } = this.props; + const { filter, setFilter, history, resetProfile, isMy } = this.props; resetProfile(); + if (isMy) { + return history.goBack(); + } + const url = filter.toUrlParams(); const backUrl = combineUrl( AppServerConfig.proxyURL, diff --git a/products/ASC.People/Client/src/pages/Profile/index.js b/products/ASC.People/Client/src/pages/Profile/index.js index 4fc7dff2a8..16bbe219cb 100644 --- a/products/ASC.People/Client/src/pages/Profile/index.js +++ b/products/ASC.People/Client/src/pages/Profile/index.js @@ -24,7 +24,9 @@ class Profile extends React.Component { t, setDocumentTitle, } = this.props; - const { userId } = match.params; + let { userId } = match.params; + + if (!userId) userId = "@self"; setDocumentTitle(t("Profile")); this.documentElement = document.getElementsByClassName("hidingHeader"); diff --git a/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/index.js b/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/index.js index 338d811389..d425571370 100644 --- a/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/index.js +++ b/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/index.js @@ -6,7 +6,7 @@ import UpdateUserForm from "./updateUserForm"; import { inject, observer } from "mobx-react"; import { withRouter } from "react-router"; -const SectionUserBody = ({ avatarEditorIsOpen, match }) => { +const SectionUserBody = ({ avatarEditorIsOpen, match, isMy }) => { const { type } = match.params; return type ? ( avatarEditorIsOpen ? ( @@ -17,7 +17,7 @@ const SectionUserBody = ({ avatarEditorIsOpen, match }) => { ) : avatarEditorIsOpen ? ( ) : ( - + ); }; diff --git a/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/updateUserForm.js b/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/updateUserForm.js index 58b558e442..a9c9bb7ed4 100644 --- a/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/updateUserForm.js +++ b/products/ASC.People/Client/src/pages/ProfileAction/Section/Body/updateUserForm.js @@ -548,6 +548,7 @@ class UpdateUserForm extends React.Component { //avatarMax, disableProfileType, isAdmin, + isMy, isSelf, } = this.props; const { @@ -780,7 +781,7 @@ class UpdateUserForm extends React.Component { { value: "false", label: userCaption }, ]} radioIsDisabled={ - isLoading || disableProfileType || radioIsDisabled + isLoading || disableProfileType || radioIsDisabled || isMy } radioOnChange={this.onUserTypeChange} tooltipContent={tooltipTypeContent} @@ -816,20 +817,22 @@ class UpdateUserForm extends React.Component { inputOnChange={this.onInputChange} inputTabIndex={9} /> - + {!isMy && ( + + )} diff --git a/products/ASC.People/Client/src/pages/ProfileAction/Section/Header/index.js b/products/ASC.People/Client/src/pages/ProfileAction/Section/Header/index.js index 5481174a6d..4ff354c073 100644 --- a/products/ASC.People/Client/src/pages/ProfileAction/Section/Header/index.js +++ b/products/ASC.People/Client/src/pages/ProfileAction/Section/Header/index.js @@ -40,6 +40,7 @@ const SectionHeaderContent = (props) => { setIsVisibleDataLossDialog, toggleAvatarEditor, avatarEditorIsOpen, + isMy, } = props; const { userCaption, guestCaption } = customNames; const { type } = match.params; @@ -72,6 +73,10 @@ const SectionHeaderContent = (props) => { ); const goBackAndReset = useCallback(() => { + if (isMy) { + return history.goBack(); + } + if (!profile || !document.referrer) { setFilterAndReset(filter); const urlFilter = filter.toUrlParams(); diff --git a/products/ASC.People/Client/src/pages/ProfileAction/index.js b/products/ASC.People/Client/src/pages/ProfileAction/index.js index 15065b0141..f587735d25 100644 --- a/products/ASC.People/Client/src/pages/ProfileAction/index.js +++ b/products/ASC.People/Client/src/pages/ProfileAction/index.js @@ -71,7 +71,7 @@ class ProfileAction extends React.Component { console.log("ProfileAction render"); this.loaded = false; - const { profile, match } = this.props; + const { profile, match, isMy } = this.props; const { userId, type } = match.params; if (type) { @@ -100,7 +100,7 @@ class ProfileAction extends React.Component { {this.loaded ? ( - + ) : ( )} diff --git a/products/ASC.People/Client/webpack.config.js b/products/ASC.People/Client/webpack.config.js index 9a0fc92c3a..b2c372c386 100644 --- a/products/ASC.People/Client/webpack.config.js +++ b/products/ASC.People/Client/webpack.config.js @@ -148,6 +148,7 @@ var config = { "./PeopleSelector": "./src/components/PeopleSelector", "./PeopleSelector/UserTooltip": "./src/components/PeopleSelector/sub-components/UserTooltip.js", + "./MyProfile": "./src/pages/My", }, shared: { ...deps, diff --git a/products/ASC.Projects/Client/src/App.js b/products/ASC.Projects/Client/src/App.js index 4ed936eff8..c3a3323af5 100644 --- a/products/ASC.Projects/Client/src/App.js +++ b/products/ASC.Projects/Client/src/App.js @@ -1,7 +1,15 @@ //import "./wdyr"; import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; -const App = () => ; +const App = () => { + return ( + + + + ); +}; export default App; diff --git a/products/ASC.Projects/Client/src/Projects.jsx b/products/ASC.Projects/Client/src/Projects.jsx index 13644c7fcb..2fe3225088 100644 --- a/products/ASC.Projects/Client/src/Projects.jsx +++ b/products/ASC.Projects/Client/src/Projects.jsx @@ -8,7 +8,6 @@ import PrivateRoute from "@appserver/common/components/PrivateRoute"; import AppLoader from "@appserver/common/components/AppLoader"; import { combineUrl, updateTempContent } from "@appserver/common/utils"; import config from "../package.json"; -import "./custom.scss"; import i18n from "./i18n"; import { I18nextProvider } from "react-i18next"; import Home from "./pages/Home"; diff --git a/products/ASC.Projects/Client/src/custom.scss b/products/ASC.Projects/Client/src/custom.scss deleted file mode 100644 index 835034402f..0000000000 --- a/products/ASC.Projects/Client/src/custom.scss +++ /dev/null @@ -1,27 +0,0 @@ -// Override default variables before the import -$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - position: relative; - - .pageLoader { - position: absolute; - left: calc(50% - 20px); - top: 35%; - } -} - -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} diff --git a/web/ASC.Web.Client/src/App.js b/web/ASC.Web.Client/src/App.js index e79a83e99e..f24a4217b4 100644 --- a/web/ASC.Web.Client/src/App.js +++ b/web/ASC.Web.Client/src/App.js @@ -1,6 +1,7 @@ import React from "react"; import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; import Shell from "studio/shell"; +import "@appserver/common/custom.scss"; const App = () => { return ( diff --git a/web/ASC.Web.Client/src/Shell.jsx b/web/ASC.Web.Client/src/Shell.jsx index 6586575b01..93bd4ffb46 100644 --- a/web/ASC.Web.Client/src/Shell.jsx +++ b/web/ASC.Web.Client/src/Shell.jsx @@ -16,7 +16,6 @@ import ThemeProvider from "@appserver/components/theme-provider"; import { Base } from "@appserver/components/themes"; import store from "studio/store"; import config from "../package.json"; -import "./custom.scss"; import { I18nextProvider } from "react-i18next"; import i18n from "./i18n"; import AppLoader from "@appserver/common/components/AppLoader"; @@ -40,17 +39,11 @@ const LOGIN_URLS = [ combineUrl(PROXY_HOMEPAGE_URL, "/login/confirmed-email=:confirmedEmail"), ]; const CONFIRM_URL = combineUrl(PROXY_HOMEPAGE_URL, "/confirm"); -const COMING_SOON_URLS = [ - combineUrl(PROXY_HOMEPAGE_URL, "/coming-soon"), - //combineUrl(PROXY_HOMEPAGE_URL, "/products/mail"), - //combineUrl(PROXY_HOMEPAGE_URL, "/products/projects"), - //combineUrl(PROXY_HOMEPAGE_URL, "/products/crm"), - //combineUrl(PROXY_HOMEPAGE_URL, "/products/calendar"), - //combineUrl(PROXY_HOMEPAGE_URL, "/products/talk/"), -]; +const COMING_SOON_URLS = [combineUrl(PROXY_HOMEPAGE_URL, "/coming-soon")]; const PAYMENTS_URL = combineUrl(PROXY_HOMEPAGE_URL, "/payments"); const SETTINGS_URL = combineUrl(PROXY_HOMEPAGE_URL, "/settings"); const ERROR_401_URL = combineUrl(PROXY_HOMEPAGE_URL, "/error401"); +const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/my"); const Payments = React.lazy(() => import("./components/pages/Payments")); const Error404 = React.lazy(() => import("studio/Error404")); @@ -62,6 +55,7 @@ const Wizard = React.lazy(() => import("./components/pages/Wizard")); const Settings = React.lazy(() => import("./components/pages/Settings")); const ComingSoon = React.lazy(() => import("./components/pages/ComingSoon")); const Confirm = React.lazy(() => import("./components/pages/Confirm")); +const MyProfile = React.lazy(() => import("people/MyProfile")); const SettingsRoute = (props) => ( }> @@ -141,6 +135,14 @@ const ComingSoonRoute = (props) => ( ); +const MyProfileRoute = (props) => ( + }> + + + + +); + const Shell = ({ items = [], page = "home", ...rest }) => { const { isLoaded, loadBaseInfo, modules, isDesktop } = rest; @@ -240,6 +242,12 @@ const Shell = ({ items = [], page = "home", ...rest }) => { path={SETTINGS_URL} component={SettingsRoute} /> + {dynamicRoutes} diff --git a/web/ASC.Web.Client/src/components/NavMenu/sub-components/header-nav.js b/web/ASC.Web.Client/src/components/NavMenu/sub-components/header-nav.js index d38b40bd78..547e7e663b 100644 --- a/web/ASC.Web.Client/src/components/NavMenu/sub-components/header-nav.js +++ b/web/ASC.Web.Client/src/components/NavMenu/sub-components/header-nav.js @@ -16,10 +16,11 @@ const homepage = config.homepage; const PROXY_HOMEPAGE_URL = combineUrl(proxyURL, homepage); const ABOUT_URL = combineUrl(PROXY_HOMEPAGE_URL, "/about"); -const PROFILE_URL = combineUrl( +const PROFILE_SELF_URL = combineUrl( PROXY_HOMEPAGE_URL, "/products/people/view/@self" ); +const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/my"); const StyledNav = styled.nav` display: flex; @@ -49,11 +50,18 @@ const StyledNav = styled.nav` padding: 0 16px; } `; -const HeaderNav = ({ history, modules, user, logout, isAuthenticated }) => { +const HeaderNav = ({ + history, + modules, + user, + logout, + isAuthenticated, + peopleAvailable, +}) => { const { t } = useTranslation("NavMenu"); const onProfileClick = useCallback(() => { - history.push(PROFILE_URL); + history.push(peopleAvailable ? PROFILE_SELF_URL : PROFILE_MY_URL); }, []); const onAboutClick = useCallback(() => history.push(ABOUT_URL), []); @@ -76,7 +84,7 @@ const HeaderNav = ({ history, modules, user, logout, isAuthenticated }) => { key: "ProfileBtn", label: t("Profile"), onClick: onProfileClick, - url: PROFILE_URL, + url: peopleAvailable ? PROFILE_SELF_URL : PROFILE_MY_URL, }, { key: "SwitchToBtn", @@ -154,15 +162,16 @@ export default withRouter( } = auth; const { defaultPage } = settingsStore; const { user } = userStore; - + const modules = auth.availableModules; return { user, isAuthenticated, isLoaded, language, defaultPage: defaultPage || "/", - modules: auth.availableModules, + modules, logout, + peopleAvailable: modules.some((m) => m.appName === "people"), }; })(observer(HeaderNav)) ); diff --git a/web/ASC.Web.Client/src/components/pages/About/index.js b/web/ASC.Web.Client/src/components/pages/About/index.js index 5865863acc..75b1425676 100644 --- a/web/ASC.Web.Client/src/components/pages/About/index.js +++ b/web/ASC.Web.Client/src/components/pages/About/index.js @@ -2,14 +2,12 @@ import Text from "@appserver/components/text"; import Link from "@appserver/components/link"; import PageLayout from "@appserver/common/components/PageLayout"; -import { I18nextProvider, useTranslation, Trans } from "react-i18next"; -import version from "../../../../package.json"; +import { I18nextProvider, Trans, withTranslation } from "react-i18next"; import styled from "styled-components"; import { isMobile } from "react-device-detect"; import { setDocumentTitle } from "../../../helpers/utils"; import i18n from "./i18n"; import config from "../../../../package.json"; -import { inject } from "mobx-react"; const BodyStyle = styled.div` margin-top: ${isMobile ? "80px" : "24px"}; @@ -77,9 +75,7 @@ const VersionStyle = styled.div` padding: 8px 0px 20px 0px; `; -const Body = () => { - const { t } = useTranslation("About"); - +const Body = ({ t }) => { useEffect(() => { setDocumentTitle(t("AboutTitle")); //TODO: implement the ability to read the current module in redux to implement the template `${t("AboutTitle")} – ${t("People")}` }, [t]); @@ -121,7 +117,7 @@ const Body = () => { - {`${t("AboutCompanyVersion")}: ${version.version}`} + {`${t("AboutCompanyVersion")}: ${config.version}`} @@ -193,24 +189,18 @@ const Body = () => { ); }; -const About = ({ language, setModuleInfo }) => { - useEffect(() => { - setModuleInfo(config.homepage, "home"); - }, []); +const BodyWrapper = withTranslation("About")(Body); +const About = (props) => { return ( - + ); }; -export default inject(({ auth }) => { - return { - setModuleInfo: auth.settingsStore.setModuleInfo, - }; -})(About); +export default About; diff --git a/web/ASC.Web.Client/src/components/pages/Home/index.js b/web/ASC.Web.Client/src/components/pages/Home/index.js index 22b7307a7b..c6167bc523 100644 --- a/web/ASC.Web.Client/src/components/pages/Home/index.js +++ b/web/ASC.Web.Client/src/components/pages/Home/index.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useEffect } from "react"; import PropTypes from "prop-types"; import { withRouter } from "react-router"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import ModuleTile from "./ModuleTile"; import { tryRedirectTo } from "@appserver/common/utils"; import { setDocumentTitle } from "../../../helpers/utils"; import { inject, observer } from "mobx-react"; +import config from "../../../../package.json"; const HomeContainer = styled.div` padding: 62px 15px 0 15px; @@ -96,23 +97,13 @@ const Body = ({ modules, match, isLoaded }) => { ); }; -const Home = ({ - defaultPage, - currentProductId, - setCurrentProductId, - ...props -}) => { - useEffect(() => { - console.log("SET setCurrentProductId"); - currentProductId !== "homePage" && setCurrentProductId("homePage"); - }, [currentProductId, setCurrentProductId]); - +const Home = ({ defaultPage, ...rest }) => { return tryRedirectTo(defaultPage) ? ( <> ) : ( - + ); @@ -126,12 +117,11 @@ Home.propTypes = { export default inject(({ auth }) => { const { isLoaded, settingsStore, moduleStore } = auth; - const { defaultPage, setCurrentProductId } = settingsStore; + const { defaultPage } = settingsStore; const { modules } = moduleStore; return { defaultPage, modules, isLoaded, - setCurrentProductId, }; })(withRouter(observer(Home))); diff --git a/web/ASC.Web.Client/src/custom.scss b/web/ASC.Web.Client/src/custom.scss deleted file mode 100644 index 84bb0c7753..0000000000 --- a/web/ASC.Web.Client/src/custom.scss +++ /dev/null @@ -1,34 +0,0 @@ -// Override default variables before the import -//$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - - .pageLoader { - position: fixed; - left: calc(50% - 20px); - top: 35%; - } -} -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -} - -body.desktop { - user-select: none; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; - mozuserselect: none; -} diff --git a/web/ASC.Web.Editor/src/App.js b/web/ASC.Web.Editor/src/App.js index 15bbd14d9b..fd55aed6be 100644 --- a/web/ASC.Web.Editor/src/App.js +++ b/web/ASC.Web.Editor/src/App.js @@ -1,8 +1,14 @@ import React from "react"; import Editor from "./Editor"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; const App = () => { - return ; + return ( + + + + ); }; export default App; diff --git a/web/ASC.Web.Editor/src/Editor.jsx b/web/ASC.Web.Editor/src/Editor.jsx index 1912a9378a..9d0ed3d095 100644 --- a/web/ASC.Web.Editor/src/Editor.jsx +++ b/web/ASC.Web.Editor/src/Editor.jsx @@ -28,7 +28,6 @@ import throttle from "lodash/throttle"; import { isIOS, deviceType } from "react-device-detect"; import { homepage } from "../package.json"; -import "./custom.scss"; import { AppServerConfig } from "@appserver/common/constants"; import SharingDialog from "files/SharingDialog"; diff --git a/web/ASC.Web.Login/src/App.js b/web/ASC.Web.Login/src/App.js index 95796706f1..d4f9244891 100644 --- a/web/ASC.Web.Login/src/App.js +++ b/web/ASC.Web.Login/src/App.js @@ -1,8 +1,14 @@ import React from "react"; import Shell from "studio/shell"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import "@appserver/common/custom.scss"; const App = () => { - return ; + return ( + + + + ); }; export default App; diff --git a/web/ASC.Web.Login/src/custom.scss b/web/ASC.Web.Login/src/custom.scss deleted file mode 100644 index cbde4e195a..0000000000 --- a/web/ASC.Web.Login/src/custom.scss +++ /dev/null @@ -1,25 +0,0 @@ -// Override default variables before the import -//$font-family-base: "Open Sans", sans-serif; - -html, -body { - height: 100%; -} - -#root { - min-height: 100%; - - .pageLoader { - position: fixed; - left: calc(50% - 20px); - top: 35%; - } -} -body { - margin: 0; - overflow: hidden; -} - -body.loading * { - cursor: wait !important; -}