Updated License page with new design (#3405)
This commit is contained in:
32
web-app/src/screens/Console/License/CheckIcon.tsx
Normal file
32
web-app/src/screens/Console/License/CheckIcon.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2024 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import * as React from "react";
|
||||
import { SVGProps } from "react";
|
||||
|
||||
const CheckIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
{...props}
|
||||
>
|
||||
<polygon points="8.5 16.5 21.5 3.6 23.4 5.5 8.5 20.4 .6 12.5 2.5 10.5 8.5 16.5" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default CheckIcon;
|
||||
@@ -1,41 +0,0 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
import LicenseFAQ from "./LicenseFAQ";
|
||||
import { useSelector } from "react-redux";
|
||||
import { AppState, useAppDispatch } from "../../../store";
|
||||
import { closeFAQModal } from "./licenseSlice";
|
||||
|
||||
const FAQModal = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isOpen = useSelector((state: AppState) => state.license.faqModalOpen);
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={isOpen}
|
||||
title="License FAQ"
|
||||
onClose={() => {
|
||||
dispatch(closeFAQModal());
|
||||
}}
|
||||
>
|
||||
<LicenseFAQ />
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default FAQModal;
|
||||
@@ -14,30 +14,13 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
AGPLV3Logo,
|
||||
Box,
|
||||
breakPoints,
|
||||
Button,
|
||||
CheckCircleIcon,
|
||||
ConsoleEnterprise,
|
||||
ConsoleStandard,
|
||||
LicenseDocIcon,
|
||||
} from "mds";
|
||||
import React, { Fragment } from "react";
|
||||
import { Box, Button } from "mds";
|
||||
import { SubnetInfo } from "./types";
|
||||
import {
|
||||
COMMUNITY_PLAN_FEATURES,
|
||||
ENTERPRISE_PLAN_FEATURES,
|
||||
FEATURE_ITEMS,
|
||||
getRenderValue,
|
||||
LICENSE_PLANS,
|
||||
PAID_PLANS,
|
||||
STANDARD_PLAN_FEATURES,
|
||||
} from "./utils";
|
||||
import { FEATURE_ITEMS, FeatureItem, LICENSE_PLANS_INFORMATION } from "./utils";
|
||||
import styled from "styled-components";
|
||||
import get from "lodash/get";
|
||||
import CheckIcon from "./CheckIcon";
|
||||
|
||||
interface IRegisterStatus {
|
||||
activateProductModal: any;
|
||||
@@ -47,441 +30,105 @@ interface IRegisterStatus {
|
||||
setActivateProductModal: any;
|
||||
}
|
||||
|
||||
const PlanListContainer = styled.div(({ theme }) => ({
|
||||
const LicensesInformation = styled.div(({ theme }) => ({
|
||||
display: "grid",
|
||||
|
||||
margin: "0 1.5rem 0 1.5rem",
|
||||
|
||||
gridTemplateColumns: "1fr 1fr 1fr 1fr",
|
||||
|
||||
[`@media (max-width: ${breakPoints.sm}px)`]: {
|
||||
gridTemplateColumns: "1fr 1fr 1fr",
|
||||
},
|
||||
|
||||
"&.paid-plans-only": {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr 1fr",
|
||||
},
|
||||
|
||||
"& .features-col": {
|
||||
flex: 1,
|
||||
minWidth: "260px",
|
||||
|
||||
"@media (max-width: 600px)": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
"& .xs-only": {
|
||||
display: "none",
|
||||
},
|
||||
|
||||
"& .button-box": {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gridTemplateColumns: "repeat(4, minmax(350px, 400px));",
|
||||
justifyContent: "flex-start",
|
||||
marginTop: 30,
|
||||
marginLeft: 30,
|
||||
"& > div": {
|
||||
borderBottom: `${get(theme, "borderColor", "#EAEAEA")} 1px solid`,
|
||||
padding: "25px 40px",
|
||||
justifyContent: "center",
|
||||
padding: "5px 0px 25px 0px",
|
||||
borderLeft: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
},
|
||||
"& .plan-header": {
|
||||
height: "99px",
|
||||
borderBottom: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
},
|
||||
"& .feature-title": {
|
||||
height: "25px",
|
||||
paddingLeft: "26px",
|
||||
fontSize: "14px",
|
||||
|
||||
background: get(theme, "signalColors.disabled", "#E5E5E5"),
|
||||
color: get(theme, "signalColors.main", "#07193E"),
|
||||
|
||||
"@media (max-width: 600px)": {
|
||||
"& .feature-title-info .xs-only": {
|
||||
"&.openSource": {
|
||||
borderRight: `#002562 2px solid`,
|
||||
borderLeft: `#002562 2px solid`,
|
||||
position: "relative",
|
||||
"&.first:before": {
|
||||
content: "' '",
|
||||
width: "calc(100% + 4px)",
|
||||
height: 16,
|
||||
display: "block",
|
||||
backgroundColor: "#001F55",
|
||||
position: "absolute",
|
||||
top: -14,
|
||||
left: -2,
|
||||
border: `#002562 2px solid`,
|
||||
borderBottom: 0,
|
||||
borderTopLeftRadius: 12,
|
||||
borderTopRightRadius: 12,
|
||||
},
|
||||
"&.last": {
|
||||
paddingBottom: 30,
|
||||
"&:after": {
|
||||
content: "' '",
|
||||
width: "calc(100% + 4px)",
|
||||
height: 16,
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
bottom: -14,
|
||||
left: -2,
|
||||
border: `#002562 2px solid`,
|
||||
borderTop: 0,
|
||||
borderBottomLeftRadius: 12,
|
||||
borderBottomRightRadius: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"& .feature-name": {
|
||||
minHeight: "60px",
|
||||
padding: "5px",
|
||||
borderBottom: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
paddingLeft: "26px",
|
||||
fontSize: "14px",
|
||||
},
|
||||
"& .feature-item": {
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
minHeight: "60px",
|
||||
padding: "0 15px 0 15px",
|
||||
borderBottom: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
borderLeft: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
fontSize: "14px",
|
||||
"& .link-text": {
|
||||
color: "#2781B0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "underline",
|
||||
"&.feature-information": {
|
||||
textAlign: "center",
|
||||
},
|
||||
|
||||
"&.icon-yes": {
|
||||
width: "15px",
|
||||
height: "15px",
|
||||
"&.feature-label": {
|
||||
paddingLeft: 5,
|
||||
},
|
||||
"&.noBorderBottom": {
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
|
||||
"& .feature-item-info": {
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-around",
|
||||
"& .planName": {
|
||||
fontWeight: 600,
|
||||
fontSize: 35,
|
||||
marginBottom: 20,
|
||||
textAlign: "center",
|
||||
|
||||
"@media (max-width: 600px)": {
|
||||
justifyContent: "space-evenly",
|
||||
width: "100%",
|
||||
"& .xs-only": {
|
||||
display: "block",
|
||||
},
|
||||
"& .plan-feature": {
|
||||
textAlign: "center",
|
||||
paddingRight: "10px",
|
||||
},
|
||||
},
|
||||
marginTop: 10,
|
||||
},
|
||||
|
||||
"& .plan-col": {
|
||||
minWidth: "260px",
|
||||
flex: 1,
|
||||
},
|
||||
|
||||
"& .active-plan-col": {
|
||||
background: `${get(
|
||||
theme,
|
||||
"boxBackground",
|
||||
"#FDFDFD",
|
||||
)} 0% 0% no-repeat padding-box`,
|
||||
boxShadow: " 0px 3px 20px #00000038",
|
||||
|
||||
"& .plan-header": {
|
||||
backgroundColor: get(theme, "signalColors.info", "#2781B0"),
|
||||
},
|
||||
|
||||
"& .feature-title": {
|
||||
background: get(theme, "signalColors.disabled", "#E5E5E5"),
|
||||
color: get(theme, "fontColor", "#000"),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const PlanHeaderContainer = styled.div(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "center",
|
||||
flexFlow: "column",
|
||||
borderLeft: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
borderBottom: "0px !important",
|
||||
"& .plan-header": {
|
||||
"& .planIcon": {
|
||||
height: 45,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "center",
|
||||
flexFlow: "column",
|
||||
"& svg": {
|
||||
height: 35,
|
||||
},
|
||||
"&.commercial": {
|
||||
"& svg": {
|
||||
height: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"& .title-block": {
|
||||
"& .planDescription": {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexFlow: "column",
|
||||
width: "100%",
|
||||
"& .title-main": {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flex: 1,
|
||||
},
|
||||
"& .iconContainer": {
|
||||
"& .min-icon": {
|
||||
minWidth: 140,
|
||||
width: "100%",
|
||||
maxHeight: 55,
|
||||
height: "100%",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"& .open-source": {
|
||||
fontSize: "14px",
|
||||
display: "flex",
|
||||
marginBottom: "5px",
|
||||
alignItems: "center",
|
||||
"& .min-icon": {
|
||||
marginRight: "8px",
|
||||
height: "12px",
|
||||
width: "12px",
|
||||
},
|
||||
},
|
||||
|
||||
"& .cur-plan-text": {
|
||||
fontSize: "12px",
|
||||
textTransform: "uppercase",
|
||||
},
|
||||
|
||||
"@media (max-width: 600px)": {
|
||||
cursor: "pointer",
|
||||
"& .title-block": {
|
||||
"& .title": {
|
||||
fontSize: "14px",
|
||||
fontWeight: 600,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"&.active, &.active.xs-active": {
|
||||
color: "#ffffff",
|
||||
position: "relative",
|
||||
|
||||
"& .min-icon": {
|
||||
fill: "#ffffff",
|
||||
},
|
||||
|
||||
"&:before": {
|
||||
content: "' '",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "18px",
|
||||
backgroundColor: get(theme, "signalColors.info", "#2781B0"),
|
||||
display: "block",
|
||||
top: -16,
|
||||
},
|
||||
"& .iconContainer": {
|
||||
"& .min-icon": {
|
||||
marginTop: "-12px",
|
||||
},
|
||||
},
|
||||
},
|
||||
"&.active": {
|
||||
backgroundColor: get(theme, "signalColors.info", "#2781B0"),
|
||||
color: "#ffffff",
|
||||
},
|
||||
"&.xs-active": {
|
||||
background: "#eaeaea",
|
||||
justifyContent: "center",
|
||||
},
|
||||
}));
|
||||
|
||||
const ListContainer = styled.div(({ theme }) => ({
|
||||
border: `1px solid ${get(theme, "borderColor", "#EAEAEA")}`,
|
||||
borderTop: "0px",
|
||||
marginBottom: "45px",
|
||||
"&::-webkit-scrollbar": {
|
||||
width: "5px",
|
||||
height: "5px",
|
||||
},
|
||||
"&::-webkit-scrollbar-track": {
|
||||
background: "#F0F0F0",
|
||||
borderRadius: 0,
|
||||
boxShadow: "inset 0px 0px 0px 0px #F0F0F0",
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
background: "#777474",
|
||||
borderRadius: 0,
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb:hover": {
|
||||
background: "#5A6375",
|
||||
},
|
||||
}));
|
||||
|
||||
const PlanHeader = ({
|
||||
isActive,
|
||||
isXsViewActive,
|
||||
title,
|
||||
onClick,
|
||||
children,
|
||||
}: {
|
||||
isActive: boolean;
|
||||
isXsViewActive: boolean;
|
||||
title: string;
|
||||
price?: string;
|
||||
onClick: any;
|
||||
children: any;
|
||||
}) => {
|
||||
const plan = title.toLowerCase();
|
||||
return (
|
||||
<PlanHeaderContainer
|
||||
className={clsx({
|
||||
"plan-header": true,
|
||||
active: isActive,
|
||||
[`xs-active`]: isXsViewActive,
|
||||
})}
|
||||
onClick={() => {
|
||||
onClick && onClick(plan);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</PlanHeaderContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const FeatureTitleRowCmp = (props: { featureLabel: any }) => {
|
||||
return (
|
||||
<Box className="feature-title">
|
||||
<Box className="feature-title-info">
|
||||
<div className="xs-only">{props.featureLabel} </div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const PricingFeatureItem = (props: {
|
||||
featureLabel: any;
|
||||
label?: any;
|
||||
detail?: any;
|
||||
xsLabel?: string;
|
||||
style?: any;
|
||||
}) => {
|
||||
return (
|
||||
<Box className="feature-item" style={props.style}>
|
||||
<Box className="feature-item-info">
|
||||
<div className="xs-only">
|
||||
{getRenderValue(props.featureLabel || "")}
|
||||
</div>
|
||||
<Box className="plan-feature">
|
||||
<div>{getRenderValue(props.label || "")}</div>
|
||||
{getRenderValue(props.detail)}
|
||||
|
||||
<div className="xs-only">{props.xsLabel} </div>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const LicensePlans = ({ licenseInfo }: IRegisterStatus) => {
|
||||
const [isSmallScreen, setIsSmallScreen] = useState<boolean>(
|
||||
window.innerWidth >= breakPoints.sm,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const handleWindowResize = () => {
|
||||
let extMD = false;
|
||||
if (window.innerWidth >= breakPoints.sm) {
|
||||
extMD = true;
|
||||
}
|
||||
setIsSmallScreen(extMD);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleWindowResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleWindowResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
let currentPlan = !licenseInfo
|
||||
? "community"
|
||||
: licenseInfo?.plan?.toLowerCase();
|
||||
|
||||
const isCommunityPlan = currentPlan === LICENSE_PLANS.COMMUNITY;
|
||||
const isStandardPlan = currentPlan === LICENSE_PLANS.STANDARD;
|
||||
const isEnterprisePlan = [
|
||||
LICENSE_PLANS.ENTERPRISE,
|
||||
LICENSE_PLANS.ENTERPRISE_LITE,
|
||||
LICENSE_PLANS.ENTERPRISE_PLUS,
|
||||
].includes(currentPlan);
|
||||
|
||||
const isPaidPlan = PAID_PLANS.includes(currentPlan);
|
||||
|
||||
/*In smaller screen use tabbed view to show features*/
|
||||
const [xsPlanView, setXsPlanView] = useState("");
|
||||
let isXsViewCommunity = xsPlanView === LICENSE_PLANS.COMMUNITY;
|
||||
let isXsViewStandard = xsPlanView === LICENSE_PLANS.STANDARD;
|
||||
let isXsViewEnterprise = [
|
||||
LICENSE_PLANS.ENTERPRISE,
|
||||
LICENSE_PLANS.ENTERPRISE_LITE,
|
||||
LICENSE_PLANS.ENTERPRISE_PLUS,
|
||||
].includes(xsPlanView);
|
||||
|
||||
const getCommunityPlanHeader = () => {
|
||||
return (
|
||||
<PlanHeader
|
||||
key={"community-header"}
|
||||
isActive={isCommunityPlan}
|
||||
isXsViewActive={isXsViewCommunity}
|
||||
title={"community"}
|
||||
onClick={isSmallScreen ? onPlanClick : null}
|
||||
>
|
||||
<Box className="title-block">
|
||||
<Box className="title-main">
|
||||
<div className="iconContainer">
|
||||
<AGPLV3Logo style={{ width: 117 }} />
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
</PlanHeader>
|
||||
);
|
||||
};
|
||||
|
||||
const getStandardPlanHeader = () => {
|
||||
return (
|
||||
<PlanHeader
|
||||
key={"standard-header"}
|
||||
isActive={isStandardPlan}
|
||||
isXsViewActive={isXsViewStandard}
|
||||
title={"Standard"}
|
||||
onClick={isSmallScreen ? onPlanClick : null}
|
||||
>
|
||||
<Box className="title-block">
|
||||
<Box className="title-main">
|
||||
<div className="iconContainer">
|
||||
<ConsoleStandard />
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
</PlanHeader>
|
||||
);
|
||||
};
|
||||
|
||||
const getEnterpriseHeader = () => {
|
||||
return (
|
||||
<PlanHeader
|
||||
key={"enterprise-header"}
|
||||
isActive={isEnterprisePlan}
|
||||
isXsViewActive={isXsViewEnterprise}
|
||||
title={"Enterprise"}
|
||||
onClick={isSmallScreen ? onPlanClick : null}
|
||||
>
|
||||
<Box className="title-block">
|
||||
<Box className="title-main">
|
||||
<div className="iconContainer">
|
||||
<ConsoleEnterprise />
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
</PlanHeader>
|
||||
);
|
||||
};
|
||||
|
||||
const getButton = (
|
||||
link: string,
|
||||
btnText: string,
|
||||
variant: any,
|
||||
plan: string,
|
||||
) => {
|
||||
const getButton = (link: string, btnText: string, variant: any) => {
|
||||
let linkToNav =
|
||||
currentPlan !== "community" ? "https://subnet.min.io" : link;
|
||||
return (
|
||||
<Button
|
||||
id={`license-action-${link}`}
|
||||
variant={variant}
|
||||
style={{
|
||||
sx={{
|
||||
marginTop: "12px",
|
||||
width: "80%",
|
||||
height: "55px",
|
||||
}}
|
||||
disabled={
|
||||
currentPlan !== LICENSE_PLANS.COMMUNITY && currentPlan !== plan
|
||||
}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -492,264 +139,88 @@ const LicensePlans = ({ licenseInfo }: IRegisterStatus) => {
|
||||
);
|
||||
};
|
||||
|
||||
const onPlanClick = (plan: string) => {
|
||||
setXsPlanView(plan);
|
||||
const renderFeatureInformation = (content: FeatureItem | null) => {
|
||||
if (content) {
|
||||
return (
|
||||
<Fragment>
|
||||
{content.content}
|
||||
{content.isCheck && <CheckIcon style={{ width: 16, height: 16 }} />}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
return <Fragment />;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isSmallScreen) {
|
||||
setXsPlanView(currentPlan || "community");
|
||||
} else {
|
||||
setXsPlanView("");
|
||||
}
|
||||
}, [isSmallScreen, currentPlan]);
|
||||
|
||||
const featureList = FEATURE_ITEMS;
|
||||
return (
|
||||
<Fragment>
|
||||
<ListContainer>
|
||||
<Box
|
||||
className={"title-blue-bar"}
|
||||
sx={{
|
||||
height: "8px",
|
||||
borderBottom: "8px solid rgb(6 48 83)",
|
||||
}}
|
||||
/>
|
||||
<PlanListContainer className={isPaidPlan ? "paid-plans-only" : ""}>
|
||||
<Box className="features-col">
|
||||
{featureList.map((fi) => {
|
||||
const featureTitleRow = fi.featureTitleRow;
|
||||
const isHeader = fi.isHeader;
|
||||
|
||||
if (isHeader) {
|
||||
if (isPaidPlan) {
|
||||
return (
|
||||
<Box
|
||||
key={`plan-header-${fi.desc}`}
|
||||
className="plan-header"
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
paddingLeft: "26px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
borderBottom: "0px !important",
|
||||
|
||||
"& .link-text": {
|
||||
color: "#2781B0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "underline",
|
||||
},
|
||||
|
||||
"& .min-icon": {
|
||||
marginRight: "10px",
|
||||
color: "#2781B0",
|
||||
fill: "#2781B0",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<LicenseDocIcon />
|
||||
<a
|
||||
href={`https://subnet.min.io/terms-and-conditions/${currentPlan}`}
|
||||
rel="noopener"
|
||||
className={"link-text"}
|
||||
>
|
||||
View License agreement <br />
|
||||
for the registered plan.
|
||||
</a>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LicensesInformation>
|
||||
{[null, ...LICENSE_PLANS_INFORMATION].map((element, index) => {
|
||||
return (
|
||||
<Box className={`${index === 1 ? "openSource first" : ""}`}>
|
||||
{element !== null && (
|
||||
<Box>
|
||||
<Box className={"planName"}>{element.planName}</Box>
|
||||
<Box
|
||||
key={`plan-header-label-${fi.desc}`}
|
||||
className={`plan-header`}
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
paddingLeft: "26px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
borderBottom: "0px !important",
|
||||
}}
|
||||
className={`planIcon ${
|
||||
element.planType === "commercial" ? "commercial" : ""
|
||||
}`}
|
||||
>
|
||||
{fi.label}
|
||||
{element?.planIcon}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (featureTitleRow) {
|
||||
return (
|
||||
<Box
|
||||
key={`plan-descript-${fi.desc}`}
|
||||
className="feature-title"
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
fontWeight: 600,
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
<div>{getRenderValue(fi.desc)} </div>
|
||||
<Box className={"planDescription"}>
|
||||
{element?.planDescription}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box
|
||||
key={`plan-feature-name-${fi.desc}`}
|
||||
className="feature-name"
|
||||
style={fi.style}
|
||||
>
|
||||
<div>{getRenderValue(fi.desc)} </div>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
{!isPaidPlan ? (
|
||||
<Box
|
||||
className={`plan-col ${
|
||||
isCommunityPlan ? "active-plan-col" : "non-active-plan-col"
|
||||
}`}
|
||||
>
|
||||
{COMMUNITY_PLAN_FEATURES.map((fi, idx) => {
|
||||
const featureLabel = featureList[idx].desc;
|
||||
const { featureTitleRow, isHeader } = fi;
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
{FEATURE_ITEMS.map((feature, index) => {
|
||||
const lastItem =
|
||||
index === FEATURE_ITEMS.length - 1 ? "noBorderBottom" : "";
|
||||
|
||||
if (isHeader) {
|
||||
return getCommunityPlanHeader();
|
||||
}
|
||||
|
||||
if (featureTitleRow) {
|
||||
return (
|
||||
<FeatureTitleRowCmp
|
||||
key={`title-row-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PricingFeatureItem
|
||||
key={`pricing-feature-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
label={fi.label}
|
||||
detail={fi.detail}
|
||||
xsLabel={fi.xsLabel}
|
||||
style={fi.style}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Box className="button-box">
|
||||
{getButton(
|
||||
`https://slack.min.io`,
|
||||
"Join Slack",
|
||||
"regular",
|
||||
LICENSE_PLANS.COMMUNITY,
|
||||
return (
|
||||
<Fragment>
|
||||
<Box className={`feature-label ${lastItem}`}>
|
||||
{feature.featureLabel}
|
||||
</Box>
|
||||
<Box className={`feature-information openSource ${lastItem}`}>
|
||||
{renderFeatureInformation(
|
||||
feature.featurePlans.openSource || null,
|
||||
)}
|
||||
</Box>
|
||||
<Box className={`feature-information ${lastItem}`}>
|
||||
{renderFeatureInformation(feature.featurePlans.eosLite || null)}
|
||||
</Box>
|
||||
<Box className={`feature-information ${lastItem}`}>
|
||||
{renderFeatureInformation(feature.featurePlans.eosPlus || null)}
|
||||
</Box>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
{[null, ...LICENSE_PLANS_INFORMATION].map((element, index) => {
|
||||
return (
|
||||
<Box
|
||||
className={`${
|
||||
index === 1 ? "openSource last" : ""
|
||||
} noBorderBottom`}
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{element &&
|
||||
getButton(
|
||||
`https://min.io/signup`,
|
||||
element.planType === "commercial"
|
||||
? "Subscribe"
|
||||
: "Join Slack",
|
||||
element.planType === "commercial" ? "callAction" : "regular",
|
||||
)}
|
||||
</Box>
|
||||
) : null}
|
||||
<Box
|
||||
className={`plan-col ${
|
||||
isStandardPlan ? "active-plan-col" : "non-active-plan-col"
|
||||
}`}
|
||||
>
|
||||
{STANDARD_PLAN_FEATURES.map((fi, idx) => {
|
||||
const featureLabel = featureList[idx].desc;
|
||||
const featureTitleRow = fi.featureTitleRow;
|
||||
const isHeader = fi.isHeader;
|
||||
|
||||
if (isHeader) {
|
||||
return getStandardPlanHeader();
|
||||
}
|
||||
|
||||
if (featureTitleRow) {
|
||||
return (
|
||||
<FeatureTitleRowCmp
|
||||
key={`feature-title-row-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PricingFeatureItem
|
||||
key={`feature-item-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
label={fi.label}
|
||||
detail={fi.detail}
|
||||
xsLabel={fi.xsLabel}
|
||||
style={fi.style}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
<Box className="button-box">
|
||||
{getButton(
|
||||
`https://min.io/signup`,
|
||||
!PAID_PLANS.includes(currentPlan)
|
||||
? "Subscribe"
|
||||
: "Login to SUBNET",
|
||||
"callAction",
|
||||
LICENSE_PLANS.STANDARD,
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
className={`plan-col ${
|
||||
isEnterprisePlan ? "active-plan-col" : "non-active-plan-col"
|
||||
}`}
|
||||
>
|
||||
{ENTERPRISE_PLAN_FEATURES.map((fi, idx) => {
|
||||
const featureLabel = featureList[idx].desc;
|
||||
const { featureTitleRow, isHeader, yesIcon } = fi;
|
||||
|
||||
if (isHeader) {
|
||||
return getEnterpriseHeader();
|
||||
}
|
||||
|
||||
if (featureTitleRow) {
|
||||
return (
|
||||
<FeatureTitleRowCmp
|
||||
key={`feature-title-row2-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (yesIcon) {
|
||||
return (
|
||||
<Box className="feature-item" key={`ent-feature-yes${fi.id}`}>
|
||||
<Box className="feature-item-info">
|
||||
<div className="xs-only"></div>
|
||||
<Box className="plan-feature">
|
||||
<CheckCircleIcon />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PricingFeatureItem
|
||||
key={`pricing-feature-item-${fi.id}`}
|
||||
featureLabel={featureLabel}
|
||||
label={fi.label}
|
||||
detail={fi.detail}
|
||||
style={fi.style}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Box className="button-box">
|
||||
{getButton(
|
||||
`https://min.io/signup`,
|
||||
!PAID_PLANS.includes(currentPlan)
|
||||
? "Subscribe"
|
||||
: "Login to SUBNET",
|
||||
"callAction",
|
||||
LICENSE_PLANS.ENTERPRISE,
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</PlanListContainer>
|
||||
</ListContainer>
|
||||
);
|
||||
})}
|
||||
</LicensesInformation>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,444 +14,217 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import LicenseLink from "./LicenseLink";
|
||||
import { openFAQModal } from "./licenseSlice";
|
||||
import store from "../../../store";
|
||||
import FAQModal from "./FAQModal";
|
||||
import { Box } from "mds";
|
||||
import React from "react";
|
||||
import { ApplicationLogo } from "mds";
|
||||
|
||||
export const LICENSE_PLANS = {
|
||||
COMMUNITY: "community",
|
||||
STANDARD: "standard",
|
||||
ENTERPRISE: "enterprise",
|
||||
ENTERPRISE_LITE: "enterprise-lite",
|
||||
ENTERPRISE_PLUS: "enterprise-plus",
|
||||
};
|
||||
export interface LicensePlanOption {
|
||||
planId: string;
|
||||
planName: string;
|
||||
planType: "commercial" | "open-source";
|
||||
planIcon: React.ReactNode;
|
||||
planDescription: React.ReactNode;
|
||||
}
|
||||
|
||||
type FeatureItem = {
|
||||
label?: any;
|
||||
isHeader?: boolean;
|
||||
style?: any;
|
||||
desc?: any;
|
||||
featureTitleRow?: boolean;
|
||||
};
|
||||
export interface FeatureElementObject {
|
||||
[name: string]: FeatureItem;
|
||||
}
|
||||
|
||||
const FeatureLink = ({ text, anchor }: { text: string; anchor: string }) => {
|
||||
return (
|
||||
<a
|
||||
href={`https://min.io/product/subnet?ref=con#${anchor}`}
|
||||
className={"link-text"}
|
||||
target="_blank"
|
||||
rel="noopener "
|
||||
style={{
|
||||
color: "#2781B0",
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
export interface FeatureItem {
|
||||
content: React.ReactNode;
|
||||
isCheck?: boolean;
|
||||
}
|
||||
|
||||
export const FEATURE_ITEMS: FeatureItem[] = [
|
||||
export interface PlansFeatures {
|
||||
featureLabel: string;
|
||||
featurePlans: FeatureElementObject;
|
||||
}
|
||||
|
||||
export const FEATURE_ITEMS: PlansFeatures[] = [
|
||||
{
|
||||
label: "License ",
|
||||
isHeader: true,
|
||||
},
|
||||
{
|
||||
label: "",
|
||||
isHeader: false,
|
||||
style: {
|
||||
height: "400px",
|
||||
verticalAlign: "top",
|
||||
alignItems: "start",
|
||||
featureLabel: "License",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "Requires AGPLv3 License Compliance",
|
||||
},
|
||||
eosLite: {
|
||||
content: "Commercial License",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "Commercial License",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Features",
|
||||
featureTitleRow: true,
|
||||
},
|
||||
{
|
||||
desc: "Unit Price",
|
||||
},
|
||||
{
|
||||
desc: () => {
|
||||
return (
|
||||
<FeatureLink
|
||||
anchor={"sa-long-term-support"}
|
||||
text={"Software Release"}
|
||||
/>
|
||||
);
|
||||
featureLabel: "Release",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "Upstream Community Release",
|
||||
},
|
||||
eosLite: {
|
||||
content: "Enterprise Stable Release",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "Enterprise Stable Release",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SLA",
|
||||
},
|
||||
{
|
||||
desc: "Support",
|
||||
},
|
||||
{
|
||||
desc: "Critical Security and Bug Detection",
|
||||
},
|
||||
{
|
||||
desc: () => {
|
||||
return <FeatureLink anchor={"sa-panic-button"} text={"Panic Button"} />;
|
||||
featureLabel: "Additional Features",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "None",
|
||||
},
|
||||
eosLite: {
|
||||
content:
|
||||
"Global Console, Observability, Cache, Data Firewall, Key Management Server Catalog",
|
||||
},
|
||||
eosPlus: {
|
||||
content:
|
||||
"Global Console, Observability, Cache, Data Firewall, Key Management Server Catalog",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: () => {
|
||||
return (
|
||||
<FeatureLink anchor={"sa-healthcheck"} text={"Health Diagnostics"} />
|
||||
);
|
||||
featureLabel: "Long Term Release Support",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "None",
|
||||
},
|
||||
eosLite: {
|
||||
content: "1 year LTS",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "5 years LTS",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Annual Architecture Review",
|
||||
featureLabel: "Support SLA",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "No SLA",
|
||||
},
|
||||
eosLite: {
|
||||
content: "Next Business Day SLA",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "Less than 4 Hour SLA",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Annual Performance Review",
|
||||
featureLabel: "Panic button",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "None",
|
||||
},
|
||||
eosLite: {
|
||||
content: "1 Panic Button Per Year",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "Unlimited Panic Buttons Per Year",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Indemnification",
|
||||
featureLabel:
|
||||
"Call Home Diagnostics, Health Check, Performance Benchmark, Security and Critical Vulnerabilities Notifications",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "",
|
||||
},
|
||||
eosLite: {
|
||||
content: "",
|
||||
isCheck: true,
|
||||
},
|
||||
eosPlus: {
|
||||
content: "",
|
||||
isCheck: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Security and Policy Review",
|
||||
featureLabel: "Indemnification",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "",
|
||||
},
|
||||
eosLite: {
|
||||
content: "",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "",
|
||||
isCheck: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
featureLabel: "Annual Review of Architecture, Performance and Security",
|
||||
featurePlans: {
|
||||
openSource: {
|
||||
content: "",
|
||||
},
|
||||
eosLite: {
|
||||
content: "",
|
||||
},
|
||||
eosPlus: {
|
||||
content: "",
|
||||
isCheck: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const COMMUNITY_PLAN_FEATURES = [
|
||||
export const LICENSE_PLANS_INFORMATION: LicensePlanOption[] = [
|
||||
{
|
||||
label: "Community",
|
||||
isHeader: true,
|
||||
style: {
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: () => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
Designed for developers who are building open source applications in
|
||||
compliance with the <LicenseLink /> license, MinIO Trademarks and
|
||||
are able to self support themselves. It is fully featured. If you
|
||||
distribute, host or create derivative works of the MinIO software
|
||||
over the network, the <LicenseLink /> license requires that you also
|
||||
distribute the complete, corresponding source code of the combined
|
||||
work under the same <LicenseLink /> license. This requirement
|
||||
applies whether or not you modified MinIO.
|
||||
<br />
|
||||
<br />
|
||||
<span
|
||||
className="link-text"
|
||||
onClick={() => {
|
||||
store.dispatch(openFAQModal());
|
||||
}}
|
||||
>
|
||||
Compliance FAQ
|
||||
</span>
|
||||
<FAQModal />
|
||||
</span>
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
isHeader: false,
|
||||
style: {
|
||||
height: "400px",
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "com_feat_title",
|
||||
featureTitleRow: true,
|
||||
},
|
||||
{
|
||||
id: "com_license_cost",
|
||||
},
|
||||
{
|
||||
id: "com_release",
|
||||
label: "Upstream",
|
||||
},
|
||||
{
|
||||
id: "com_sla",
|
||||
label: "No SLA",
|
||||
},
|
||||
{
|
||||
id: "com_support",
|
||||
label: "Community:",
|
||||
detail: "Slack + GitHub",
|
||||
},
|
||||
{
|
||||
id: "com_security",
|
||||
label: "Self",
|
||||
},
|
||||
{
|
||||
id: "com_panic",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "com_diag",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "com_arch",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "com_perf",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "com_indemnity",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "com_sec_policy",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
];
|
||||
|
||||
export const STANDARD_PLAN_FEATURES = [
|
||||
{
|
||||
label: "Standard",
|
||||
isHeader: true,
|
||||
style: {
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
isHeader: false,
|
||||
label: () => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "-85px",
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
Designed for customers who require a commercial license and can
|
||||
mostly self-support but want the peace of mind that comes with the
|
||||
MinIO Subscription Network’s suite of operational capabilities and
|
||||
direct-to-engineer interaction. The Standard version is fully
|
||||
featured but with SLA limitations. <br /> <br /> To learn more about
|
||||
the MinIO Subscription Network
|
||||
</span>{" "}
|
||||
<a
|
||||
href="https://min.io/product/subnet?ref=con"
|
||||
className={"link-text"}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
click here
|
||||
</a>
|
||||
.
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
style: {
|
||||
height: "400px",
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "std_feat_title",
|
||||
featureTitleRow: true,
|
||||
},
|
||||
{
|
||||
id: "std_license_cost",
|
||||
label: () => (
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
$10 per TiB per month
|
||||
</Box>
|
||||
planId: "openSource",
|
||||
planName: "Open Source",
|
||||
planType: "open-source",
|
||||
planIcon: (
|
||||
<ApplicationLogo applicationName={"console"} subVariant={"AGPL"} />
|
||||
),
|
||||
detail: () => (
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
fontWeight: 400,
|
||||
marginBottom: "5px",
|
||||
}}
|
||||
>
|
||||
(Minimum of 200TiB)
|
||||
</Box>
|
||||
planDescription: (
|
||||
<span>
|
||||
Designed for developers who are building open source applications in
|
||||
compliance with the GNU AGPL v3 license which requires developers to
|
||||
distribute their code under the same AGPL v3 license when they
|
||||
distribute, host or modify MinIO.
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "std_release",
|
||||
label: "1 Year Long Term Support",
|
||||
},
|
||||
{
|
||||
id: "std_sla",
|
||||
label: "<48 Hours",
|
||||
detail: "(Local Business Hours)",
|
||||
},
|
||||
{
|
||||
id: "std_support",
|
||||
label: "L4 Direct Engineering",
|
||||
detail: "support via SUBNET",
|
||||
},
|
||||
{
|
||||
id: "std_security",
|
||||
label: "Continuous Scan and Alert",
|
||||
},
|
||||
{
|
||||
id: "std_panic",
|
||||
label: "1 Per year",
|
||||
},
|
||||
{
|
||||
id: "std_diag",
|
||||
label: "24/7/365",
|
||||
},
|
||||
{
|
||||
id: "std_arch",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "std_perf",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "std_indemnity",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
{
|
||||
id: "std_sec_policy",
|
||||
xsLabel: "N/A",
|
||||
},
|
||||
];
|
||||
|
||||
export const ENTERPRISE_PLAN_FEATURES = [
|
||||
{
|
||||
label: "Enterprise",
|
||||
isHeader: true,
|
||||
style: {
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
isHeader: false,
|
||||
label: () => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "-135px",
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
Designed for mission critical environments where both a license and
|
||||
strict SLAs are required. The Enterprise version is fully featured
|
||||
but comes with additional capabilities. <br /> <br /> To learn more
|
||||
about the MinIO Subscription Network
|
||||
</span>{" "}
|
||||
<a
|
||||
href="https://min.io/product/subnet?ref=con"
|
||||
className={"link-text"}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
click here
|
||||
</a>
|
||||
.
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
style: {
|
||||
height: "400px",
|
||||
borderBottom: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "end_feat_title",
|
||||
featureTitleRow: true,
|
||||
},
|
||||
{
|
||||
id: "ent_license_cost",
|
||||
label: () => (
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
$20 per TiB per month
|
||||
</Box>
|
||||
planId: "eosLite",
|
||||
planName: "Enterprise Lite",
|
||||
planType: "commercial",
|
||||
planIcon: (
|
||||
<ApplicationLogo applicationName={"minio"} subVariant={"enterpriseos"} />
|
||||
),
|
||||
detail: () => (
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
fontWeight: 400,
|
||||
marginBottom: "5px",
|
||||
}}
|
||||
>
|
||||
(Minimum of 100TiB)
|
||||
</Box>
|
||||
planDescription: (
|
||||
<span>
|
||||
Designed for customers who require a commercial license and can mostly
|
||||
self-support but want the peace of mind that comes with an
|
||||
engineer-backend SLA, additional features and operational capabilities.
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "ent_release",
|
||||
label: "5 Years Long Term Support",
|
||||
},
|
||||
{
|
||||
id: "ent_sla",
|
||||
label: "<1 hour",
|
||||
},
|
||||
{
|
||||
id: "ent_support",
|
||||
label: "L4 Direct Engineering support via",
|
||||
detail: "SUBNET, Phone, Web Conference",
|
||||
},
|
||||
{
|
||||
id: "ent_security",
|
||||
label: "Continuous Scan and Alert",
|
||||
},
|
||||
{
|
||||
id: "ent_panic",
|
||||
label: "Unlimited",
|
||||
},
|
||||
{
|
||||
id: "ent_diag",
|
||||
label: "24/7/365",
|
||||
},
|
||||
{
|
||||
id: "ent_arch",
|
||||
yesIcon: true,
|
||||
},
|
||||
{
|
||||
id: "ent_perf",
|
||||
yesIcon: true,
|
||||
},
|
||||
{
|
||||
id: "ent_indemnity",
|
||||
yesIcon: true,
|
||||
},
|
||||
{
|
||||
id: "ent_sec_policy",
|
||||
yesIcon: true,
|
||||
planId: "eosPlus",
|
||||
planName: "Enterprise Plus",
|
||||
planType: "commercial",
|
||||
planIcon: (
|
||||
<ApplicationLogo applicationName={"minio"} subVariant={"enterpriseos"} />
|
||||
),
|
||||
planDescription: (
|
||||
<span>
|
||||
Designed for customers where a commercial license and the
|
||||
strictest,engineer-backed SLA are required. The Plus tiers offers
|
||||
additional features and operational capabilities, more interaction
|
||||
options and more enterprise deliverables.
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export const PAID_PLANS = [
|
||||
LICENSE_PLANS.STANDARD,
|
||||
LICENSE_PLANS.ENTERPRISE,
|
||||
LICENSE_PLANS.ENTERPRISE_LITE,
|
||||
LICENSE_PLANS.ENTERPRISE_PLUS,
|
||||
];
|
||||
|
||||
export const getRenderValue = (val: any) => {
|
||||
return typeof val === "function" ? val() : val;
|
||||
};
|
||||
|
||||
export const LICENSE_CONSENT_STORE_KEY = "agpl_minio_license_consent";
|
||||
export const setLicenseConsent = () => {
|
||||
localStorage.setItem(LICENSE_CONSENT_STORE_KEY, "true");
|
||||
|
||||
Reference in New Issue
Block a user