chore: update upgrade page (#17988)
* chore: upgrade page for usage * fix: upgrade page scroll * chore: scrollable and design upgrade for upgradePage * fix: module imports
This commit is contained in:
parent
633493ac74
commit
e4f8e8a755
|
|
@ -10,8 +10,8 @@ const Header = {
|
|||
};
|
||||
|
||||
const Carousel = {
|
||||
Left: "[data-testid='t--carousel-left']",
|
||||
Right: "[data-testid='t--carousel-right']",
|
||||
Left: "[data-testid='t--carousel-triggers']",
|
||||
Right: "[data-testid='t--carousel-targets']",
|
||||
};
|
||||
|
||||
const UpgradePage = {
|
||||
|
|
|
|||
|
|
@ -1281,7 +1281,34 @@ export const INVALID_URL = () =>
|
|||
// Alert options and labels for showMessage types
|
||||
export const ALERT_STYLE_OPTIONS = [
|
||||
{ label: "Info", value: "'info'", id: "info" },
|
||||
{ label: "Success", value: "'success'", id: "success" },
|
||||
{
|
||||
label: "Success",
|
||||
value: "'success'",
|
||||
id: "success",
|
||||
},
|
||||
{ label: "Error", value: "'error'", id: "error" },
|
||||
{ label: "Warning", value: "'warning'", id: "warning" },
|
||||
];
|
||||
|
||||
export const USAGE_AND_BILLING = {
|
||||
usage: () => "Usage",
|
||||
billing: () => "Billing",
|
||||
usageAndBilling: () => "Usage & Billing",
|
||||
usageOverNDays: (days: number) => `Usage over the past ${days} days!`,
|
||||
usageDetails: () =>
|
||||
"This is how much you have used Appsmith to build and run apps.",
|
||||
unit: () => "minutes/day",
|
||||
averaged: () => "*averaged",
|
||||
approximated: () => "*approximated",
|
||||
sell: () => "Figure out your usage before purchasing Appsmith",
|
||||
upgradeToBusiness: () => "UPGRADE TO BUSINESS EDITION",
|
||||
rbacHeading: () => "Role Based Access Control",
|
||||
rbacDetails: () =>
|
||||
"RBAC is here to allow you to control access to appsmith as easy as you maintain your organization.",
|
||||
ssoHeading: () => "SSO and Custom Authentication",
|
||||
ssoDetails: () => "SSO and custom auth allow you to onboard users faster.",
|
||||
gitHeading: () => "Unlimited private git repositories",
|
||||
gitDetails: () => "Expand your single source of truth capability to infinite",
|
||||
exclusive: () =>
|
||||
"These features are exclusively available on business edition.",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import { Category } from "@appsmith/pages/AdminSettings/config/types";
|
|||
import { adminSettingsCategoryUrl } from "RouteBuilder";
|
||||
import { useParams } from "react-router";
|
||||
import { Icon, IconSize } from "design-system";
|
||||
import { createMessage } from "design-system/build/constants/messages";
|
||||
import { USAGE_AND_BILLING } from "@appsmith/constants/messages";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectFeatureFlags } from "selectors/usersSelectors";
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
flex-basis: ${(props) =>
|
||||
|
|
@ -121,6 +125,7 @@ export function Categories({
|
|||
}
|
||||
|
||||
export default function LeftPane() {
|
||||
const features = useSelector(selectFeatureFlags);
|
||||
const categories = getSettingsCategory();
|
||||
const { category, selected: subCategory } = useParams() as any;
|
||||
return (
|
||||
|
|
@ -150,6 +155,20 @@ export default function LeftPane() {
|
|||
<div>Audit logs</div>
|
||||
</StyledLink>
|
||||
</CategoryItem>
|
||||
{features.USAGE && (
|
||||
<CategoryItem>
|
||||
<StyledLink
|
||||
$active={category === "usage"}
|
||||
data-testid="t--enterprise-settings-category-item-usage"
|
||||
to="/settings/usage"
|
||||
>
|
||||
<div>
|
||||
<Icon name="lock-2-line" size={IconSize.XL} />
|
||||
</div>
|
||||
<div>{createMessage(USAGE_AND_BILLING.usage)}</div>
|
||||
</StyledLink>
|
||||
</CategoryItem>
|
||||
)}
|
||||
</CategoryList>
|
||||
</>
|
||||
</Wrapper>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { ADMIN_SETTINGS_CATEGORY_DEFAULT_PATH } from "constants/routes";
|
|||
import SettingsForm from "pages/Settings/SettingsForm";
|
||||
import { AuditLogsUpgradePage } from "../Upgrade/AuditLogsUpgradePage";
|
||||
import { AccessControlUpgradePage } from "../Upgrade/AccessControlUpgradePage";
|
||||
import { UsageUpgradePage } from "../Upgrade/UsageUpgradePage";
|
||||
|
||||
const Main = () => {
|
||||
const params = useParams() as any;
|
||||
|
|
@ -22,6 +23,9 @@ const Main = () => {
|
|||
if (category === "audit-logs") {
|
||||
return <AuditLogsUpgradePage />;
|
||||
}
|
||||
if (category === "usage") {
|
||||
return <UsageUpgradePage />;
|
||||
}
|
||||
|
||||
/* Old, still working flow; config, factory based */
|
||||
if (!!wrapperCategory?.component) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Header } from "./types";
|
||||
import { Carousel, Header } from "./types";
|
||||
import UpgradePage from "./UpgradePage";
|
||||
|
||||
export function AccessControlUpgradePage() {
|
||||
|
|
@ -7,7 +7,7 @@ export function AccessControlUpgradePage() {
|
|||
heading: "Access Control",
|
||||
subHeadings: ["sub heading 1", "sub heading 2"],
|
||||
};
|
||||
const carousel = {
|
||||
const carousel: Carousel = {
|
||||
triggers: [
|
||||
{
|
||||
icon: "lock-2-line",
|
||||
|
|
@ -26,6 +26,7 @@ export function AccessControlUpgradePage() {
|
|||
},
|
||||
],
|
||||
targets: ["first", "second", "third"],
|
||||
design: "split-left-trigger",
|
||||
};
|
||||
const footer = {
|
||||
onClick: () => null,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Header } from "./types";
|
||||
import { Carousel, Header } from "./types";
|
||||
import UpgradePage from "./UpgradePage";
|
||||
import DebuggingImage from "assets/svg/upgrade/audit-logs/debugging.svg";
|
||||
import IncidentManagementImage from "assets/svg/upgrade/audit-logs/incident-management.svg";
|
||||
|
|
@ -29,7 +29,7 @@ export function AuditLogsUpgradePage() {
|
|||
heading: createMessage(INTRODUCING, createMessage(AUDIT_LOGS)),
|
||||
subHeadings: [createMessage(AUDIT_LOGS_UPGRADE_PAGE_SUB_HEADING)],
|
||||
};
|
||||
const carousel = {
|
||||
const carousel: Carousel = {
|
||||
triggers: [
|
||||
{
|
||||
icon: "lock-2-line",
|
||||
|
|
@ -63,6 +63,7 @@ export function AuditLogsUpgradePage() {
|
|||
src={IncidentManagementImage}
|
||||
/>,
|
||||
],
|
||||
design: "split-left-trigger",
|
||||
};
|
||||
|
||||
const footer = {
|
||||
|
|
|
|||
|
|
@ -4,17 +4,15 @@ import { Icon, IconSize, Text, TextType } from "design-system";
|
|||
import { CarouselProps } from "./types";
|
||||
|
||||
const CarouselContainer = styled.div`
|
||||
flex-grow: 1;
|
||||
gap: 64px;
|
||||
margin-bottom: 86px;
|
||||
display: flex;
|
||||
flex: 1 1;
|
||||
gap: 64px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 542px;
|
||||
padding: 16px;
|
||||
|
||||
& .carousel-left {
|
||||
& .carousel-triggers {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
|
|
@ -29,7 +27,7 @@ const CarouselContainer = styled.div`
|
|||
|
||||
&.active {
|
||||
height: max-content;
|
||||
min-height: 152px;
|
||||
min-height: 156px;
|
||||
box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.06),
|
||||
0 4px 8px -2px rgba(0, 0, 0, 0.1);
|
||||
|
||||
|
|
@ -64,9 +62,14 @@ const CarouselContainer = styled.div`
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
& .carousel-targets {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
& .carousel-right {
|
||||
& .carousel-targets {
|
||||
width: 680px;
|
||||
height: 472px;
|
||||
display: flex;
|
||||
|
|
@ -82,39 +85,46 @@ const CarouselContainer = styled.div`
|
|||
|
||||
export function CarouselComponent(props: CarouselProps) {
|
||||
const [active, setActive] = useState(0);
|
||||
const [rightContent, setRightContent] = useState(null);
|
||||
const { targets, triggers } = props;
|
||||
const [targetContent, setTargetContent] = useState(null);
|
||||
const { design, targets, triggers } = props;
|
||||
useEffect(() => {
|
||||
setRightContent(targets[active]);
|
||||
setTargetContent(targets[active]);
|
||||
}, [active]);
|
||||
|
||||
const isActive = (i: number) => i === active;
|
||||
|
||||
return (
|
||||
<CarouselContainer
|
||||
className="upgrade-page-carousel-container"
|
||||
data-testid="t--upgrade-page-carousel-container"
|
||||
const targetsComponent = (
|
||||
<div
|
||||
className={`carousel-targets ${design}`}
|
||||
data-testid="t--carousel-targets"
|
||||
>
|
||||
<div className="carousel-left" data-testid="t--carousel-left">
|
||||
{triggers.map((d, i) => {
|
||||
return (
|
||||
<div
|
||||
className={`carousel-item-container carousel-trigger ${
|
||||
isActive(i) ? "active" : ""
|
||||
}`}
|
||||
key={`carousel-item-${i}`}
|
||||
onClick={() => setActive(i)}
|
||||
role="button"
|
||||
>
|
||||
<div className={"trigger"}>
|
||||
<div className="icon-container">
|
||||
<Icon name={d.icon} size={IconSize.XXXXL} />
|
||||
{targetContent}
|
||||
</div>
|
||||
);
|
||||
const triggersComponent = (
|
||||
<div
|
||||
className={`carousel-triggers ${design}`}
|
||||
data-testid="t--carousel-triggers"
|
||||
>
|
||||
{triggers.map((d, i) => {
|
||||
return (
|
||||
<div
|
||||
className={`carousel-item-container carousel-trigger ${
|
||||
isActive(i) ? "active" : ""
|
||||
}`}
|
||||
key={`carousel-item-${i}`}
|
||||
onClick={() => setActive(i)}
|
||||
role="button"
|
||||
>
|
||||
<div className={"trigger"}>
|
||||
<div className="icon-container">
|
||||
<Icon name={d.icon} size={IconSize.XXXXL} />
|
||||
</div>
|
||||
<div className="trigger-content">
|
||||
<div className="trigger-heading">
|
||||
<Text type={TextType.H1}>{d.heading}</Text>
|
||||
</div>
|
||||
<div className="trigger-content">
|
||||
<div className="trigger-heading">
|
||||
<Text type={TextType.H1}>{d.heading}</Text>
|
||||
</div>
|
||||
{isActive(i) && (
|
||||
{isActive(i) && (
|
||||
<>
|
||||
<div className="trigger-details-container">
|
||||
{d.details.map((detail, di) => {
|
||||
return (
|
||||
|
|
@ -127,16 +137,48 @@ export function CarouselComponent(props: CarouselProps) {
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{design === "trigger-contains-target" && (
|
||||
<div>{targetsComponent}</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="carousel-right" data-testid="t--carousel-right">
|
||||
{rightContent}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
let display = (
|
||||
<>
|
||||
{triggersComponent}
|
||||
{targetsComponent}
|
||||
</>
|
||||
);
|
||||
switch (design) {
|
||||
case "no-target":
|
||||
display = triggersComponent;
|
||||
break;
|
||||
case "trigger-contains-target":
|
||||
display = triggersComponent;
|
||||
break;
|
||||
case "split-right-trigger":
|
||||
display = (
|
||||
<>
|
||||
{targetsComponent}
|
||||
{triggersComponent}
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<CarouselContainer
|
||||
className="upgrade-page-carousel-container"
|
||||
data-testid="t--upgrade-page-carousel-container"
|
||||
>
|
||||
{display}
|
||||
</CarouselContainer>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,10 @@ import { HeaderProps } from "./types";
|
|||
import { FontWeight, Text, TextType } from "design-system";
|
||||
|
||||
export const HeaderContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
width: 496px;
|
||||
|
||||
text-align: center;
|
||||
height: 120px;
|
||||
padding: 32px;
|
||||
|
||||
& .header-heading-container {
|
||||
& .cs-text {
|
||||
|
|
|
|||
|
|
@ -5,38 +5,31 @@ import { CarouselComponent as Carousel } from "./Carousel";
|
|||
import { FooterComponent as Footer } from "./Footer";
|
||||
import { UpgradePageProps } from "./types";
|
||||
|
||||
export const ExternalContainer = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - 50px);
|
||||
max-height: 100vh;
|
||||
border-left: thin solid var(--appsmith-color-black-50);
|
||||
background-color: var(--ads-color-black-50);
|
||||
`;
|
||||
|
||||
export const InternalContainer = styled.div`
|
||||
export const Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
gap: 32px;
|
||||
justify-content: center;
|
||||
flex: 1 1;
|
||||
border-left: thin solid var(--appsmith-color-black-50);
|
||||
background-color: var(--ads-color-black-50);
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
height: calc(100vh - 50px - 112px);
|
||||
min-width: 1180px;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
gap: 32px;
|
||||
`;
|
||||
|
||||
export default function UpgradePage(props: UpgradePageProps) {
|
||||
const { carousel, footer, header } = props;
|
||||
return (
|
||||
<ExternalContainer
|
||||
<Container
|
||||
className="upgrade-page-container"
|
||||
data-testid="t--upgrade-page-container"
|
||||
>
|
||||
<InternalContainer>
|
||||
<Header {...header} />
|
||||
<Carousel {...carousel} />
|
||||
<Footer {...footer} />
|
||||
</InternalContainer>
|
||||
</ExternalContainer>
|
||||
<Header {...header} />
|
||||
<Carousel {...carousel} />
|
||||
<Footer {...footer} />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
82
app/client/src/ce/pages/Upgrade/UsageUpgradePage.tsx
Normal file
82
app/client/src/ce/pages/Upgrade/UsageUpgradePage.tsx
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import React from "react";
|
||||
import { Carousel, Header } from "./types";
|
||||
import { createMessage } from "design-system/build/constants/messages";
|
||||
import { USAGE_AND_BILLING } from "@appsmith/constants/messages";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import UpgradePage from "./UpgradePage";
|
||||
import { getAppsmithConfigs } from "../../configs";
|
||||
import { FontWeight, Text, TextType } from "design-system";
|
||||
|
||||
const { intercomAppID } = getAppsmithConfigs();
|
||||
|
||||
export function UsageUpgradePage() {
|
||||
const header: Header = {
|
||||
heading: createMessage(USAGE_AND_BILLING.usage),
|
||||
subHeadings: [createMessage(USAGE_AND_BILLING.sell)],
|
||||
};
|
||||
const carousel: Carousel = {
|
||||
triggers: [
|
||||
{
|
||||
icon: "lock-2-line",
|
||||
heading: createMessage(USAGE_AND_BILLING.usageOverNDays, 20),
|
||||
details: [createMessage(USAGE_AND_BILLING.usageDetails)],
|
||||
},
|
||||
{
|
||||
icon: "search-eye-line",
|
||||
heading: createMessage(USAGE_AND_BILLING.rbacHeading),
|
||||
details: [createMessage(USAGE_AND_BILLING.rbacDetails)],
|
||||
},
|
||||
{
|
||||
icon: "alert-line",
|
||||
heading: createMessage(USAGE_AND_BILLING.ssoHeading),
|
||||
details: [createMessage(USAGE_AND_BILLING.ssoDetails)],
|
||||
},
|
||||
{
|
||||
icon: "alert-line",
|
||||
heading: createMessage(USAGE_AND_BILLING.gitHeading),
|
||||
details: [createMessage(USAGE_AND_BILLING.gitDetails)],
|
||||
},
|
||||
],
|
||||
targets: [
|
||||
<div key={"usage-over-past-n-days"}>
|
||||
<div>
|
||||
<Text type={TextType.H1} weight={FontWeight.BOLD}>
|
||||
201
|
||||
</Text>
|
||||
|
||||
<Text type={TextType.P1}>
|
||||
{createMessage(USAGE_AND_BILLING.unit)}{" "}
|
||||
</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type={TextType.P3}>
|
||||
{createMessage(USAGE_AND_BILLING.averaged)}{" "}
|
||||
{createMessage(USAGE_AND_BILLING.approximated)}
|
||||
</Text>
|
||||
</div>
|
||||
</div>,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
design: "trigger-contains-target",
|
||||
};
|
||||
|
||||
const footer = {
|
||||
onClick: () => {
|
||||
AnalyticsUtil.logEvent("ADMIN_SETTINGS_UPGRADE_HOOK", {
|
||||
source: "Usage",
|
||||
});
|
||||
if (intercomAppID && window.Intercom) {
|
||||
window.Intercom(
|
||||
"showNewMessage",
|
||||
createMessage(USAGE_AND_BILLING.upgradeToBusiness),
|
||||
);
|
||||
}
|
||||
},
|
||||
message: createMessage(USAGE_AND_BILLING.exclusive),
|
||||
};
|
||||
|
||||
const props = { header, carousel, footer };
|
||||
return <UpgradePage {...props} />;
|
||||
}
|
||||
|
|
@ -14,6 +14,11 @@ export type CarouselTrigger = {
|
|||
export type Carousel = {
|
||||
triggers: CarouselTrigger[];
|
||||
targets: any[];
|
||||
design:
|
||||
| "split-left-trigger"
|
||||
| "split-right-trigger"
|
||||
| "trigger-contains-target"
|
||||
| "no-target";
|
||||
};
|
||||
|
||||
export type Footer = {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ type FeatureFlags = {
|
|||
TEMPLATES_PHASE_2?: boolean;
|
||||
RBAC?: boolean;
|
||||
CONTEXT_SWITCHING?: boolean;
|
||||
USAGE?: boolean;
|
||||
};
|
||||
|
||||
export default FeatureFlags;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user