feat: one click code splitting - Branding, SSO (#25231)

## Description
Adds Support to show different versions of the following pages based on
the plan the user is subscribed to.
-Branding
-SSO

#### PR fixes following issue(s)
Fixes #https://github.com/appsmithorg/appsmith-ee/issues/1800


#### Media


https://www.notion.so/appsmith/POC-Code-Splitting-1-Click-Upgrade-Downgrade-Frontend-4fe83a8de6c54224bad2bc43e8e4d34b



#### Type of change
- New feature (non-breaking change which adds functionality)

## Testing
- [x] Manual
- [ ] Jest
- [x] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
This commit is contained in:
Dipyaman Biswas 2023-08-16 15:51:04 +05:30 committed by GitHub
parent f2636358af
commit dbe3884417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 82 additions and 20 deletions

View File

@ -53,6 +53,7 @@ describe("Admin settings page", function () {
stubPricingPage();
cy.get(".t--settings-category-branding").click();
cy.url().should("contain", "/settings/branding");
cy.get(adminsSettings.brandingSubmitButton).should("be.disabled");
cy.xpath(adminsSettings.upgrade).click();
cy.get("@pricingPage").should("be.called");
cy.wait(2000);

View File

@ -31,6 +31,7 @@ export default {
auditLogs: ".t--settings-category-audit-logs",
provisioning: ".t--settings-category-provisioning",
upgrageLeftPane: "[data-testid='t--enterprise-settings-category-item-be']",
brandingSubmitButton: ".t--settings-branding-submit-button",
businessTag: "[data-testid='t--business-tag']",
enterpriseTag: "[data-testid='t--enterprise-tag']",
};

View File

@ -1386,9 +1386,9 @@ export const DISCONNECT_AUTH_METHOD = () => "Disconnect";
export const DISCONNECT_CONFIRMATION = () => "Are you sure?";
// Branding
export const ADMIN_BRANDING_SETTINGS_TITLE = () =>
export const ADMIN_BRANDING_SETTINGS_TITLE_UPGRADE = () =>
"Custom Branding for your workspaces";
export const ADMIN_BRANDING_SETTINGS_SUBTITLE = () =>
export const ADMIN_BRANDING_SETTINGS_SUBTITLE_UPGRADE = () =>
"Make your workspaces and apps look more yours in a few clicks as in the example below. Upload your logo and favicon, set your primary color, and preview the new look. To save a look you like, upgrade to our Business Edition.";
export const ADMIN_BRANDING_COLOR_TOOLTIP = () =>
`When you choose a primary color, we auto-magically fill in the secondary and accent colors. You can change them to get the look you want.`;

View File

@ -15,6 +15,8 @@ export const FEATURE_FLAG = {
ab_gsheet_schema_enabled: "ab_gsheet_schema_enabled",
ab_wds_enabled: "ab_wds_enabled",
release_widgetdiscovery_enabled: "release_widgetdiscovery_enabled",
license_sso_enabled: "license_sso_enabled",
license_branding_enabled: "license_branding_enabled",
ab_table_widget_activation_enabled: "ab_table_widget_activation_enabled",
} as const;
@ -35,6 +37,8 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
ab_gsheet_schema_enabled: false,
ab_wds_enabled: false,
release_widgetdiscovery_enabled: false,
license_sso_enabled: false,
license_branding_enabled: false,
ab_table_widget_activation_enabled: false,
};

View File

@ -94,6 +94,7 @@ export type AuthMethodType = {
isConnected?: boolean;
calloutBanner?: banner;
icon?: string;
isFeatureEnabled: boolean;
};
const ButtonWrapper = styled.div`
@ -109,7 +110,7 @@ export function ActionButton({ method }: { method: AuthMethodType }) {
});
const onClickHandler = (method: AuthMethodType) => {
if (!method.needsUpgrade || method.isConnected) {
if (method?.isFeatureEnabled || method.isConnected) {
AnalyticsUtil.logEvent(
method.isConnected
? "ADMIN_SETTINGS_EDIT_AUTH_METHOD"
@ -133,7 +134,9 @@ export function ActionButton({ method }: { method: AuthMethodType }) {
<ButtonWrapper>
<Button
className={`t--settings-sub-category-${
method.needsUpgrade ? `upgrade-${method.category}` : method.category
!method?.isFeatureEnabled
? `upgrade-${method.category}`
: method.category
}`}
data-testid="btn-auth-account"
kind={"secondary"}
@ -141,7 +144,11 @@ export function ActionButton({ method }: { method: AuthMethodType }) {
size="md"
>
{createMessage(
method.isConnected ? EDIT : !!method.needsUpgrade ? UPGRADE : ENABLE,
method.isConnected
? EDIT
: !method?.isFeatureEnabled
? UPGRADE
: ENABLE,
)}
</Button>
</ButtonWrapper>
@ -183,7 +190,7 @@ export function AuthPage({ authMethods }: { authMethods: AuthMethodType[] }) {
renderAs="p"
>
{method.label}&nbsp;
{method.needsUpgrade && <BusinessTag />}
{!method.isFeatureEnabled && <BusinessTag />}
{method.isConnected && (
<Tooltip
content={createMessage(

View File

@ -31,6 +31,11 @@ import {
SAML_AUTH_DESC,
createMessage,
} from "@appsmith/constants/messages";
import { isSSOEnabled } from "@appsmith/utils/planHelpers";
import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
import store from "store";
const featureFlags = selectFeatureFlags(store.getState());
const FormAuth: AdminConfigType = {
type: SettingCategories.FORM_AUTH,
@ -195,6 +200,7 @@ export const FormAuthCallout: AuthMethodType = {
subText: createMessage(FORM_LOGIN_DESC),
image: Lock,
icon: "lock-password-line",
isFeatureEnabled: true,
};
export const GoogleAuthCallout: AuthMethodType = {
@ -203,6 +209,7 @@ export const GoogleAuthCallout: AuthMethodType = {
label: "Google",
subText: createMessage(GOOGLE_AUTH_DESC),
image: Google,
isFeatureEnabled: true,
};
export const GithubAuthCallout: AuthMethodType = {
@ -211,6 +218,7 @@ export const GithubAuthCallout: AuthMethodType = {
label: "GitHub",
subText: createMessage(GITHUB_AUTH_DESC),
image: Github,
isFeatureEnabled: true,
};
export const SamlAuthCallout: AuthMethodType = {
@ -219,7 +227,7 @@ export const SamlAuthCallout: AuthMethodType = {
label: "SAML 2.0",
subText: createMessage(SAML_AUTH_DESC),
image: SamlSso,
needsUpgrade: true,
isFeatureEnabled: isSSOEnabled(featureFlags),
};
export const OidcAuthCallout: AuthMethodType = {
@ -228,7 +236,7 @@ export const OidcAuthCallout: AuthMethodType = {
label: "OIDC",
subText: createMessage(OIDC_AUTH_DESC),
image: OIDC,
needsUpgrade: true,
isFeatureEnabled: isSSOEnabled(featureFlags),
};
const AuthMethods = [

View File

@ -2,8 +2,8 @@ import React from "react";
import { Button } from "design-system";
import { ContentBox } from "pages/Settings/components";
import {
ADMIN_BRANDING_SETTINGS_SUBTITLE,
ADMIN_BRANDING_SETTINGS_TITLE,
ADMIN_BRANDING_SETTINGS_SUBTITLE_UPGRADE,
ADMIN_BRANDING_SETTINGS_TITLE_UPGRADE,
createMessage,
} from "@appsmith/constants/messages";
import useOnUpgrade from "utils/hooks/useOnUpgrade";
@ -34,7 +34,7 @@ const UpgradeBanner = () => {
kind="heading-l"
renderAs="h1"
>
{createMessage(ADMIN_BRANDING_SETTINGS_TITLE)}
{createMessage(ADMIN_BRANDING_SETTINGS_TITLE_UPGRADE)}
</SettingsHeader>
<StyledSettingsSubHeader
className="w-7/12 mt-1"
@ -42,11 +42,16 @@ const UpgradeBanner = () => {
kind="body-m"
renderAs="h2"
>
{createMessage(ADMIN_BRANDING_SETTINGS_SUBTITLE)}
{createMessage(ADMIN_BRANDING_SETTINGS_SUBTITLE_UPGRADE)}
</StyledSettingsSubHeader>
</main>
<aside>
<Button onClick={onUpgrade} size="md" startIcon="star-line">
<Button
data-testid="t--branding-upgrade-button"
onClick={onUpgrade}
size="md"
startIcon="star-line"
>
Upgrade
</Button>
</aside>

View File

@ -4,7 +4,12 @@ import {
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
import { isBrandingEnabled } from "@appsmith/utils/planHelpers";
import BrandingPage from "pages/Settings/config/branding/BrandingPage";
import store from "store";
const featureFlags = selectFeatureFlags(store.getState());
export const config: AdminConfigType = {
type: SettingCategories.BRANDING,
@ -14,4 +19,5 @@ export const config: AdminConfigType = {
title: "Branding",
icon: "pantone",
component: BrandingPage,
isFeatureEnabled: isBrandingEnabled(featureFlags),
};

View File

@ -97,6 +97,7 @@ export interface Category {
categoryType: string;
needsUpgrade?: boolean;
isEnterprise?: boolean;
isFeatureEnabled?: boolean;
}
export const SettingCategories = {
@ -136,4 +137,5 @@ export type AdminConfigType = {
needsUpgrade?: boolean;
categoryType: CategoryType;
isEnterprise?: boolean;
isFeatureEnabled?: boolean;
};

View File

@ -64,7 +64,7 @@ export function FooterComponent(props: FooterProps) {
</div>
</div>
<div className="right">
<Button onClick={onClick} size="md">
<Button data-testid="t--button-upgrade" onClick={onClick} size="md">
{createMessage(UPGRADE)}
</Button>
</div>

View File

@ -0,0 +1,10 @@
import type { FeatureFlags } from "@appsmith/entities/FeatureFlag";
//if feature flag is true then return feature is enbaled
export const isBrandingEnabled = (featureFlags: FeatureFlags) => {
return featureFlags?.license_branding_enabled;
};
export const isSSOEnabled = (featureFlags: FeatureFlags) => {
return featureFlags?.license_sso_enabled;
};

View File

@ -0,0 +1 @@
export * from "ce/utils/planHelpers";

View File

@ -47,6 +47,7 @@ export class ConfigFactory {
needsUpgrade: config.needsUpgrade,
isEnterprise: config.isEnterprise,
needsRefresh: config.needsRefresh,
isFeatureEnabled: config.isFeatureEnabled,
children: config?.children?.map((child) =>
ConfigFactory.getCategory(child),
),

View File

@ -5,10 +5,11 @@ import { useForm } from "react-hook-form";
import Previews from "./previews";
import SettingsForm from "./SettingsForm";
import { getTenantConfig } from "@appsmith/selectors/tenantSelectors";
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import { Wrapper } from "@appsmith/pages/AdminSettings/config/authentication/AuthPage";
import UpgradeBanner from "@appsmith/pages/AdminSettings/config/branding/UpgradeBanner";
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import { getUpgradeBanner } from "utils/BusinessFeatures/brandingPageHelpers";
export type brandColorsKeys =
| "primary"
@ -29,7 +30,7 @@ type BrandingPageProps = {
function BrandingPage(props: BrandingPageProps) {
const { category } = props;
const { needsUpgrade = true } = category;
const isBrandingEnabled = category?.isFeatureEnabled ?? false;
const tentantConfig = useSelector(getTenantConfig);
const defaultValues = {
brandColors: tentantConfig.brandColors,
@ -66,12 +67,12 @@ function BrandingPage(props: BrandingPageProps) {
return (
<Wrapper>
<UpgradeBanner />
{getUpgradeBanner(isBrandingEnabled)}
<div className="grid md:grid-cols-[1fr] lg:grid-cols-[max(300px,30%)_1fr] gap-8 mt-4 pr-7">
<SettingsForm
control={control}
defaultValues={defaultValues}
disabled={needsUpgrade}
disabled={!isBrandingEnabled}
formState={formState}
handleSubmit={handleSubmit}
reset={reset}

View File

@ -177,7 +177,12 @@ function SettingsForm(props: SettingsFormProps) {
/>
</div>
<Button isDisabled={disabled || !hasDirtyFields} size="md" type="submit">
<Button
className="t--settings-branding-submit-button"
isDisabled={disabled || !hasDirtyFields}
size="md"
type="submit"
>
Submit
</Button>
</Wrapper>

View File

@ -0,0 +1,10 @@
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { default as UpgradeBanner_CE } from "ce/pages/AdminSettings/config/branding/UpgradeBanner";
import { default as UpgradeBanner_EE } from "ee/pages/AdminSettings/config/branding/UpgradeBanner";
import React from "react";
export const getUpgradeBanner = (isEnabled: boolean) => {
if (isEnabled) {
return <UpgradeBanner_EE />;
} else return <UpgradeBanner_CE />;
};