Client: Added dialogues if the limits for adding users and rooms have been reached.
This commit is contained in:
parent
a19211f9a6
commit
ec0dbf9518
@ -9,6 +9,8 @@
|
||||
"BusinessSuggestion": "Customize your {{planName}} plan",
|
||||
"BusinessTitle": "You are using {{planName}} plan",
|
||||
"BusinessUpdated": "{{planName}} plan updated",
|
||||
"CannotCreateNewRoom": "Cannot create new room.",
|
||||
"CannotCreatePaidUsers": "Cannot add new paid users. ",
|
||||
"ChooseNewPayer": "Choose a new Payer",
|
||||
"ChooseNewPlan": "Would you like to choose a new pricing plan?",
|
||||
"ContactUs": "For sales questions, contact us at",
|
||||
@ -22,6 +24,8 @@
|
||||
"InvalidEmailWithoutActiveSubscription": "We recommend choosing a new Payer who gets access to subscription settings in {{productName}}.",
|
||||
"InvalidEmailWithoutActiveSubscriptionByAdmin": "We recommend contacting the {{productName}} owner to choose a new Payer.",
|
||||
"ManagerTypesDescription": "Admin account types and their privileges",
|
||||
"NewRoomWillExceedLimit": "Creating new room will exceed the maximum number of rooms allowed by your current pricing plan.",
|
||||
"NewUsersWillExceedMembersLimit": "Adding new users will exceed the maximum number of portal paid members allowed by your current pricing plan.",
|
||||
"Pay": "Pay",
|
||||
"Payer": "Payer",
|
||||
"PayerDescription": "This user has access to payment details and is the only user who can adjust the quota and make payments. The {{productName}} owner, as well as the paying manager themselves, can reassign the paying manager role using the Stripe customer portal.",
|
||||
|
@ -83,7 +83,7 @@ const withHotkeys = (Component) => {
|
||||
isVisitor,
|
||||
deleteRooms,
|
||||
archiveRooms,
|
||||
isGracePeriod,
|
||||
isWarningRoomsDialog,
|
||||
setInviteUsersWarningDialogVisible,
|
||||
|
||||
security,
|
||||
@ -158,7 +158,7 @@ const withHotkeys = (Component) => {
|
||||
|
||||
const onCreateRoom = () => {
|
||||
if (!isVisitor && isRoomsFolder && security?.Create) {
|
||||
if (isGracePeriod) {
|
||||
if (isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
@ -436,7 +436,7 @@ const withHotkeys = (Component) => {
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
userStore,
|
||||
currentTariffStatusStore,
|
||||
currentQuotaStore,
|
||||
}) => {
|
||||
const {
|
||||
setSelected,
|
||||
@ -487,7 +487,6 @@ const withHotkeys = (Component) => {
|
||||
|
||||
const { visible: mediaViewerIsVisible } = mediaViewerDataStore;
|
||||
const { setHotkeyPanelVisible } = settingsStore;
|
||||
const { isGracePeriod } = currentTariffStatusStore;
|
||||
|
||||
const isVisitor = userStore.user?.isVisitor;
|
||||
|
||||
@ -499,6 +498,8 @@ const withHotkeys = (Component) => {
|
||||
isRoomsFolder,
|
||||
} = treeFoldersStore;
|
||||
|
||||
const { isWarningRoomsDialog } = currentQuotaStore;
|
||||
|
||||
const security = selectedFolderStore.security;
|
||||
const isFormRoom = selectedFolderStore.roomType === RoomsType.FormRoom;
|
||||
const isParentFolderFormRoom =
|
||||
@ -553,7 +554,7 @@ const withHotkeys = (Component) => {
|
||||
deleteRooms,
|
||||
archiveRooms,
|
||||
|
||||
isGracePeriod,
|
||||
isWarningRoomsDialog,
|
||||
setInviteUsersWarningDialogVisible,
|
||||
|
||||
security,
|
||||
|
@ -171,7 +171,6 @@ const ArticleMainButtonContent = (props) => {
|
||||
copyPanelVisible,
|
||||
|
||||
security,
|
||||
isGracePeriod,
|
||||
setInviteUsersWarningDialogVisible,
|
||||
currentDeviceType,
|
||||
|
||||
@ -181,6 +180,7 @@ const ArticleMainButtonContent = (props) => {
|
||||
parentRoomType,
|
||||
isFolder,
|
||||
showWarningDialog,
|
||||
isWarningRoomsDialog,
|
||||
} = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -219,7 +219,7 @@ const ArticleMainButtonContent = (props) => {
|
||||
);
|
||||
|
||||
const onCreateRoom = React.useCallback(() => {
|
||||
if (isGracePeriod) {
|
||||
if (isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
@ -940,8 +940,8 @@ export default inject(
|
||||
const isFolder = selectedFolderStore.isFolder;
|
||||
|
||||
const { isAdmin, isOwner, isRoomAdmin } = userStore.user;
|
||||
const { isGracePeriod } = currentTariffStatusStore;
|
||||
const { showWarningDialog } = currentQuotaStore;
|
||||
|
||||
const { showWarningDialog, isWarningRoomsDialog } = currentQuotaStore;
|
||||
|
||||
const { setOformFromFolderId, oformsFilter } = oformsStore;
|
||||
const { mainButtonItemsList } = pluginStore;
|
||||
@ -949,7 +949,6 @@ export default inject(
|
||||
const { frameConfig, isFrame } = settingsStore;
|
||||
|
||||
return {
|
||||
isGracePeriod,
|
||||
setInviteUsersWarningDialogVisible,
|
||||
showText: settingsStore.showText,
|
||||
isMobileArticle: settingsStore.isMobileArticle,
|
||||
@ -1002,6 +1001,7 @@ export default inject(
|
||||
setSelectFileFormRoomDialogVisible,
|
||||
|
||||
showWarningDialog,
|
||||
isWarningRoomsDialog,
|
||||
};
|
||||
},
|
||||
)(
|
||||
|
@ -79,7 +79,7 @@ const EmptyContainer = ({
|
||||
};
|
||||
|
||||
const onCreateRoom = (e) => {
|
||||
if (isGracePeriod) {
|
||||
if (isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
@ -126,7 +126,7 @@ export default inject(
|
||||
settingsStore,
|
||||
filesStore,
|
||||
dialogsStore,
|
||||
|
||||
currentQuotaStore,
|
||||
selectedFolderStore,
|
||||
clientLoadingStore,
|
||||
currentTariffStatusStore,
|
||||
@ -144,6 +144,7 @@ export default inject(
|
||||
isFiltered === null && isErrorRoomNotAvailable;
|
||||
|
||||
const isRoot = selectedFolderStore.pathParts?.length === 1;
|
||||
const { isWarningRoomsDialog } = currentQuotaStore;
|
||||
|
||||
return {
|
||||
theme: settingsStore.theme,
|
||||
@ -157,6 +158,7 @@ export default inject(
|
||||
type: selectedFolderStore.type,
|
||||
isRoot,
|
||||
isPublicRoom,
|
||||
isWarningRoomsDialog,
|
||||
};
|
||||
},
|
||||
)(observer(EmptyContainer));
|
||||
|
@ -27,14 +27,16 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import moment from "moment-timezone";
|
||||
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import { getDaysRemaining } from "@docspace/shared/utils/common";
|
||||
|
||||
import RoomsContent from "./sub-components/RoomsContent";
|
||||
import UsersContent from "./sub-components/UsersContent";
|
||||
|
||||
const InviteUsersWarningDialog = (props) => {
|
||||
const {
|
||||
t,
|
||||
@ -48,6 +50,8 @@ const InviteUsersWarningDialog = (props) => {
|
||||
isGracePeriod,
|
||||
currentTariffPlanTitle,
|
||||
isPaymentPageAvailable,
|
||||
isRoomsTariffLimit,
|
||||
isUserTariffLimit,
|
||||
} = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -84,6 +88,31 @@ const InviteUsersWarningDialog = (props) => {
|
||||
navigate(paymentPageUrl);
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
const isAccounts = location.pathname.includes("accounts/people");
|
||||
|
||||
const contentForGracePeriod = (
|
||||
<>
|
||||
<Text fontWeight={700} noSelect>
|
||||
{t("BusinessPlanPaymentOverdue", {
|
||||
planName: currentTariffPlanTitle,
|
||||
})}
|
||||
</Text>
|
||||
<br />
|
||||
<Text noSelect as="div">
|
||||
<Trans t={t} i18nKey="GracePeriodActivatedInfo" ns="Payments">
|
||||
Grace period activated
|
||||
<strong>
|
||||
from {{ fromDate }} to {{ byDate }}
|
||||
</strong>
|
||||
(days remaining: {{ delayDaysCount }})
|
||||
</Trans>
|
||||
</Text>
|
||||
<br />
|
||||
<Text>{t("GracePeriodActivatedDescription")}</Text>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
isLarge={isGracePeriod}
|
||||
@ -95,37 +124,24 @@ const InviteUsersWarningDialog = (props) => {
|
||||
>
|
||||
<ModalDialog.Header>{t("Common:Warning")}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
{isGracePeriod ? (
|
||||
<>
|
||||
<Text fontWeight={700} noSelect>
|
||||
{t("BusinessPlanPaymentOverdue", {
|
||||
planName: currentTariffPlanTitle,
|
||||
})}
|
||||
</Text>
|
||||
<br />
|
||||
<Text noSelect as="div">
|
||||
<Trans t={t} i18nKey="GracePeriodActivatedInfo" ns="Payments">
|
||||
Grace period activated
|
||||
<strong>
|
||||
from {{ fromDate }} to {{ byDate }}
|
||||
</strong>
|
||||
(days remaining: {{ delayDaysCount }})
|
||||
</Trans>
|
||||
</Text>
|
||||
<br />
|
||||
<Text>{t("GracePeriodActivatedDescription")}</Text>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text fontWeight={700} noSelect>
|
||||
{t("PaymentOverdue")}
|
||||
</Text>
|
||||
<br />
|
||||
<Text>{t("UpgradePlanInfo")}</Text>
|
||||
<br />
|
||||
<Text>{t("ChooseNewPlan")}</Text>
|
||||
</>
|
||||
)}
|
||||
{
|
||||
isGracePeriod ? (
|
||||
contentForGracePeriod
|
||||
) : isAccounts ? (
|
||||
<UsersContent />
|
||||
) : (
|
||||
<RoomsContent />
|
||||
)
|
||||
// <>
|
||||
// <Text fontWeight={700} noSelect>
|
||||
// {t("PaymentOverdue")}
|
||||
// </Text>
|
||||
// <br />
|
||||
// <Text>{t("UpgradePlanInfo")}</Text>
|
||||
// <br />
|
||||
// <Text>{t("ChooseNewPlan")}</Text>
|
||||
// </>
|
||||
}
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
@ -161,7 +177,8 @@ export default inject(
|
||||
}) => {
|
||||
const { isPaymentPageAvailable } = authStore;
|
||||
const { dueDate, delayDueDate, isGracePeriod } = currentTariffStatusStore;
|
||||
const { currentTariffPlanTitle } = currentQuotaStore;
|
||||
const { currentTariffPlanTitle, isRoomsTariffLimit, isUserTariffLimit } =
|
||||
currentQuotaStore;
|
||||
|
||||
const {
|
||||
inviteUsersWarningDialogVisible,
|
||||
@ -177,6 +194,8 @@ export default inject(
|
||||
dueDate,
|
||||
delayDueDate,
|
||||
isGracePeriod,
|
||||
isRoomsTariffLimit,
|
||||
isUserTariffLimit,
|
||||
};
|
||||
},
|
||||
)(observer(withTranslation(["Payments", "Common"])(InviteUsersWarningDialog)));
|
||||
|
@ -0,0 +1,56 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// 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
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
export interface RoomsContentProps {
|
||||
isRoomsTariffLimit: boolean;
|
||||
}
|
||||
|
||||
const RoomsContent = ({ isRoomsTariffLimit }: RoomsContentProps) => {
|
||||
const { t } = useTranslation(["Payments", "Common"]);
|
||||
if (isRoomsTariffLimit)
|
||||
return (
|
||||
<>
|
||||
<Text fontWeight={600}>{t("CannotCreateNewRoom")}</Text>
|
||||
<br />
|
||||
<Text>{t("NewRoomWillExceedLimit")}</Text>
|
||||
<br />
|
||||
<Text>{t("ChooseNewPlan")}</Text>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ currentQuotaStore }) => {
|
||||
const { isRoomsTariffLimit } = currentQuotaStore;
|
||||
|
||||
return {
|
||||
isRoomsTariffLimit,
|
||||
};
|
||||
})(observer(RoomsContent));
|
@ -0,0 +1,82 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// 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
|
||||
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// 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
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
export interface UsersContentProps {
|
||||
isUserTariffLimit: boolean;
|
||||
}
|
||||
|
||||
const UsersContent = ({ isUserTariffLimit }: UsersContentProps) => {
|
||||
const { t } = useTranslation(["Payments", "Common"]);
|
||||
if (isUserTariffLimit)
|
||||
return (
|
||||
<>
|
||||
<Text fontWeight={600}>{t("CannotCreatePaidUsers")}</Text>
|
||||
<br />
|
||||
<Text>{t("NewUsersWillExceedMembersLimit")}</Text>
|
||||
<br />
|
||||
<Text>{t("ChooseNewPlan")}</Text>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ currentQuotaStore }) => {
|
||||
const { isUserTariffLimit } = currentQuotaStore;
|
||||
|
||||
return {
|
||||
isUserTariffLimit,
|
||||
};
|
||||
})(observer(UsersContent));
|
@ -886,14 +886,14 @@ class ContextOptionsStore {
|
||||
onClickArchive = (e) => {
|
||||
const data = (e.currentTarget && e.currentTarget.dataset) || e;
|
||||
const { action } = data;
|
||||
const { isGracePeriod } = this.currentTariffStatusStore;
|
||||
const { isWarningRoomsDialog } = this.currentQuotaStore;
|
||||
const {
|
||||
setArchiveDialogVisible,
|
||||
setRestoreRoomDialogVisible,
|
||||
setInviteUsersWarningDialogVisible,
|
||||
} = this.dialogsStore;
|
||||
|
||||
if (action === "unarchive" && isGracePeriod) {
|
||||
if (action === "unarchive" && isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
@ -1117,7 +1117,7 @@ class ContextOptionsStore {
|
||||
|
||||
if (isExistActiveItems) return;
|
||||
|
||||
if (this.currentTariffStatusStore.isGracePeriod) {
|
||||
if (this.currentQuotaStore.isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
@ -2138,7 +2138,7 @@ class ContextOptionsStore {
|
||||
};
|
||||
|
||||
onCreateRoom = () => {
|
||||
if (this.currentTariffStatusStore.isGracePeriod) {
|
||||
if (this.currentQuotaStore.isWarningRoomsDialog) {
|
||||
this.dialogsStore.setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
|
@ -1799,9 +1799,10 @@ class FilesActionStore {
|
||||
setInviteUsersWarningDialogVisible,
|
||||
setRestoreRoomDialogVisible,
|
||||
} = this.dialogsStore;
|
||||
const { isGracePeriod } = this.currentTariffStatusStore;
|
||||
|
||||
if (action === "unarchive" && isGracePeriod) {
|
||||
const { isWarningRoomsDialog } = this.currentQuotaStore;
|
||||
|
||||
if (action === "unarchive" && isWarningRoomsDialog) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
|
@ -259,6 +259,14 @@ class CurrentQuotasStore {
|
||||
);
|
||||
}
|
||||
|
||||
get isRoomsTariffLimit() {
|
||||
return (
|
||||
this.maxCountRoomsByQuota - this.usedRoomsCount <=
|
||||
COUNT_FOR_SHOWING_BAR &&
|
||||
this.usedRoomsCount >= this.maxCountRoomsByQuota
|
||||
);
|
||||
}
|
||||
|
||||
get isStorageTariffAlmostLimit() {
|
||||
return (
|
||||
(this.usedTotalStorageSizeCount / this.maxTotalSizeByQuota) * 100 >=
|
||||
@ -326,6 +334,12 @@ class CurrentQuotasStore {
|
||||
return this.currentTariffStatusStore?.isGracePeriod;
|
||||
};
|
||||
|
||||
get isWarningRoomsDialog() {
|
||||
return (
|
||||
this.currentTariffStatusStore?.isGracePeriod || this.isRoomsTariffLimit
|
||||
);
|
||||
}
|
||||
|
||||
get isPersonalQuotaLimit() {
|
||||
const personalQuotaLimitReached = this.userStore?.personalQuotaLimitReached;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user