mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-01-16 23:00:51 +00:00
feat(ui): add EditionLabel and expose IS_ENTERPRISE across apps
- Add EditionLabel component to Common UI to show current edition and info modal - Show edition label in Login page, Dashboard header and Footer - Add IS_ENTERPRISE env var to config.example.env and export in Common UI Config - Propagate IS_ENTERPRISE into docker-compose.base.yml service envs
This commit is contained in:
parent
f7c05645a9
commit
5e19849ac8
7 changed files with 115 additions and 0 deletions
|
|
@ -12,6 +12,7 @@ import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchem
|
|||
import Link from "Common/UI/Components/Link/Link";
|
||||
import { DASHBOARD_URL } from "Common/UI/Config";
|
||||
import OneUptimeLogo from "Common/UI/Images/logos/OneUptimeSVG/3-transparent.svg";
|
||||
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
|
||||
import UiAnalytics from "Common/UI/Utils/Analytics";
|
||||
import LoginUtil from "Common/UI/Utils/Login";
|
||||
import UserTotpAuth from "Common/Models/DatabaseModels/UserTotpAuth";
|
||||
|
|
@ -192,6 +193,9 @@ const LoginPage: () => JSX.Element = () => {
|
|||
src={OneUptimeLogo}
|
||||
alt="OneUptime"
|
||||
/>
|
||||
<div className="mt-4 flex justify-center">
|
||||
<EditionLabel />
|
||||
</div>
|
||||
{!showTwoFactorAuth && (
|
||||
<>
|
||||
<h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import Logo from "./Logo";
|
|||
import UserProfile from "./UserProfile";
|
||||
import Button, { ButtonStyleType } from "Common/UI/Components/Button/Button";
|
||||
import Header from "Common/UI/Components/Header/Header";
|
||||
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
|
||||
import { DASHBOARD_URL } from "Common/UI/Config";
|
||||
import Navigation from "Common/UI/Utils/Navigation";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
|
|
@ -27,6 +28,7 @@ const DashboardHeader: FunctionComponent = (): ReactElement => {
|
|||
}
|
||||
rightComponents={
|
||||
<>
|
||||
<EditionLabel className="mr-3 hidden md:inline-flex" />
|
||||
<Button
|
||||
title="Exit Admin"
|
||||
buttonStyle={ButtonStyleType.NORMAL}
|
||||
|
|
|
|||
98
Common/UI/Components/EditionLabel/EditionLabel.tsx
Normal file
98
Common/UI/Components/EditionLabel/EditionLabel.tsx
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import Modal from "../Modal/Modal";
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
ReactElement,
|
||||
useState,
|
||||
} from "react";
|
||||
import { BILLING_ENABLED, IS_ENTERPRISE } from "../../Config";
|
||||
|
||||
export interface ComponentProps {
|
||||
className?: string | undefined;
|
||||
}
|
||||
|
||||
const ENTERPRISE_URL: string = "https://oneuptime.com/enterprise";
|
||||
|
||||
const EditionLabel: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
|
||||
|
||||
if (BILLING_ENABLED) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const editionName: string = IS_ENTERPRISE
|
||||
? "Enterprise Edition"
|
||||
: "Community Edition";
|
||||
|
||||
const openDialog: () => void = () => {
|
||||
setIsDialogOpen(true);
|
||||
};
|
||||
|
||||
const closeDialog: () => void = () => {
|
||||
setIsDialogOpen(false);
|
||||
};
|
||||
|
||||
const handlePrimaryAction: () => void = () => {
|
||||
if (typeof window !== "undefined") {
|
||||
window.open(ENTERPRISE_URL, "_blank", "noopener,noreferrer");
|
||||
}
|
||||
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={openDialog}
|
||||
className={`inline-flex items-center justify-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-indigo-700 transition hover:bg-indigo-100 focus:outline-none focus-visible:ring focus-visible:ring-indigo-300 ${
|
||||
props.className ? props.className : ""
|
||||
}`}
|
||||
>
|
||||
{editionName}
|
||||
</button>
|
||||
|
||||
{isDialogOpen && (
|
||||
<Modal
|
||||
title={editionName}
|
||||
submitButtonText={IS_ENTERPRISE ? "Learn More" : "Talk to Sales"}
|
||||
closeButtonText="Close"
|
||||
onClose={closeDialog}
|
||||
onSubmit={handlePrimaryAction}
|
||||
>
|
||||
<div className="space-y-3 text-sm text-gray-600">
|
||||
{IS_ENTERPRISE ? (
|
||||
<>
|
||||
<p>
|
||||
You are running the Enterprise Edition of OneUptime. This
|
||||
includes premium capabilities such as enterprise-grade
|
||||
support, governance controls, and unlimited project scale.
|
||||
</p>
|
||||
<p>
|
||||
Reach out to our team if you need help enabling additional
|
||||
enterprise features or onboarding new teams.
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
You are running the Community Edition of OneUptime. Upgrade to
|
||||
Enterprise to unlock advanced automation, security controls,
|
||||
and priority support.
|
||||
</p>
|
||||
<ul className="list-disc space-y-1 pl-5">
|
||||
<li>Unlimited monitors, workflows, and integrations.</li>
|
||||
<li>Role-based access controls and audit trails.</li>
|
||||
<li>24/7 priority support with guaranteed SLAs.</li>
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditionLabel;
|
||||
|
|
@ -48,6 +48,7 @@ export const HTTP_PROTOCOL: Protocol =
|
|||
export const HOST: string = env("HOST") || "";
|
||||
|
||||
export const BILLING_ENABLED: boolean = env("BILLING_ENABLED") === "true";
|
||||
export const IS_ENTERPRISE: boolean = env("IS_ENTERPRISE") === "true";
|
||||
export const BILLING_PUBLIC_KEY: string = env("BILLING_PUBLIC_KEY") || "";
|
||||
|
||||
// VAPID Configuration for Push Notifications
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { JSONObject } from "Common/Types/JSON";
|
|||
import API from "Common/Utils/API";
|
||||
import Footer from "Common/UI/Components/Footer/Footer";
|
||||
import ConfirmModal from "Common/UI/Components/Modal/ConfirmModal";
|
||||
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
|
||||
import { HOST, HTTP_PROTOCOL } from "Common/UI/Config";
|
||||
import React from "react";
|
||||
|
||||
|
|
@ -66,6 +67,9 @@ const DashboardFooter: () => JSX.Element = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-white px-8 pb-4 flex justify-center">
|
||||
<EditionLabel />
|
||||
</div>
|
||||
<Footer
|
||||
className="bg-white px-8"
|
||||
copyright="HackerBay, Inc."
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ ENVIRONMENT=production
|
|||
# What image should we pull from docker hub. This only applies when the ENVIRONMENT is production or test
|
||||
APP_TAG=release
|
||||
|
||||
# Change this to true if you are using enterprise edition. Keep it false if you are using community edition.
|
||||
IS_ENTERPRISE=false
|
||||
|
||||
# What is the name of the docker compose project. This is used to prefix the docker containers.
|
||||
COMPOSE_PROJECT_NAME=oneuptime
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ x-common-variables: &common-variables
|
|||
|
||||
NODE_ENV: ${ENVIRONMENT}
|
||||
BILLING_ENABLED: ${BILLING_ENABLED}
|
||||
IS_ENTERPRISE: ${IS_ENTERPRISE}
|
||||
BILLING_PUBLIC_KEY: ${BILLING_PUBLIC_KEY}
|
||||
SUBSCRIPTION_PLAN_BASIC: ${SUBSCRIPTION_PLAN_BASIC}
|
||||
SUBSCRIPTION_PLAN_GROWTH: ${SUBSCRIPTION_PLAN_GROWTH}
|
||||
|
|
@ -444,6 +445,7 @@ services:
|
|||
PORT: ${ISOLATED_VM_PORT}
|
||||
ONEUPTIME_SECRET: ${ONEUPTIME_SECRET}
|
||||
DISABLE_TELEMETRY: ${DISABLE_TELEMETRY_FOR_ISOLATED_VM}
|
||||
IS_ENTERPRISE: ${IS_ENTERPRISE}
|
||||
logging:
|
||||
driver: "local"
|
||||
options:
|
||||
|
|
@ -533,6 +535,7 @@ services:
|
|||
DISABLE_COPILOT: ${DISABLE_COPILOT}
|
||||
OPENAI_API_KEY: ${COPILOT_OPENAI_API_KEY}
|
||||
LOG_LEVEL: ${LOG_LEVEL}
|
||||
IS_ENTERPRISE: ${IS_ENTERPRISE}
|
||||
logging:
|
||||
driver: "local"
|
||||
options:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue