From e8e78604f1d62f1a32549d4c874a934b7774f0ea Mon Sep 17 00:00:00 2001 From: AlexeySafronov Date: Fri, 12 Mar 2021 13:52:30 +0300 Subject: [PATCH 1/8] Web: Added products/apps dynamic loading --- packages/asc-web-common/store/ModuleStore.js | 119 ++++++++++-------- web/ASC.Web.Client/src/Shell.jsx | 93 ++++++-------- .../src/components/AppLoader/index.js | 13 ++ .../src/components/System/index.js | 107 ++++++++++++++++ web/ASC.Web.Client/webpack.config.js | 2 - yarn.lock | 58 ++++----- 6 files changed, 256 insertions(+), 136 deletions(-) create mode 100644 web/ASC.Web.Client/src/components/AppLoader/index.js create mode 100644 web/ASC.Web.Client/src/components/System/index.js diff --git a/packages/asc-web-common/store/ModuleStore.js b/packages/asc-web-common/store/ModuleStore.js index e2347bdd56..30e6c27c02 100644 --- a/packages/asc-web-common/store/ModuleStore.js +++ b/packages/asc-web-common/store/ModuleStore.js @@ -56,69 +56,84 @@ class ModuleStore { iconName = null, iconUrl = null ) => { - switch (item.id) { - case "6743007c-6f95-4d20-8c88-a8601ce5e76d": - item.iconName = "CrmIcon"; - item.iconUrl = "/static/images/crm.react.svg"; - item.imageUrl = "/images/crm.svg"; - item.helpUrl = "https://helpcenter.onlyoffice.com/userguides/crm.aspx"; - break; - case "1e044602-43b5-4d79-82f3-fd6208a11960": - item.iconName = "ProjectsIcon"; - item.iconUrl = "/static/images/projects.react.svg"; - item.imageUrl = "/images/projects.svg"; - item.helpUrl = - "https://helpcenter.onlyoffice.com/userguides/projects.aspx"; - break; - case "2A923037-8B2D-487b-9A22-5AC0918ACF3F": - item.iconName = "MailIcon"; - item.iconUrl = "/static/images/mail.react.svg"; - item.imageUrl = "/images/mail.svg"; - break; - case "32D24CB5-7ECE-4606-9C94-19216BA42086": - item.iconName = "CalendarCheckedIcon"; - item.iconUrl = "/static/images/calendar.checked.react.svg"; - item.imageUrl = "/images/calendar.svg"; - break; - case "BF88953E-3C43-4850-A3FB-B1E43AD53A3E": - item.iconName = "ChatIcon"; - item.iconUrl = "/static/images/chat.react.svg"; - item.imageUrl = "/images/talk.svg"; - item.isolateMode = true; - break; - default: - break; - } + const id = + item.id && typeof item.id === "string" ? item.id.toLowerCase() : null; - const actions = noAction - ? null - : { - onClick: (e) => { - if (e) { - window.open(item.link, "_self"); - e.preventDefault(); - } - }, - onBadgeClick: (e) => console.log(iconName + " Badge Clicked", e), - }; - - const description = noAction ? { description: item.description } : null; - - return { - id: item.id, + const result = { + id, + appName: "none", title: item.title, link: item.link, originUrl: item.originUrl, helpUrl: item.helpUrl, + notifications: 0, iconName: item.iconName || iconName || "/static/images/people.react.svg", //TODO: Change to URL iconUrl: item.iconUrl || iconUrl, imageUrl: item.imageUrl, - notifications: 0, isolateMode: item.isolateMode, isPrimary: item.isPrimary, - ...description, - ...actions, }; + + switch (id) { + case "6743007c-6f95-4d20-8c88-a8601ce5e76d": + result.appName = "crm"; + result.iconName = "CrmIcon"; + result.iconUrl = "/static/images/crm.react.svg"; + result.imageUrl = "/images/crm.svg"; + result.helpUrl = + "https://helpcenter.onlyoffice.com/userguides/crm.aspx"; + break; + case "1e044602-43b5-4d79-82f3-fd6208a11960": + result.appName = "projects"; + result.iconName = "ProjectsIcon"; + result.iconUrl = "/static/images/projects.react.svg"; + result.imageUrl = "/images/projects.svg"; + result.helpUrl = + "https://helpcenter.onlyoffice.com/userguides/projects.aspx"; + break; + case "2a923037-8b2d-487b-9a22-5ac0918acf3f": + result.appName = "mail"; + result.iconName = "MailIcon"; + result.iconUrl = "/static/images/mail.react.svg"; + result.imageUrl = "/images/mail.svg"; + break; + case "32d24cb5-7ece-4606-9c94-19216ba42086": + result.appName = "calendar"; + result.iconName = "CalendarCheckedIcon"; + result.iconUrl = "/static/images/calendar.checked.react.svg"; + result.imageUrl = "/images/calendar.svg"; + break; + case "bf88953e-3c43-4850-a3fb-b1e43ad53a3e": + result.appName = "chat"; + result.iconName = "ChatIcon"; + result.iconUrl = "/static/images/chat.react.svg"; + result.imageUrl = "/images/talk.svg"; + result.isolateMode = true; + break; + case "e67be73d-f9ae-4ce1-8fec-1880cb518cb4": + result.appName = "files"; + break; + case "f4d98afd-d336-4332-8778-3c6945c81ea0": + result.appName = "people"; + break; + default: + result.appName = "none"; + break; + } + + if (!noAction) { + result.onClick = (e) => { + if (e) { + window.open(item.link, "_self"); + e.preventDefault(); + } + }; + result.onBadgeClick = (e) => console.log(iconName + " Badge Clicked", e); + } else { + result.description = item.description; + } + + return result; }; get totalNotificationsCount() { diff --git a/web/ASC.Web.Client/src/Shell.jsx b/web/ASC.Web.Client/src/Shell.jsx index fd581e331f..914b1adb1a 100644 --- a/web/ASC.Web.Client/src/Shell.jsx +++ b/web/ASC.Web.Client/src/Shell.jsx @@ -1,5 +1,4 @@ import React, { useEffect } from "react"; -import styled from "styled-components"; import { Router, Switch } from "react-router-dom"; import { inject, observer } from "mobx-react"; import NavMenu from "./components/NavMenu"; @@ -12,9 +11,6 @@ import Layout from "./components/Layout"; import ScrollToTop from "./components/Layout/ScrollToTop"; import history from "@appserver/common/history"; import toastr from "studio/toastr"; -import Loader from "@appserver/components/loader"; -import Grid from "@appserver/components/grid"; -import PageLayout from "@appserver/common/components/PageLayout"; import { updateTempContent } from "@appserver/common/utils"; import { Provider as MobxProvider } from "mobx-react"; import ThemeProvider from "@appserver/components/theme-provider"; @@ -23,35 +19,27 @@ import store from "studio/store"; import config from "../package.json"; import "./custom.scss"; import "./i18n"; +import AppLoader from "./components/AppLoader"; +import System from "./components/System"; const Payments = React.lazy(() => import("./components/pages/Payments")); const Error404 = React.lazy(() => import("studio/Error404")); const Error401 = React.lazy(() => import("studio/Error401")); const Home = React.lazy(() => import("./components/pages/Home")); const Login = React.lazy(() => import("login/app")); -const People = React.lazy(() => import("people/app")); -const Files = React.lazy(() => import("files/app")); const About = React.lazy(() => import("./components/pages/About")); const Settings = React.lazy(() => import("./components/pages/Settings")); const ComingSoon = React.lazy(() => import("./components/pages/ComingSoon")); -const LoadingShell = () => ( - - - - - -); - const SettingsRoute = (props) => ( - }> + }> ); const PaymentsRoute = (props) => ( - }> + }> @@ -59,7 +47,7 @@ const PaymentsRoute = (props) => ( ); const Error404Route = (props) => ( - }> + }> @@ -67,14 +55,14 @@ const Error404Route = (props) => ( ); const Error401Route = (props) => ( - }> + }> ); const HomeRoute = (props) => ( - }> + }> @@ -82,35 +70,15 @@ const HomeRoute = (props) => ( ); const LoginRoute = (props) => ( - }> + }> ); -const PeopleRoute = (props) => { - return ( - }> - - - - - ); -}; - -const FilesRoute = (props) => { - return ( - }> - - - - - ); -}; - const AboutRoute = (props) => ( - }> + }> @@ -118,12 +86,28 @@ const AboutRoute = (props) => ( ); const ComingSoonRoute = (props) => ( - }> + }> ); + +const DynamicAppRoute = ({ link, appName, ...rest }) => { + const system = { + url: `${window.location.origin}${link}remoteEntry.js`, + scope: appName, + module: "./app", + }; + return ( + }> + + + + + ); +}; + const Shell = ({ items = [], page = "home", ...rest }) => { // useEffect(() => { // //utils.removeTempContent(); @@ -159,7 +143,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => { // .catch((err) => toastr.error(err.message)); // }, []); - const { isLoaded, loadBaseInfo, isThirdPartyResponse } = rest; + const { isLoaded, loadBaseInfo, isThirdPartyResponse, modules } = rest; useEffect(() => { try { @@ -167,7 +151,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => { } catch (err) { toastr.error(err); } - }, [loadBaseInfo]); + }, []); useEffect(() => { if (isLoaded) updateTempContent(); @@ -181,6 +165,16 @@ const Shell = ({ items = [], page = "home", ...rest }) => { const pathname = window.location.pathname.toLowerCase(); const isEditor = pathname.indexOf("doceditor") !== -1; + const dynamicRoutes = modules.map((m) => ( + + )); + return ( @@ -194,14 +188,6 @@ const Shell = ({ items = [], page = "home", ...rest }) => { path={["/", "/error=:error"]} component={HomeRoute} /> - - { path="/settings" component={SettingsRoute} /> + {dynamicRoutes} @@ -242,7 +229,6 @@ const Shell = ({ items = [], page = "home", ...rest }) => { const ShellWrapper = inject(({ auth }) => { const { init, isLoaded } = auth; - const pathname = window.location.pathname.toLowerCase(); const isThirdPartyResponse = pathname.indexOf("thirdparty") !== -1; @@ -253,6 +239,7 @@ const ShellWrapper = inject(({ auth }) => { }, isThirdPartyResponse, isLoaded, + modules: auth.moduleStore.modules, }; })(observer(Shell)); diff --git a/web/ASC.Web.Client/src/components/AppLoader/index.js b/web/ASC.Web.Client/src/components/AppLoader/index.js new file mode 100644 index 0000000000..36121cf181 --- /dev/null +++ b/web/ASC.Web.Client/src/components/AppLoader/index.js @@ -0,0 +1,13 @@ +import React from "react"; +import PageLayout from "@appserver/common/components/PageLayout"; +import Loader from "@appserver/components/loader"; + +const AppLoader = () => ( + + + + + +); + +export default AppLoader; diff --git a/web/ASC.Web.Client/src/components/System/index.js b/web/ASC.Web.Client/src/components/System/index.js new file mode 100644 index 0000000000..e5a637e8b6 --- /dev/null +++ b/web/ASC.Web.Client/src/components/System/index.js @@ -0,0 +1,107 @@ +import React from "react"; +import AppLoader from "../AppLoader"; +import ErrorBoundary from "@appserver/common/components/ErrorBoundary"; +import Error520 from "studio/Error520"; +import Error404 from "studio/Error404"; + +function loadComponent(scope, module) { + return async () => { + // Initializes the share scope. This fills it with known provided modules from this build and all remotes + await __webpack_init_sharing__("default"); + const container = window[scope]; // or get the container somewhere else + // Initialize the container, it may provide shared modules + await container.init(__webpack_share_scopes__.default); + const factory = await window[scope].get(module); + const Module = factory(); + return Module; + }; +} + +const useDynamicScript = (args) => { + const [ready, setReady] = React.useState(false); + const [failed, setFailed] = React.useState(false); + + React.useEffect(() => { + if (!args.url) { + return; + } + + const exists = document.getElementById(args.id); + + if (exists) { + setReady(true); + setFailed(false); + return; + } + + const element = document.createElement("script"); + + element.id = args.id; + element.src = args.url; + element.type = "text/javascript"; + element.async = true; + + setReady(false); + setFailed(false); + + element.onload = () => { + console.log(`Dynamic Script Loaded: ${args.url}`); + setReady(true); + }; + + element.onerror = () => { + console.error(`Dynamic Script Error: ${args.url}`); + setReady(false); + setFailed(true); + }; + + document.head.appendChild(element); + + //TODO: Uncomment if you need to remove loaded remoteEntry + // return () => { + // console.log(`Dynamic Script Removed: ${args.url}`); + // document.head.removeChild(element); + // }; + }, [args.url]); + + return { + ready, + failed, + }; +}; + +const System = (props) => { + const { ready, failed } = useDynamicScript({ + url: props.system && props.system.url, + id: props.system && props.system.scope, + }); + + if (!props.system) { + console.log(`Not system specified`); + return ; + } + + if (!ready) { + console.log(`Loading dynamic script: ${props.system.url}`); + return ; + } + + if (failed) { + console.log(`Failed to load dynamic script: ${props.system.url}`); + return ; + } + + const Component = React.lazy( + loadComponent(props.system.scope, props.system.module) + ); + + return ( + }> + + + + + ); +}; + +export default System; diff --git a/web/ASC.Web.Client/webpack.config.js b/web/ASC.Web.Client/webpack.config.js index 54b2989085..dcf16e3193 100644 --- a/web/ASC.Web.Client/webpack.config.js +++ b/web/ASC.Web.Client/webpack.config.js @@ -126,8 +126,6 @@ const config = { filename: "remoteEntry.js", remotes: { studio: `studio@${homepage}/remoteEntry.js`, - people: `people@${homepage}/products/people/remoteEntry.js`, - files: `files@${homepage}/products/files/remoteEntry.js`, login: `login@${homepage}/login/remoteEntry.js`, }, exposes: { diff --git a/yarn.lock b/yarn.lock index 2ad5dadfd7..ecaf362bbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5778,9 +5778,9 @@ can-use-dom@^0.1.0: integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo= caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: - version "1.0.30001198" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001198.tgz#ed2d9b5f060322ba2efa42afdc56dee3255473f4" - integrity sha512-r5GGgESqOPZzwvdLVER374FpQu2WluCF1Z2DSiFJ89KSmGjT0LVKjgv4NcAqHmGWF9ihNpqRI9KXO9Ex4sKsgA== + version "1.0.30001199" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001199.tgz#062afccaad21023e2e647d767bac4274b8b8fd7f" + integrity sha512-ifbK2eChUCFUwGhlEzIoVwzFt1+iriSjyKKFYNfv6hN34483wyWpLLavYQXhnR036LhkdUYaSDpHg1El++VgHQ== capture-exit@^2.0.0: version "2.0.0" @@ -6049,9 +6049,9 @@ cli-width@^3.0.0: integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== clipboard@^2.0.0: - version "2.0.7" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.7.tgz#da927f817b1859426df39212ac81feb07dbaeadc" - integrity sha512-8M8WEZcIvs0hgOma+wAPkrUxpv0PMY1L6VsAJh/2DOKARIMpyWe6ZLcEoe1qktl6/ced5ceYHs+oGedSbgZ3sg== + version "2.0.8" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba" + integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ== dependencies: good-listener "^1.2.2" select "^1.1.2" @@ -7318,9 +7318,9 @@ domutils@^1.5.1, domutils@^1.7.0: domelementtype "1" domutils@^2.4.2, domutils@^2.4.3, domutils@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" - integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.0.tgz#42f49cffdabb92ad243278b331fd761c1c2d3039" + integrity sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg== dependencies: dom-serializer "^1.0.1" domelementtype "^2.0.1" @@ -7428,9 +7428,9 @@ ejs@^3.1.2: jake "^10.6.1" electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649: - version "1.3.684" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.684.tgz#053fbb0a4b2d5c076dfa6e1d8ecd06a3075a558a" - integrity sha512-GV/vz2EmmtRSvfGSQ5A0Lucic//IRSDijgL15IgzbBEEnp4rfbxeUSZSlBfmsj7BQvE4sBdgfsvPzLCnp6L21w== + version "1.3.687" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.687.tgz#c336184b7ab70427ffe2ee79eaeaedbc1ad8c374" + integrity sha512-IpzksdQNl3wdgkzf7dnA7/v10w0Utf1dF2L+B4+gKrloBrxCut+au+kky3PYvle3RMdSxZP+UiCZtLbcYRxSNQ== element-resize-detector@^1.2.1: version "1.2.2" @@ -12219,9 +12219,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + version "5.4.5" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.5.tgz#0cbc1a2b0f658493b4025775a13ad938e96091ef" + integrity sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ== dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -13758,11 +13758,11 @@ react-dev-utils@^11.0.3: text-table "0.2.0" react-device-detect@^1.14.0, react-device-detect@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-1.15.0.tgz#5321f94ae3c4d51ef399b0502a6c739e32d0f315" - integrity sha512-ywjtWW04U7vaJK87IAFHhKozZhTPeDVWsfYx5CxQSQCjU5+fnMMxWZt9HnVWaNTqBEn6g8wCNWyqav7sXJrURg== + version "1.17.0" + resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-1.17.0.tgz#a00b4fd6880cebfab3fd8a42a79dc0290cdddca9" + integrity sha512-bBblIStwpHmoS281JFIVqeimcN3LhpoP5YKDWzxQdBIUP8S2xPvHDgizLDhUq2ScguLfVPmwfF5y268EEQR60w== dependencies: - ua-parser-js "^0.7.23" + ua-parser-js "^0.7.24" react-docgen-typescript-plugin@^0.6.2: version "0.6.3" @@ -14832,9 +14832,9 @@ rollup-pluginutils@^2.8.2: estree-walker "^0.6.1" rollup@^2.25.0: - version "2.41.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.41.0.tgz#b2a398bbabbf227738dedaef099e494aed468982" - integrity sha512-Gk76XHTggulWPH95q8V62bw6uqDH6UGvbD6LOa3QUyhuMF3eOuaeDHR7SLm1T9faitkpNrqzUAVYx47klcMnlA== + version "2.41.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.41.1.tgz#c7c7ada42b13be505facd516f13fb697c24c1116" + integrity sha512-nepLFAW5W71/MWpS2Yr7r31eS7HRfYg2RXnxb6ehqN9zY42yACxKtEfb4xq8SmNfUohAzGMcyl6jkwdLOAiUbg== optionalDependencies: fsevents "~2.3.1" @@ -16533,7 +16533,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -ua-parser-js@^0.7.23: +ua-parser-js@^0.7.24: version "0.7.24" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.24.tgz#8d3ecea46ed4f1f1d63ec25f17d8568105dc027c" integrity sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw== @@ -16547,9 +16547,9 @@ uglify-js@3.4.x: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.13.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.0.tgz#66ed69f7241f33f13531d3d51d5bcebf00df7f69" - integrity sha512-TWYSWa9T2pPN4DIJYbU9oAjQx+5qdV5RUDxwARg8fmJZrD/V27Zj0JngW5xg1DFz42G0uDYl2XhzF6alSzD62w== + version "3.13.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.1.tgz#2749d4b8b5b7d67460b4a418023ff73c3fefa60a" + integrity sha512-EWhx3fHy3M9JbaeTnO+rEqzCe1wtyQClv6q3YWq0voOj4E+bMZBErVS1GAHPDiRGONYq34M1/d8KuQMgvi6Gjw== uid-number@0.0.6: version "0.0.6" @@ -17731,9 +17731,9 @@ yargs-parser@^15.0.1: decamelize "^1.2.0" yargs-parser@^20.2.3: - version "20.2.6" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.6.tgz#69f920addf61aafc0b8b89002f5d66e28f2d8b20" - integrity sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA== + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== yargs@^13.0.0, yargs@^13.3.0, yargs@^13.3.2: version "13.3.2" From 4fc9fbe4d30b71e985b6b997242f0ca0ad6efc33 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Mar 2021 15:20:52 +0300 Subject: [PATCH 2/8] Web: Files: fixed context-menu-button clickOutsideAction --- packages/asc-web-components/context-menu-button/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/asc-web-components/context-menu-button/index.js b/packages/asc-web-components/context-menu-button/index.js index 66426967da..0531394cb1 100644 --- a/packages/asc-web-components/context-menu-button/index.js +++ b/packages/asc-web-components/context-menu-button/index.js @@ -103,9 +103,9 @@ class ContextMenuButton extends React.Component { }; clickOutsideAction = (e) => { - /* const path = e.path || (e.composedPath && e.composedPath()); + const path = e.path || (e.composedPath && e.composedPath()); const dropDownItem = path ? path.find((x) => x === this.ref.current) : null; - if (!dropDownItem) return; */ + if (dropDownItem) return; this.onIconButtonClick(); }; From 0a096a13045618cd43b151bac5bf87e6b89cb99c Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Fri, 12 Mar 2021 15:40:21 +0300 Subject: [PATCH 3/8] Web: Components: Row: Removed unused property from PropTypes --- packages/asc-web-components/row/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/asc-web-components/row/index.js b/packages/asc-web-components/row/index.js index 9f3c3b201a..4d918d13f8 100644 --- a/packages/asc-web-components/row/index.js +++ b/packages/asc-web-components/row/index.js @@ -27,7 +27,8 @@ class Row extends React.Component { } componentWillUnmount() { - this.container.removeEventListener("contextmenu", this.onContextMenu); + this.container && + this.container.removeEventListener("contextmenu", this.onContextMenu); } onContextMenu = (e) => { @@ -141,12 +142,10 @@ Row.propTypes = { element: PropTypes.element, /** Accepts id */ id: PropTypes.string, + /** If true, this state is shown as a rectangle in the checkbox */ indeterminate: PropTypes.bool, - /** shouldComponentUpdate function */ - needForUpdate: PropTypes.func, /** when selecting row element. Returns data value. */ onSelect: PropTypes.func, - selectItem: PropTypes.func, /** Accepts css style */ style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), sectionWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), From fc2b9cff343f7c97fc71a7c9ce0ba68b94dac5a6 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Fri, 12 Mar 2021 15:40:49 +0300 Subject: [PATCH 4/8] Web: Components: Row: Added tests --- packages/asc-web-components/row/row.test.js | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/packages/asc-web-components/row/row.test.js b/packages/asc-web-components/row/row.test.js index 77f109397d..36a44608a2 100644 --- a/packages/asc-web-components/row/row.test.js +++ b/packages/asc-web-components/row/row.test.js @@ -32,6 +32,44 @@ describe("", () => { expect(onSelect).toHaveBeenCalled(); }); + it("renders with children", () => { + const wrapper = mount(); + + expect(wrapper).toHaveProp("children", baseProps.children); + }); + + it("renders with contentElement and sectionWidth", () => { + const element =
content
; + const wrapper = mount( + + ); + + expect(wrapper).toHaveProp("contentElement", element); + }); + + it("can apply contextButtonSpacerWidth", () => { + const test = "10px"; + const wrapper = mount( + + ); + + expect(wrapper).toHaveProp("contextButtonSpacerWidth", test); + }); + + it("can apply data property", () => { + const test = { test: "test" }; + const wrapper = mount(); + + expect(wrapper).toHaveProp("data", test); + }); + + it("can apply indeterminate", () => { + const test = true; + const wrapper = mount(); + + expect(wrapper).toHaveProp("indeterminate", test); + }); + it("accepts id", () => { const wrapper = mount(); @@ -49,4 +87,13 @@ describe("", () => { expect(wrapper.getDOMNode().style).toHaveProperty("color", "red"); }); + + it("componentWillUnmount() props lifecycle test", () => { + const wrapper = shallow(); + const instance = wrapper.instance(); + + instance.componentWillUnmount(); + + expect(wrapper).toExist(false); + }); }); From 60d1408d0dacda5cb2aa278d23f23967df9a5f93 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Fri, 12 Mar 2021 15:41:17 +0300 Subject: [PATCH 5/8] Web: Components: RowContainer: Fixed and added tests --- .../row-container/row-container.test.js | 66 ++++++++----------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/packages/asc-web-components/row-container/row-container.test.js b/packages/asc-web-components/row-container/row-container.test.js index d74b7d3a8b..4142df6e6e 100644 --- a/packages/asc-web-components/row-container/row-container.test.js +++ b/packages/asc-web-components/row-container/row-container.test.js @@ -17,6 +17,33 @@ describe("", () => { expect(wrapper).toExist(); }); + it("stop event on context click", () => { + const wrapper = shallow( + + Demo + + ); + + const event = { preventDefault: () => {} }; + + jest.spyOn(event, "preventDefault"); + + wrapper.simulate("contextmenu", event); + + expect(event.preventDefault).not.toBeCalled(); + }); + + it("renders like list", () => { + const wrapper = mount( + + Demo + + ); + + expect(wrapper).toExist(); + expect(wrapper.getDOMNode().style).toHaveProperty("height", ""); + }); + it("renders without manualHeight", () => { const wrapper = mount( @@ -27,45 +54,6 @@ describe("", () => { expect(wrapper).toExist(); }); - it("call onRowContextClick() with normal options", () => { - const options = [ - { - key: "1", - label: "test", - }, - ]; - - const wrapper = mount( - - Demo - - ); - - const instance = wrapper.instance(); - - instance.onRowContextClick(options); - - expect(wrapper.state("contextOptions")).toEqual(options); - }); - - it("call onRowContextClick() with wrong options", () => { - const options = { - key: "1", - label: "test", - }; - const wrapper = mount( - - Demo - - ); - - const instance = wrapper.instance(); - - instance.onRowContextClick(options); - - expect(wrapper.state("contextOptions")).toEqual([]); - }); - it("componentWillUnmount() props lifecycle test", () => { const wrapper = shallow( From 9f458a8bb50eadfd15eb1867c2be6c560d6597c7 Mon Sep 17 00:00:00 2001 From: Alexey Kostenko Date: Fri, 12 Mar 2021 15:43:53 +0300 Subject: [PATCH 6/8] Web: People: Fixed icons path in profile --- .../Client/src/helpers/people-helpers.js | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/products/ASC.People/Client/src/helpers/people-helpers.js b/products/ASC.People/Client/src/helpers/people-helpers.js index 89a7559b19..3692e03b63 100644 --- a/products/ASC.People/Client/src/helpers/people-helpers.js +++ b/products/ASC.People/Client/src/helpers/people-helpers.js @@ -37,39 +37,71 @@ export const getUserRole = (user) => { export const getUserContactsPattern = () => { return { contact: [ - { type: "mail", icon: "MailIcon", link: "mailto:{0}" }, - { type: "phone", icon: "PhoneIcon", link: "tel:{0}" }, - { type: "mobphone", icon: "MobileIcon", link: "tel:{0}" }, - { type: "gmail", icon: "GmailIcon", link: "mailto:{0}" }, - { type: "skype", icon: "SkypeIcon", link: "skype:{0}?userinfo" }, - { type: "msn", icon: "WindowsMsnIcon" }, - { type: "icq", icon: "IcqIcon", link: "https://www.icq.com/people/{0}" }, - { type: "jabber", icon: "JabberIcon" }, - { type: "aim", icon: "AimIcon" }, + { + type: "mail", + icon: "/static/images/mail.react.svg", + link: "mailto:{0}", + }, + { + type: "phone", + icon: "/products/people/images/phone.react.svg", + link: "tel:{0}", + }, + { + type: "mobphone", + icon: "/products/people/images/mobile.react.svg", + link: "tel:{0}", + }, + { + type: "gmail", + icon: "/products/people/images/gmail.react.svg", + link: "mailto:{0}", + }, + { + type: "skype", + icon: "/products/people/images/skype.react.svg", + link: "skype:{0}?userinfo", + }, + { type: "msn", icon: "/products/people/images/windows.msn.react.svg" }, + { + type: "icq", + icon: "/products/people/images/icq.react.svg", + link: "https://www.icq.com/people/{0}", + }, + { type: "jabber", icon: "/products/people/images/jabber.react.svg" }, + { type: "aim", icon: "/products/people/images/aim.react.svg" }, ], social: [ { type: "facebook", - icon: "ShareFacebookIcon", + icon: "/products/people/images/share.facebook.react.svg", link: "https://facebook.com/{0}", }, { type: "livejournal", - icon: "LivejournalIcon", + icon: "/products/people/images/livejournal.react.svg", link: "https://{0}.livejournal.com", }, - { type: "myspace", icon: "MyspaceIcon", link: "https://myspace.com/{0}" }, + { + type: "myspace", + icon: "/products/people/images/myspace.react.svg", + link: "https://myspace.com/{0}", + }, { type: "twitter", - icon: "ShareTwitterIcon", + icon: "/products/people/images/share.twitter.react.svg", link: "https://twitter.com/{0}", }, { type: "blogger", - icon: "BloggerIcon", + icon: "/products/people/images/blogger.react.svg", link: "https://{0}.blogspot.com", }, - { type: "yahoo", icon: "YahooIcon", link: "mailto:{0}@yahoo.com" }, + { + type: "yahoo", + icon: "/products/people/images/yahoo.react.svg", + link: "mailto:{0}@yahoo.com", + }, ], }; }; From ca94ae28cd9f0ece6450fe88cab5270338ed6410 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Mar 2021 16:30:36 +0300 Subject: [PATCH 7/8] Web: Files: fixed empty filter container --- packages/asc-web-components/drop-down/index.js | 2 +- .../Home/Section/Body/EmptyContainer/EmptyFilterContainer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/asc-web-components/drop-down/index.js b/packages/asc-web-components/drop-down/index.js index 7c6ff2af5f..ff1e3b4a2d 100644 --- a/packages/asc-web-components/drop-down/index.js +++ b/packages/asc-web-components/drop-down/index.js @@ -239,7 +239,7 @@ DropDownContainer.propTypes = { DropDownContainer.defaultProps = { directionX: "left", directionY: "bottom", - withBackdrop: false, + withBackdrop: true, showDisabledItems: false, }; diff --git a/products/ASC.Files/Client/src/components/pages/Home/Section/Body/EmptyContainer/EmptyFilterContainer.js b/products/ASC.Files/Client/src/components/pages/Home/Section/Body/EmptyContainer/EmptyFilterContainer.js index 5c646a7bef..dcaeaf1f03 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/Section/Body/EmptyContainer/EmptyFilterContainer.js +++ b/products/ASC.Files/Client/src/components/pages/Home/Section/Body/EmptyContainer/EmptyFilterContainer.js @@ -17,7 +17,7 @@ const EmptyFilterContainer = ({ const subheadingText = t("EmptyFilterSubheadingText"); const descriptionText = t("EmptyFilterDescriptionText"); - onResetFilter = () => { + const onResetFilter = () => { setIsLoading(true); const newFilter = FilesFilter.getDefault(); fetchFiles(selectedFolderId, newFilter) From 2489c2522427e3bb14e08e647d6790906a4c940d Mon Sep 17 00:00:00 2001 From: Alexey Kostenko Date: Fri, 12 Mar 2021 16:53:47 +0300 Subject: [PATCH 8/8] Web: Files: Fixed icons path in Sharing panel --- .../Client/src/components/panels/AddGroupsPanel/index.js | 2 +- .../Client/src/components/panels/AddUsersPanel/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/products/ASC.Files/Client/src/components/panels/AddGroupsPanel/index.js b/products/ASC.Files/Client/src/components/panels/AddGroupsPanel/index.js index a86e0735b4..4aab8215da 100644 --- a/products/ASC.Files/Client/src/components/panels/AddGroupsPanel/index.js +++ b/products/ASC.Files/Client/src/components/panels/AddGroupsPanel/index.js @@ -121,7 +121,7 @@ class AddGroupsPanelComponent extends React.Component { diff --git a/products/ASC.Files/Client/src/components/panels/AddUsersPanel/index.js b/products/ASC.Files/Client/src/components/panels/AddUsersPanel/index.js index fa4aef3875..aa4bd1817f 100644 --- a/products/ASC.Files/Client/src/components/panels/AddUsersPanel/index.js +++ b/products/ASC.Files/Client/src/components/panels/AddUsersPanel/index.js @@ -154,7 +154,7 @@ class AddUsersPanelComponent extends React.Component {