Merge pull request #689 from ONLYOFFICE/feature/admin-messages

Feature/admin messages
This commit is contained in:
Viktor Fomin 2022-06-07 13:44:28 +03:00 committed by GitHub
commit d3f37b37be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 231 additions and 12 deletions

View File

@ -504,6 +504,11 @@ class SettingsStore {
this.ipRestrictionEnable = res.enable;
};
setMessageSettings = async (turnOn) => {
await api.settings.setMessageSettings(turnOn);
this.enableAdmMess = turnOn;
};
setIsBurgerLoading = (isBurgerLoading) => {
this.isBurgerLoading = isBurgerLoading;
};

View File

@ -1921,7 +1921,7 @@ const Base = {
header: {
backgroundColor: "#0F4071",
recoveryColor: "#27537F",
linkColor: "#7a95b0",
productColor: white,
},

View File

@ -1922,7 +1922,7 @@ const Dark = {
header: {
backgroundColor: "#1f1f1f ",
recoveryColor: "#4C4C4C",
linkColor: "#606060",
productColor: "#eeeeee",
},

View File

@ -15,6 +15,9 @@
"AdministratorsAddedSuccessfully": "Administrators added successfully",
"AdministratorsRemovedSuccessfully": "Administrators removed successfully",
"Admins": "Admins",
"AdminsMessage": "Administrator Message Settings",
"AdminsMessageDescription": "Administrator Message Settings is a way to contact the portal administrator.",
"AdminsMessageHelper": "Enable this option to display the contact form on the Sign In page so that people could send the message to the portal administrator in case they have troubles accessing the portal.",
"AllDomains": "Any domains",
"AutoBackup": "Automatic backup",
"AutoBackupDescription": "Use this option for automatic backup of the portal data.",

View File

@ -15,6 +15,9 @@
"AdministratorsAddedSuccessfully": "Администраторы успешно добавлены",
"AdministratorsRemovedSuccessfully": "Администраторы успешно удалены",
"Admins": "Администраторы",
"AdminsMessage": "Настройки сообщений администратору",
"AdminsMessageDescription": "Настройки сообщений администратору это способ связаться с администратором портала.",
"AdminsMessageHelper": "Включите эту опцию для отображения формы связи на странице Входа, чтобы пользователи могли отправить сообщение администратору портала в случае, если у них возникают проблемы со входом на портал.",
"AllDomains": "Любые домены",
"AutoBackup": "Автоматическое резервное копирование",
"AutoBackupDescription": "Используйте эту опцию для автоматического выполнения резервного копирования данных портала.",

View File

@ -13,10 +13,9 @@ const Header = styled.header`
align-items: left;
background-color: ${(props) => props.theme.header.backgroundColor};
display: flex;
width: calc(100vw - 64px);
width: 100vw;
height: 48px;
justify-content: left;
padding: 0 32px;
justify-content: center;
.header-items-wrapper {
width: 960px;
@ -25,7 +24,7 @@ const Header = styled.header`
width: 475px;
}
@media (max-width: 375px) {
width: 311px;
padding: 0 16px;
}
}
@ -110,7 +109,7 @@ export default inject(({ auth }) => {
const { enableAdmMess, wizardToken } = settingsStore;
return {
enableAdmMess,
wizardToken: wizardToken || "/",
wizardToken,
isAuthenticated,
isLoaded,
};

View File

@ -9,6 +9,7 @@ import UnionIcon from "../svg/union.react.svg";
import RecoverAccessModalDialog from "./recover-access-modal-dialog";
import { sendRecoverRequest } from "@appserver/common/api/settings/index";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
import { Base } from "@appserver/components/themes";
const StyledUnionIcon = styled(UnionIcon)`
${commonIconsStyles}
@ -16,6 +17,7 @@ const StyledUnionIcon = styled(UnionIcon)`
const RecoverContainer = styled(Box)`
cursor: pointer;
background-color: ${(props) => props.theme.header.recoveryColor};
.recover-icon {
@media (max-width: 450px) {
@ -29,6 +31,8 @@ const RecoverContainer = styled(Box)`
}
`;
RecoverContainer.defaultProps = { theme: Base };
const RecoverAccess = ({ t }) => {
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
@ -88,7 +92,6 @@ const RecoverAccess = ({ t }) => {
alignItems="center"
>
<RecoverContainer
backgroundProp="#27537F"
heightProp="100%"
displayProp="flex"
onClick={onRecoverClick}

View File

@ -0,0 +1,177 @@
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { withRouter } from "react-router";
import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import RadioButtonGroup from "@appserver/components/radio-button-group";
import Text from "@appserver/components/text";
import Link from "@appserver/components/link";
import toastr from "@appserver/components/toast/toastr";
import { getLanguage } from "@appserver/common/utils";
import { LearnMoreWrapper } from "../StyledSecurity";
import { size } from "@appserver/components/utils/device";
import { saveToSessionStorage, getFromSessionStorage } from "../../../utils";
import SaveCancelButtons from "@appserver/components/save-cancel-buttons";
import isEqual from "lodash/isEqual";
const MainContainer = styled.div`
width: 100%;
.page-subtitle {
margin-bottom: 10px;
}
.box {
margin-bottom: 24px;
}
`;
const AdminMessage = (props) => {
const {
t,
history,
enableAdmMess,
setMessageSettings,
initSettings,
isInit,
} = props;
const [type, setType] = useState("");
const [showReminder, setShowReminder] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const getSettings = () => {
const currentSettings = getFromSessionStorage(
"currentAdminMessageSettings"
);
const enable = enableAdmMess ? "enable" : "disabled";
saveToSessionStorage("defaultAdminMessageSettings", enable);
if (currentSettings) {
setType(currentSettings);
} else {
setType(enable);
}
};
useEffect(() => {
checkWidth();
if (!isInit) initSettings().then(() => setIsLoading(true));
else setIsLoading(true);
window.addEventListener("resize", checkWidth);
return () => window.removeEventListener("resize", checkWidth);
}, []);
useEffect(() => {
if (!isInit) return;
getSettings();
}, [isLoading]);
useEffect(() => {
if (!isLoading) return;
const defaultSettings = getFromSessionStorage(
"defaultAdminMessageSettings"
);
saveToSessionStorage("currentAdminMessageSettings", type);
if (isEqual(defaultSettings, type)) {
setShowReminder(false);
} else {
setShowReminder(true);
}
}, [type]);
const checkWidth = () => {
window.innerWidth > size.smallTablet &&
history.location.pathname.includes("admin-message") &&
history.push("/settings/security/access-portal");
};
const onSelectType = (e) => {
if (type !== e.target.value) {
setType(e.target.value);
}
};
const onSaveClick = () => {
setMessageSettings(type);
toastr.success(t("SuccessfullySaveSettingsMessage"));
saveToSessionStorage("defaultAdminMessageSettings", type);
setShowReminder(false);
};
const onCancelClick = () => {
const defaultSettings = getFromSessionStorage(
"defaultAdminMessageSettings"
);
setType(defaultSettings);
setShowReminder(false);
};
const lng = getLanguage(localStorage.getItem("language") || "en");
return (
<MainContainer>
<LearnMoreWrapper>
<Text className="page-subtitle">{t("AdminsMessageHelper")}</Text>
<Link
color="#316DAA"
target="_blank"
isHovered
href={`https://helpcenter.onlyoffice.com/${lng}/administration/configuration.aspx#ChangingSecuritySettings_block`}
>
{t("Common:LearnMore")}
</Link>
</LearnMoreWrapper>
<RadioButtonGroup
className="box"
fontSize="13px"
fontWeight="400"
name="group"
orientation="vertical"
spacing="8px"
options={[
{
label: t("Disabled"),
value: "disabled",
},
{
label: t("Common:Enable"),
value: "enable",
},
]}
selected={type}
onClick={onSelectType}
/>
<SaveCancelButtons
className="save-cancel-buttons"
onSaveClick={onSaveClick}
onCancelClick={onCancelClick}
showReminder={showReminder}
reminderTest={t("YouHaveUnsavedChanges")}
saveButtonLabel={t("Common:SaveButton")}
cancelButtonLabel={t("Common:CancelButton")}
displaySettings={true}
hasScroll={false}
/>
</MainContainer>
);
};
export default inject(({ auth, setup }) => {
const { enableAdmMess, setMessageSettings } = auth.settingsStore;
const { initSettings, isInit } = setup;
return {
enableAdmMess,
setMessageSettings,
initSettings,
isInit,
};
})(withTranslation(["Settings", "Common"])(withRouter(observer(AdminMessage))));

View File

@ -8,6 +8,7 @@ import TfaSection from "./tfa";
import PasswordStrengthSection from "./passwordStrength";
import TrustedMailSection from "./trustedMail";
import IpSecuritySection from "./ipSecurity";
import AdminMessageSection from "./adminMessage";
import MobileView from "./mobileView";
import CategoryWrapper from "../sub-components/category-wrapper";
import { size } from "@appserver/components/utils/device";
@ -67,6 +68,14 @@ const AccessPortal = (props) => {
tooltipTitle={t("IPSecurityDescription")}
/>
<IpSecuritySection />
<hr />
<CategoryWrapper
t={t}
title={t("AdminsMessage")}
tooltipTitle={t("AdminsMessageDescription")}
tooltipUrl={`https://helpcenter.onlyoffice.com/${lng}/administration/configuration.aspx#ChangingSecuritySettings_block`}
/>
<AdminMessageSection />
</MainContainer>
);
};

View File

@ -43,6 +43,12 @@ const MobileView = (props) => {
url="/settings/security/access-portal/ip"
onClickLink={onClickLink}
/>
<MobileCategoryWrapper
title={t("AdminsMessage")}
subtitle={t("AdminsMessageDescription")}
url="/settings/security/access-portal/admin-message"
onClickLink={onClickLink}
/>
</MainContainer>
);
};

View File

@ -17,6 +17,9 @@ const TrustedMailPage = lazy(() =>
const IpSecurityPage = lazy(() =>
import("./categories/security/access-portal/ipSecurity")
);
const AdminMessagePage = lazy(() =>
import("./categories/security/access-portal/adminMessage")
);
const CommonSettings = lazy(() => import("./categories/common/index.js"));
@ -99,6 +102,10 @@ const IP_SECURITY_PAGE_URL = combineUrl(
PROXY_BASE_URL,
"/security/access-portal/ip"
);
const ADMIN_MESSAGE_PAGE_URL = combineUrl(
PROXY_BASE_URL,
"/security/access-portal/admin-message"
);
const ADMINS_URL = combineUrl(PROXY_BASE_URL, "/security/access-rights/admins");
const THIRD_PARTY_URL = combineUrl(
@ -154,6 +161,11 @@ const Settings = (props) => {
component={TrustedMailPage}
/>
<Route exact path={IP_SECURITY_PAGE_URL} component={IpSecurityPage} />
<Route
exact
path={ADMIN_MESSAGE_PAGE_URL}
component={AdminMessagePage}
/>
<Route exact path={THIRD_PARTY_URL} component={ThirdPartyServices} />
<Route

View File

@ -83,6 +83,12 @@ export const settingsTree = [
link: "ip",
tKey: "IPSecurity",
},
{
key: "1-0-4",
icon: "",
link: "admin-message",
tKey: "AdminsMessage",
},
],
},
{

View File

@ -218,10 +218,6 @@ class SettingsSetupStore {
const res = await api.settings.setMailDomainSettings(dnsName, enable);
};
setMessageSettings = async (turnOn) => {
const res = await api.settings.setMessageSettings(turnOn);
};
setCookieSettings = async (lifeTime) => {
const res = await api.settings.setCookieSettings(lifeTime);
};