Merge branch 'feature/virtual-rooms-1.2' of github.com:ONLYOFFICE/AppServer into feature/virtual-rooms-1.2

This commit is contained in:
Timofey Boyko 2022-03-29 10:09:38 +03:00
commit 61abc26732
10 changed files with 276 additions and 227 deletions

View File

@ -1592,7 +1592,7 @@ const Dark = {
contentPadding: "10px 0px 0px 0px", contentPadding: "10px 0px 0px 0px",
arrowMargin: "4px 8px 4px 0px", arrowMargin: "4px 8px 4px 0px",
transform: "rotate(180deg)", transform: "rotate(180deg)",
iconColor: black, iconColor: white,
childrenContent: { childrenContent: {
color: black, color: black,

View File

@ -0,0 +1,76 @@
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { Base } from "@appserver/components/themes";
import { isSmallTablet } from "@appserver/components/utils/device";
const StyledComponent = styled.div`
.combo-button-label {
max-width: 100%;
}
.settings-block {
margin-bottom: 24px;
}
.category-description {
line-height: 20px;
color: #657077;
margin-bottom: 20px;
}
.category-item-wrapper:not(:last-child) {
border-bottom: 1px solid #eceef1;
margin-bottom: 24px;
}
.category-item-description {
color: ${(props) => props.theme.studio.settings.common.descriptionColor};
font-size: 12px;
max-width: 1024px;
}
.category-item-heading {
display: flex;
align-items: center;
padding-bottom: 16px;
}
.category-item-title {
font-weight: bold;
font-size: 16px;
line-height: 22px;
margin-right: 4px;
}
@media (min-width: 600px) {
.settings-block {
max-width: 350px;
height: auto;
}
}
`;
StyledComponent.defaultProps = { theme: Base };
const SettingsPageLayout = ({ children }) => {
const [mobileView, setMobileView] = useState();
const checkInnerWidth = () => {
if (isSmallTablet()) {
setMobileView(true);
} else {
setMobileView(false);
}
};
useEffect(() => {
window.addEventListener("resize", checkInnerWidth);
return () => window.removeEventListener("resize", checkInnerWidth);
}, [checkInnerWidth]);
//TODO: Add menu, hide along the route
const isMobile = !!(isSmallTablet() || mobileView);
return <>{children(isMobile)}</>;
};
export default SettingsPageLayout;

View File

@ -0,0 +1,37 @@
import React from "react";
import styled from "styled-components";
import { Base } from "@appserver/components/themes";
const StyledComponent = styled.div`
.combo-button-label {
max-width: 100%;
}
.category-item-wrapper {
padding-top: 20px;
.category-item-heading {
padding-bottom: 8px;
}
.category-item-description {
color: #657077;
font-size: 13px;
max-width: 1024px;
}
.inherit-title-link {
margin-right: 4px;
font-size: 16px;
font-weight: 700;
}
}
`;
StyledComponent.defaultProps = { theme: Base };
const SettingsPageMobileView = ({ children }) => {
return <StyledComponent>{children}</StyledComponent>;
};
export default SettingsPageMobileView;

View File

@ -1,123 +0,0 @@
import React from "react";
import { withTranslation } from "react-i18next";
import styled from "styled-components";
import Text from "@appserver/components/text";
import Box from "@appserver/components/box";
import Link from "@appserver/components/link";
import ArrowRightIcon from "../../../../../../public/images/arrow.right.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
import { combineUrl } from "@appserver/common/utils";
import { inject, observer } from "mobx-react";
import { AppServerConfig } from "@appserver/common/constants";
import withCultureNames from "@appserver/common/hoc/withCultureNames";
import { Base } from "@appserver/components/themes";
import history from "@appserver/common/history";
const StyledArrowRightIcon = styled(ArrowRightIcon)`
${commonIconsStyles}
path {
fill: ${(props) => props.theme.studio.settings.common.arrowColor};
}
`;
StyledArrowRightIcon.defaultProps = { theme: Base };
const StyledComponent = styled.div`
.combo-button-label {
max-width: 100%;
}
.category-item-wrapper {
padding-top: 20px;
.category-item-heading {
padding-bottom: 8px;
}
.category-item-description {
color: #657077;
font-size: 13px;
max-width: 1024px;
}
.inherit-title-link {
margin-right: 4px;
font-size: 16px;
font-weight: 700;
}
}
`;
StyledComponent.defaultProps = { theme: Base };
const CustomizationNavbar = ({ t, theme, helpUrlCommonSettings }) => {
const onClickLink = (e) => {
e.preventDefault();
history.push(e.target.pathname);
};
return (
<StyledComponent>
<div className="category-item-wrapper">
<div className="category-item-heading">
<Link
className="inherit-title-link header"
onClick={onClickLink}
truncate={true}
href={combineUrl(
AppServerConfig.proxyURL,
"/settings/common/customization/language-and-time-zone"
)}
>
{t("StudioTimeLanguageSettings")}
</Link>
<StyledArrowRightIcon size="small" color="#333333" />
</div>
<Text className="category-item-description">
{t("LanguageAndTimeZoneSettingsDescription")}
</Text>
<Box paddingProp="10px 0 3px 0">
<Link
color={theme.studio.settings.common.linkColorHelp}
target="_blank"
isHovered={true}
href={helpUrlCommonSettings}
>
{t("Common:LearnMore")}
</Link>
</Box>
</div>
<div className="category-item-wrapper">
<div className="category-item-heading">
<Link
truncate={true}
className="inherit-title-link header"
onClick={onClickLink}
href={combineUrl(
AppServerConfig.proxyURL,
"/settings/common/customization/custom-titles"
)}
>
{t("CustomTitlesWelcome")}
</Link>
<StyledArrowRightIcon size="small" color="#333333" />
</div>
<Text className="category-item-description">
{t("CustomTitlesSettingsDescription")}
</Text>
</div>
</StyledComponent>
);
};
export default inject(({ auth }) => {
const { helpUrlCommonSettings, theme } = auth.settingsStore;
return {
theme,
helpUrlCommonSettings,
};
})(
withCultureNames(
observer(withTranslation(["Settings", "Common"])(CustomizationNavbar))
)
);

View File

@ -1,15 +1,15 @@
import React, { useEffect, useState } from "react"; import React from "react";
import { withTranslation } from "react-i18next"; import { withTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import withCultureNames from "@appserver/common/hoc/withCultureNames"; import withCultureNames from "@appserver/common/hoc/withCultureNames";
import CustomizationNavbar from "./customization-navbar"; import LanguageAndTimeZone from "./settingsCustomization/language-and-time-zone";
import LanguageAndTimeZone from "./language-and-time-zone"; import CustomTitles from "./settingsCustomization/custom-titles";
import CustomTitles from "./custom-titles"; import PortalRenaming from "./settingsCustomization/portal-renaming";
import PortalRenaming from "./portal-renaming"; import SettingsPageLayout from "./SettingsPageLayout";
import { Base } from "@appserver/components/themes"; import SettingsPageMobileView from "./SettingsPageMobileView";
import { isSmallTablet } from "@appserver/components/utils/device";
import { Base } from "@appserver/components/themes";
import commonSettingsStyles from "../../utils/commonSettingsStyles";
const StyledComponent = styled.div` const StyledComponent = styled.div`
.combo-button-label { .combo-button-label {
max-width: 100%; max-width: 100%;
@ -60,38 +60,25 @@ const StyledComponent = styled.div`
StyledComponent.defaultProps = { theme: Base }; StyledComponent.defaultProps = { theme: Base };
const Customization = ({ t }) => { const Customization = ({ t }) => {
const [mobileView, setMobileView] = useState(); return (
<SettingsPageLayout>
const checkInnerWidth = () => { {(isMobile) =>
if (window.innerWidth < 600) { isMobile ? (
setMobileView(true); <SettingsPageMobileView>
} else { <LanguageAndTimeZone isMobileView={isMobile} />
setMobileView(false); {/* <CustomTitles /> */}
} </SettingsPageMobileView>
};
useEffect(() => {
window.addEventListener("resize", checkInnerWidth);
return () => window.removeEventListener("resize", checkInnerWidth);
}, [checkInnerWidth]);
return isSmallTablet() || mobileView ? (
<CustomizationNavbar />
) : ( ) : (
<StyledComponent> <StyledComponent>
<div className="category-description">{`${t( <div className="category-description">{`${t(
"Settings:CustomizationDescription" "Settings:CustomizationDescription"
)}`}</div> )}`}</div>
<div className="category-item-wrapper"> <LanguageAndTimeZone isMobileView={isMobile} />
<LanguageAndTimeZone /> {/* <CustomTitles /> */}
</div>
{/* <div className="category-item-wrapper">
<CustomTitles />
</div>
<div className="category-item-wrapper">
<PortalRenaming />
</div> */}
</StyledComponent> </StyledComponent>
)
}
</SettingsPageLayout>
); );
}; };

View File

@ -8,10 +8,10 @@ import TextInput from "@appserver/components/text-input";
import HelpButton from "@appserver/components/help-button"; import HelpButton from "@appserver/components/help-button";
import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; import SaveCancelButtons from "@appserver/components/save-cancel-buttons";
import { showLoader, hideLoader } from "@appserver/common/utils"; import { showLoader, hideLoader } from "@appserver/common/utils";
import { saveToSessionStorage, getFromSessionStorage } from "../../utils"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils";
import { setDocumentTitle } from "../../../../../helpers/utils"; import { setDocumentTitle } from "../../../../../../helpers/utils";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { CustomTitlesTooltip } from "./sub-components/common-tooltips"; import { CustomTitlesTooltip } from "../sub-components/common-tooltips";
const StyledComponent = styled.div` const StyledComponent = styled.div`
.settings-block { .settings-block {

View File

@ -8,20 +8,27 @@ import Loader from "@appserver/components/loader";
import toastr from "@appserver/components/toast/toastr"; import toastr from "@appserver/components/toast/toastr";
import HelpButton from "@appserver/components/help-button"; import HelpButton from "@appserver/components/help-button";
import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; import SaveCancelButtons from "@appserver/components/save-cancel-buttons";
import { saveToSessionStorage, getFromSessionStorage } from "../../utils"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils";
import { setDocumentTitle } from "../../../../../helpers/utils"; import { setDocumentTitle } from "../../../../../../helpers/utils";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { LANGUAGE } from "@appserver/common/constants"; import { LANGUAGE } from "@appserver/common/constants";
import { convertLanguage } from "@appserver/common/utils"; import { convertLanguage } from "@appserver/common/utils";
import withCultureNames from "@appserver/common/hoc/withCultureNames"; import withCultureNames from "@appserver/common/hoc/withCultureNames";
import { LanguageTimeSettingsTooltip } from "./sub-components/common-tooltips"; import { LanguageTimeSettingsTooltip } from "../sub-components/common-tooltips";
import { combineUrl } from "@appserver/common/utils"; import { combineUrl } from "@appserver/common/utils";
import { AppServerConfig } from "@appserver/common/constants"; import { AppServerConfig } from "@appserver/common/constants";
import config from "../../../../../../package.json"; import config from "../../../../../../../package.json";
import history from "@appserver/common/history"; import history from "@appserver/common/history";
import { isMobileOnly } from "react-device-detect"; import { isMobileOnly } from "react-device-detect";
import Scrollbar from "@appserver/components/scrollbar"; import Scrollbar from "@appserver/components/scrollbar";
import Text from "@appserver/components/text";
import Box from "@appserver/components/box";
import Link from "@appserver/components/link";
import ArrowRightIcon from "../../../../../../../public/images/arrow.right.react.svg";
import { isSmallTablet } from "@appserver/components/utils/device";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
import { Base } from "@appserver/components/themes";
import checkScrollSettingsBlock from "../utils";
const mapTimezonesToArray = (timezones) => { const mapTimezonesToArray = (timezones) => {
return timezones.map((timezone) => { return timezones.map((timezone) => {
return { key: timezone.id, label: timezone.displayName }; return { key: timezone.id, label: timezone.displayName };
@ -38,6 +45,15 @@ const paddingSectionWrapperContent = "22px";
const saveCancelButtons = "56px"; const saveCancelButtons = "56px";
const flex = "4px"; const flex = "4px";
const StyledArrowRightIcon = styled(ArrowRightIcon)`
${commonIconsStyles}
path {
fill: ${(props) => props.theme.studio.settings.common.arrowColor};
}
`;
StyledArrowRightIcon.defaultProps = { theme: Base };
const StyledScrollbar = styled(Scrollbar)` const StyledScrollbar = styled(Scrollbar)`
height: calc( height: calc(
100vh - 100vh -
@ -144,6 +160,7 @@ class LanguageAndTimeZone extends React.Component {
timezoneDefaultFromSessionStorage = getFromSessionStorage( timezoneDefaultFromSessionStorage = getFromSessionStorage(
"timezoneDefault" "timezoneDefault"
); );
setDocumentTitle(t("Customization")); setDocumentTitle(t("Customization"));
this.state = { this.state = {
@ -158,10 +175,7 @@ class LanguageAndTimeZone extends React.Component {
isLoadingGreetingRestore: false, isLoadingGreetingRestore: false,
hasChanged: false, hasChanged: false,
showReminder: false, showReminder: false,
sectionWidth: null,
hasScroll: false, hasScroll: false,
heightSettingsBlock: null,
heightScrollBody: null,
}; };
} }
@ -221,7 +235,13 @@ class LanguageAndTimeZone extends React.Component {
} }
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
const { timezones, timezoneDefault, languageDefault } = this.state; const {
timezones,
timezoneDefault,
languageDefault,
hasScroll,
} = this.state;
const { const {
i18n, i18n,
language, language,
@ -230,8 +250,16 @@ class LanguageAndTimeZone extends React.Component {
cultureNames, cultureNames,
} = this.props; } = this.props;
this.checkHeightSettingsBlock(); const checkScroll = checkScrollSettingsBlock();
window.addEventListener("resize", this.checkHeightSettingsBlock);
window.addEventListener("resize", checkScroll);
const scrollLngTZSettings = checkScroll();
if (scrollLngTZSettings !== hasScroll) {
this.setState({
hasScroll: scrollLngTZSettings,
});
}
// TODO: Remove div with height 64 and remove settings-mobile class // TODO: Remove div with height 64 and remove settings-mobile class
const settingsMobile = document.getElementsByClassName( const settingsMobile = document.getElementsByClassName(
@ -268,7 +296,7 @@ class LanguageAndTimeZone extends React.Component {
window.removeEventListener( window.removeEventListener(
"resize", "resize",
this.checkInnerWidth, this.checkInnerWidth,
this.checkHeightSettingsBlock checkScrollSettingsBlock
); );
} }
@ -373,7 +401,7 @@ class LanguageAndTimeZone extends React.Component {
}; };
checkInnerWidth = () => { checkInnerWidth = () => {
if (window.innerWidth > 600) { if (!isSmallTablet()) {
history.push( history.push(
combineUrl( combineUrl(
AppServerConfig.proxyURL, AppServerConfig.proxyURL,
@ -385,50 +413,19 @@ class LanguageAndTimeZone extends React.Component {
} }
}; };
checkHeightSettingsBlock = () => { onClickLink = (e) => {
if (this.settingsDiv && this.scrollBody) return; e.preventDefault();
history.push(e.target.pathname);
this.settingsDiv = document.getElementsByClassName("settings-block")[0];
if (!this.settingsDiv) return;
this.scrollBody = this.settingsDiv.closest(".scroll-body");
if (!this.scrollBody) return;
const height = getComputedStyle(this.settingsDiv).height.slice(0, -2);
const heightScrollBody = getComputedStyle(this.scrollBody).height.slice(
0,
-2
);
if (
this.state.heightSettingsBlock === height &&
this.state.heightScrollBody === heightScrollBody
) {
return;
}
this.setState({
heightSettingsBlock: height,
});
this.setState({
heightScrollBody: heightScrollBody,
});
if (parseInt(height, 10) > parseInt(heightScrollBody, 10)) {
this.setState({
hasScroll: true,
});
} else {
this.setState({
hasScroll: false,
});
}
}; };
render() { render() {
const { t, theme, cultureNames } = this.props; const {
t,
theme,
cultureNames,
isMobileView,
helpUrlCommonSettings,
} = this.props;
const { const {
isLoadedData, isLoadedData,
language, language,
@ -443,6 +440,37 @@ class LanguageAndTimeZone extends React.Component {
<LanguageTimeSettingsTooltip theme={theme} t={t} /> <LanguageTimeSettingsTooltip theme={theme} t={t} />
); );
const isMobileViewLanguageTimeSettings = (
<div className="category-item-wrapper">
<div className="category-item-heading">
<Link
className="inherit-title-link header"
onClick={this.onClickLink}
truncate={true}
href={combineUrl(
AppServerConfig.proxyURL,
"/settings/common/customization/language-and-time-zone"
)}
>
{t("StudioTimeLanguageSettings")}
</Link>
<StyledArrowRightIcon size="small" color="#333333" />
</div>
<Text className="category-item-description">
{t("LanguageAndTimeZoneSettingsDescription")}
</Text>
<Box paddingProp="10px 0 3px 0">
<Link
color={theme.studio.settings.common.linkColorHelp}
target="_blank"
isHovered={true}
href={helpUrlCommonSettings}
>
{t("Common:LearnMore")}
</Link>
</Box>
</div>
);
const settingsBlock = ( const settingsBlock = (
<div className="settings-block"> <div className="settings-block">
<FieldContainer <FieldContainer
@ -493,9 +521,12 @@ class LanguageAndTimeZone extends React.Component {
return !isLoadedData ? ( return !isLoadedData ? (
<Loader className="pageLoader" type="rombs" size="40px" /> <Loader className="pageLoader" type="rombs" size="40px" />
) : isMobileView ? (
isMobileViewLanguageTimeSettings
) : ( ) : (
<StyledComponent hasScroll={hasScroll}> <StyledComponent hasScroll={hasScroll}>
{this.checkInnerWidth() && ( {/* Added isMobileView */}
{this.checkInnerWidth() && !isMobileView && (
<div className="category-item-heading"> <div className="category-item-heading">
<div className="category-item-title"> <div className="category-item-title">
{t("StudioTimeLanguageSettings")} {t("StudioTimeLanguageSettings")}
@ -507,8 +538,7 @@ class LanguageAndTimeZone extends React.Component {
/> />
</div> </div>
)} )}
{(isMobileOnly && window.innerWidth < 600) || {(isMobileOnly && isSmallTablet()) || isSmallTablet() ? (
window.innerWidth < 600 ? (
<StyledScrollbar stype="smallBlack">{settingsBlock}</StyledScrollbar> <StyledScrollbar stype="smallBlack">{settingsBlock}</StyledScrollbar>
) : ( ) : (
<> {settingsBlock}</> <> {settingsBlock}</>
@ -541,6 +571,7 @@ export default inject(({ auth, setup }) => {
//getPortalCultures, //getPortalCultures,
getPortalTimezones, getPortalTimezones,
getCurrentCustomSchema, getCurrentCustomSchema,
helpUrlCommonSettings,
} = auth.settingsStore; } = auth.settingsStore;
const { user } = auth.userStore; const { user } = auth.userStore;
@ -562,6 +593,7 @@ export default inject(({ auth, setup }) => {
setLanguageAndTime, setLanguageAndTime,
getCurrentCustomSchema, getCurrentCustomSchema,
getPortalTimezones, getPortalTimezones,
helpUrlCommonSettings,
}; };
})( })(
withCultureNames( withCultureNames(

View File

@ -23,7 +23,7 @@ const StyledComponent = styled.div`
`; `;
const PortalRenaming = ({ t, theme, sectionWidth }) => { const PortalRenaming = ({ t, theme, sectionWidth }) => {
// todo: Изменить на false // TODO: Change false
const [isLoadedData, setIsLoadedData] = useState(true); const [isLoadedData, setIsLoadedData] = useState(true);
const onSavePortalRename = () => { const onSavePortalRename = () => {

View File

@ -0,0 +1,38 @@
const checkScrollSettingsBlock = () => {
let initHeight = 0;
let initHeightScroll = 0;
const settingsDiv = document.getElementsByClassName("settings-block")?.[0];
const scrollBody = settingsDiv?.closest(".scroll-body");
const height = parseInt(
!!settingsDiv ? getComputedStyle(settingsDiv).height.slice(0, -2) : 0,
0
);
const heightScroll = parseInt(
!!scrollBody ? getComputedStyle(scrollBody).height.slice(0, -2) : 0,
0
);
return () => {
if (height === initHeight && heightScroll !== initHeightScroll) {
return;
}
if (height !== initHeight) {
initHeight = height;
}
if (heightScroll !== initHeightScroll) {
initHeightScroll = heightScroll;
}
if (height > heightScroll) {
return true;
} else {
return false;
}
};
};
export default checkScrollSettingsBlock;

View File

@ -19,9 +19,11 @@ const CustomizationSettings = lazy(() =>
import("./categories/common/customization") import("./categories/common/customization")
); );
const LanguageAndTimeZoneSettings = lazy(() => const LanguageAndTimeZoneSettings = lazy(() =>
import("./categories/common/language-and-time-zone") import("./categories/common/settingsCustomization/language-and-time-zone")
);
const CustomTitles = lazy(() =>
import("./categories/common/settingsCustomization/custom-titles")
); );
const CustomTitles = lazy(() => import("./categories/common/custom-titles"));
const TeamTemplate = lazy(() => import("./categories/common/team-template")); const TeamTemplate = lazy(() => import("./categories/common/team-template"));
const ThirdPartyServices = lazy(() => const ThirdPartyServices = lazy(() =>
import("./categories/integration/thirdPartyServicesSettings") import("./categories/integration/thirdPartyServicesSettings")