diff --git a/packages/client/src/components/TariffBar/helpers.js b/packages/client/src/components/TariffBar/helpers.js new file mode 100644 index 0000000000..5d90547430 --- /dev/null +++ b/packages/client/src/components/TariffBar/helpers.js @@ -0,0 +1,63 @@ +const ORANGE = "#F97A0B"; +const RED = "#F2665A"; + +export const getSaasBar = ( + t, + isPaymentPageAvailable, + isNonProfit, + isFreeTariff, + isGracePeriod +) => { + if ( + isPaymentPageAvailable && + !isNonProfit && + (isFreeTariff || isGracePeriod) + ) { + if (isFreeTariff) return { label: t("Common:TryBusiness"), color: ORANGE }; + if (isGracePeriod) return { label: t("Common:LatePayment"), color: RED }; + } +}; + +export const getEnterpriseBar = ( + t, + isPaymentPageAvailable, + isEnterprise, + isTrial, + isLicenseExpiring, + isLicenseDateExpired, + trialDaysLeft, + paymentDate +) => { + if ( + isPaymentPageAvailable && + isEnterprise && + (isTrial || isLicenseExpiring || isLicenseDateExpired) + ) { + if (isTrial) { + if (isLicenseDateExpired) + return { label: t("Common:TrialExpired"), color: ORANGE }; + return { + label: t("Common:TrialDaysLeft", { count: trialDaysLeft }), + color: ORANGE, + }; + } else { + if (isLicenseDateExpired) + return { + label: t("Common:SubscriptionExpiredTitle"), + color: RED, + }; + return { + label: t("Common:SubscriptionIsExpiring", { date: paymentDate }), + color: ORANGE, + }; + } + } +}; + +export const checkBar = () => { + const el = document.getElementById("tariff-bar-text"); + el?.classList?.remove("hidden"); + if (el?.offsetWidth < el?.scrollWidth) { + el?.classList?.add("hidden"); + } +}; diff --git a/packages/client/src/components/TariffBar/index.js b/packages/client/src/components/TariffBar/index.js new file mode 100644 index 0000000000..1104fd3a26 --- /dev/null +++ b/packages/client/src/components/TariffBar/index.js @@ -0,0 +1,135 @@ +import { useEffect } from "react"; +import styled from "styled-components"; +import { useNavigate } from "react-router-dom"; +import { inject, observer } from "mobx-react"; +import { useTranslation } from "react-i18next"; + +import { combineUrl } from "@docspace/shared/utils/combineUrl"; +import { Text } from "@docspace/shared/components/text"; +import { getSaasBar, getEnterpriseBar, checkBar } from "./helpers"; + +const StyledWrapper = styled.div` + display: grid; + cursor: pointer; + + #tariff-bar-text:hover { + opacity: 0.85; + } + + #tariff-bar-text:active { + filter: brightness(0.9); + } + + .hidden { + visibility: hidden; + } +`; + +const PROXY_BASE_URL = combineUrl( + window.DocSpaceConfig?.proxy?.url, + "/portal-settings" +); + +const TariffBar = ({ + isEnterprise, + isNonProfit, + isGracePeriod, + isFreeTariff, + isPaymentPageAvailable, + isLicenseExpiring, + isLicenseDateExpired, + isTrial, + standalone, + paymentDate, + trialDaysLeft, + title, +}) => { + const navigate = useNavigate(); + const { t } = useTranslation("Common"); + + const onClick = () => { + const paymentPageUrl = combineUrl( + PROXY_BASE_URL, + "/payments/portal-payments" + ); + navigate(paymentPageUrl); + }; + + useEffect(() => { + checkBar(); + }, []); + + useEffect(() => { + checkBar(); + }, [title]); + + const tariffBar = !standalone + ? getSaasBar( + t, + isPaymentPageAvailable, + isNonProfit, + isFreeTariff, + isGracePeriod + ) + : getEnterpriseBar( + t, + isPaymentPageAvailable, + isEnterprise, + isTrial, + isLicenseExpiring, + isLicenseDateExpired, + trialDaysLeft, + paymentDate + ); + + if (!tariffBar) return <>; + return ( + + + {tariffBar.label} + + + ); +}; + +export default inject(({ auth }) => { + const { + settingsStore, + currentQuotaStore, + isPaymentPageAvailable, + currentTariffStatusStore, + isEnterprise, + } = auth; + const { isFreeTariff, isNonProfit, isTrial } = currentQuotaStore; + const { + isGracePeriod, + isLicenseExpiring, + isLicenseDateExpired, + paymentDate, + trialDaysLeft, + } = currentTariffStatusStore; + const { standalone } = settingsStore; + + return { + isEnterprise, + isNonProfit, + isGracePeriod, + isFreeTariff, + isPaymentPageAvailable, + isLicenseExpiring, + isLicenseDateExpired, + isTrial, + standalone, + paymentDate, + trialDaysLeft, + }; +})(observer(TariffBar)); diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/handlers/TagHandler.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/handlers/TagHandler.js index a9d9d7cd65..c994ba6869 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/handlers/TagHandler.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/handlers/TagHandler.js @@ -22,6 +22,11 @@ class TagHandler { addTag(name) { let newTags = [...this.tags]; + + if (this.isAlreadyAdded(name)) { + return; //already added + } + newTags.push({ id: this.createRandomTagId(), name, @@ -29,11 +34,26 @@ class TagHandler { this.setTags(newTags); } + isAlreadyAdded(name) { + return !!this.tags.find((t) => t.name.toLowerCase() === name.toLowerCase()); + } + + isNew(name) { + return !this.fetchedTags.find( + (t) => t.toLowerCase() === name.toLowerCase() + ); + } + addNewTag(name) { let newTags = [...this.tags]; + + if (this.isAlreadyAdded(name)) { + return; //already added + } + newTags.push({ id: this.createRandomTagId(), - isNew: true, + isNew: this.isNew(name), name, }); this.setTags(newTags); diff --git a/packages/client/src/components/dialogs/ReportDialog/index.js b/packages/client/src/components/dialogs/ReportDialog/index.js index 993590305e..bdaa60b60b 100644 --- a/packages/client/src/components/dialogs/ReportDialog/index.js +++ b/packages/client/src/components/dialogs/ReportDialog/index.js @@ -119,7 +119,7 @@ const ReportDialog = (props) => { onChange={onChangeTextareaValue} autoFocus areaSelect - heightTextArea={72} + heightTextArea="72px" fontSize={13} />
diff --git a/packages/client/src/components/panels/EmbeddingPanel/EmbeddingBody.js b/packages/client/src/components/panels/EmbeddingPanel/EmbeddingBody.js index 56038605cc..deb2efeb83 100644 --- a/packages/client/src/components/panels/EmbeddingPanel/EmbeddingBody.js +++ b/packages/client/src/components/panels/EmbeddingPanel/EmbeddingBody.js @@ -145,7 +145,7 @@ const EmbeddingBody = ({ t, link, requestToken, roomId }) => { iconName={CopyReactSvgUrl} onClick={onCopyLink} /> -