Merge branch 'develop' into feature/shared-redesign-third-party

This commit is contained in:
Alexey Safronov 2022-10-20 11:36:22 +03:00
commit 0d680dd005
58 changed files with 1678 additions and 636 deletions

View File

@ -724,20 +724,30 @@ public class TariffService : ITariffService
CreateOn = DateTime.UtcNow
};
efTariff.CustomerId = efTariff.CustomerId == null ? "" : efTariff.CustomerId;
if (efTariff.Id == default)
{
efTariff.Id = (-tenant);
}
if (efTariff.CustomerId == default)
{
efTariff.CustomerId = "";
}
efTariff = dbContext.AddOrUpdate(r => r.Tariffs, efTariff);
dbContext.SaveChanges();
var tariffRows = tariffInfo.Quotas.Select(q => new DbTariffRow
foreach (var q in tariffInfo.Quotas)
{
dbContext.AddOrUpdate(r => r.TariffRows, new DbTariffRow
{
TariffId = efTariff.Id,
Quota = q.Id,
Quantity = q.Quantity,
Tenant = tenant
});
}
dbContext.TariffRows.AddRange(tariffRows);
dbContext.SaveChanges();
inserted = true;

View File

@ -1,9 +1,10 @@
{
"AboutCompanyAddressTitle": "address",
"AboutCompanyEmailTitle": "email",
"AboutCompanyAddressTitle": "Address",
"AboutCompanyEmailTitle": "E-mail",
"AboutCompanyTelTitle": "tel.",
"AboutHeader": "About this program",
"DocumentManagement": "Document management",
"OnlineEditors": "Online editors",
"Site": "Site",
"SoftwareLicense": "Software license"
}

View File

@ -45,10 +45,11 @@
"BackupList": "Backup List",
"BackupListWarningText": "If you delete any items from the list, their corresponding files will also be deleted. This action cannot be undone. To delete all the files use the link:",
"Branding": "Branding",
"BrandingSectionDescription": "Specify your company information, add links to external resources, and email addresses displayed within the online office interface.",
"BrandingSubtitle": "Use this option to provide on-brand experience to your users. These settings will be effective for all of your portals.",
"BrowserNoCanvasSupport": "Your browser does not support the HTML5 canvas tag.",
"BreakpointWarningText": "This section is only available in desktop version",
"BreakpointWarningTextPrompt": "Please use the desktop site to access",
"BreakpointWarningTextPrompt": "Please use the desktop site to access <1>{{content}}</1>",
"ByApp": "By authenticator app",
"BySms": "By sms",
"ChangeLogoButton": "Change Logo",
@ -58,6 +59,7 @@
"ClearBackupList": "Delete all backups",
"CompanyInfoSettings": "Company info settings",
"CompanyNameForCanvasLogo": "Company name",
"CompanyInfoSettingsDescription": "This information will be displayed in the <1>{{link}}</1> window.",
"ConfirmEmailSended": "Confirmation e-mail has been sent to {{ownerName}}",
"CustomDomains": "Custom domains",
"CustomTitles": "Custom titles",
@ -161,7 +163,7 @@
"RestoreBackupHelpNote": "Select the storage where the data is saved, enter necessary details and check the <strong>Send notification to portal users</strong> to alert your portal users about the backup/restore operations.",
"RestoreBackupResetInfoWarningText": "All current passwords will be reset. Portal users will get an email with the access restoration link.",
"RestoreBackupWarningText": "The portal will become unavailable during the restore process. After the restore is complete all the changes made after the date of the selected restore point will be lost.",
"RestoreDefaultButton": "Restore to Default",
"RestoreDefaultButton": "Restore to default",
"RoomsModule": "Backup room",
"RoomsModuleDescription": "You may create a new room specifically for the backup, choose one of the existing rooms, or save the copy in their {{roomName}} room.",
"SelectFileInGZFormat": "Select the file in .GZ format",
@ -190,7 +192,6 @@
"Template": "Template",
"TemporaryStorage": "Temporary storage",
"TemporaryStorageDescription": "Backup is stored in the 'Backup' section, you will be able to download it within 24 hours after creating.",
"TheAppearanceSettings": "the Appearance settings",
"ThirdPartyAuthorization": "Third-party Authorization",
"ThirdPartyBodyDescription": "Detailed instructions in our <2>Help Center</2>.",
"ThirdPartyBottomDescription": "Need help? Contact our <2>Support Team.</2>",

View File

@ -76,6 +76,7 @@ export default function withFileActions(WrappedFileItem) {
setStartDrag,
isPrivacy,
isTrashFolder,
isRoomsFolder,
isArchiveFolder,
item,
setBufferSelection,
@ -91,6 +92,7 @@ export default function withFileActions(WrappedFileItem) {
if (
isPrivacy ||
isTrashFolder ||
isRoomsFolder ||
isArchiveFolder ||
(!draggable && !isFileName && !isActive) ||
window.innerWidth < 1025 ||

View File

@ -1,11 +1,10 @@
import React from "react";
import { withTranslation } from "react-i18next";
import { Trans, withTranslation } from "react-i18next";
import StyledBreakpointWarning from "./sub-components/StyledBreakpointWarning";
import Loader from "./sub-components/loader";
const BreakpointWarning = ({ t, content, isLoading }) => {
return isLoading ? (
const BreakpointWarning = ({ t, sectionName, tReady }) => {
return !tReady ? (
<Loader />
) : (
<StyledBreakpointWarning>
@ -14,7 +13,10 @@ const BreakpointWarning = ({ t, content, isLoading }) => {
<div className="description">
<div className="text-breakpoint">{t("BreakpointWarningText")}</div>
<div className="text-prompt">
{t("BreakpointWarningTextPrompt")} {content}
<Trans t={t} i18nKey="BreakpointWarningTextPrompt" ns="Settings">
"Please use the desktop site to access the {{ sectionName }}
settings."
</Trans>
</div>
</div>
</StyledBreakpointWarning>

View File

@ -2,11 +2,13 @@ import styled from "styled-components";
const StyledBreakpointWarning = styled.div`
padding: 24px 44px 0 24px;
display: flex;
flex-direction: column;
.description {
display: flex;
flex-direction: column;
padding-top: 28px;
padding-top: 32px;
white-space: break-spaces;
}
@ -15,6 +17,7 @@ const StyledBreakpointWarning = styled.div`
font-size: 16px;
line-height: 22px;
padding-bottom: 8px;
max-width: 348px;
}
.text-prompt {
@ -22,6 +25,26 @@ const StyledBreakpointWarning = styled.div`
font-size: 12px;
line-height: 16px;
}
img {
width: 72px;
height: 72px;
}
@media (min-width: 600px) {
flex-direction: row;
padding: 65px 0 0 104px;
.description {
padding: 0 0 0 32px;
}
img {
width: 100px;
height: 100px;
}
}
`;
export default StyledBreakpointWarning;

View File

@ -1,33 +1,80 @@
import React from "react";
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Loaders from "@docspace/common/components/Loaders";
import { isMobileOnly } from "react-device-detect";
const StyledLoader = styled.div`
padding: 0 28px;
padding-top: 25px;
padding-left: 32px;
display: flex;
flex-direction: column;
.img {
padding-bottom: 32px;
}
.loader-description {
display: flex;
flex-direction: column;
}
.loader-text {
padding-bottom: 8px;
padding-top: 8px;
}
.block {
display: block;
}
@media (min-width: 600px) {
flex-direction: row;
padding: 65px 0 0 104px;
.loader-description {
padding: 0 0 0 32px;
}
}
`;
const Loader = () => {
const [viewMobile, setViewMobile] = useState(false);
useEffect(() => {
onCheckView();
window.addEventListener("resize", onCheckView);
return () => window.removeEventListener("resize", onCheckView);
}, []);
const onCheckView = () => {
if (isMobileOnly || window.innerWidth < 600) {
setViewMobile(true);
} else {
setViewMobile(false);
}
};
return (
<StyledLoader>
<Loaders.Rectangle height="72px" width="72px" className="img block" />
<Loaders.Rectangle
height={viewMobile ? "72px" : "100px"}
width={viewMobile ? "72px" : "100px"}
className="img block"
/>
<div className="loader-description">
<Loaders.Rectangle
height="44px"
width="287px"
width={viewMobile ? "287px" : "332px"}
className="block"
/>
<Loaders.Rectangle
height={viewMobile ? "32px" : "16px"}
width={viewMobile ? "287px" : "332px"}
className="loader-text block"
/>
<Loaders.Rectangle height="32px" width="287px" className="block" />
</div>
</StyledLoader>
);
};

View File

@ -22,12 +22,18 @@ const StyledAboutBody = styled.div`
}
.copyright {
margin-top: 16px;
margin-top: 14px;
margin-bottom: 4px;
font-weight: 700;
}
.no-select {
${NoUserSelect}
}
.row {
line-height: 20px;
}
.tel-title,
.address-title {
display: inline;
@ -49,20 +55,50 @@ const StyledAboutBody = styled.div`
}
}
}
.logo-docspace-theme {
svg {
path:nth-child(4) {
fill: ${(props) => props.theme.client.about.logoColor};
}
}
}
`;
const AboutContent = (props) => {
const { personal, buildVersionInfo, theme } = props;
const {
personal,
buildVersionInfo,
theme,
companyInfoSettingsData,
previewData,
docSpaceLogo,
} = props;
const { t } = useTranslation("About");
const license = "AGPL-3.0";
const linkAppServer = "https://github.com/ONLYOFFICE/AppServer";
const linkAppServer = "https://github.com/ONLYOFFICE/DocSpace";
const linkDocs = "https://github.com/ONLYOFFICE/DocumentServer";
const phone = "+371 660-16425";
const email = "support@onlyoffice.com";
const address =
"20A-12 Ernesta Birznieka-Upisha street, Riga, Latvia, EU, LV-1050";
const companyName = previewData
? previewData.companyName
: companyInfoSettingsData?.companyName;
const email = previewData
? previewData.email
: companyInfoSettingsData?.email;
const phone = previewData
? previewData.phone
: companyInfoSettingsData?.phone;
const site = previewData ? previewData.site : companyInfoSettingsData?.site;
const address = previewData
? previewData.address
: companyInfoSettingsData?.address;
return (
companyInfoSettingsData && (
<StyledAboutBody>
<div className="avatar">
{personal ? (
@ -71,14 +107,10 @@ const AboutContent = (props) => {
className="logo-theme no-select"
/>
) : (
<img
src={
theme.isBase
? "/images/dark_general.png"
: "/images/white_general.png"
}
<ReactSVG
src={docSpaceLogo}
alt="Logo"
className="no-select"
className="logo-docspace-theme no-select"
/>
)}
</div>
@ -136,7 +168,7 @@ const AboutContent = (props) => {
</div>
<Text className="copyright" fontSize="14px" fontWeight="600" noSelect>
© Ascensio System SIA
© {companyName}
</Text>
<div className="row">
@ -150,7 +182,7 @@ const AboutContent = (props) => {
<div className="row">
<Text className="tel-title" fontSize="13px" noSelect>
{t("AboutCompanyTelTitle")}:{" "}
{t("Common:Phone")}:{" "}
</Text>
<Text className="tel-title select-el" fontSize="13px">
{phone}
@ -169,15 +201,39 @@ const AboutContent = (props) => {
className="row-el"
fontSize="13px"
fontWeight="600"
href={`mailto:${email}`}
href={`mailto:${companyInfoSettingsData.email}`}
>
&nbsp;{email}
</ColorTheme>
</div>
<div className="row">
<Text className="row-el" fontSize="13px" noSelect>
{t("Site")}:
</Text>
<ColorTheme
{...props}
tag="a"
themeId={ThemeType.Link}
className="row-el"
fontSize="13px"
fontWeight="600"
target="_blank"
href={site}
>
&nbsp;{site.replace(/^https?\:\/\//i, "")}
</ColorTheme>
</div>
</StyledAboutBody>
)
);
};
export default inject(({ auth }) => {
return { theme: auth.settingsStore.theme };
const { settingsStore } = auth;
const { theme, companyInfoSettingsData, docSpaceLogo } = settingsStore;
return { theme, companyInfoSettingsData, docSpaceLogo };
})(observer(AboutContent));

View File

@ -7,7 +7,7 @@ import AboutContent from "./AboutContent";
import i18n from "./i18n";
const AboutDialog = (props) => {
const { visible, onClose, personal, buildVersionInfo } = props;
const { visible, onClose, personal, buildVersionInfo, previewData } = props;
const { t, ready } = useTranslation(["About", "Common"]);
return (
@ -20,7 +20,11 @@ const AboutDialog = (props) => {
>
<ModalDialog.Header>{t("AboutHeader")}</ModalDialog.Header>
<ModalDialog.Body>
<AboutContent personal={personal} buildVersionInfo={buildVersionInfo} />
<AboutContent
personal={personal}
buildVersionInfo={buildVersionInfo}
previewData={previewData}
/>
</ModalDialog.Body>
</ModalDialogContainer>
);
@ -31,6 +35,7 @@ AboutDialog.propTypes = {
onClose: PropTypes.func,
personal: PropTypes.bool,
buildVersionInfo: PropTypes.object,
previewData: PropTypes.object,
};
const AboutDialogWrapper = (props) => {

View File

@ -123,6 +123,12 @@ const StyledComponent = styled.div`
cursor: auto;
background-color: ${(props) => props.colorPreview};
border-radius: 3px;
&:active {
background-color: ${(props) => props.colorPreview} !important;
opacity: none !important;
filter: none !important;
}
}
.color-badge rect {

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useCallback } from "react";
import { withTranslation } from "react-i18next";
import SaveCancelButtons from "@docspace/components/save-cancel-buttons";
import { inject, observer } from "mobx-react";
@ -24,7 +24,7 @@ const StyledComponent = styled.div`
}
.additional-description {
padding-bottom: 1px;
padding-bottom: 18px;
}
.save-cancel-buttons {
@ -46,6 +46,7 @@ const AdditionalResources = (props) => {
setAdditionalResources,
restoreAdditionalResources,
additionalResourcesData,
additionalResourcesIsDefault,
setIsLoadedAdditionalResources,
isLoadedAdditionalResources,
} = props;
@ -63,14 +64,7 @@ const AdditionalResources = (props) => {
);
const [hasChange, setHasChange] = useState(false);
const [hasChangesDefaultSettings, setHasChangesDefaultSettings] = useState(
false
);
const defaultAdditionalResources = JSON.parse(
localStorage.getItem("defaultAdditionalResources")
);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setShowFeedback(additionalResourcesData?.feedbackAndSupportEnabled);
@ -85,27 +79,25 @@ const AdditionalResources = (props) => {
helpCenterEnabled,
};
const hasСhange = !_.isEqual(settings, additionalResourcesData);
const dataAdditionalResources = {
feedbackAndSupportEnabled:
additionalResourcesData.feedbackAndSupportEnabled,
videoGuidesEnabled: additionalResourcesData.videoGuidesEnabled,
helpCenterEnabled: additionalResourcesData.helpCenterEnabled,
};
const hasСhangeDefaul = !_.isEqual(settings, defaultAdditionalResources);
const hasСhange = !isEqual(settings, dataAdditionalResources);
if (hasСhange) {
setHasChange(true);
} else {
setHasChange(false);
}
if (hasСhangeDefaul) {
setHasChangesDefaultSettings(true);
} else {
setHasChangesDefaultSettings(false);
}
}, [
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled,
additionalResourcesData,
defaultAdditionalResources,
]);
useEffect(() => {
@ -114,36 +106,55 @@ const AdditionalResources = (props) => {
setIsLoadedAdditionalResources(true);
}, [additionalResourcesData, tReady]);
const onSave = () => {
setAdditionalResources(
const onSave = useCallback(async () => {
setIsLoading(true);
await setAdditionalResources(
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled
)
.then(() => {
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
getAdditionalResources();
if (!localStorage.getItem("isFirstAdditionalResources")) {
localStorage.setItem("isFirstAdditionalResources", true);
setIsFirstAdditionalResources("true");
}
})
.catch((error) => {
toastr.error(error);
});
};
const onRestore = () => {
restoreAdditionalResources()
await getAdditionalResources();
setIsLoading(false);
}, [
setIsLoading,
setAdditionalResources,
getAdditionalResources,
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled,
]);
const onRestore = useCallback(async () => {
setIsLoading(true);
await restoreAdditionalResources()
.then(() => {
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
getAdditionalResources();
})
.catch((error) => {
toastr.error(error);
});
};
await getAdditionalResources();
setIsLoading(false);
}, [
setIsLoading,
restoreAdditionalResources,
getAdditionalResources,
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled,
]);
if (!isLoadedAdditionalResources) return <LoaderAdditionalResources />;
@ -156,12 +167,11 @@ const AdditionalResources = (props) => {
</div>
</div>
<div className="settings_unavailable additional-description">
<div className="additional-description">
{t("Settings:AdditionalResourcesDescription")}
</div>
</div>
<div className="branding-checkbox">
<Checkbox
tabIndex={12}
className="checkbox"
isDisabled={!isSettingPaid}
label={t("ShowFeedbackAndSupport")}
@ -170,6 +180,7 @@ const AdditionalResources = (props) => {
/>
<Checkbox
tabIndex={13}
className="checkbox"
isDisabled={!isSettingPaid}
label={t("ShowVideoGuides")}
@ -177,6 +188,7 @@ const AdditionalResources = (props) => {
onChange={() => setShowVideoGuides(!videoGuidesEnabled)}
/>
<Checkbox
tabIndex={14}
className="checkbox"
isDisabled={!isSettingPaid}
label={t("ShowHelpCenter")}
@ -186,13 +198,14 @@ const AdditionalResources = (props) => {
</div>
{isSettingPaid && (
<SaveCancelButtons
tabIndex={15}
onSaveClick={onSave}
onCancelClick={onRestore}
saveButtonLabel={t("Common:SaveButton")}
cancelButtonLabel={t("Settings:RestoreDefaultButton")}
displaySettings={true}
showReminder={isSettingPaid && hasChange}
disableRestoreToDefault={!hasChangesDefaultSettings}
showReminder={(isSettingPaid && hasChange) || isLoading}
disableRestoreToDefault={additionalResourcesIsDefault || isLoading}
/>
)}
</StyledComponent>
@ -213,6 +226,7 @@ export default inject(({ auth, common }) => {
setAdditionalResources,
restoreAdditionalResources,
additionalResourcesData,
additionalResourcesIsDefault,
} = settingsStore;
return {
@ -220,6 +234,7 @@ export default inject(({ auth, common }) => {
setAdditionalResources,
restoreAdditionalResources,
additionalResourcesData,
additionalResourcesIsDefault,
setIsLoadedAdditionalResources,
isLoadedAdditionalResources,
};

View File

@ -0,0 +1,406 @@
import React, { useState, useEffect, useCallback } from "react";
import { Trans, withTranslation } from "react-i18next";
import toastr from "@docspace/components/toast/toastr";
import FieldContainer from "@docspace/components/field-container";
import TextInput from "@docspace/components/text-input";
import SaveCancelButtons from "@docspace/components/save-cancel-buttons";
import { inject, observer } from "mobx-react";
import isEqual from "lodash/isEqual";
import withLoading from "SRC_DIR/HOCs/withLoading";
import styled from "styled-components";
import Link from "@docspace/components/link";
import LoaderCompanyInfoSettings from "../sub-components/loaderCompanyInfoSettings";
import AboutDialog from "../../../../About/AboutDialog";
const StyledComponent = styled.div`
.link {
font-weight: 600;
border-bottom: 1px dashed #333333;
border-color: ${(props) => !props.isSettingPaid && "#A3A9AE"};
}
.description,
.link {
color: ${(props) => !props.isSettingPaid && "#A3A9AE"};
}
.text-input {
font-size: 13px;
}
.save-cancel-buttons {
margin-top: 24px;
}
`;
const CompanyInfoSettings = (props) => {
const {
t,
isSettingPaid,
getCompanyInfoSettings,
setCompanyInfoSettings,
companyInfoSettingsIsDefault,
restoreCompanyInfoSettings,
companyInfoSettingsData,
tReady,
setIsLoadedCompanyInfoSettingsData,
isLoadedCompanyInfoSettingsData,
buildVersionInfo,
personal,
} = props;
const [companyName, setCompanyName] = useState(
companyInfoSettingsData.companyName
);
const [email, setEmail] = useState(companyInfoSettingsData.email);
const [phone, setPhone] = useState(companyInfoSettingsData.phone);
const [site, setSite] = useState(companyInfoSettingsData.site);
const [address, setAddress] = useState(companyInfoSettingsData.address);
const [hasErrorSite, setHasErrorSite] = useState(false);
const [hasErrorEmail, setHasErrorEmail] = useState(false);
const [hasErrorCompanyName, setHasErrorCompanyName] = useState(false);
const [hasErrorPhone, setHasErrorPhone] = useState(false);
const [hasErrorAddress, setHasErrorAddress] = useState(false);
const [isChangesSettings, setIsChangesSettings] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [showModal, setShowModal] = useState(false);
const previewData = { companyName, email, phone, site, address };
const link = t("Common:AboutCompanyTitle");
useEffect(() => {
if (!(companyInfoSettingsData && tReady)) return;
setIsLoadedCompanyInfoSettingsData(true);
}, [companyInfoSettingsData, tReady]);
useEffect(() => {
setCompanyName(companyInfoSettingsData.companyName);
setEmail(companyInfoSettingsData.email);
setPhone(companyInfoSettingsData.phone);
setSite(companyInfoSettingsData.site);
setAddress(companyInfoSettingsData.address);
}, [companyInfoSettingsData]);
useEffect(() => {
const settings = {
address,
companyName,
email,
phone,
site,
};
const dataСompanyInfoSettings = {
address: companyInfoSettingsData.address,
companyName: companyInfoSettingsData.companyName,
email: companyInfoSettingsData.email,
phone: companyInfoSettingsData.phone,
site: companyInfoSettingsData.site,
};
const hasError =
hasErrorSite ||
hasErrorEmail ||
hasErrorCompanyName ||
hasErrorPhone ||
hasErrorAddress;
const noСhange = isEqual(settings, dataСompanyInfoSettings);
if (!(hasError || noСhange)) {
setIsChangesSettings(true);
} else {
setIsChangesSettings(false);
}
}, [
address,
companyName,
email,
phone,
site,
hasErrorSite,
hasErrorEmail,
hasErrorCompanyName,
hasErrorPhone,
hasErrorAddress,
companyInfoSettingsData,
]);
const validateUrl = (url) => {
const urlRegex = /^(ftp|http|https):\/\/[^ "]+$/;
const hasError = !urlRegex.test(url);
setHasErrorSite(hasError);
};
const validateEmail = (email) => {
const emailRegex = /.+@.+\..+/;
const hasError = !emailRegex.test(email);
setHasErrorEmail(hasError);
};
const validateEmpty = (value, type) => {
const hasError = value.trim() === "";
if (type === "companyName") {
setHasErrorCompanyName(hasError);
}
if (type === "phone") {
setHasErrorPhone(hasError);
}
if (type === "address") {
setHasErrorAddress(hasError);
}
};
const onChangeSite = (url) => {
validateUrl(url);
setSite(url);
};
const onChangeEmail = (email) => {
validateEmail(email);
setEmail(email);
};
const onChangeСompanyName = (companyName) => {
validateEmpty(companyName, "companyName");
setCompanyName(companyName);
};
const onChangePhone = (phone) => {
validateEmpty(phone, "phone");
setPhone(phone);
};
const onChangeAddress = (address) => {
validateEmpty(address, "address");
setAddress(address);
};
const onSave = useCallback(async () => {
setIsLoading(true);
await setCompanyInfoSettings(address, companyName, email, phone, site)
.then(() => {
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
})
.catch((error) => {
toastr.error(error);
});
await getCompanyInfoSettings();
setIsLoading(false);
}, [
setIsLoading,
setCompanyInfoSettings,
getCompanyInfoSettings,
address,
companyName,
email,
phone,
site,
]);
const onRestore = useCallback(async () => {
setIsLoading(true);
await restoreCompanyInfoSettings()
.then(() => {
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
})
.catch((error) => {
toastr.error(error);
});
await getCompanyInfoSettings();
setIsLoading(false);
}, [setIsLoading, restoreCompanyInfoSettings, getCompanyInfoSettings]);
const onShowExample = () => {
if (!isSettingPaid) return;
setShowModal(true);
};
const onCloseModal = () => {
setShowModal(false);
};
if (!isLoadedCompanyInfoSettingsData) return <LoaderCompanyInfoSettings />;
return (
<>
<AboutDialog
visible={showModal}
onClose={onCloseModal}
buildVersionInfo={buildVersionInfo}
personal={personal}
previewData={previewData}
/>
<StyledComponent isSettingPaid={isSettingPaid}>
<div className="header settings_unavailable">
{t("Settings:CompanyInfoSettings")}
</div>
<div className="description settings_unavailable">
<Trans t={t} i18nKey="CompanyInfoSettingsDescription" ns="Settings">
"This information will be displayed in the
{isSettingPaid ? (
<Link className="link" onClick={onShowExample} noHover={true}>
{{ link }}
</Link>
) : (
<span className="link"> {{ link }}</span>
)}
window."
</Trans>
</div>
<div className="settings-block">
<FieldContainer
id="fieldContainerCompanyName"
className="field-container-width settings_unavailable"
labelText={t("Common:CompanyName")}
isVertical={true}
>
<TextInput
id="textInputContainerCompanyName"
className="text-input"
isDisabled={!isSettingPaid}
scale={true}
value={companyName}
hasError={hasErrorCompanyName}
onChange={(e) => onChangeСompanyName(e.target.value)}
tabIndex={5}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerEmail"
isDisabled={!isSettingPaid}
className="field-container-width settings_unavailable"
labelText={t("Common:Email")}
isVertical={true}
>
<TextInput
id="textInputContainerEmail"
className="text-input"
isDisabled={!isSettingPaid}
scale={true}
value={email}
hasError={hasErrorEmail}
onChange={(e) => onChangeEmail(e.target.value)}
tabIndex={6}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerPhone"
className="field-container-width settings_unavailable"
labelText={t("Common:Phone")}
isVertical={true}
>
<TextInput
id="textInputContainerPhone"
className="text-input"
isDisabled={!isSettingPaid}
scale={true}
value={phone}
hasError={hasErrorPhone}
onChange={(e) => onChangePhone(e.target.value)}
tabIndex={7}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerWebsite"
className="field-container-width settings_unavailable"
labelText={t("Common:Website")}
isVertical={true}
>
<TextInput
id="textInputContainerWebsite"
className="text-input"
isDisabled={!isSettingPaid}
scale={true}
value={site}
hasError={hasErrorSite}
onChange={(e) => onChangeSite(e.target.value)}
tabIndex={8}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerAddress"
className="field-container-width settings_unavailable"
labelText={t("Common:Address")}
isVertical={true}
>
<TextInput
id="textInputContainerAddress"
className="text-input"
isDisabled={!isSettingPaid}
scale={true}
value={address}
hasError={hasErrorAddress}
onChange={(e) => onChangeAddress(e.target.value)}
tabIndex={9}
/>
</FieldContainer>
</div>
<SaveCancelButtons
tabIndex={10}
className="save-cancel-buttons"
onSaveClick={onSave}
onCancelClick={onRestore}
saveButtonLabel={t("Common:SaveButton")}
cancelButtonLabel={t("Settings:RestoreDefaultButton")}
displaySettings={true}
showReminder={(isSettingPaid && isChangesSettings) || isLoading}
disableRestoreToDefault={companyInfoSettingsIsDefault || isLoading}
/>
</StyledComponent>
</>
);
};
export default inject(({ auth, common }) => {
const { settingsStore } = auth;
const {
setIsLoadedCompanyInfoSettingsData,
isLoadedCompanyInfoSettingsData,
} = common;
const {
getCompanyInfoSettings,
setCompanyInfoSettings,
companyInfoSettingsIsDefault,
restoreCompanyInfoSettings,
companyInfoSettingsData,
buildVersionInfo,
personal,
} = settingsStore;
return {
getCompanyInfoSettings,
setCompanyInfoSettings,
companyInfoSettingsIsDefault,
restoreCompanyInfoSettings,
companyInfoSettingsData,
setIsLoadedCompanyInfoSettingsData,
isLoadedCompanyInfoSettingsData,
buildVersionInfo,
personal,
};
})(
withLoading(
withTranslation(["Settings", "Common"])(observer(CompanyInfoSettings))
)
);

View File

@ -840,6 +840,7 @@ const WhiteLabel = (props) => {
{isSettingPaid && (
<SaveCancelButtons
tabIndex={3}
className="save-cancel-buttons"
onSaveClick={onSave}
onCancelClick={onRestoreLogo}
@ -857,20 +858,20 @@ const WhiteLabel = (props) => {
export default inject(({ setup, auth, common }) => {
const { setWhiteLabelSettings, restoreWhiteLabelSettings } = setup;
const { whiteLabelLogoSizes, whiteLabelLogoText } = common;
const {
whiteLabel,
whiteLabelLogoUrls,
getWhiteLabelLogoText,
getWhiteLabelLogoSizes,
getWhiteLabelLogoUrls,
} = common;
const { logoText, logoSizes, logoUrls } = whiteLabel;
} = auth.settingsStore;
return {
theme: auth.settingsStore.theme,
logoText,
logoSizes,
logoUrls,
logoText: whiteLabelLogoText,
logoSizes: whiteLabelLogoSizes,
logoUrls: whiteLabelLogoUrls,
getWhiteLabelLogoText,
getWhiteLabelLogoSizes,
getWhiteLabelLogoUrls,

View File

@ -62,6 +62,12 @@ const StyledSettingsComponent = styled.div`
height: 40px;
}
.combo-box-settings {
.combo-button {
justify-content: space-between !important;
}
}
@media (max-width: 599px) {
${(props) =>
props.hasScroll &&

View File

@ -103,6 +103,7 @@ const DNSSettings = (props) => {
isVertical={true}
>
<TextInput
tabIndex={8}
id="textInputContainerDNSSettings"
scale={true}
value={location.hostname}
@ -141,6 +142,7 @@ const DNSSettings = (props) => {
)}
<div className="send-request-container">
<Button
tabIndex={9}
label={t("Common:SendRequest")}
className="save-cancel-buttons send-request-button"
onClick={onSendRequest}

View File

@ -445,6 +445,7 @@ class LanguageAndTimeZone extends React.Component {
isVertical={true}
>
<ComboBox
tabIndex={1}
id="comboBoxLanguage"
options={cultureNames}
selectedOption={language}
@ -454,7 +455,7 @@ class LanguageAndTimeZone extends React.Component {
scaled={true}
scaledOptions={true}
dropDownMaxHeight={300}
className="dropdown-item-width"
className="dropdown-item-width combo-box-settings"
/>
</FieldContainer>
<FieldContainer
@ -463,6 +464,7 @@ class LanguageAndTimeZone extends React.Component {
isVertical={true}
>
<ComboBox
tabIndex={2}
id="comboBoxTimezone"
options={timezones}
selectedOption={timezone}
@ -472,7 +474,7 @@ class LanguageAndTimeZone extends React.Component {
scaled={true}
scaledOptions={true}
dropDownMaxHeight={300}
className="dropdown-item-width"
className="dropdown-item-width combo-box-settings"
/>
</FieldContainer>
</div>
@ -503,6 +505,7 @@ class LanguageAndTimeZone extends React.Component {
<> {settingsBlock}</>
)}
<SaveCancelButtons
tabIndex={3}
className="save-cancel-buttons"
onSaveClick={this.onSaveLngTZSettings}
onCancelClick={this.onCancelClick}

View File

@ -238,6 +238,7 @@ const PortalRenaming = (props) => {
isVertical={true}
>
<TextInput
tabIndex={10}
id="textInputContainerPortalRenaming"
scale={true}
value={portalName}
@ -274,6 +275,7 @@ const PortalRenaming = (props) => {
<> {settingsBlock}</>
)}
<SaveCancelButtons
tabIndex={11}
id="buttonsPortalRenaming"
className="save-cancel-buttons"
onSaveClick={onSavePortalRename}

View File

@ -22,7 +22,6 @@ import withLoading from "SRC_DIR/HOCs/withLoading";
let greetingTitleFromSessionStorage = "";
let greetingTitleDefaultFromSessionStorage = "";
let isFirstWelcomePageSettings = "";
const settingNames = ["greetingTitle"];
class WelcomePageSettings extends React.Component {
@ -37,10 +36,6 @@ class WelcomePageSettings extends React.Component {
"greetingTitleDefault"
);
isFirstWelcomePageSettings = localStorage.getItem(
"isFirstWelcomePageSettings"
);
setDocumentTitle(t("CustomTitlesWelcome"));
const greetingTitle =
@ -64,7 +59,6 @@ class WelcomePageSettings extends React.Component {
hasChanged: false,
showReminder: false,
hasScroll: false,
isFirstWelcomePageSettings: isFirstWelcomePageSettings,
isCustomizationView: false,
};
}
@ -94,9 +88,14 @@ class WelcomePageSettings extends React.Component {
}
componentDidUpdate(prevProps, prevState) {
const { isLoaded, setIsLoadedWelcomePageSettings, tReady } = this.props;
const {
isLoaded,
setIsLoadedWelcomePageSettings,
tReady,
greetingSettings,
} = this.props;
const { hasScroll } = this.state;
const { hasScroll, greetingTitle } = this.state;
if (isLoaded !== prevProps.isLoaded || tReady !== prevProps.tReady) {
const isLoadedSetting = isLoaded && tReady;
@ -126,7 +125,13 @@ class WelcomePageSettings extends React.Component {
settingsMobile.style.display = "none";
}
if (this.state.greetingTitleDefault || this.state.greetingTitle) {
if (greetingSettings !== prevProps.greetingSettings) {
this.setState({
greetingTitle: greetingSettings,
});
}
if (this.state.greetingTitleDefault || greetingTitle) {
this.checkChanges();
}
}
@ -152,49 +157,48 @@ class WelcomePageSettings extends React.Component {
};
onSaveGreetingSettings = () => {
const { setGreetingTitle, t } = this.props;
const { setGreetingTitle, t, getSettings } = this.props;
const { greetingTitle } = this.state;
this.setState({ isLoadingGreetingSave: true }, function () {
setGreetingTitle(greetingTitle)
.then(() =>
toastr.success(t("SuccessfullySaveGreetingSettingsMessage"))
)
.then(() => {
toastr.success(t("SuccessfullySaveGreetingSettingsMessage"));
getSettings();
})
.catch((error) => toastr.error(error))
.finally(() => this.setState({ isLoadingGreetingSave: false }));
});
this.setState({
showReminder: false,
greetingTitle: greetingTitle,
greetingTitleDefault: greetingTitle,
});
saveToSessionStorage("greetingTitle", greetingTitle);
saveToSessionStorage("greetingTitleDefault", greetingTitle);
if (!localStorage.getItem("isFirstWelcomePageSettings")) {
localStorage.setItem("isFirstWelcomePageSettings", true);
this.setState({
isFirstWelcomePageSettings: "true",
});
}
};
onRestoreGreetingSettings = () => {
const { restoreGreetingTitle, t } = this.props;
const {
restoreGreetingTitle,
t,
getSettings,
greetingSettings,
} = this.props;
this.setState({ isLoadingGreetingRestore: true }, function () {
restoreGreetingTitle()
.then(() => {
getSettings();
this.setState({
greetingTitle: this.props.greetingSettings,
greetingTitleDefault: this.props.greetingSettings,
greetingTitle: greetingSettings,
greetingTitleDefault: greetingSettings,
showReminder: false,
});
saveToSessionStorage("greetingTitle", this.props.greetingSettings);
saveToSessionStorage(
"greetingTitleDefault",
this.props.greetingSettings
);
saveToSessionStorage("greetingTitle", "none");
saveToSessionStorage("greetingTitleDefault", "none");
toastr.success(t("SuccessfullySaveGreetingSettingsMessage"));
})
.catch((error) => toastr.error(error))
@ -255,14 +259,18 @@ class WelcomePageSettings extends React.Component {
};
render() {
const { t, isMobileView, isLoadedPage } = this.props;
const {
t,
isMobileView,
isLoadedPage,
greetingSettingsIsDefault,
} = this.props;
const {
greetingTitle,
isLoadingGreetingSave,
isLoadingGreetingRestore,
showReminder,
hasScroll,
isFirstWelcomePageSettings,
isCustomizationView,
} = this.state;
@ -277,6 +285,7 @@ class WelcomePageSettings extends React.Component {
isVertical={true}
>
<TextInput
tabIndex={5}
id="textInputContainerWelcomePage"
scale={true}
value={greetingTitle}
@ -313,6 +322,7 @@ class WelcomePageSettings extends React.Component {
<> {settingsBlock}</>
)}
<SaveCancelButtons
tabIndex={6}
id="buttonsWelcomePage"
className="save-cancel-buttons"
onSaveClick={this.onSaveGreetingSettings}
@ -323,7 +333,7 @@ class WelcomePageSettings extends React.Component {
cancelButtonLabel={t("Settings:RestoreDefaultButton")}
displaySettings={true}
hasScroll={hasScroll}
isFirstWelcomePageSettings={isFirstWelcomePageSettings}
disableRestoreToDefault={greetingSettingsIsDefault}
/>
</StyledSettingsComponent>
);
@ -331,7 +341,13 @@ class WelcomePageSettings extends React.Component {
}
export default inject(({ auth, setup, common }) => {
const { greetingSettings, organizationName, theme } = auth.settingsStore;
const {
greetingSettings,
organizationName,
theme,
getSettings,
greetingSettingsIsDefault,
} = auth.settingsStore;
const { setGreetingTitle, restoreGreetingTitle } = setup;
const {
isLoaded,
@ -347,6 +363,8 @@ export default inject(({ auth, setup, common }) => {
restoreGreetingTitle,
isLoaded,
setIsLoadedWelcomePageSettings,
greetingSettingsIsDefault,
getSettings,
initSettings,
setIsLoaded,
};

View File

@ -6,7 +6,7 @@ import { inject, observer } from "mobx-react";
import Button from "@docspace/components/button";
import TabContainer from "@docspace/components/tabs-container";
import Preview from "./settingsAppearance/preview";
import Preview from "./Appearance/preview";
import ColorSchemeDialog from "./sub-components/colorSchemeDialog";
@ -18,7 +18,7 @@ import { isMobileOnly } from "react-device-detect";
import Loader from "./sub-components/loaderAppearance";
import { StyledComponent } from "./settingsAppearance/StyledApperance.js";
import { StyledComponent } from "./Appearance/StyledApperance.js";
import BreakpointWarning from "../../../../components/BreakpointWarning/index";
@ -355,10 +355,7 @@ const Appearance = (props) => {
);
return viewMobile ? (
<BreakpointWarning
isLoading={!tReady}
content={t("Settings:TheAppearanceSettings")}
/>
<BreakpointWarning sectionName={t("Settings:Appearance")} />
) : !tReady ? (
<Loader />
) : (

View File

@ -1,16 +1,19 @@
import React from "react";
import React, { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
import withLoading from "SRC_DIR/HOCs/withLoading";
import Whitelabel from "./settingsBranding/whitelabel";
import CompanyInfoSettings from "./settingsBranding/companyInfoSettings";
import styled, { css } from "styled-components";
import AdditionalResources from "./settingsBranding/additionalResources";
import Whitelabel from "./Branding/whitelabel";
import CompanyInfoSettings from "./Branding/companyInfoSettings";
import styled from "styled-components";
import AdditionalResources from "./Branding/additionalResources";
import LoaderBrandingDescription from "./sub-components/loaderBrandingDescription";
import BreakpointWarning from "../../../../components/BreakpointWarning/index";
import ForbiddenPage from "../ForbiddenPage";
import { UnavailableStyles } from "../../utils/commonSettingsStyles";
const StyledComponent = styled.div`
@ -23,7 +26,7 @@ const StyledComponent = styled.div`
font-weight: 700;
font-size: 16px;
line-height: 22px;
padding-bottom: 16px;
padding-bottom: 9px;
}
.description {
@ -49,28 +52,51 @@ const StyledComponent = styled.div`
${(props) => !props.isSettingPaid && UnavailableStyles}
`;
const Branding = ({ isSettingPaid }) => {
if (isMobile) return <ForbiddenPage />;
const Branding = ({ t, isLoadedCompanyInfoSettingsData, isSettingPaid }) => {
const [viewDesktop, setViewDesktop] = useState(false);
useEffect(() => {
onCheckView();
window.addEventListener("resize", onCheckView);
return () => window.removeEventListener("resize", onCheckView);
}, []);
const onCheckView = () => {
if (!isMobile && window.innerWidth > 1024) {
setViewDesktop(true);
} else {
setViewDesktop(false);
}
};
if (!viewDesktop)
return <BreakpointWarning sectionName={t("Settings:Branding")} />;
return (
<StyledComponent isSettingPaid={isSettingPaid}>
<Whitelabel isSettingPaid={isSettingPaid} />
<hr />
{isLoadedCompanyInfoSettingsData ? (
<div className="section-description settings_unavailable">
Specify your company information, add links to external resources, and
email addresses displayed within the online office interface.
{t("Settings:BrandingSectionDescription")}
</div>
) : (
<LoaderBrandingDescription />
)}
<CompanyInfoSettings isSettingPaid={isSettingPaid} />
<AdditionalResources isSettingPaid={isSettingPaid} />
</StyledComponent>
);
};
export default inject(({ auth }) => {
export default inject(({ auth, setup, common }) => {
const { currentQuotaStore } = auth;
const { isBrandingAndCustomizationAvailable } = currentQuotaStore;
const { isLoadedCompanyInfoSettingsData } = common;
return {
isLoadedCompanyInfoSettingsData,
isSettingPaid: isBrandingAndCustomizationAvailable,
};
})(withLoading(withTranslation(["Settings", "Common"])(observer(Branding))));

View File

@ -11,7 +11,7 @@ import withCultureNames from "@docspace/common/hoc/withCultureNames";
import history from "@docspace/common/history";
import { Base } from "@docspace/components/themes";
import LoaderCustomizationNavbar from "./sub-components/loaderCustomizationNavbar";
import { StyledArrowRightIcon } from "../common/settingsCustomization/StyledSettings";
import { StyledArrowRightIcon } from "./Customization/StyledSettings";
import { withRouter } from "react-router";
import Badge from "@docspace/components/badge";

View File

@ -3,10 +3,10 @@ import { withTranslation } from "react-i18next";
import styled from "styled-components";
import { inject, observer } from "mobx-react";
import withCultureNames from "@docspace/common/hoc/withCultureNames";
import LanguageAndTimeZone from "./settingsCustomization/language-and-time-zone";
import WelcomePageSettings from "./settingsCustomization/welcome-page-settings";
import PortalRenaming from "./settingsCustomization/portal-renaming";
import DNSSettings from "./settingsCustomization/dns-settings";
import LanguageAndTimeZone from "./Customization/language-and-time-zone";
import WelcomePageSettings from "./Customization/welcome-page-settings";
import PortalRenaming from "./Customization/portal-renaming";
import DNSSettings from "./Customization/dns-settings";
import { isSmallTablet } from "@docspace/components/utils/device";
import CustomizationNavbar from "./customization-navbar";
import { Base } from "@docspace/components/themes";
@ -31,7 +31,6 @@ const StyledComponent = styled.div`
max-width: 700px;
}
.category-item-description {
color: ${(props) => props.theme.client.settings.common.descriptionColor};
font-size: 12px;

View File

@ -1,123 +0,0 @@
import React, { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import FieldContainer from "@docspace/components/field-container";
import TextInput from "@docspace/components/text-input";
import SaveCancelButtons from "@docspace/components/save-cancel-buttons";
import { inject, observer } from "mobx-react";
import withLoading from "SRC_DIR/HOCs/withLoading";
import styled from "styled-components";
const StyledComponent = styled.div`
.save-cancel-buttons {
margin-top: 8px;
}
`;
const CompanyInfoSettings = (props) => {
const { t, isSettingPaid } = props;
const [companyName, setCompanyName] = useState("");
const [email, setEmail] = useState("");
const [phone, setPhone] = useState("");
const [website, setWebsite] = useState("");
const [address, setAddress] = useState("");
return (
<StyledComponent>
<div className="header settings_unavailable">Company info settings</div>
<div className="description settings_unavailable">
This information will be displayed in the About this program window.
</div>
<div className="settings-block">
<FieldContainer
id="fieldContainerCompanyName"
className="field-container-width settings_unavailable"
labelText={t("Common:CompanyName")}
isVertical={true}
>
<TextInput
id="textInputContainerCompanyName"
isDisabled={!isSettingPaid}
scale={true}
value={companyName}
onChange={(e) => setCompanyName(e.target.value)}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerEmail"
isDisabled={!isSettingPaid}
className="field-container-width settings_unavailable"
labelText={t("Common:Email")}
isVertical={true}
>
<TextInput
id="textInputContainerEmail"
isDisabled={!isSettingPaid}
scale={true}
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerPhone"
className="field-container-width settings_unavailable"
labelText={t("Common:Phone")}
isVertical={true}
>
<TextInput
id="textInputContainerPhone"
isDisabled={!isSettingPaid}
scale={true}
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerWebsite"
className="field-container-width settings_unavailable"
labelText={t("Common:Website")}
isVertical={true}
>
<TextInput
id="textInputContainerWebsite"
isDisabled={!isSettingPaid}
scale={true}
value={website}
onChange={(e) => setWebsite(e.target.value)}
/>
</FieldContainer>
<FieldContainer
id="fieldContainerAddress"
className="field-container-width settings_unavailable"
labelText={t("Common:Address")}
isVertical={true}
>
<TextInput
id="textInputContainerAddress"
isDisabled={!isSettingPaid}
scale={true}
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
</FieldContainer>
</div>
{isSettingPaid && (
<SaveCancelButtons
className="save-cancel-buttons"
onSaveClick={() => console.log("click")}
onCancelClick={() => console.log("click")}
saveButtonLabel={t("Common:SaveButton")}
cancelButtonLabel={t("Settings:RestoreDefaultButton")}
displaySettings={true}
/>
)}
</StyledComponent>
);
};
export default inject(({ auth, setup, common }) => {})(
withLoading(
withTranslation(["Settings", "Common"])(observer(CompanyInfoSettings))
)
);

View File

@ -0,0 +1,27 @@
import React from "react";
import Loaders from "@docspace/common/components/Loaders";
import styled from "styled-components";
const StyledLoader = styled.div`
padding-bottom: 18px;
.loader-description {
display: block;
padding-bottom: 8px;
}
`;
const LoaderBrandingDescription = () => {
return (
<StyledLoader>
<Loaders.Rectangle
width="700px"
height="16px"
className="loader-description"
/>
<Loaders.Rectangle width="93px" height="16px" />
</StyledLoader>
);
};
export default LoaderBrandingDescription;

View File

@ -0,0 +1,94 @@
import React from "react";
import Loaders from "@docspace/common/components/Loaders";
import styled from "styled-components";
const StyledLoader = styled.div`
.item {
padding-bottom: 12px;
}
.loader-header {
padding-bottom: 5px;
display: block;
}
.loader-label {
padding-bottom: 4px;
display: block;
}
.button {
padding-top: 8px;
}
.save {
padding-right: 8px;
}
`;
const LoaderCompanyInfoSettings = () => {
return (
<StyledLoader>
<div className="item">
<Loaders.Rectangle
width="179px"
height="22px"
className="loader-header"
/>
<Loaders.Rectangle width="419px" height="22px" />
</div>
<div className="item">
<Loaders.Rectangle
width="99px"
height="20px"
className="loader-label"
/>
<Loaders.Rectangle width="433px" height="32px" />
</div>
<div className="item">
<Loaders.Rectangle
width="35px"
height="20px"
className="loader-label"
/>
<Loaders.Rectangle width="433px" height="32px" />
</div>
<div className="item">
<Loaders.Rectangle
width="40px"
height="20px"
className="loader-label"
/>
<Loaders.Rectangle width="433px" height="32px" />
</div>
<div className="item">
<Loaders.Rectangle
width="51px"
height="20px"
className="loader-label"
/>
<Loaders.Rectangle width="433px" height="32px" />
</div>
<div className="item">
<Loaders.Rectangle
width="51px"
height="20px"
className="loader-label"
/>
<Loaders.Rectangle width="433px" height="32px" />
</div>
<div className="button">
<Loaders.Rectangle width="86px" height="32px" className="save" />
<Loaders.Rectangle width="170px" height="32px" />
</div>
</StyledLoader>
);
};
export default LoaderCompanyInfoSettings;

View File

@ -31,18 +31,18 @@ const CustomizationSettings = lazy(() =>
import("./categories/common/customization")
);
const LanguageAndTimeZoneSettings = lazy(() =>
import("./categories/common/settingsCustomization/language-and-time-zone")
import("./categories/common/Customization/language-and-time-zone")
);
const WelcomePageSettings = lazy(() =>
import("./categories/common/settingsCustomization/welcome-page-settings")
import("./categories/common/Customization/welcome-page-settings")
);
const DNSSettings = lazy(() =>
import("./categories/common/settingsCustomization/dns-settings")
import("./categories/common/Customization/dns-settings")
);
const PortalRenaming = lazy(() =>
import("./categories/common/settingsCustomization/portal-renaming")
import("./categories/common/Customization/portal-renaming")
);
const TeamTemplate = lazy(() => import("./categories/common/team-template"));
@ -61,7 +61,7 @@ const RestoreBackup = lazy(() =>
import("./categories/data-management/backup/restore-backup/index")
);
const WhiteLabel = lazy(() =>
import("./categories/common/settingsBranding/whitelabel")
import("./categories/common/Branding/whitelabel")
);
const Branding = lazy(() => import("./categories/common/branding"));

View File

@ -2,7 +2,7 @@ import React from "react";
import RadioButton from "@docspace/components/radio-button";
import { StyledWrapper } from "./styled-preview";
import Preview from "SRC_DIR/pages/PortalSettings/categories/common/settingsAppearance/preview";
import Preview from "SRC_DIR/pages/PortalSettings/categories/common/Appearance/preview";
const ThemePreview = (props) => {
const {

View File

@ -3,11 +3,8 @@ import authStore from "@docspace/common/store/AuthStore";
import api from "@docspace/common/api";
class CommonStore {
whiteLabel = {
logoSizes: [],
logoText: null,
logoUrls: [],
};
whiteLabelLogoSizes = [];
whiteLabelLogoText = null;
isInit = false;
isLoaded = false;
@ -22,6 +19,8 @@ class CommonStore {
isLoadedWelcomePageSettings = false;
isLoadedAdditionalResources = false;
isLoadedCompanyInfoSettingsData = false;
constructor() {
this.authStore = authStore;
makeAutoObservable(this);
@ -36,23 +35,18 @@ class CommonStore {
authStore.settingsStore.getPortalTimezones(),
authStore.settingsStore.getPortalCultures(),
this.getWhiteLabelLogoText(),
this.getWhiteLabelLogoSizes(),
this.getWhiteLabelLogoUrls()
this.getWhiteLabelLogoSizes()
);
return Promise.all(requests).finally(() => this.setIsLoaded(true));
};
setLogoText = (text) => {
this.whiteLabel.logoText = text;
this.whiteLabelLogoText = text;
};
setLogoSizes = (sizes) => {
this.whiteLabel.logoSizes = sizes;
};
setLogoUrls = (urls) => {
this.whiteLabel.logoUrls = urls;
this.whiteLabelLogoSizes = sizes;
};
getWhiteLabelLogoText = async () => {
@ -65,11 +59,6 @@ class CommonStore {
this.setLogoSizes(res);
};
getWhiteLabelLogoUrls = async () => {
const res = await api.settings.getLogoUrls();
this.setLogoUrls(Object.values(res));
};
setIsLoadedArticleBody = (isLoadedArticleBody) => {
this.isLoadedArticleBody = isLoadedArticleBody;
};
@ -110,6 +99,10 @@ class CommonStore {
this.isLoadedAdditionalResources = isLoadedAdditionalResources;
};
setIsLoadedCompanyInfoSettingsData = (isLoadedCompanyInfoSettingsData) => {
this.isLoadedCompanyInfoSettingsData = isLoadedCompanyInfoSettingsData;
};
setIsLoaded = (isLoaded) => {
this.isLoaded = isLoaded;
};

View File

@ -221,13 +221,11 @@ class SettingsSetupStore {
};
setLanguageAndTime = async (lng, timeZoneID) => {
const res = await api.settings.setLanguageAndTime(lng, timeZoneID);
//console.log("setLanguageAndTime", res);
//if (res) this.setPortalLanguageAndTime({ lng, timeZoneID });
return api.settings.setLanguageAndTime(lng, timeZoneID);
};
setPortalRename = async (alias) => {
const res = await api.portal.setPortalRename(alias);
return api.portal.setPortalRename(alias);
};
setDNSSettings = async (dnsName, enable) => {
@ -278,9 +276,7 @@ class SettingsSetupStore {
};
setGreetingTitle = async (greetingTitle) => {
const res = await api.settings.setGreetingSettings(greetingTitle);
//if (res) this.setGreetingSettings(greetingTitle);
return api.settings.setGreetingSettings(greetingTitle);
};
setAuditTrailReport = (report) => {
@ -316,8 +312,7 @@ class SettingsSetupStore {
};
restoreGreetingTitle = async () => {
const res = await api.settings.restoreGreetingSettings();
//if (res) this.setGreetingSettings(res.Content);
return api.settings.restoreGreetingSettings();
};
getConsumers = async () => {

View File

@ -157,6 +157,13 @@ export function setGreetingSettings(title) {
});
}
export function getGreetingSettingsIsDefault() {
return request({
method: "get",
url: `/settings/greetingsettings/isDefault.json`,
});
}
export function restoreGreetingSettings() {
return request({
method: "post",
@ -217,6 +224,38 @@ export function restoreWhiteLabelSettings(isDefault) {
});
}
export function setCompanyInfoSettings(
address,
companyName,
email,
phone,
site
) {
const data = {
settings: { address, companyName, email, phone, site },
};
return request({
method: "post",
url: `/settings/rebranding/company.json`,
data,
});
}
export function getCompanyInfoSettings() {
return request({
method: "get",
url: `/settings/rebranding/company.json`,
});
}
export function restoreCompanyInfoSettings() {
return request({
method: "delete",
url: `/settings/rebranding/company.json`,
});
}
export function getCustomSchemaList() {
return request({
method: "get",

View File

@ -55,7 +55,8 @@ const getDefaultStyles = ({
? hoverCss
: !disableHover &&
css`
&:hover {
&:hover,
&:focus {
${hoverCss}
}
`)}

View File

@ -9,6 +9,13 @@ const getDefaultStyles = ({ $currentColorScheme, isOpen, theme }) =>
(theme.isBase
? $currentColorScheme.accentColor
: theme.comboBox.button.openBorderColor)};
:focus {
border-color: ${isOpen &&
(theme.isBase
? $currentColorScheme.accentColor
: theme.comboBox.button.hoverBorderColor)};
}
`;
StyledComboButton.defaultProps = { theme: Base };

View File

@ -6,19 +6,12 @@ import SettingsStore from "./SettingsStore";
import UserStore from "./UserStore";
import TfaStore from "./TfaStore";
import InfoPanelStore from "./InfoPanelStore";
import { logout as logoutDesktop, desktopConstants } from "../desktop";
import { combineUrl, isAdmin, setCookie, getCookie } from "../utils";
import CurrentQuotasStore from "./CurrentQuotaStore";
import CurrentTariffStatusStore from "./CurrentTariffStatusStore";
import PaymentQuotasStore from "./PaymentQuotasStore";
import {
logout as logoutDesktop,
desktopConstants,
} from "../desktop";
import {
combineUrl,
isAdmin,
setCookie,
getCookie,
} from "../utils";import {
AppServerConfig,
LANGUAGE,
COOKIE_EXPIRATION_YEAR,
@ -79,7 +72,9 @@ class AuthStore {
!this.settingsStore.passwordSettings &&
requests.push(
this.settingsStore.getPortalPasswordSettings(),
this.settingsStore.getAdditionalResources()
this.settingsStore.getAdditionalResources(),
this.settingsStore.getCompanyInfoSettings(),
this.settingsStore.getWhiteLabelLogoUrls()
);
}

View File

@ -143,6 +143,14 @@ class SettingsStore {
pluginOptions = [];
additionalResourcesData = null;
additionalResourcesIsDefault = true;
companyInfoSettingsData = null;
companyInfoSettingsIsDefault = true;
whiteLabelLogoUrls = [];
docSpaceLogo = "";
greetingSettingsIsDefault = true;
constructor() {
makeAutoObservable(this);
@ -188,6 +196,14 @@ class SettingsStore {
this.defaultPage = defaultPage;
};
setGreetingSettings = (greetingSettings) => {
this.greetingSettings = greetingSettings;
};
getGreetingSettingsIsDefault = async () => {
this.greetingSettingsIsDefault = await api.settings.getGreetingSettingsIsDefault();
};
getSettings = async () => {
let newSettings = null;
@ -227,6 +243,8 @@ class SettingsStore {
}
});
this.setGreetingSettings(newSettings.greetingSettings);
this.getGreetingSettingsIsDefault();
return newSettings;
};
@ -304,12 +322,16 @@ class SettingsStore {
this.additionalResourcesData = data;
};
setAdditionalResourcesIsDefault = (additionalResourcesIsDefault) => {
this.additionalResourcesIsDefault = additionalResourcesIsDefault;
};
setAdditionalResources = async (
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled
) => {
const res = await api.settings.setAdditionalResources(
return await api.settings.setAdditionalResources(
feedbackAndSupportEnabled,
videoGuidesEnabled,
helpCenterEnabled
@ -319,24 +341,12 @@ class SettingsStore {
getAdditionalResources = async () => {
const res = await api.settings.getAdditionalResources();
delete res.buyUrl;
delete res.feedbackAndSupportUrl;
delete res.licenseAgreementsEnabled;
delete res.licenseAgreementsUrl;
delete res.salesEmail;
delete res.startDocsEnabled;
delete res.userForumEnabled;
delete res.videoGuidesUrl;
this.setAdditionalResourcesData(res);
if (!localStorage.getItem("defaultAdditionalResources")) {
localStorage.setItem("defaultAdditionalResources", JSON.stringify(res));
}
this.setAdditionalResourcesIsDefault(res.isDefault);
};
restoreAdditionalResources = async () => {
const res = await api.settings.restoreAdditionalResources();
return await api.settings.restoreAdditionalResources();
};
getPortalCultures = async () => {
@ -362,11 +372,83 @@ class SettingsStore {
this.updateEncryptionKeys(keys);
};
setCompanyInfoSettingsData = (data) => {
this.companyInfoSettingsData = data;
};
setCompanyInfoSettingsIsDefault = (companyInfoSettingsIsDefault) => {
this.companyInfoSettingsIsDefault = companyInfoSettingsIsDefault;
};
setCompanyInfoSettings = async (address, companyName, email, phone, site) => {
return api.settings.setCompanyInfoSettings(
address,
companyName,
email,
phone,
site
);
};
setDocSpaceLogo = (urls) => {
this.docSpaceLogo = urls[1];
};
setLogoUrls = (urls) => {
this.whiteLabelLogoUrls = urls;
};
getCompanyInfoSettings = async () => {
const res = await api.settings.getCompanyInfoSettings();
this.setCompanyInfoSettingsData(res);
this.setCompanyInfoSettingsIsDefault(res.isDefault);
};
getWhiteLabelLogoUrls = async () => {
const res = await api.settings.getLogoUrls();
this.setLogoUrls(Object.values(res));
this.setDocSpaceLogo(Object.values(res));
};
restoreCompanyInfoSettings = async () => {
return await api.settings.restoreCompanyInfoSettings();
};
getEncryptionKeys = async () => {
const encryptionKeys = await api.files.getEncryptionKeys();
this.updateEncryptionKeys(encryptionKeys);
};
getOAuthToken = (tokenGetterWin) => {
return new Promise((resolve, reject) => {
localStorage.removeItem("code");
let interval = null;
interval = setInterval(() => {
try {
const code = localStorage.getItem("code");
if (code) {
localStorage.removeItem("code");
clearInterval(interval);
resolve(code);
} else if (tokenGetterWin && tokenGetterWin.closed) {
clearInterval(interval);
reject();
}
} catch (e) {
clearInterval(interval);
reject(e);
}
}, 500);
});
};
getLoginLink = (token, code) => {
return combineUrl(proxyURL, `/login.ashx?p=${token}&code=${code}`);
};
setModuleInfo = (homepage, productId) => {
if (this.homepage === homepage || this.currentProductId === productId)
return;
@ -609,7 +691,7 @@ class SettingsStore {
};
sendAppearanceTheme = async (data) => {
const res = await api.settings.sendAppearanceTheme(data);
return api.settings.sendAppearanceTheme(data);
};
}

View File

@ -8,7 +8,7 @@ import CheckboxCheckedIcon from "./svg/checkbox.checked.react.svg";
import CheckboxIcon from "./svg/checkbox.react.svg";
// eslint-disable-next-line react/prop-types
const RenderCheckboxIcon = ({ isChecked, isIndeterminate }) => {
const RenderCheckboxIcon = ({ isChecked, isIndeterminate, tabIndex }) => {
// let newProps = {
// size: "medium",
// className: "checkbox",
@ -19,11 +19,17 @@ const RenderCheckboxIcon = ({ isChecked, isIndeterminate }) => {
return (
<>
{isIndeterminate ? (
<CheckboxIndeterminateIcon className="checkbox not-selectable" />
<CheckboxIndeterminateIcon
tabIndex={tabIndex}
className="checkbox not-selectable"
/>
) : isChecked ? (
<CheckboxCheckedIcon className="checkbox not-selectable" />
<CheckboxCheckedIcon
tabIndex={tabIndex}
className="checkbox not-selectable"
/>
) : (
<CheckboxIcon className="checkbox not-selectable" />
<CheckboxIcon tabIndex={tabIndex} className="checkbox not-selectable" />
)}
</>
);
@ -83,6 +89,7 @@ class Checkbox extends React.Component {
helpButton,
onChange,
isChecked,
tabIndex,
...rest
} = this.props;
@ -104,9 +111,10 @@ class Checkbox extends React.Component {
ref={this.ref}
value={value}
onChange={this.onInputChange}
tabIndex={-1}
{...rest}
/>
<RenderCheckboxIcon {...this.props} />
<RenderCheckboxIcon tabIndex={tabIndex} {...this.props} />
<div className="wrapper">
{this.props.label && (
<Text
@ -158,11 +166,13 @@ Checkbox.propTypes = {
truncate: PropTypes.bool,
/** Help button render */
helpButton: PropTypes.any,
tabIndex: PropTypes.number,
};
Checkbox.defaultProps = {
isChecked: false,
truncate: false,
tabIndex: -1,
};
export default React.memo(Checkbox);

View File

@ -46,6 +46,12 @@ const StyledLabel = styled.label`
path {
fill: ${(props) => props.theme.checkbox.arrowColor};
}
&:focus {
outline: none;
rect {
stroke: ${(props) => props.theme.checkbox.focusColor};
}
}
`
: !props.isDisabled &&
css`

View File

@ -112,6 +112,9 @@ class ComboBox extends React.Component {
advancedOptionsCount,
} = this.props;
const { tabIndex, ...props } = this.props;
const { isOpen, selectedOption } = this.state;
const dropDownMaxHeightProp = dropDownMaxHeight
@ -152,7 +155,7 @@ class ComboBox extends React.Component {
toggleAction={toggleAction}
isOpen={isOpen}
disableMobileView={disableMobileView}
{...this.props}
{...props}
>
<ComboButton
noBorder={noBorder}
@ -169,6 +172,7 @@ class ComboBox extends React.Component {
comboIcon={comboIcon}
modernView={modernView}
fillIcon={fillIcon}
tabIndex={tabIndex}
/>
{displayType !== "toggle" && (
<DropDown
@ -294,6 +298,7 @@ ComboBox.propTypes = {
/**Count of advanced options */
advancedOptionsCount: PropTypes.number,
tabIndex: PropTypes.number,
};
ComboBox.defaultProps = {
@ -313,6 +318,7 @@ ComboBox.defaultProps = {
disableItemClick: false,
isExternalLink: false,
modernView: false,
tabIndex: -1,
};
export default ComboBox;

View File

@ -37,6 +37,7 @@ class ComboButton extends React.Component {
comboIcon,
fillIcon,
modernView,
tabIndex,
} = this.props;
const defaultOption = selectedOption?.default;
@ -56,6 +57,7 @@ class ComboButton extends React.Component {
modernView={modernView}
className="combo-button"
themeId={ThemeType.ComboButton}
tabIndex={tabIndex}
>
{innerContainer && (
<StyledOptionalItem
@ -138,6 +140,7 @@ ComboButton.propTypes = {
comboIcon: PropTypes.string,
fillIcon: PropTypes.bool,
modernView: PropTypes.bool,
tabIndex: PropTypes.number,
};
ComboButton.defaultProps = {
@ -150,6 +153,7 @@ ComboButton.defaultProps = {
size: "content",
scaled: false,
modernView: false,
tabIndex: -1,
};
export default ComboButton;

View File

@ -117,6 +117,14 @@ const StyledComboButton = styled.div`
line-height: ${props.theme.comboBox.label.lineHeightWithoutBorder};
`}
}
:focus {
outline: none;
border-color: ${(props) =>
props.isOpen
? props.theme.comboBox.button.hoverBorderColorOpen
: props.theme.comboBox.button.hoverBorderColor};
}
`;
StyledComboButton.defaultProps = { theme: Base };

View File

@ -216,7 +216,7 @@ class ContextMenuButton extends React.Component {
zIndex={zIndex}
isDefaultMode={usePortal}
>
{this.state.data.map(
{this.state.data?.map(
(item, index) =>
item &&
(item.label || item.icon || item.key) && (

View File

@ -20,7 +20,9 @@ class SaveCancelButtons extends React.Component {
}
onKeydown = (e) => {
const { onSaveClick, onCancelClick } = this.props;
const { onSaveClick, onCancelClick, displaySettings } = this.props;
if (displaySettings) return;
switch (e.keyCode) {
case ButtonKeys.enter:
@ -49,6 +51,7 @@ class SaveCancelButtons extends React.Component {
id,
isSaving,
cancelEnable,
tabIndex,
} = this.props;
const cancelButtonDisabled = cancelEnable
@ -57,6 +60,9 @@ class SaveCancelButtons extends React.Component {
? disableRestoreToDefault
: !showReminder;
const tabIndexSaveButton = tabIndex ? tabIndex : -1;
const tabIndexCancelButton = tabIndex ? tabIndex + 1 : -1;
return (
<StyledSaveCancelButtons
className={className}
@ -67,6 +73,7 @@ class SaveCancelButtons extends React.Component {
>
<div className="buttons-flex">
<Button
tabIndex={tabIndexSaveButton}
className="save-button"
size="normal"
isDisabled={!showReminder}
@ -77,6 +84,7 @@ class SaveCancelButtons extends React.Component {
isLoading={isSaving}
/>
<Button
tabIndex={tabIndexCancelButton}
className="cancel-button"
size="normal"
isDisabled={cancelButtonDisabled || isSaving}
@ -117,6 +125,7 @@ SaveCancelButtons.propTypes = {
disableRestoreToDefault: PropTypes.bool,
isSaving: PropTypes.bool,
cancelEnable: PropTypes.bool,
tabIndex: PropTypes.number,
};
SaveCancelButtons.defaultProps = {

View File

@ -442,6 +442,8 @@ const Base = {
hoverBorderColor: gray,
hoverIndeterminateColor: black,
focusColor: "#A3A9AE",
},
// slider: {

View File

@ -440,6 +440,8 @@ const Dark = {
hoverBorderColor: "#646464",
hoverIndeterminateColor: grayMaxLight,
focusColor: "#858585",
},
// slider: {

View File

@ -21,8 +21,6 @@ import Register from "./sub-components/register-container";
import { ColorTheme, ThemeType } from "@docspace/common/components/ColorTheme";
import SSOIcon from "../../../../../public/images/sso.react.svg";
const greetingTitle = "Web Office Applications"; // from PortalSettingsStore
interface ILoginProps extends IInitialState {
isDesktopEditor?: boolean;
}
@ -38,7 +36,7 @@ const Login: React.FC<ILoginProps> = ({
const [moreAuthVisible, setMoreAuthVisible] = useState(false);
const [recoverDialogVisible, setRecoverDialogVisible] = useState(false);
const { enabledJoin } = portalSettings;
const { enabledJoin, greetingSettings } = portalSettings;
const { ssoLabel, ssoUrl } = capabilities;
const { t } = useTranslation(["Login", "Common"]);
@ -171,7 +169,7 @@ const Login: React.FC<ILoginProps> = ({
textAlign="center"
className="greeting-title"
>
{greetingTitle}
{greetingSettings}
</Text>
<FormWrapper>
{ssoExists() && <ButtonsWrapper>{ssoButton()}</ButtonsWrapper>}

View File

@ -34,6 +34,7 @@ public class GreetingSettingsController : BaseSettingsController
private readonly TenantManager _tenantManager;
private readonly PermissionContext _permissionContext;
private readonly TenantInfoSettingsHelper _tenantInfoSettingsHelper;
private readonly IConfiguration _configuration;
public GreetingSettingsController(
TenantInfoSettingsHelper tenantInfoSettingsHelper,
@ -43,12 +44,14 @@ public class GreetingSettingsController : BaseSettingsController
PermissionContext permissionContext,
WebItemManager webItemManager,
IMemoryCache memoryCache,
IHttpContextAccessor httpContextAccessor) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_tenantInfoSettingsHelper = tenantInfoSettingsHelper;
_messageService = messageService;
_tenantManager = tenantManager;
_permissionContext = permissionContext;
_configuration = configuration;
}
[HttpGet("greetingsettings")]
@ -57,6 +60,12 @@ public class GreetingSettingsController : BaseSettingsController
return new ContentResult { Content = Tenant.Name == "" ? Resource.PortalName : Tenant.Name };
}
[HttpGet("greetingsettings/isdefault")]
public bool IsDefault()
{
return Tenant.Name == "";
}
[HttpPost("greetingsettings")]
public ContentResult SaveGreetingSettings(GreetingSettingsRequestsDto inDto)
{

View File

@ -57,7 +57,7 @@ public class SettingsController : BaseSettingsController
private readonly ILogger _log;
private readonly TelegramHelper _telegramHelper;
private readonly DnsSettings _dnsSettings;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
private readonly AdditionalWhiteLabelSettingsHelperInit _additionalWhiteLabelSettingsHelper;
private readonly CustomColorThemesSettingsHelper _customColorThemesSettingsHelper;
private readonly QuotaUsageManager _quotaUsageManager;
private readonly QuotaSyncOperation _quotaSyncOperation;
@ -93,7 +93,7 @@ public class SettingsController : BaseSettingsController
PasswordHasher passwordHasher,
IHttpContextAccessor httpContextAccessor,
DnsSettings dnsSettings,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelper,
CustomColorThemesSettingsHelper customColorThemesSettingsHelper,
QuotaSyncOperation quotaSyncOperation,
QuotaUsageManager quotaUsageManager

View File

@ -37,6 +37,9 @@ public class WhitelabelController : BaseSettingsController
private readonly TenantLogoManager _tenantLogoManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly IMapper _mapper;
private readonly CompanyWhiteLabelSettingsHelper _companyWhiteLabelSettingsHelper;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
public WhitelabelController(
ApiContext apiContext,
@ -49,7 +52,9 @@ public class WhitelabelController : BaseSettingsController
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
IMemoryCache memoryCache,
IHttpContextAccessor httpContextAccessor) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
IHttpContextAccessor httpContextAccessor,
IMapper mapper,
CompanyWhiteLabelSettingsHelper companyWhiteLabelSettingsHelper, AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_permissionContext = permissionContext;
_settingsManager = settingsManager;
@ -58,6 +63,9 @@ public class WhitelabelController : BaseSettingsController
_tenantLogoManager = tenantLogoManager;
_coreBaseSettings = coreBaseSettings;
_commonLinkUtility = commonLinkUtility;
_mapper = mapper;
_companyWhiteLabelSettingsHelper = companyWhiteLabelSettingsHelper;
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
}
///<visible>false</visible>
@ -123,8 +131,6 @@ public class WhitelabelController : BaseSettingsController
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
DemandWhiteLabelPermission();
return
new[]
{
@ -145,10 +151,6 @@ public class WhitelabelController : BaseSettingsController
[HttpGet("whitelabel/logos")]
public Dictionary<string, string> GetWhiteLabelLogos([FromQuery] WhiteLabelQueryRequestsDto inDto)
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
DemandWhiteLabelPermission();
Dictionary<string, string> result;
var _tenantWhiteLabelSettings = _settingsManager.Load<TenantWhiteLabelSettings>();
@ -174,8 +176,6 @@ public class WhitelabelController : BaseSettingsController
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
DemandWhiteLabelPermission();
var settings = _settingsManager.Load<TenantWhiteLabelSettings>();
return settings.LogoText ?? TenantWhiteLabelSettings.DefaultLogoText;
@ -204,15 +204,13 @@ public class WhitelabelController : BaseSettingsController
[HttpGet("companywhitelabel")]
public List<CompanyWhiteLabelSettings> GetLicensorData()
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
var result = new List<CompanyWhiteLabelSettings>();
var instance = CompanyWhiteLabelSettings.Instance(_settingsManager);
var instance = _companyWhiteLabelSettingsHelper.Instance();
result.Add(instance);
if (!instance.IsDefault && !instance.IsLicensor)
if (!_companyWhiteLabelSettingsHelper.IsDefault(instance) && !instance.IsLicensor)
{
result.Add(_settingsManager.GetDefault<CompanyWhiteLabelSettings>());
}
@ -241,11 +239,9 @@ public class WhitelabelController : BaseSettingsController
///<visible>false</visible>
[HttpGet("rebranding/company")]
public CompanyWhiteLabelSettings GetCompanyWhiteLabelSettings()
public CompanyWhiteLabelSettingsDto GetCompanyWhiteLabelSettings()
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
return _settingsManager.Load<CompanyWhiteLabelSettings>();
return _mapper.Map<CompanyWhiteLabelSettings, CompanyWhiteLabelSettingsDto>(_settingsManager.Load<CompanyWhiteLabelSettings>());
}
///<visible>false</visible>
@ -281,9 +277,9 @@ public class WhitelabelController : BaseSettingsController
///<visible>false</visible>
[HttpGet("rebranding/additional")]
public AdditionalWhiteLabelSettings GetAdditionalWhiteLabelSettings()
public AdditionalWhiteLabelSettingsDto GetAdditionalWhiteLabelSettings()
{
return _settingsManager.Load<AdditionalWhiteLabelSettings>();
return _mapper.Map<AdditionalWhiteLabelSettings, AdditionalWhiteLabelSettingsDto>(_settingsManager.Load<AdditionalWhiteLabelSettings>());
}
///<visible>false</visible>
@ -333,8 +329,6 @@ public class WhitelabelController : BaseSettingsController
[HttpGet("rebranding/mail")]
public MailWhiteLabelSettings GetMailWhiteLabelSettings()
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
return _settingsManager.Load<MailWhiteLabelSettings>();
}

View File

@ -0,0 +1,62 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Api.ApiModels.ResponseDto;
public class AdditionalWhiteLabelSettingsDto: IMapFrom<AdditionalWhiteLabelSettings>
{
public bool StartDocsEnabled { get; set; }
public bool HelpCenterEnabled { get; set; }
public bool FeedbackAndSupportEnabled { get; set; }
public string FeedbackAndSupportUrl { get; set; }
public bool UserForumEnabled { get; set; }
public string UserForumUrl { get; set; }
public bool VideoGuidesEnabled { get; set; }
public string VideoGuidesUrl { get; set; }
public string SalesEmail { get; set; }
public string BuyUrl { get; set; }
public bool LicenseAgreementsEnabled { get; set; }
public bool IsDefault { get; set; }
public string LicenseAgreementsUrl { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<AdditionalWhiteLabelSettings, AdditionalWhiteLabelSettingsDto>()
.ConvertUsing<AdditionalWhiteLabelSettingsConverter>();
}
}

View File

@ -0,0 +1,50 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Api.ApiModels.ResponseDto;
public class CompanyWhiteLabelSettingsDto: IMapFrom<CompanyWhiteLabelSettings>
{
public string CompanyName { get; set; }
public string Site { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public bool IsLicensor { get; set; }
public bool IsDefault { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<CompanyWhiteLabelSettings, CompanyWhiteLabelSettingsDto>()
.ConvertUsing<CompanyWhiteLabelSettingsConverter>();
}
}

View File

@ -0,0 +1,70 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Api.Mapping;
[Scope(Additional = typeof(AdditionalWhiteLabelSettingsConverterExtension))]
public class AdditionalWhiteLabelSettingsConverter : ITypeConverter<AdditionalWhiteLabelSettings, AdditionalWhiteLabelSettingsDto>
{
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
public AdditionalWhiteLabelSettingsConverter(AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper)
{
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
}
public AdditionalWhiteLabelSettingsDto Convert(AdditionalWhiteLabelSettings source, AdditionalWhiteLabelSettingsDto destination, ResolutionContext context)
{
var result = new AdditionalWhiteLabelSettingsDto()
{
BuyUrl = source.BuyUrl,
FeedbackAndSupportEnabled = source.FeedbackAndSupportEnabled,
FeedbackAndSupportUrl = source.FeedbackAndSupportUrl,
HelpCenterEnabled = source.HelpCenterEnabled,
IsDefault = _additionalWhiteLabelSettingsHelper.IsDefault(source),
LicenseAgreementsEnabled = source.LicenseAgreementsEnabled,
LicenseAgreementsUrl = source.LicenseAgreementsUrl,
SalesEmail = source.SalesEmail,
StartDocsEnabled = source.StartDocsEnabled,
UserForumEnabled = source.UserForumEnabled,
UserForumUrl = source.UserForumUrl,
VideoGuidesEnabled = source.VideoGuidesEnabled,
VideoGuidesUrl = source.VideoGuidesUrl
};
return result;
}
}
public static class AdditionalWhiteLabelSettingsConverterExtension
{
public static void Register(DIHelper dIHelper)
{
dIHelper.TryAdd<AdditionalWhiteLabelSettingsHelper>();
}
}

View File

@ -0,0 +1,51 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Api.Mapping;
[Scope]
public class CompanyWhiteLabelSettingsConverter : ITypeConverter<CompanyWhiteLabelSettings, CompanyWhiteLabelSettingsDto>
{
private readonly CompanyWhiteLabelSettingsHelper _companyWhiteLabelSettingsHelper;
public CompanyWhiteLabelSettingsConverter(CompanyWhiteLabelSettingsHelper companyWhiteLabelSettingsHelper)
{
_companyWhiteLabelSettingsHelper = companyWhiteLabelSettingsHelper;
}
public CompanyWhiteLabelSettingsDto Convert(CompanyWhiteLabelSettings source, CompanyWhiteLabelSettingsDto destination, ResolutionContext context)
{
var result = new CompanyWhiteLabelSettingsDto()
{
Address = source.Address,
CompanyName = source.CompanyName,
Email = source.Email,
IsDefault = _companyWhiteLabelSettingsHelper.IsDefault(source),
IsLicensor = source.IsLicensor,
Phone = source.Phone,
Site = source.Site
};
return result;
}
}

View File

@ -272,7 +272,7 @@ public class NotifyTransferRequest : INotifyEngineAction
private readonly TenantExtra _tenantExtra;
private readonly WebItemManager _webItemManager;
private readonly TenantLogoManager _tenantLogoManager;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
private readonly AdditionalWhiteLabelSettingsHelperInit _additionalWhiteLabelSettingsHelper;
private readonly TenantUtil _tenantUtil;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
@ -289,7 +289,7 @@ public class NotifyTransferRequest : INotifyEngineAction
TenantExtra tenantExtra,
WebItemManager webItemManager,
TenantLogoManager tenantLogoManager,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelper,
TenantUtil tenantUtil,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,

View File

@ -51,7 +51,7 @@ public class StudioNotifyHelper
StudioNotifySource studioNotifySource,
UserManager userManager,
SettingsManager settingsManager,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelper,
CommonLinkUtility commonLinkUtility,
TenantManager tenantManager,
TenantExtra tenantExtra,

View File

@ -496,7 +496,7 @@ public class CommonLinkUtility : BaseCommonLinkUtility
#region Help Centr
public string GetHelpLink(SettingsManager settingsManager, AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper, bool inCurrentCulture = true)
public string GetHelpLink(SettingsManager settingsManager, AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelper, bool inCurrentCulture = true)
{
if (!settingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>().HelpCenterEnabled)
{

View File

@ -34,7 +34,7 @@ public class AdditionalWhiteLabelSettingsWrapper
[Serializable]
public class AdditionalWhiteLabelSettings : ISettings<AdditionalWhiteLabelSettings>
{
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
public AdditionalWhiteLabelSettingsHelperInit AdditionalWhiteLabelSettingsHelper;
public bool StartDocsEnabled { get; set; }
@ -60,54 +60,33 @@ public class AdditionalWhiteLabelSettings : ISettings<AdditionalWhiteLabelSettin
public string LicenseAgreementsUrl { get; set; }
public bool IsDefault
{
get
{
var defaultSettings = GetDefault();
return StartDocsEnabled == defaultSettings.StartDocsEnabled &&
HelpCenterEnabled == defaultSettings.HelpCenterEnabled &&
FeedbackAndSupportEnabled == defaultSettings.FeedbackAndSupportEnabled &&
FeedbackAndSupportUrl == defaultSettings.FeedbackAndSupportUrl &&
UserForumEnabled == defaultSettings.UserForumEnabled &&
UserForumUrl == defaultSettings.UserForumUrl &&
VideoGuidesEnabled == defaultSettings.VideoGuidesEnabled &&
VideoGuidesUrl == defaultSettings.VideoGuidesUrl &&
SalesEmail == defaultSettings.SalesEmail &&
BuyUrl == defaultSettings.BuyUrl &&
LicenseAgreementsEnabled == defaultSettings.LicenseAgreementsEnabled &&
LicenseAgreementsUrl == defaultSettings.LicenseAgreementsUrl;
}
}
[JsonIgnore]
public Guid ID
{
get { return new Guid("{0108422F-C05D-488E-B271-30C4032494DA}"); }
}
public AdditionalWhiteLabelSettings(AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper)
public AdditionalWhiteLabelSettings(AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelper)
{
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
this.AdditionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
}
public AdditionalWhiteLabelSettings() { }
public AdditionalWhiteLabelSettings GetDefault()
{
return new AdditionalWhiteLabelSettings(_additionalWhiteLabelSettingsHelper)
return new AdditionalWhiteLabelSettings(AdditionalWhiteLabelSettingsHelper)
{
StartDocsEnabled = true,
HelpCenterEnabled = _additionalWhiteLabelSettingsHelper?.DefaultHelpCenterUrl != null,
FeedbackAndSupportEnabled = _additionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl != null,
FeedbackAndSupportUrl = _additionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl,
UserForumEnabled = _additionalWhiteLabelSettingsHelper?.DefaultUserForumUrl != null,
UserForumUrl = _additionalWhiteLabelSettingsHelper?.DefaultUserForumUrl,
VideoGuidesEnabled = _additionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl != null,
VideoGuidesUrl = _additionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl,
SalesEmail = _additionalWhiteLabelSettingsHelper?.DefaultMailSalesEmail,
BuyUrl = _additionalWhiteLabelSettingsHelper?.DefaultBuyUrl,
HelpCenterEnabled = AdditionalWhiteLabelSettingsHelper?.DefaultHelpCenterUrl != null,
FeedbackAndSupportEnabled = AdditionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl != null,
FeedbackAndSupportUrl = AdditionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl,
UserForumEnabled = AdditionalWhiteLabelSettingsHelper?.DefaultUserForumUrl != null,
UserForumUrl = AdditionalWhiteLabelSettingsHelper?.DefaultUserForumUrl,
VideoGuidesEnabled = AdditionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl != null,
VideoGuidesUrl = AdditionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl,
SalesEmail = AdditionalWhiteLabelSettingsHelper?.DefaultMailSalesEmail,
BuyUrl = AdditionalWhiteLabelSettingsHelper?.DefaultBuyUrl,
LicenseAgreementsEnabled = true,
LicenseAgreementsUrl = DefaultLicenseAgreements
};
@ -122,12 +101,45 @@ public class AdditionalWhiteLabelSettings : ISettings<AdditionalWhiteLabelSettin
}
}
[Singletone]
[Scope]
public class AdditionalWhiteLabelSettingsHelper
{
private readonly AdditionalWhiteLabelSettingsHelperInit _additionalWhiteLabelSettingsHelperInit;
public AdditionalWhiteLabelSettingsHelper(AdditionalWhiteLabelSettingsHelperInit additionalWhiteLabelSettingsHelperInit)
{
_additionalWhiteLabelSettingsHelperInit = additionalWhiteLabelSettingsHelperInit;
}
public bool IsDefault(AdditionalWhiteLabelSettings settings)
{
if (settings.AdditionalWhiteLabelSettingsHelper == null)
{
settings.AdditionalWhiteLabelSettingsHelper = _additionalWhiteLabelSettingsHelperInit;
}
var defaultSettings = settings.GetDefault();
return settings.StartDocsEnabled == defaultSettings.StartDocsEnabled &&
settings.HelpCenterEnabled == defaultSettings.HelpCenterEnabled &&
settings.FeedbackAndSupportEnabled == defaultSettings.FeedbackAndSupportEnabled &&
settings.FeedbackAndSupportUrl == defaultSettings.FeedbackAndSupportUrl &&
settings.UserForumEnabled == defaultSettings.UserForumEnabled &&
settings.UserForumUrl == defaultSettings.UserForumUrl &&
settings.VideoGuidesEnabled == defaultSettings.VideoGuidesEnabled &&
settings.VideoGuidesUrl == defaultSettings.VideoGuidesUrl &&
settings.SalesEmail == defaultSettings.SalesEmail &&
settings.BuyUrl == defaultSettings.BuyUrl &&
settings.LicenseAgreementsEnabled == defaultSettings.LicenseAgreementsEnabled &&
settings.LicenseAgreementsUrl == defaultSettings.LicenseAgreementsUrl;
}
}
[Singletone]
public class AdditionalWhiteLabelSettingsHelperInit
{
private readonly IConfiguration _configuration;
public AdditionalWhiteLabelSettingsHelper(IConfiguration configuration)
public AdditionalWhiteLabelSettingsHelperInit(IConfiguration configuration)
{
_configuration = configuration;
}

View File

@ -34,7 +34,7 @@ public class CompanyWhiteLabelSettingsWrapper
[Serializable]
public class CompanyWhiteLabelSettings : ISettings<CompanyWhiteLabelSettings>
{
private CoreSettings _coreSettings;
public CoreSettings CoreSettings;
public string CompanyName { get; set; }
@ -51,7 +51,7 @@ public class CompanyWhiteLabelSettings : ISettings<CompanyWhiteLabelSettings>
public CompanyWhiteLabelSettings(CoreSettings coreSettings)
{
_coreSettings = coreSettings;
CoreSettings = coreSettings;
}
public CompanyWhiteLabelSettings()
@ -59,21 +59,6 @@ public class CompanyWhiteLabelSettings : ISettings<CompanyWhiteLabelSettings>
}
public bool IsDefault
{
get
{
var defaultSettings = GetDefault();
return CompanyName == defaultSettings.CompanyName &&
Site == defaultSettings.Site &&
Email == defaultSettings.Email &&
Address == defaultSettings.Address &&
Phone == defaultSettings.Phone &&
IsLicensor == defaultSettings.IsLicensor;
}
}
#region ISettings Members
[JsonIgnore]
@ -85,19 +70,45 @@ public class CompanyWhiteLabelSettings : ISettings<CompanyWhiteLabelSettings>
public CompanyWhiteLabelSettings GetDefault()
{
var settings = _coreSettings.GetSetting("CompanyWhiteLabelSettings");
var settings = CoreSettings.GetSetting("CompanyWhiteLabelSettings");
var result = string.IsNullOrEmpty(settings) ? new CompanyWhiteLabelSettings(_coreSettings) : JsonConvert.DeserializeObject<CompanyWhiteLabelSettings>(settings);
var result = string.IsNullOrEmpty(settings) ? new CompanyWhiteLabelSettings(CoreSettings) : JsonConvert.DeserializeObject<CompanyWhiteLabelSettings>(settings);
result._coreSettings = _coreSettings;
result.CoreSettings = CoreSettings;
return result;
}
#endregion
}
public static CompanyWhiteLabelSettings Instance(SettingsManager settingsManager)
[Scope]
public class CompanyWhiteLabelSettingsHelper
{
private readonly CoreSettings _coreSettings;
private readonly SettingsManager _settingsManager;
public CompanyWhiteLabelSettingsHelper(CoreSettings coreSettings, SettingsManager settingsManager)
{
return settingsManager.LoadForDefaultTenant<CompanyWhiteLabelSettings>();
_coreSettings = coreSettings;
_settingsManager = settingsManager;
}
public CompanyWhiteLabelSettings Instance()
{
return _settingsManager.LoadForDefaultTenant<CompanyWhiteLabelSettings>();
}
public bool IsDefault(CompanyWhiteLabelSettings settings)
{
settings.CoreSettings = _coreSettings;
var defaultSettings = settings.GetDefault();
return settings.CompanyName == defaultSettings.CompanyName &&
settings.Site == defaultSettings.Site &&
settings.Email == defaultSettings.Email &&
settings.Address == defaultSettings.Address &&
settings.Phone == defaultSettings.Phone &&
settings.IsLicensor == defaultSettings.IsLicensor;
}
}