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

This commit is contained in:
Vladislav Makhov 2021-02-26 18:33:28 +03:00
commit 7bf2a8e9b5
17 changed files with 137 additions and 81 deletions

View File

@ -18,7 +18,6 @@ Headline.propTypes = {
}; };
Headline.defaultProps = { Headline.defaultProps = {
//color: "#333333",
title: null, title: null,
truncate: false, truncate: false,
isInline: false, isInline: false,

View File

@ -19,7 +19,7 @@ const StyledHeading = styled(Heading)`
line-height: 65px; line-height: 65px;
font-size: ${(props) => size[props.headlineType]}; font-size: ${(props) => size[props.headlineType]};
font-weight: ${(props) => weight[props.headlineType]}; font-weight: ${(props) => weight[props.headlineType]};
color: ${(props) => props.theme.color}; color: ${(props) => (props.color ? props.color : props.theme.color)};
`; `;
StyledHeading.defaultProps = { theme: Base }; StyledHeading.defaultProps = { theme: Base };

View File

@ -96,8 +96,9 @@ const HeaderNav = ({
iconName={m.iconName} iconName={m.iconName}
iconUrl={m.iconUrl} iconUrl={m.iconUrl}
badgeNumber={m.notifications} badgeNumber={m.notifications}
url={m.link}
onClick={(e) => { onClick={(e) => {
window.open(m.link, "_self"); history.push(m.link);
e.preventDefault(); e.preventDefault();
}} }}
onBadgeClick={(e) => console.log(m.iconName + "Badge Clicked", e)} onBadgeClick={(e) => console.log(m.iconName + "Badge Clicked", e)}

View File

@ -2,7 +2,7 @@ import React from "react";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import styled from "styled-components"; import styled from "styled-components";
import { Link as LogoLink } from "react-router-dom"; import { useLocation, Link as LinkWithoutRedirect } from "react-router-dom";
import NavItem from "./nav-item"; import NavItem from "./nav-item";
import Headline from "../../Headline"; import Headline from "../../Headline";
import Nav from "./nav"; import Nav from "./nav";
@ -67,6 +67,23 @@ const Header = styled.header`
} }
`; `;
const StyledLink = styled.div`
display: inline;
.nav-menu-header_link {
color: #7a95b0;
font-size: 13px;
}
a {
text-decoration: none;
}
:hover {
color: #7a95b0;
-webkit-text-decoration: underline;
text-decoration: underline;
}
`;
const versionBadgeProps = { const versionBadgeProps = {
color: "#7A95B0", color: "#7A95B0",
fontWeight: "600", fontWeight: "600",
@ -91,6 +108,7 @@ const HeaderComponent = ({
...props ...props
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { pathname } = useLocation();
const isNavAvailable = mainModules.length > 0; const isNavAvailable = mainModules.length > 0;
@ -114,7 +132,7 @@ const HeaderComponent = ({
const onItemClick = (e) => { const onItemClick = (e) => {
if (!e) return; if (!e) return;
const link = e.currentTarget.dataset.link; const link = e.currentTarget.dataset.link;
window.open(link, "_self"); history.push(link);
e.preventDefault(); e.preventDefault();
}; };
@ -147,7 +165,7 @@ const HeaderComponent = ({
</> </>
); );
}; };
const isMainPage = pathname === "/";
return ( return (
<> <>
<Header <Header
@ -162,7 +180,7 @@ const HeaderComponent = ({
noHover={true} noHover={true}
/> />
<LogoLink className="header-logo-wrapper" to={defaultPage}> <LinkWithoutRedirect className="header-logo-wrapper" to={defaultPage}>
<ReactSVG <ReactSVG
className="header-logo-icon" className="header-logo-icon"
loading={() => ( loading={() => (
@ -177,7 +195,7 @@ const HeaderComponent = ({
)} )}
src={props.logoUrl} src={props.logoUrl}
/> />
</LogoLink> </LinkWithoutRedirect>
<Headline className="header-module-title" type="header" color="#FFF"> <Headline className="header-module-title" type="header" color="#FFF">
{currentProductName} {currentProductName}
</Headline> </Headline>
@ -212,7 +230,7 @@ const HeaderComponent = ({
data-id={id} data-id={id}
data-link={link} data-link={link}
opened={isNavOpened} opened={isNavOpened}
active={id == currentProductId} active={isMainPage ? false : id == currentProductId}
iconName={iconName} iconName={iconName}
iconUrl={iconUrl} iconUrl={iconUrl}
badgeNumber={notifications} badgeNumber={notifications}
@ -239,14 +257,11 @@ const HeaderComponent = ({
{" "} {" "}
-{" "} -{" "}
</Text> </Text>
<Link <StyledLink>
as="a" <LinkWithoutRedirect to="/about" className="nav-menu-header_link">
onClick={onLinkClick} {t("AboutShort")}
target="_blank" </LinkWithoutRedirect>
{...versionBadgeProps} </StyledLink>
>
{t("AboutShort")}
</Link>
</Box> </Box>
</Nav> </Nav>
)} )}

View File

@ -1,5 +1,5 @@
import styled from "styled-components"; import styled from "styled-components";
import Base from "../themes/base"; import { Base } from "../themes";
const StyledButtonsWrapper = styled.div` const StyledButtonsWrapper = styled.div`
display: grid; display: grid;

View File

@ -22,6 +22,10 @@ const textColor = "#333333",
const StyledExpanderDownIcon = styled(ExpanderDownIcon)` const StyledExpanderDownIcon = styled(ExpanderDownIcon)`
${commonIconsStyles} ${commonIconsStyles}
path { path {
color: ${(props) =>
props.disabled
? props.theme.groupButton.disableColor
: props.theme.groupButton.color};
fill: ${(props) => props.color}; fill: ${(props) => props.color};
} }
`; `;
@ -98,7 +102,6 @@ class GroupButton extends React.Component {
style, style,
} = this.props; } = this.props;
const color = disabled ? disabledTextColor : textColor;
const itemLabel = !isSelect ? label : this.state.selected; const itemLabel = !isSelect ? label : this.state.selected;
const dropDownMaxHeightProp = dropDownMaxHeight const dropDownMaxHeightProp = dropDownMaxHeight
? { maxHeight: dropDownMaxHeight } ? { maxHeight: dropDownMaxHeight }
@ -131,7 +134,7 @@ class GroupButton extends React.Component {
> >
{itemLabel} {itemLabel}
<Caret isOpen={this.state.isOpen}> <Caret isOpen={this.state.isOpen}>
<StyledExpanderDownIcon size="scale" color={color} /> <StyledExpanderDownIcon size="scale" disabled={disabled} />
</Caret> </Caret>
</StyledDropdownToggle> </StyledDropdownToggle>
<DropDown <DropDown

View File

@ -1,3 +1,4 @@
import React from "react";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
@ -35,7 +36,7 @@ SimpleLinkWithDropdown.propTypes = {
}; };
const color = (props) => const color = (props) =>
isDisabled ? props.theme.linkWithDropdown.disableColor : props.color; props.isDisabled ? props.theme.linkWithDropdown.disableColor : props.color;
// eslint-disable-next-line react/prop-types, no-unused-vars // eslint-disable-next-line react/prop-types, no-unused-vars
const ExpanderDownIconWrapper = ({ const ExpanderDownIconWrapper = ({

View File

@ -10,6 +10,22 @@ import CatalogFolderIcon from "../../../../public/images/catalog.folder.react.sv
import CheckboxCheckedIcon from "../../../../public/images/checkbox.checked.react.svg"; import CheckboxCheckedIcon from "../../../../public/images/checkbox.checked.react.svg";
import CheckboxIndeterminateIcon from "../../../../public/images/checkbox.indeterminate.react.svg"; import CheckboxIndeterminateIcon from "../../../../public/images/checkbox.indeterminate.react.svg";
import CheckboxIcon from "../../../../public/images/checkbox.react.svg"; import CheckboxIcon from "../../../../public/images/checkbox.react.svg";
import commonIconsStyles from "../../utils/common-icons-style";
const StyledCheckboxIcon = styled(CheckboxIcon)`
${(props) => props.color && `color: ${props.color}`};
${commonIconsStyles}
`;
const StyledCheckboxCheckedIcon = styled(CheckboxCheckedIcon)`
${(props) => props.color && `color: ${props.color}`};
${commonIconsStyles}
`;
const StyledCheckboxIndeterminateIcon = styled(CheckboxIndeterminateIcon)`
${(props) => props.color && `color: ${props.color}`};
${commonIconsStyles}
`;
var checkboxIcon, var checkboxIcon,
checkboxСheckedIcon, checkboxСheckedIcon,
@ -24,60 +40,60 @@ var checkboxIcon,
treeIcon; treeIcon;
(function () { (function () {
checkboxIcon = getCssFromSvg(ReactDOMServer.renderToString(<CheckboxIcon />)); checkboxIcon = getCssFromSvg(
ReactDOMServer.renderToString(<StyledCheckboxIcon />)
);
сheckboxDisabledIcon = getCssFromSvg( сheckboxDisabledIcon = getCssFromSvg(
ReactDOMServer.renderToString( ReactDOMServer.renderToString(<StyledCheckboxIcon color="#F8F9F9" />)
<CheckboxIcon isfill={true} color="#F8F9F9" />
)
); );
сheckboxHoverIcon = getCssFromSvg( сheckboxHoverIcon = getCssFromSvg(
ReactDOMServer.renderToString(<CheckboxIcon isfill={true} color="white" />) ReactDOMServer.renderToString(<StyledCheckboxIcon color="white" />)
); );
checkboxСheckedIcon = getCssFromSvg( checkboxСheckedIcon = getCssFromSvg(
ReactDOMServer.renderToString(<CheckboxCheckedIcon />) ReactDOMServer.renderToString(<StyledCheckboxCheckedIcon />)
); );
checkboxCheckedDisabledIcon = getCssFromSvg( checkboxCheckedDisabledIcon = getCssFromSvg(
ReactDOMServer.renderToString( ReactDOMServer.renderToString(
<CheckboxCheckedIcon <StyledCheckboxCheckedIcon
isfill={true} //isfill={true}
color="#F8F9F9" color="#F8F9F9"
isStroke={true} //isStroke={true}
stroke="#ECEEF1" //stroke="#ECEEF1"
/> />
) )
); );
checkboxCheckedHoverIcon = getCssFromSvg( checkboxCheckedHoverIcon = getCssFromSvg(
ReactDOMServer.renderToString( ReactDOMServer.renderToString(
<CheckboxCheckedIcon <StyledCheckboxCheckedIcon
isfill={true} //isfill={true}
color="white" color="white"
isStroke={true} //isStroke={true}
stroke="#A3A9AE" //stroke="#A3A9AE"
/> />
) )
); );
сheckboxIndeterminateIcon = getCssFromSvg( сheckboxIndeterminateIcon = getCssFromSvg(
ReactDOMServer.renderToString(<CheckboxIndeterminateIcon />) ReactDOMServer.renderToString(<StyledCheckboxIndeterminateIcon />)
); );
checkboxIndeterminateDisabledIcon = getCssFromSvg( checkboxIndeterminateDisabledIcon = getCssFromSvg(
ReactDOMServer.renderToString( ReactDOMServer.renderToString(
<CheckboxIndeterminateIcon <StyledCheckboxIndeterminateIcon
isfill={true} //isfill={true}
color="#F8F9F9" color="#F8F9F9"
isStroke={true} //isStroke={true}
stroke="#ECEEF1" //stroke="#ECEEF1"
/> />
) )
); );
checkboxIndeterminateHoverIcon = getCssFromSvg( checkboxIndeterminateHoverIcon = getCssFromSvg(
ReactDOMServer.renderToString( ReactDOMServer.renderToString(
<CheckboxIndeterminateIcon <StyledCheckboxIndeterminateIcon
isfill={true} //isfill={true}
color="white" color="white"
isStroke={true} //isStroke={true}
stroke="#A3A9AE" //stroke="#A3A9AE"
/> />
) )
); );

View File

@ -102,12 +102,11 @@ class FilesContent extends React.Component {
} }
const Files = inject(({ auth, initFilesStore }) => { const Files = inject(({ auth, initFilesStore }) => {
const homepage = config.homepage; // "/products/files"; //TODO: add homepage to config?
return { return {
//isDesktop: auth.settingsStore.isDesktopClient, //isDesktop: auth.settingsStore.isDesktopClient,
user: auth.userStore.user, user: auth.userStore.user,
isAuthenticated: auth.isAuthenticated, isAuthenticated: auth.isAuthenticated,
homepage: auth.settingsStore.homepage || homepage, homepage: auth.settingsStore.homepage || config.homepage,
encryptionKeys: auth.settingsStore.encryptionKeys, encryptionKeys: auth.settingsStore.encryptionKeys,
isEncryption: auth.settingsStore.isEncryptionSupport, isEncryption: auth.settingsStore.isEncryptionSupport,
isLoaded: auth.isLoaded && initFilesStore.isLoaded, isLoaded: auth.isLoaded && initFilesStore.isLoaded,

View File

@ -1,4 +1,5 @@
import React from "react"; import React from "react";
import styled from "styled-components";
import Row from "@appserver/components/row"; import Row from "@appserver/components/row";
import LinkWithDropdown from "@appserver/components/link-with-dropdown"; import LinkWithDropdown from "@appserver/components/link-with-dropdown";
import ToggleButton from "@appserver/components/toggle-button"; import ToggleButton from "@appserver/components/toggle-button";
@ -6,6 +7,14 @@ import { StyledLinkRow } from "../StyledPanels";
import AccessComboBox from "./AccessComboBox"; import AccessComboBox from "./AccessComboBox";
import { ShareAccessRights } from "@appserver/common/constants"; import { ShareAccessRights } from "@appserver/common/constants";
import AccessEditIcon from "../../../../public/images/access.edit.react.svg"; import AccessEditIcon from "../../../../public/images/access.edit.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
const StyledAccessEditIcon = styled(AccessEditIcon)`
${commonIconsStyles}
path {
fill: "#A3A9AE";
}
`;
class LinkRow extends React.Component { class LinkRow extends React.Component {
onToggleButtonChange = () => { onToggleButtonChange = () => {
@ -48,11 +57,9 @@ class LinkRow extends React.Component {
isDisabled={isDisabled} isDisabled={isDisabled}
/> />
) : ( ) : (
<AccessEditIcon <StyledAccessEditIcon
size="medium" size="medium"
className="sharing_panel-owner-icon" className="sharing_panel-owner-icon"
isfill={true}
color="#A3A9AE"
/> />
) )
} }

View File

@ -11,7 +11,6 @@ import { LANGUAGE } from "@appserver/common/constants";
// for passing in lng and translations on init // for passing in lng and translations on init
const languages = ["en", "ru"]; const languages = ["en", "ru"];
const homepage = "/products/files"; //TODO: add homepage to config?
i18n i18n
/* /*
@ -49,7 +48,7 @@ i18n
}, },
backend: { backend: {
loadPath: `${homepage}/locales/{{lng}}/{{ns}}.json`, loadPath: `${config.homepage}/locales/{{lng}}/{{ns}}.json`,
}, },
react: { react: {

View File

@ -233,8 +233,7 @@ class FilesStore {
params.push(`${SORT_ORDER}=${filter.sortOrder}`); params.push(`${SORT_ORDER}=${filter.sortOrder}`);
//console.log("window", window.location); //console.log("window", window.location);
const homepage = "/products/files"; //TODO: add homepage to config? history.push(`${config.homepage}/filter?${params.join("&")}`);
history.push(`${homepage}/filter?${params.join("&")}`);
}; };
fetchFiles = (folderId, filter, clearFilter = true) => { fetchFiles = (folderId, filter, clearFilter = true) => {

View File

@ -97,8 +97,7 @@ class InitFilesStore {
setModuleInfo, setModuleInfo,
} = auth.settingsStore; } = auth.settingsStore;
const homepage = "/products/files"; //TODO: add homepage to config? setModuleInfo(config.homepage, "e67be73d-f9ae-4ce1-8fec-1880cb518cb4");
setModuleInfo(homepage, "e67be73d-f9ae-4ce1-8fec-1880cb518cb4");
const requests = []; const requests = [];

View File

@ -14,6 +14,6 @@ const ArticleHeaderContent = ({ isLoaded, currentModuleName }) => {
export default inject(({ auth }) => { export default inject(({ auth }) => {
return { return {
isLoaded: auth.isLoaded, isLoaded: auth.isLoaded,
currentModuleName: "", //TODO: FIX (auth.isLoaded && auth.product.title) || null, currentModuleName: auth.product.title,
}; };
})(observer(ArticleHeaderContent)); })(observer(ArticleHeaderContent));

View File

@ -1,4 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import styled from "styled-components";
import { Router, Switch } from "react-router-dom"; import { Router, Switch } from "react-router-dom";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import NavMenu from "@appserver/common/components/NavMenu"; import NavMenu from "@appserver/common/components/NavMenu";
@ -11,6 +12,7 @@ import Layout from "@appserver/common/components/Layout";
import ScrollToTop from "@appserver/common/components/Layout/ScrollToTop"; import ScrollToTop from "@appserver/common/components/Layout/ScrollToTop";
import history from "@appserver/common/history"; import history from "@appserver/common/history";
import toastr from "@appserver/common/components/Toast"; import toastr from "@appserver/common/components/Toast";
import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader";
import { updateTempContent } from "@appserver/common/utils"; import { updateTempContent } from "@appserver/common/utils";
import { Provider as MobxProvider } from "mobx-react"; import { Provider as MobxProvider } from "mobx-react";
import ThemeProvider from "@appserver/components/theme-provider"; import ThemeProvider from "@appserver/components/theme-provider";
@ -30,15 +32,24 @@ const About = React.lazy(() => import("./components/pages/About"));
const Settings = React.lazy(() => import("./components/pages/Settings")); const Settings = React.lazy(() => import("./components/pages/Settings"));
const ComingSoon = React.lazy(() => import("./components/pages/ComingSoon")); const ComingSoon = React.lazy(() => import("./components/pages/ComingSoon"));
const LoadingBody = styled.div`
padding: 20px;
`;
const LoadingShell = () => (
<LoadingBody>
<RectangleLoader height="100%" />
</LoadingBody>
);
const SettingsRoute = (props) => ( const SettingsRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Settings {...props} /> <Settings {...props} />
</ErrorBoundary> </ErrorBoundary>
</React.Suspense> </React.Suspense>
); );
const PaymentsRoute = (props) => ( const PaymentsRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Payments {...props} /> <Payments {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -46,7 +57,7 @@ const PaymentsRoute = (props) => (
); );
const Error404Route = (props) => ( const Error404Route = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Error404 {...props} /> <Error404 {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -54,7 +65,7 @@ const Error404Route = (props) => (
); );
const HomeRoute = (props) => ( const HomeRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Home {...props} /> <Home {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -62,7 +73,7 @@ const HomeRoute = (props) => (
); );
const LoginRoute = (props) => ( const LoginRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Login {...props} /> <Login {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -70,7 +81,7 @@ const LoginRoute = (props) => (
); );
const PeopleRoute = (props) => ( const PeopleRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<People {...props} /> <People {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -78,7 +89,7 @@ const PeopleRoute = (props) => (
); );
const FilesRoute = (props) => ( const FilesRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<Files {...props} /> <Files {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -86,7 +97,7 @@ const FilesRoute = (props) => (
); );
const AboutRoute = (props) => ( const AboutRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<About {...props} /> <About {...props} />
</ErrorBoundary> </ErrorBoundary>
@ -94,7 +105,7 @@ const AboutRoute = (props) => (
); );
const ComingSoonRoute = (props) => ( const ComingSoonRoute = (props) => (
<React.Suspense fallback={null}> <React.Suspense fallback={<LoadingShell />}>
<ErrorBoundary> <ErrorBoundary>
<ComingSoon {...props} /> <ComingSoon {...props} />
</ErrorBoundary> </ErrorBoundary>

View File

@ -2,7 +2,7 @@ import React, { useCallback } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Text from "@appserver/components/text"; import Text from "@appserver/components/text";
import StyledModuleTile from "./StyledModuleTile"; import StyledModuleTile from "./StyledModuleTile";
import { Link } from "react-router-dom";
const ModuleTile = (props) => { const ModuleTile = (props) => {
// console.log("ModuleTile render", props); // console.log("ModuleTile render", props);
const { title, imageUrl, link, description, isPrimary, onClick } = props; const { title, imageUrl, link, description, isPrimary, onClick } = props;
@ -15,7 +15,7 @@ const ModuleTile = (props) => {
}, },
[link, onClick] [link, onClick]
); );
console.log("imageUrl", imageUrl);
return ( return (
<StyledModuleTile> <StyledModuleTile>
{isPrimary ? ( {isPrimary ? (
@ -29,13 +29,15 @@ const ModuleTile = (props) => {
</div> </div>
<div className="title-text-wrapper"> <div className="title-text-wrapper">
<div onClick={handleClick} className="title-text"> <div className="title-text">
<Text fontSize="36px" className="title-text-header selectable"> <Link to={`${link}`}>
{title} <Text fontSize="36px" className="title-text-header selectable">
</Text> {title}
<Text fontSize="12px" className="title-text-description"> </Text>
{description} <Text fontSize="12px" className="title-text-description">
</Text> {description}
</Text>
</Link>
</div> </div>
</div> </div>
</div> </div>
@ -50,13 +52,11 @@ const ModuleTile = (props) => {
</div> </div>
<div> <div>
<div> <div>
<Text <Link to={`${link}`}>
fontSize="18px" <Text fontSize="18px" className="sub-title-text">
className="sub-title-text" {title}
onClick={handleClick} </Text>
> </Link>
{title}
</Text>
</div> </div>
</div> </div>
</div> </div>

View File

@ -44,7 +44,11 @@ const StyledModuleTile = styled.div`
width: auto; width: auto;
max-width: 50%; max-width: 50%;
} }
a {
text-decoration: none;
}
} }
.title-text { .title-text {
flex: 1 1 auto; flex: 1 1 auto;
padding: 1.25rem; padding: 1.25rem;
@ -74,6 +78,9 @@ const StyledModuleTile = styled.div`
margin: 16px 0 16px 0; margin: 16px 0 16px 0;
text-align: center; text-align: center;
} }
a {
text-decoration: none;
}
} }
`; `;