Merge branch 'develop' into bugfix/context-actions

This commit is contained in:
Ilya Oleshko 2021-05-20 13:24:18 +03:00
commit cda77e1234
42 changed files with 370 additions and 387 deletions

View File

@ -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 <Route {...rest} render={renderComponent} />;
@ -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));

View File

@ -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;
}

View File

@ -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);
}
};

View File

@ -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 = () => <Shell />;
const App = () => {
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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;
}

View File

@ -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 = () => <Shell />;
const App = () => {
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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;
}

View File

@ -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 <Shell />;
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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(
// <MobxProvider
// auth={authStore}
// filesStore={filesStore}
// settingsStore={settingsStore}
// mediaViewerDataStore={mediaViewerDataStore}
// formatsStore={formatsStore}
// versionHistoryStore={versionHistoryStore}
// uploadDataStore={uploadDataStore}
// dialogsStore={dialogsStore}
// treeFoldersStore={treeFoldersStore}
// selectedFolderStore={selectedFolderStore}
// >
// <ErrorBoundary>
// <App />
// </ErrorBoundary>
// </MobxProvider>,
// 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();

View File

@ -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 = () => <Shell />;
const App = () => {
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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;
}

View File

@ -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 = () => <Shell />;
const App = () => {
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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;
}

View File

@ -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(
// <MobxProvider auth={authStore} peopleStore={peopleStore}>
// <ErrorBoundary>
// <App />
// </ErrorBoundary>
// </MobxProvider>,
// 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();

View File

@ -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;

View File

@ -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 (
<PageLayout withBodyAutoFocus>
<PageLayout.SectionHeader>
{profile && tReady ? (
isEdit ? (
<EditHeaderContent isMy={true} />
) : (
<ViewHeaderContent isMy={true} />
)
) : (
<Loaders.SectionHeader />
)}
</PageLayout.SectionHeader>
<PageLayout.SectionBody>
{profile && tReady ? (
isEdit ? (
<EditBodyContent isMy={true} />
) : (
<ViewBodyContent isMy={true} />
)
) : (
<Loaders.ProfileView />
)}
</PageLayout.SectionBody>
</PageLayout>
);
}
}
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 (
<PeopleProvider peopleStore={peopleStore}>
<I18nextProvider i18n={MyProfileI18n}>
<MyProfile {...rest} />
</I18nextProvider>
</PeopleProvider>
);
};

View File

@ -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) => {

View File

@ -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,

View File

@ -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");

View File

@ -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 ? (
<AvatarEditorPage />
) : (
<UpdateUserForm />
<UpdateUserForm isMy={isMy} />
);
};

View File

@ -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}
/>
<DepartmentField
labelText={`${groupCaption}:`}
isDisabled={isLoading || !isAdmin}
showGroupSelectorButtonTitle={t("AddButton")}
onShowGroupSelector={this.onShowGroupSelector}
onCloseGroupSelector={this.onCloseGroupSelector}
onRemoveGroup={this.onRemoveGroup}
selectorIsVisible={selector.visible}
selectorOptions={selector.options}
selectorSelectedOptions={selector.selected}
selectorSelectAllText={t("SelectAll")}
selectorOnSearchGroups={this.onSearchGroups}
selectorOnSelectGroups={this.onSelectGroups}
/>
{!isMy && (
<DepartmentField
labelText={`${groupCaption}:`}
isDisabled={isLoading || !isAdmin}
showGroupSelectorButtonTitle={t("AddButton")}
onShowGroupSelector={this.onShowGroupSelector}
onCloseGroupSelector={this.onCloseGroupSelector}
onRemoveGroup={this.onRemoveGroup}
selectorIsVisible={selector.visible}
selectorOptions={selector.options}
selectorSelectedOptions={selector.selected}
selectorSelectAllText={t("SelectAll")}
selectorOnSearchGroups={this.onSearchGroups}
selectorOnSelectGroups={this.onSelectGroups}
/>
)}
</MainFieldsContainer>
</MainContainer>
<InfoFieldContainer headerText={t("Comments")}>

View File

@ -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();

View File

@ -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 {
<PageLayout.SectionBody>
{this.loaded ? (
<SectionUserBody />
<SectionUserBody isMy={isMy} />
) : (
<Loaders.ProfileView isEdit={false} />
)}

View File

@ -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,

View File

@ -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 = () => <Shell />;
const App = () => {
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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;
}

View File

@ -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 (

View File

@ -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) => (
<React.Suspense fallback={<AppLoader />}>
@ -141,6 +135,14 @@ const ComingSoonRoute = (props) => (
</React.Suspense>
);
const MyProfileRoute = (props) => (
<React.Suspense fallback={<AppLoader />}>
<ErrorBoundary>
<MyProfile {...props} />
</ErrorBoundary>
</React.Suspense>
);
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}
/>
<PrivateRoute
exact
allowForMe
path={PROFILE_MY_URL}
component={MyProfileRoute}
/>
{dynamicRoutes}
<PrivateRoute path={ERROR_401_URL} component={Error401Route} />
<PrivateRoute component={Error404Route} />

View File

@ -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))
);

View File

@ -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 = () => {
<VersionStyle>
<Text className="text_style" fontSize="14px" color="#A3A9AE">
{`${t("AboutCompanyVersion")}: ${version.version}`}
{`${t("AboutCompanyVersion")}: ${config.version}`}
</Text>
</VersionStyle>
@ -193,24 +189,18 @@ const Body = () => {
);
};
const About = ({ language, setModuleInfo }) => {
useEffect(() => {
setModuleInfo(config.homepage, "home");
}, []);
const BodyWrapper = withTranslation("About")(Body);
const About = (props) => {
return (
<I18nextProvider i18n={i18n}>
<PageLayout>
<PageLayout.SectionBody>
<Body language={language} />
<BodyWrapper {...props} />
</PageLayout.SectionBody>
</PageLayout>
</I18nextProvider>
);
};
export default inject(({ auth }) => {
return {
setModuleInfo: auth.settingsStore.setModuleInfo,
};
})(About);
export default About;

View File

@ -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) ? (
<></>
) : (
<PageLayout>
<PageLayout.SectionBody>
<Body {...props} />
<Body {...rest} />
</PageLayout.SectionBody>
</PageLayout>
);
@ -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)));

View File

@ -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;
}

View File

@ -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 <Editor />;
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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";

View File

@ -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 <Shell />;
return (
<ErrorBoundary>
<Shell />
</ErrorBoundary>
);
};
export default App;

View File

@ -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;
}