chore: Optimising the code for admin settings page (#25404)

## Description


#### PR fixes following issue(s)
Fixes [#25264](https://github.com/appsmithorg/appsmith/issues/25264)

#### Type of change
- Chore (housekeeping or task changes that don't impact user perception)

## Testing

#### How Has This Been Tested?
- [x] Manual
- [x] Jest
- [x] Cypress

## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] 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:
Ankita Kinger 2023-07-18 15:18:48 +05:30 committed by GitHub
parent 8342d15b03
commit e0edd068f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 488 additions and 162 deletions

View File

@ -2,8 +2,7 @@ import { REPO, CURRENT_REPO } from "../../../../fixtures/REPO";
const Access = {
AdminSettingsEntryLink: ".admin-settings-menu-option",
LeftPaneAuditLogsLink:
"[data-testid='t--enterprise-settings-category-item-audit-logs']",
LeftPaneAuditLogsLink: ".t--settings-category-audit-logs",
};
const Header = {

View File

@ -76,13 +76,6 @@ describe("Admin settings page", function () {
cy.get("@pricingPage").should("be.called");
cy.wait(2000);
cy.go(-1);
cy.get(adminsSettings.upgrageLeftPane).click();
cy.url().should("contain", "/settings/business-edition");
stubPricingPage();
cy.xpath(adminsSettings.upgrade).click();
cy.get("@pricingPage").should("be.called");
cy.wait(2000);
cy.go(-1);
}
});
});

View File

@ -27,8 +27,7 @@ export default {
formLoginDisabled: "[data-testid='APPSMITH_FORM_LOGIN_DISABLED']",
embedSettings: ".t--admin-settings-APPSMITH_ALLOWED_FRAME_ANCESTORS",
upgrade: "//button//span[text()='Upgrade']",
accessControl:
"[data-testid='t--enterprise-settings-category-item-access-control']",
auditLogs: "[data-testid='t--enterprise-settings-category-item-audit-logs']",
accessControl: ".t--settings-category-access-control",
auditLogs: ".t--settings-category-audit-logs",
upgrageLeftPane: "[data-testid='t--enterprise-settings-category-item-be']",
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -37,6 +37,3 @@ export const SETTINGS_FORM_NAME = "SettingsForm";
export const WELCOME_NON_SUPER_FORM_NAME = "WelcomeNonSuperSetupForm";
export const SAVE_THEME_FORM_NAME = "SaveThemeForm";
export const ORIGIN_URI_FORM = "OriginURIForm";
export const REDIRECT_URL_FORM = "RedirectURLForm";
export const ENTITYID_URL_FORM = "EntityIdURLForm";

View File

@ -324,6 +324,7 @@ export const OAUTH_2_0 = () => "OAuth 2.0";
export const ENABLE = () => "Enable";
export const UPGRADE = () => "Upgrade";
export const EDIT = () => "Edit";
export const CONFIGURE = () => "Configure";
export const UNEXPECTED_ERROR = () => "An unexpected error occurred";
export const EXPECTED_ERROR = () => "An error occurred";
export const NO_DATASOURCE_FOR_QUERY = () =>
@ -1248,6 +1249,14 @@ export const SAVE_BUTTON = () => "Save";
export const SAVE_AND_RESTART_BUTTON = () => "Save & Restart";
export const RESET_BUTTON = () => "Reset";
export const BUSINESS_TAG = () => "Business";
export const ENTERPRISE_TAG = () => "Enterprise";
// Upgrade pages begin
export const AVAILABLE_ON_BUSINESS = () => "Available on a business plan only";
export const EXCLUSIVE_TO_BUSINESS = (featureName: string) =>
`The ${featureName} feature is exclusive to workspaces on the Business Edition`;
export const AVAILABLE_ON_ENTERPRISE = () => "Available on Appsmith Enterprise";
// Upgrade pages end
// Audit logs begin
export const AUDIT_LOGS = () => "Audit logs";
@ -1269,9 +1278,6 @@ export const DEBUGGING_DETAIL1 = () =>
export const INCIDENT_MANAGEMENT = () => "Incident management";
export const INCIDENT_MANAGEMENT_DETAIL1 = () =>
"Go back in time from an incident to see who did what, correlate events with breaking changes, and run RCAs to remediate incidents for now and the future.";
export const AVAILABLE_ON_BUSINESS = () => "Available on a business plan only";
export const EXCLUSIVE_TO_BUSINESS = (featureName: string) =>
`The ${featureName} feature is exclusive to workspaces on the Business Edition`;
// Audit logs Upgrade page end
// Audit logs end
@ -1296,6 +1302,20 @@ export const ACCESS_CONTROL_UPGRADE_PAGE_FOOTER = () =>
"Unlock granular access controls along with audit logs and SSO for enhanced security and reliability with an upgrade to our Business edition.";
// Access control upgrade page end
// Provisioning upgrade page begin
export const USER_PROVISIONING_FOR_ENTERPRISES = () =>
"user provisioning for enterprises";
export const PROVISIONING_UPGRADE_PAGE_SUB_HEADING = () =>
"Provision and de-provision users on Appsmith. Automatic group sync from your IdP.";
export const PROVISION_DEPROVISION_USERS = () =>
"Provision and de-provision users on Appsmith";
export const PROVISION_DEPROVISION_USERS_DETAIL1 = () =>
`Automatically assign accounts to new employees and revoke access when they leave. Error-free, right from your Identity Provider (IdP).`;
export const AUTO_GROUP_SYNC = () => "Automatic group sync from your IdP";
export const AUTO_GROUP_SYNC_DETAIL1 = () =>
`Sync user groups from your IdP into Appsmith to manage access across your teams easily.`;
// Provisioning upgrade page end
//
export const WELCOME_FORM_NON_SUPER_USER_ROLE_DROPDOWN = () =>
"Tell us about your primary skillset";

View File

@ -11,6 +11,7 @@ export const FEATURE_FLAG = {
"release_embed_hide_share_settings_enabled",
ab_ds_schema_enabled: "ab_ds_schema_enabled",
ab_ds_binding_enabled: "ab_ds_binding_enabled",
release_scim_provisioning_enabled: "release_scim_provisioning_enabled",
} as const;
export type FeatureFlag = keyof typeof FEATURE_FLAG;
@ -27,6 +28,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
release_embed_hide_share_settings_enabled: false,
ab_ds_schema_enabled: false,
ab_ds_binding_enabled: false,
release_scim_provisioning_enabled: false,
};
export const AB_TESTING_EVENT_KEYS = {

View File

@ -2,20 +2,30 @@ import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
import AdminConfig from "@appsmith/pages/AdminSettings/config";
import type { Category } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
type Category,
} from "@appsmith/pages/AdminSettings/config/types";
import { adminSettingsCategoryUrl } from "RouteBuilder";
import { useParams } from "react-router";
import { createMessage, UPGRADE } from "@appsmith/constants/messages";
import AnalyticsUtil from "utils/AnalyticsUtil";
import { Icon, Text } from "design-system";
import { useDispatch } from "react-redux";
import { Icon, Tag, Text } from "design-system";
import { useDispatch, useSelector } from "react-redux";
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { getCurrentUser } from "selectors/usersSelectors";
import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
import {
BUSINESS_TAG,
ENTERPRISE_TAG,
createMessage,
} from "@appsmith/constants/messages";
export const Wrapper = styled.div`
flex-basis: ${(props) => props.theme.sidebarWidth};
overflow-y: auto;
border-right: 1px solid var(--ads-v2-color-border);
flex-shrink: 0;
padding: 12px 0;
&::-webkit-scrollbar {
display: none;
@ -27,13 +37,12 @@ export const Wrapper = styled.div`
`;
export const HeaderContainer = styled.div`
padding: 20px 0;
margin: 0 16px;
margin: 12px;
`;
export const StyledHeader = styled(Text)`
height: 20px;
margin: 8px 16px 8px;
margin: 16px;
color: var(--ads-v2-color-fg-emphasis);
`;
@ -47,13 +56,13 @@ export const CategoryItem = styled.li`
`;
export const StyledLink = styled(Link)<{ $active: boolean }>`
height: 38px;
padding: 8px 16px;
border-radius: var(--ads-v2-border-radius);
background-color: ${(props) =>
props.$active ? `var(--ads-v2-color-bg-muted)` : ""};
display: flex;
gap: 12px;
align-items: center;
&& {
color: var(--ads-v2-color-fg);
@ -76,8 +85,10 @@ export const SettingName = styled(Text)<{ active?: boolean }>`
font-weight: 400;
`;
export function getSettingsCategory() {
return Array.from(AdminConfig.categories);
export function getSettingsCategory(type: string) {
return Array.from(
AdminConfig.categories.filter((cat: any) => cat.categoryType === type),
);
}
export function Categories({
@ -95,12 +106,26 @@ export function Categories({
}) {
const dispatch = useDispatch();
const onClickHandler = (category: string) => {
const triggerAnalytics = (page: string) => {
const source: any = {
"audit-logs": "AuditLogs",
"access-control": "AccessControl",
provisioning: "Provisioning",
};
AnalyticsUtil.logEvent("ADMIN_SETTINGS_CLICK", {
source: source[page],
});
};
const onClickHandler = (category: string, needsUpgrade: boolean) => {
if (category === "general") {
dispatch({
type: ReduxActionTypes.FETCH_ADMIN_SETTINGS,
});
}
if (needsUpgrade) {
triggerAnalytics(category);
}
};
return (
@ -117,7 +142,9 @@ export function Categories({
className={`t--settings-category-${config.slug} ${
active ? "active" : ""
}`}
onClick={() => onClickHandler(config.slug)}
onClick={() =>
onClickHandler(config.slug, config?.needsUpgrade || false)
}
to={
!parentCategory
? adminSettingsCategoryUrl({ category: config.slug })
@ -127,8 +154,19 @@ export function Categories({
})
}
>
{config?.icon && <Icon name={config?.icon} size="md" />}
{config?.needsUpgrade ? (
<Icon name="lock-2-line" />
) : (
config?.icon && <Icon name={config?.icon} size="md" />
)}
<SettingName active={active}>{config.title}</SettingName>
{config?.needsUpgrade && (
<Tag isClosable={false}>
{createMessage(
config?.isEnterprise ? ENTERPRISE_TAG : BUSINESS_TAG,
)}
</Tag>
)}
</StyledLink>
{showSubCategory && (
<Categories
@ -146,74 +184,59 @@ export function Categories({
}
export default function LeftPane() {
const categories = getSettingsCategory();
const categories = getSettingsCategory(CategoryType.GENERAL);
const aclCategories = getSettingsCategory(CategoryType.ACL);
const othersCategories = getSettingsCategory(CategoryType.OTHER);
const { category, selected: subCategory } = useParams() as any;
const user = useSelector(getCurrentUser);
const isSuperUser = user?.isSuperUser;
const featureFlags = useSelector(selectFeatureFlags);
function triggerAnalytics(source: string) {
AnalyticsUtil.logEvent("ADMIN_SETTINGS_CLICK", {
source,
});
}
const filteredAclCategories = aclCategories
?.map((category) => {
if (
category.slug === "provisioning" &&
!featureFlags.release_scim_provisioning_enabled
) {
return null;
}
return category;
})
.filter(Boolean) as Category[];
return (
<Wrapper>
{isSuperUser && (
<HeaderContainer>
<StyledHeader kind="heading-s" renderAs="p">
Admin settings
</StyledHeader>
<Categories
categories={categories}
currentCategory={category}
currentSubCategory={subCategory}
/>
</HeaderContainer>
)}
<HeaderContainer>
<StyledHeader kind="heading-s" renderAs="p">
Admin settings
Access control
</StyledHeader>
<Categories
categories={categories}
categories={filteredAclCategories}
currentCategory={category}
currentSubCategory={subCategory}
/>
</HeaderContainer>
<HeaderContainer>
<StyledHeader kind="heading-s" renderAs="p">
Business
Others
</StyledHeader>
<CategoryList data-testid="t--enterprise-settings-category-list">
<CategoryItem>
<StyledLink
$active={category === "access-control"}
className={`${category === "access-control" ? "active" : ""}`}
data-testid="t--enterprise-settings-category-item-access-control"
to="/settings/access-control"
>
<Icon name="lock-2-line" size="md" />
<SettingName active={category === "access-control"}>
Access control
</SettingName>
</StyledLink>
</CategoryItem>
<CategoryItem>
<StyledLink
$active={category === "audit-logs"}
className={`${category === "audit-logs" ? "active" : ""}`}
data-testid="t--enterprise-settings-category-item-audit-logs"
onClick={() => triggerAnalytics("AuditLogs")}
to="/settings/audit-logs"
>
<Icon name="lock-2-line" size="md" />
<SettingName active={category === "audit-logs"}>
Audit logs
</SettingName>
</StyledLink>
</CategoryItem>
<CategoryItem>
<StyledLink
$active={category === "business-edition"}
className={`${category === "business-edition" ? "active" : ""}`}
data-testid="t--enterprise-settings-category-item-be"
onClick={() => triggerAnalytics("BusinessEdition")}
to="/settings/business-edition"
>
<Icon name="arrow-up-line" size="md" />
<SettingName active={category === "business-edition"}>
{createMessage(UPGRADE)}
</SettingName>
</StyledLink>
</CategoryItem>
</CategoryList>
<Categories
categories={othersCategories}
currentCategory={category}
currentSubCategory={subCategory}
/>
</HeaderContainer>
</Wrapper>
);

View File

@ -3,13 +3,11 @@ import AdminConfig from "./config";
import { Redirect, useParams } from "react-router";
import { SettingCategories } from "@appsmith/pages/AdminSettings/config/types";
import SettingsForm from "pages/Settings/SettingsForm";
import { AuditLogsUpgradePage } from "../Upgrade/AuditLogsUpgradePage";
import { AccessControlUpgradePage } from "../Upgrade/AccessControlUpgradePage";
import { getDefaultAdminSettingsPath } from "@appsmith/utils/adminSettingsHelpers";
import { useSelector } from "react-redux";
import { getCurrentUser } from "selectors/usersSelectors";
import { getTenantPermissions } from "@appsmith/selectors/tenantSelectors";
import { UpgradeToBEPage } from "../Upgrade/businessEdition/UpgradeToBEPage";
import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
const Main = () => {
const params = useParams() as any;
@ -19,22 +17,19 @@ const Main = () => {
const isSuperUser = user?.isSuperUser || false;
const wrapperCategory =
AdminConfig.wrapperCategories[subCategory ?? category];
const featureFlags = useSelector(selectFeatureFlags);
/* New flow, where data is hand written and processed differently than old flow
* In old flow, config and a factory was used to generate the Main content.
*/
if (category === "access-control") {
return <AccessControlUpgradePage />;
}
if (category === "audit-logs") {
return <AuditLogsUpgradePage />;
if (
category === "provisioning" &&
!featureFlags.release_scim_provisioning_enabled
) {
return (
<Redirect
to={getDefaultAdminSettingsPath({ isSuperUser, tenantPermissions })}
/>
);
}
if (category === "business-edition") {
return <UpgradeToBEPage />;
}
/* Old, still working flow; config, factory based */
if (!!wrapperCategory?.component) {
const { component: WrapperCategoryComponent } = wrapperCategory;
return <WrapperCategoryComponent category={wrapperCategory} />;

View File

@ -0,0 +1,18 @@
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import { AuditLogsUpgradePage } from "../../Upgrade/AuditLogsUpgradePage";
export const config: AdminConfigType = {
icon: "file-list-2-line",
type: SettingCategories.AUDIT_LOGS,
categoryType: CategoryType.OTHER,
controlType: SettingTypes.PAGE,
component: AuditLogsUpgradePage,
title: "Audit logs",
canSave: false,
needsUpgrade: true,
} as AdminConfigType;

View File

@ -6,8 +6,8 @@ import {
} from "constants/ThirdPartyConstants";
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingSubCategories,
SettingSubtype,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
@ -18,7 +18,6 @@ import SamlSso from "assets/images/saml.svg";
import OIDC from "assets/images/oidc.svg";
import Github from "assets/images/Github.png";
import Lock from "assets/images/lock-password-line.svg";
import { ORIGIN_URI_FORM, REDIRECT_URL_FORM } from "@appsmith/constants/forms";
import { useSelector } from "react-redux";
import {
getThirdPartyAuths,
@ -35,6 +34,7 @@ import {
const FormAuth: AdminConfigType = {
type: SettingCategories.FORM_AUTH,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Form login",
subText: createMessage(FORM_LOGIN_DESC),
@ -43,14 +43,12 @@ const FormAuth: AdminConfigType = {
{
id: "APPSMITH_FORM_LOGIN_DISABLED",
category: SettingCategories.FORM_AUTH,
subCategory: SettingSubCategories.FORMLOGIN,
controlType: SettingTypes.TOGGLE,
label: "form login",
},
{
id: "APPSMITH_SIGNUP_DISABLED",
category: SettingCategories.FORM_AUTH,
subCategory: SettingSubCategories.FORMLOGIN,
controlType: SettingTypes.TOGGLE,
label: "Form signup",
toggleText: (value: boolean) =>
@ -61,7 +59,6 @@ const FormAuth: AdminConfigType = {
{
id: "APPSMITH_FORM_CALLOUT_BANNER",
category: SettingCategories.FORM_AUTH,
subCategory: SettingSubCategories.FORMLOGIN,
controlType: SettingTypes.LINK,
label:
"The form login method does not verify the emails of users that create accounts.",
@ -73,6 +70,7 @@ const FormAuth: AdminConfigType = {
export const GoogleAuth: AdminConfigType = {
type: SettingCategories.GOOGLE_AUTH,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Google authentication",
subText: createMessage(GOOGLE_AUTH_DESC),
@ -81,7 +79,6 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GOOGLE_READ_MORE",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.LINK,
label: "How to configure?",
url: GOOGLE_SIGNUP_SETUP_DOC,
@ -89,10 +86,8 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GOOGLE_JS_ORIGIN_URL",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.UNEDITABLEFIELD,
label: "JavaScript origin URL",
formName: ORIGIN_URI_FORM,
fieldName: "js-origin-url-form",
value: "",
tooltip:
@ -102,10 +97,8 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GOOGLE_REDIRECT_URL",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.UNEDITABLEFIELD,
label: "Redirect URL",
formName: REDIRECT_URL_FORM,
fieldName: "redirect-url-form",
value: "/login/oauth2/code/google",
tooltip:
@ -115,7 +108,6 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GOOGLE_CLIENT_ID",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.TEXTINPUT,
controlSubType: SettingSubtype.TEXT,
label: "Client ID",
@ -124,7 +116,6 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.TEXTINPUT,
controlSubType: SettingSubtype.TEXT,
label: "Client secret",
@ -133,7 +124,6 @@ export const GoogleAuth: AdminConfigType = {
{
id: "APPSMITH_SIGNUP_ALLOWED_DOMAINS",
category: SettingCategories.GOOGLE_AUTH,
subCategory: SettingSubCategories.GOOGLE,
controlType: SettingTypes.TEXTINPUT,
controlSubType: SettingSubtype.TEXT,
label: "Allowed domains",
@ -144,6 +134,7 @@ export const GoogleAuth: AdminConfigType = {
export const GithubAuth: AdminConfigType = {
type: SettingCategories.GITHUB_AUTH,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "GitHub authentication",
subText: createMessage(GITHUB_AUTH_DESC),
@ -152,7 +143,6 @@ export const GithubAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GITHUB_READ_MORE",
category: SettingCategories.GITHUB_AUTH,
subCategory: SettingSubCategories.GITHUB,
controlType: SettingTypes.LINK,
label: "How to configure?",
url: GITHUB_SIGNUP_SETUP_DOC,
@ -160,10 +150,8 @@ export const GithubAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GITHUB_HOMEPAGE_URL",
category: SettingCategories.GITHUB_AUTH,
subCategory: SettingSubCategories.GITHUB,
controlType: SettingTypes.UNEDITABLEFIELD,
label: "Homepage URL",
formName: ORIGIN_URI_FORM,
fieldName: "homepage-url-form",
value: "",
tooltip:
@ -173,10 +161,8 @@ export const GithubAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GITHUB_REDIRECT_URL",
category: SettingCategories.GITHUB_AUTH,
subCategory: SettingSubCategories.GITHUB,
controlType: SettingTypes.UNEDITABLEFIELD,
label: "Redirect URL",
formName: REDIRECT_URL_FORM,
fieldName: "callback-url-form",
value: "/login/oauth2/code/github",
tooltip:
@ -186,7 +172,6 @@ export const GithubAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GITHUB_CLIENT_ID",
category: SettingCategories.GITHUB_AUTH,
subCategory: SettingSubCategories.GITHUB,
controlType: SettingTypes.TEXTINPUT,
controlSubType: SettingSubtype.TEXT,
label: "Client ID",
@ -195,7 +180,6 @@ export const GithubAuth: AdminConfigType = {
{
id: "APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET",
category: SettingCategories.GITHUB_AUTH,
subCategory: SettingSubCategories.GITHUB,
controlType: SettingTypes.TEXTINPUT,
controlSubType: SettingSubtype.TEXT,
label: "Client secret",
@ -268,6 +252,7 @@ function AuthMain() {
export const config: AdminConfigType = {
icon: "lock-password-line",
type: SettingCategories.AUTHENTICATION,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.PAGE,
title: "Authentication",
canSave: false,

View File

@ -1,5 +1,6 @@
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
@ -7,6 +8,7 @@ import BrandingPage from "pages/Settings/config/branding/BrandingPage";
export const config: AdminConfigType = {
type: SettingCategories.BRANDING,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.PAGE,
canSave: false,
title: "Branding",

View File

@ -7,6 +7,7 @@ import type {
Setting,
} from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingSubtype,
SettingTypes,
@ -169,6 +170,7 @@ export const APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING: Setting = {
export const config: AdminConfigType = {
icon: "settings-2-line",
type: SettingCategories.GENERAL,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "General",
canSave: true,

View File

@ -7,6 +7,9 @@ import { config as VersionConfig } from "pages/Settings/config/version";
import { config as AdvancedConfig } from "pages/Settings/config/advanced";
import { config as Authentication } from "@appsmith/pages/AdminSettings/config/authentication";
import { config as BrandingConfig } from "@appsmith/pages/AdminSettings/config/branding";
import { config as ProvisioningConfig } from "@appsmith/pages/AdminSettings/config/provisioning";
import { config as UserListing } from "@appsmith/pages/AdminSettings/config//userlisting";
import { config as AuditLogsConfig } from "@appsmith/pages/AdminSettings/config/auditLogsConfig";
ConfigFactory.register(GeneralConfig);
ConfigFactory.register(EmailConfig);
@ -15,5 +18,8 @@ ConfigFactory.register(Authentication);
ConfigFactory.register(AdvancedConfig);
ConfigFactory.register(VersionConfig);
ConfigFactory.register(BrandingConfig);
ConfigFactory.register(ProvisioningConfig);
ConfigFactory.register(UserListing);
ConfigFactory.register(AuditLogsConfig);
export default ConfigFactory;

View File

@ -0,0 +1,19 @@
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import { ProvisioningUpgradePage } from "../../Upgrade/ProvisioningUpgradePage";
export const config: AdminConfigType = {
icon: "user-follow-line",
type: SettingCategories.PROVISIONING,
categoryType: CategoryType.ACL,
controlType: SettingTypes.PAGE,
component: ProvisioningUpgradePage,
title: "Provisioning",
canSave: false,
needsUpgrade: true,
isEnterprise: true,
} as AdminConfigType;

View File

@ -56,7 +56,7 @@ export type Setting = ControlType & {
format?: (value: string) => any;
parse?: (value: any) => any;
helpText?: string;
label?: string;
label?: React.ReactNode;
name?: string;
placeholder?: string;
validate?: (value: string, setting?: Setting) => string | void;
@ -93,6 +93,9 @@ export interface Category {
isConnected?: boolean;
children?: Category[];
icon?: string;
categoryType: string;
needsUpgrade?: boolean;
isEnterprise?: boolean;
}
export const SettingCategories = {
@ -107,14 +110,15 @@ export const SettingCategories = {
GITHUB_AUTH: "github-auth",
AUDIT_LOGS: "audit-logs",
ACCESS_CONTROL: "access-control",
PROVISIONING: "provisioning",
BRANDING: "branding",
};
export const SettingSubCategories = {
GOOGLE: "google signup",
GITHUB: "github signup",
FORMLOGIN: "form login",
};
export enum CategoryType {
GENERAL = "general",
ACL = "acl",
OTHER = "other",
}
export type AdminConfigType = {
type: string;
@ -128,4 +132,6 @@ export type AdminConfigType = {
isConnected?: boolean;
icon?: string;
needsUpgrade?: boolean;
categoryType: CategoryType;
isEnterprise?: boolean;
};

View File

@ -0,0 +1,18 @@
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import { AccessControlUpgradePage } from "../../Upgrade/AccessControlUpgradePage";
export const config: AdminConfigType = {
icon: "user-3-line",
type: SettingCategories.ACCESS_CONTROL,
categoryType: CategoryType.ACL,
controlType: SettingTypes.PAGE,
component: AccessControlUpgradePage,
title: "Access Control",
canSave: false,
needsUpgrade: true,
} as AdminConfigType;

View File

@ -304,11 +304,7 @@ export function Item(props: {
const LeftPaneDataSection = styled.div<{ isBannerVisible?: boolean }>`
position: relative;
height: calc(
100vh -
${(props) =>
props.theme.homePage.header + 24 + (props.isBannerVisible ? 48 : 0)}px
);
height: calc(100vh - ${(props) => 48 + (props.isBannerVisible ? 48 : 0)}px);
display: flex;
flex-direction: column;
`;

View File

@ -28,7 +28,6 @@ import {
import { getTenantPermissions } from "@appsmith/selectors/tenantSelectors";
export const Wrapper = styled.div`
padding-bottom: 26px;
background-color: var(--ads-v2-color-bg);
width: 100%;
margin-top: auto;
@ -37,7 +36,6 @@ export const Wrapper = styled.div`
export const MenuWrapper = styled.div`
margin-top: 4px;
margin-bottom: 8px;
`;
export const LeftPaneVersionData = styled.div`
@ -49,9 +47,8 @@ export const LeftPaneVersionData = styled.div`
margin-top: ${(props) => props.theme.spaces[3]}px;
// reduce border width from 1px from width
width: calc(${(props) => props.theme.homePage.sidebar}px - 1px);
position: fixed;
bottom: 0;
left: 0;
position: relative;
left: -16px;
padding: 8px 30px;
background: var(--ads-v2-color-bg-subtle);
`;

View File

@ -52,17 +52,17 @@ export function AccessControlUpgradePage() {
],
targets: [
<img
alt="Secure apps by the least privilege needed"
alt={createMessage(SECURITY_APPS_LEAST_PRIVILEGE)}
key="secure-apps-least-privilege"
src={SecureAppsLeastPrivilegeImage}
/>,
<img
alt="Prevent accidental damage to data"
alt={createMessage(PREVENT_ACCIDENTAL_DAMAGE)}
key="prevent-accidental-damage"
src={PreventAccidentalDamageImage}
/>,
<img
alt="Restrict public exposure of sensitive data"
alt={createMessage(RESTRICT_PUBLIC_EXPOSURE)}
key="restrict-exposure-sensitive-data"
src={RestrictPublicExposureImage}
/>,

View File

@ -52,13 +52,17 @@ export function AuditLogsUpgradePage() {
],
targets: [
<img
alt="Security & Compliance"
alt={createMessage(SECURITY_AND_COMPLIANCE)}
key="security-and-compliance"
src={SecurityAndComplianceImage}
/>,
<img alt="Debugging" key="debugging" src={DebuggingImage} />,
<img
alt="Incident management"
alt={createMessage(DEBUGGING)}
key="debugging"
src={DebuggingImage}
/>,
<img
alt={createMessage(INCIDENT_MANAGEMENT)}
key="incident-management"
src={IncidentManagementImage}
/>,

View File

@ -4,6 +4,7 @@ import { Button, Text } from "design-system";
import type { FooterProps } from "./types";
import {
AVAILABLE_ON_BUSINESS,
AVAILABLE_ON_ENTERPRISE,
createMessage,
UPGRADE,
} from "@appsmith/constants/messages";
@ -31,11 +32,12 @@ const FooterContainer = styled.div`
& .right {
flex-grow: 1;
text-align: end;
}
`;
export function FooterComponent(props: FooterProps) {
const { message, onClick, showHeading = true } = props;
const { isEnterprise = false, message, onClick, showHeading = true } = props;
return (
<FooterContainer
className="upgrade-page-footer-container"
@ -49,7 +51,9 @@ export function FooterComponent(props: FooterProps) {
kind="heading-m"
renderAs="h1"
>
{createMessage(AVAILABLE_ON_BUSINESS)}
{createMessage(
isEnterprise ? AVAILABLE_ON_ENTERPRISE : AVAILABLE_ON_BUSINESS,
)}
</Text>
</div>
)}

View File

@ -0,0 +1,68 @@
import React from "react";
import type { Carousel, Header } from "./types";
import UpgradePage from "./UpgradePage";
import ProvisionDeprovisionUsersImage from "assets/images/upgrade/provisioning/provision-deprovision-users.svg";
import AutoGroupSyncImage from "assets/images/upgrade/provisioning/auto-group-sync.svg";
import {
ACCESS_CONTROL_UPGRADE_PAGE_FOOTER,
AUTO_GROUP_SYNC,
AUTO_GROUP_SYNC_DETAIL1,
createMessage,
INTRODUCING,
PROVISION_DEPROVISION_USERS,
PROVISION_DEPROVISION_USERS_DETAIL1,
PROVISIONING_UPGRADE_PAGE_SUB_HEADING,
USER_PROVISIONING_FOR_ENTERPRISES,
} from "@appsmith/constants/messages";
import useOnUpgrade from "utils/hooks/useOnUpgrade";
export function ProvisioningUpgradePage() {
const { onUpgrade } = useOnUpgrade({
logEventName: "PROVISIONING_UPGRADE_ADMIN_SETTINGS",
logEventData: { source: "Provisioning" },
});
const header: Header = {
heading: createMessage(
INTRODUCING,
createMessage(USER_PROVISIONING_FOR_ENTERPRISES),
),
subHeadings: [createMessage(PROVISIONING_UPGRADE_PAGE_SUB_HEADING)],
};
const carousel: Carousel = {
triggers: [
{
icon: "user-settings-line",
heading: createMessage(PROVISION_DEPROVISION_USERS),
details: [createMessage(PROVISION_DEPROVISION_USERS_DETAIL1)],
},
{
icon: "group-line",
heading: createMessage(AUTO_GROUP_SYNC),
details: [createMessage(AUTO_GROUP_SYNC_DETAIL1)],
},
],
targets: [
<img
alt={createMessage(PROVISION_DEPROVISION_USERS)}
key="provision-deprovision-users"
src={ProvisionDeprovisionUsersImage}
/>,
<img
alt={createMessage(AUTO_GROUP_SYNC)}
key="auto-group-sync"
src={AutoGroupSyncImage}
/>,
],
design: "split-left-trigger",
};
const footer = {
onClick: () => {
onUpgrade();
},
message: createMessage(ACCESS_CONTROL_UPGRADE_PAGE_FOOTER),
isEnterprise: true,
};
const props = { header, carousel, footer };
return <UpgradePage {...props} />;
}

View File

@ -25,6 +25,7 @@ export type Footer = {
onClick: ((event: React.MouseEvent<HTMLElement>) => void) | undefined;
message: string;
showHeading?: boolean;
isEnterprise?: boolean;
};
export type UpgradePageProps = {
header: Header;

View File

@ -25,6 +25,7 @@ const renderComponent = (
componentProps.meta.error &&
componentProps.meta.error
}
label={componentProps.label as string}
/>
) : (
<Input
@ -46,7 +47,7 @@ export type FormTextFieldProps = {
placeholder: string;
description?: string;
type?: InputType;
label?: string;
label?: React.ReactNode;
intent?: Intent;
disabled?: boolean;
autoFocus?: boolean;

View File

@ -0,0 +1 @@
export * from "ce/pages/AdminSettings/config/auditLogsConfig";

View File

@ -0,0 +1 @@
export * from "ce/pages/AdminSettings/config/provisioning";

View File

@ -0,0 +1 @@
export * from "ce/pages/AdminSettings/config/userlisting";

View File

@ -2,7 +2,6 @@ import React, { useState } from "react";
import styled from "styled-components";
import type { Setting } from "@appsmith/pages/AdminSettings/config/types";
import { createMessage } from "@appsmith//constants/messages";
import Group from "./group";
import { Icon, Text } from "design-system";
@ -41,7 +40,7 @@ const Line = styled.hr`
`;
type AccordionProps = {
label?: string;
label?: React.ReactNode;
settings?: Setting[];
isHidden?: boolean;
category?: string;
@ -66,7 +65,7 @@ export default function Accordion({
onClick={() => setIsOpen(!isOpen)}
renderAs="label"
>
<span>{createMessage(() => label)}</span>
<span>{label}</span>
<Line />
<Icon name={isOpen ? "expand-less" : "expand-more"} size="md" />
</AccordionHeader>

View File

@ -19,7 +19,7 @@ const CheckboxWrapper = styled.div`
`;
type CheckboxProps = {
label?: string;
label?: React.ReactNode;
id?: string;
isDisabled?: boolean;
needsUpgrade?: boolean;

View File

@ -57,7 +57,7 @@ export function FormGroup({ children, className, setting }: FieldHelperProps) {
kind="body-m"
renderAs="label"
>
{createMessage(() => setting.label || "")}
{setting.label || ""}
</Text>
)}
{setting.isRequired && (

View File

@ -24,7 +24,7 @@ const HeaderWrapper = styled.div`
function CopyUrlForm(props: {
value: string;
title: string;
title: React.ReactNode;
helpText?: string;
tooltip?: string;
fieldName?: string;

View File

@ -61,7 +61,7 @@ export default function Link({ setting }: SettingComponentProps) {
data-testid="admin-settings-link-label"
renderAs="span"
>
{createMessage(() => setting.label || "")}
{setting.label || ""}
</Text>
&nbsp;
<Text renderAs="p">

View File

@ -29,7 +29,7 @@ type TagListFieldProps = {
name: string;
placeholder: string;
type: string;
label?: string;
label?: React.ReactNode;
intent: Intent;
setting: Setting;
customError?: (err: string) => void;

View File

@ -17,7 +17,7 @@ function FieldToggleWithToggleText(
toggleText?: (value: boolean) => string,
id?: string,
isPropertyDisabled?: boolean,
label?: string,
label?: React.ReactNode,
) {
return function FieldToggle(
componentProps: FormTextFieldProps & {

View File

@ -9,11 +9,7 @@ import Button from "./Button";
import { getFormValues } from "redux-form";
import { SETTINGS_FORM_NAME } from "@appsmith/constants/forms";
import { useSelector } from "react-redux";
import {
createMessage,
LEARN_MORE,
REDIRECT_URL_TOOLTIP,
} from "@appsmith/constants/messages";
import { createMessage, LEARN_MORE } from "@appsmith/constants/messages";
import { Callout, Text } from "design-system";
import CopyUrlForm from "./CopyUrlForm";
import Accordion from "./Accordion";
@ -200,7 +196,7 @@ export default function Group({
},
]}
>
{createMessage(() => setting.label || "")}
{setting.label || ""}
</Callout>
</div>
);
@ -250,9 +246,7 @@ export default function Group({
fieldName={setting.fieldName || ""}
helpText={setting.helpText}
title={setting.label || ""}
tooltip={
setting.tooltip || createMessage(REDIRECT_URL_TOOLTIP)
}
tooltip={setting.tooltip}
value={setting.value || ""}
/>
</div>

View File

@ -43,6 +43,9 @@ export class ConfigFactory {
title: config.title,
slug: config.type,
subText: config.subText,
categoryType: config.categoryType,
needsUpgrade: config.needsUpgrade,
isEnterprise: config.isEnterprise,
children: config?.children?.map((child) =>
ConfigFactory.getCategory(child),
),

View File

@ -1,5 +1,6 @@
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingSubtype,
SettingTypes,
@ -8,6 +9,7 @@ import {
export const config: AdminConfigType = {
icon: "settings-line",
type: SettingCategories.ADVANCED,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Advanced",
canSave: true,

View File

@ -6,6 +6,7 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { isNil, omitBy } from "lodash";
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingSubtype,
SettingTypes,
@ -14,6 +15,7 @@ import {
export const config: AdminConfigType = {
icon: "mail-line",
type: SettingCategories.EMAIL,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Email",
canSave: true,

View File

@ -1,6 +1,7 @@
import { GOOGLE_MAPS_SETUP_DOC } from "constants/ThirdPartyConstants";
import type { AdminConfigType } from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingSubtype,
SettingTypes,
@ -9,6 +10,7 @@ import {
export const config: AdminConfigType = {
icon: "map-pin-2-line",
type: SettingCategories.GOOGLE_MAPS,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Google Maps",
canSave: true,

View File

@ -6,6 +6,7 @@ import type {
Setting,
} from "@appsmith/pages/AdminSettings/config/types";
import {
CategoryType,
SettingCategories,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
@ -16,6 +17,7 @@ const isAirgappedInstance = isAirgapped();
export const config: AdminConfigType = {
icon: "timer-2-line",
type: SettingCategories.VERSION,
categoryType: CategoryType.GENERAL,
controlType: SettingTypes.GROUP,
title: "Version",
canSave: false,

View File

@ -239,6 +239,7 @@ export type EventName =
| "BILLING_UPGRADE_ADMIN_SETTINGS"
| "AUDIT_LOGS_UPGRADE_ADMIN_SETTINGS"
| "GAC_UPGRADE_CLICK_ADMIN_SETTINGS"
| "PROVISIONING_UPGRADE_ADMIN_SETTINGS"
| "REFLOW_BETA_FLAG"
| "CONTAINER_JUMP"
| "CONNECT_GIT_CLICK"