diff --git a/client/packages/lowcoder/src/api/commonSettingApi.ts b/client/packages/lowcoder/src/api/commonSettingApi.ts index d549b1ff8..b2f746454 100644 --- a/client/packages/lowcoder/src/api/commonSettingApi.ts +++ b/client/packages/lowcoder/src/api/commonSettingApi.ts @@ -82,35 +82,6 @@ export interface ThemeDetail { dataLoadingIndicator?: string; } -export interface BrandingSettings { - logo: string | null; - squareLogo: string | null; - mainBrandingColor: string; - appHeaderColor: string; - adminSidebarColor: string; - adminSidebarFontColor: string; - adminSidebarActiveBgColor: string; - adminSidebarActiveFontColor: string; - editorSidebarColor: string; - editorSidebarFontColor: string; - editorSidebarActiveBgColor: string; - editorSidebarActiveFontColor: string; - font: string; - errorPageText: string; - errorPageImage: string | null; - signUpPageText: string; - signUpPageImage: string | null; - loggedOutPageText: string; - loggedOutPageImage: string | null; - standardDescription: string; - standardTitle: string; - showDocumentation: boolean; - documentationLink: string | null; - submitIssue: boolean; - whatsNew: boolean; - whatsNewLink: string | null; -} - export function getThemeDetailName(key: keyof ThemeDetail) { switch (key) { case "primary": return trans("themeDetail.primary"); diff --git a/client/packages/lowcoder/src/api/enterpriseApi.ts b/client/packages/lowcoder/src/api/enterpriseApi.ts index 8301b6865..05a1e69c5 100644 --- a/client/packages/lowcoder/src/api/enterpriseApi.ts +++ b/client/packages/lowcoder/src/api/enterpriseApi.ts @@ -1,45 +1,110 @@ import axios from 'axios'; +export interface FetchBrandingSettingPayload { + orgId?: string; +} +export interface BrandingSettings { + logo?: string | null; + squareLogo?: string | null; + mainBrandingColor?: string; + appHeaderColor?: string; + adminSidebarColor?: string; + adminSidebarFontColor?: string; + adminSidebarActiveBgColor?: string; + adminSidebarActiveFontColor?: string; + editorSidebarColor?: string; + editorSidebarFontColor?: string; + editorSidebarActiveBgColor?: string; + editorSidebarActiveFontColor?: string; + font?: string; + errorPageText?: string; + errorPageImage?: string | null; + signUpPageText?: string; + signUpPageImage?: string | null; + loggedOutPageText?: string; + loggedOutPageImage?: string | null; + standardDescription?: string; + standardTitle?: string; + showDocumentation?: boolean; + documentationLink?: string | null; + submitIssue?: boolean; + whatsNew?: boolean; + whatsNewLink?: string | null; +} +export interface BrandingConfig { + config_name?: string, + config_description?: string, + config_icon?: string, + config_set?: BrandingSettings, + org_id?: string, + user_id?: string, + id?: string, +} + +export interface BrandingSettingResponse extends BrandingConfig {}; + +export interface EnterpriseLicenseResponse { + eeActive: boolean; + remainingAPICalls: number; + eeLicenses: Array<{ + uuid: string; + issuedTo: string; + apiCallsLimit: number; + }>; +} + // Existing functions export const getEnterpriseLicense = async () => { - const response = await axios.get('/api/plugins/enterprise/license'); - return response.data; + const response = await axios.get('/api/plugins/enterprise/license'); + return response.data; }; export const getAuditLogs = async (params = {}) => { - const query = new URLSearchParams(params).toString(); - const response = await axios.get(`/api/plugins/enterprise/audit-logs${query ? `?${query}` : ''}`); - return response.data; + const query = new URLSearchParams(params).toString(); + const response = await axios.get(`/api/plugins/enterprise/audit-logs${query ? `?${query}` : ''}`); + return response.data; }; export const getAuditLogStatistics = async (groupByParam : string) => { - const response = await axios.get(`/api/plugins/enterprise/audit-logs/statistics?groupByParam=${groupByParam}`); - return response.data; + const response = await axios.get(`/api/plugins/enterprise/audit-logs/statistics?groupByParam=${groupByParam}`); + return response.data; }; export const getAppUsageLogs = async (params = {}) => { - const query = new URLSearchParams(params).toString(); - const response = await axios.get(`/api/plugins/enterprise/app-usage-logs${query ? `?${query}` : ''}`); - return response.data; + const query = new URLSearchParams(params).toString(); + const response = await axios.get(`/api/plugins/enterprise/app-usage-logs${query ? `?${query}` : ''}`); + return response.data; }; export const getAppUsageStatistics = async (groupByParam : string) => { - const response = await axios.get(`/api/plugins/enterprise/app-usage-logs/statistics?groupByParam=${groupByParam}`); - return response.data; + const response = await axios.get(`/api/plugins/enterprise/app-usage-logs/statistics?groupByParam=${groupByParam}`); + return response.data; }; -export const getBranding = async () => { - const response = await axios.get('/api/plugins/enterprise/branding'); - return response.data; +export const getBranding = async (orgId: string = '') => { + const response = await axios.get('/api/plugins/enterprise/branding?orgId='+orgId); + const data = response.data; + if (Boolean(data.error)) { + return {}; + } + return { + ...data, + config_set: JSON.parse(data.config_set), + }; }; export const createBranding = async (brandingData : any) => { - const response = await axios.post('/api/plugins/enterprise/branding', brandingData); - return response.data; + let response; + if (brandingData.id) { + response = await axios.put(`/api/plugins/enterprise/branding?brandId=${brandingData.id}`, brandingData); + } else { + response = await axios.post('/api/plugins/enterprise/branding', brandingData); + } + return response.data; }; export const updateBranding = async (brandingData : any) => { - const response = await axios.put('/api/plugins/enterprise/branding', brandingData); - return response.data; + const response = await axios.put('/api/plugins/enterprise/branding', brandingData); + return response.data; }; diff --git a/client/packages/lowcoder/src/app.tsx b/client/packages/lowcoder/src/app.tsx index cc5332c9c..b8f40ae6d 100644 --- a/client/packages/lowcoder/src/app.tsx +++ b/client/packages/lowcoder/src/app.tsx @@ -60,7 +60,8 @@ import GlobalInstances from 'components/GlobalInstances'; import { fetchHomeData, fetchServerSettingsAction } from "./redux/reduxActions/applicationActions"; import { getNpmPackageMeta } from "./comps/utils/remote"; import { packageMetaReadyAction, setLowcoderCompsLoading } from "./redux/reduxActions/npmPluginActions"; -import { fetchCommonSettings } from "./redux/reduxActions/commonSettingsActions"; +import { fetchBrandingSetting } from "./redux/reduxActions/enterpriseActions"; +import { EnterpriseProvider } from "./util/context/EnterpriseContext"; const LazyUserAuthComp = React.lazy(() => import("pages/userAuth")); const LazyInviteLanding = React.lazy(() => import("pages/common/inviteLanding")); @@ -95,7 +96,7 @@ type AppIndexProps = { defaultHomePage: string | null | undefined; fetchHomeDataFinished: boolean; fetchConfig: (orgId?: string) => void; - fetchCommonSettings: (orgId: string) => void; + fetchBrandingSetting: (orgId?: string) => void; fetchHomeData: (currentUserAnonymous?: boolean | undefined) => void; fetchLowcoderCompVersions: () => void; getCurrentUser: () => void; @@ -123,7 +124,7 @@ class AppIndex extends React.Component { if (!this.props.currentUserAnonymous) { this.props.fetchHomeData(this.props.currentUserAnonymous); this.props.fetchLowcoderCompVersions(); - this.props.fetchCommonSettings(this.props.currentOrgId!); + this.props.fetchBrandingSetting(this.props.currentOrgId); } } } @@ -430,7 +431,7 @@ const mapDispatchToProps = (dispatch: any) => ({ fetchHomeData: (currentUserAnonymous: boolean | undefined) => { dispatch(fetchHomeData({})); }, - fetchCommonSettings: (orgId: string) => dispatch(fetchCommonSettings({ orgId })), + fetchBrandingSetting: (orgId?: string) => dispatch(fetchBrandingSetting({ orgId })), fetchLowcoderCompVersions: async () => { try { dispatch(setLowcoderCompsLoading(true)); @@ -458,7 +459,9 @@ export function bootstrap() { const root = createRoot(container!); root.render( + + ); } diff --git a/client/packages/lowcoder/src/components/layout/Layout.tsx b/client/packages/lowcoder/src/components/layout/Layout.tsx index 3024fd9ce..ccc54e721 100644 --- a/client/packages/lowcoder/src/components/layout/Layout.tsx +++ b/client/packages/lowcoder/src/components/layout/Layout.tsx @@ -10,7 +10,6 @@ import { CNMainContent, CNSidebar } from "constants/styleSelectors"; import { SideBarSection, SideBarSectionProps } from "./SideBarSection"; import styled from "styled-components"; import { useSelector } from "react-redux"; -import { getBrandingSettings } from "@lowcoder-ee/redux/selectors/commonSettingSelectors"; import { MenuOutlined } from "@ant-design/icons"; import { Drawer, Button } from "antd"; @@ -58,7 +57,6 @@ const DrawerContentWrapper = styled.div` `; export function Layout(props: LayoutProps) { - const brandingSettings = useSelector(getBrandingSettings); const [drawerVisible, setDrawerVisible] = useState(false); const [isMobile, setIsMobile] = useState(false); diff --git a/client/packages/lowcoder/src/components/layout/SideBarSection.tsx b/client/packages/lowcoder/src/components/layout/SideBarSection.tsx index 3964ec420..7f105b643 100644 --- a/client/packages/lowcoder/src/components/layout/SideBarSection.tsx +++ b/client/packages/lowcoder/src/components/layout/SideBarSection.tsx @@ -11,7 +11,7 @@ import { getUser } from "../../redux/selectors/usersSelectors"; import { normalAppListSelector } from "../../redux/selectors/applicationSelector"; import { useLocation } from "react-router-dom"; import history from "../../util/history"; -import { getBrandingSettings } from "@lowcoder-ee/redux/selectors/commonSettingSelectors"; +import { getBrandingSetting } from "@lowcoder-ee/redux/selectors/enterpriseSelectors"; const defaultOnSelectedFn = (routePath: string, currentPath: string) => routePath === currentPath; @@ -24,7 +24,8 @@ const Wrapper = styled.div` export const SideBarSection = (props: SideBarSectionProps) => { const user = useSelector(getUser); const applications = useSelector(normalAppListSelector); - const brandingSettings = useSelector(getBrandingSettings); + const brandingSettings = useSelector(getBrandingSetting); + console.log('brandingSettings', brandingSettings); const currentPath = useLocation().pathname; const isShow = props.items .map((item) => (item.visible ? item.visible({ user: user, applications: applications }) : true)) @@ -47,8 +48,8 @@ export const SideBarSection = (props: SideBarSectionProps) => { ? item.onSelected(item.routePath, currentPath) : defaultOnSelectedFn(item.routePath, currentPath) } - selectedBgColor={brandingSettings?.adminSidebarActiveBgColor} - selectedFontColor={brandingSettings?.adminSidebarActiveFontColor} + selectedBgColor={brandingSettings?.config_set?.adminSidebarActiveBgColor} + selectedFontColor={brandingSettings?.config_set?.adminSidebarActiveFontColor} onClick={() => { // Trigger item's onClick if defined item.onClick diff --git a/client/packages/lowcoder/src/constants/reduxActionConstants.ts b/client/packages/lowcoder/src/constants/reduxActionConstants.ts index 48154f966..6dd42de3d 100644 --- a/client/packages/lowcoder/src/constants/reduxActionConstants.ts +++ b/client/packages/lowcoder/src/constants/reduxActionConstants.ts @@ -173,6 +173,11 @@ export const ReduxActionTypes = { FETCH_ENTERPRISE_LICENSE : "FETCH_ENTERPRISE_LICENSE", SET_ENTERPRISE_LICENSE : "SET_ENTERPRISE_LICENSE", + /* Branding Setting */ + FETCH_BRANDING_SETTING : "FETCH_BRANDING_SETTING", + SET_WORKSPACE_BRANDING_SETTING : "SET_WORKSPACE_BRANDING_SETTING", + SET_GLOBAL_BRANDING_SETTING : "SET_GLOBAL_BRANDING_SETTING", + /* application snapshot */ FETCH_APP_SNAPSHOTS: "FETCH_APP_SNAPSHOTS", FETCH_APP_SNAPSHOTS_SUCCESS: "FETCH_APP_SNAPSHOTS_SUCCESS", diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index f3083aca1..7dd58b279 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -2850,6 +2850,12 @@ export const en = { "branding": { "title": "Branding Settings", + "general": "General", + "selectWorkspace": "Select Workspace", + "brandingName": "Branding Name", + "brandingNamePlaceholder": "Enter branding name", + "brandingDescription": "Branding Description", + "brandingDescriptionPlaceholder": "Enter branding description", "logoSection": "Logos", "logo": "Logo", "logoHelp": "Upload your company's logo in SVG or PNG format.", diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx index 08364d5fa..b6612b5ef 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx @@ -149,7 +149,7 @@ export default function ApplicationHome() { return ( - + {/* */} - + {/* */} ); } diff --git a/client/packages/lowcoder/src/pages/common/header.tsx b/client/packages/lowcoder/src/pages/common/header.tsx index a2e865573..bc0cc4513 100644 --- a/client/packages/lowcoder/src/pages/common/header.tsx +++ b/client/packages/lowcoder/src/pages/common/header.tsx @@ -64,8 +64,8 @@ import Avatar from 'antd/es/avatar'; import UserApi from "@lowcoder-ee/api/userApi"; import { validateResponse } from "@lowcoder-ee/api/apiUtils"; import ProfileImage from "./profileImage"; -import { getBrandingSettings } from "@lowcoder-ee/redux/selectors/commonSettingSelectors"; import { buildMaterialPreviewURL } from "@lowcoder-ee/util/materialUtils"; +import { getBrandingSetting } from "@lowcoder-ee/redux/selectors/enterpriseSelectors"; const { Countdown } = Statistic; const { Text } = Typography; @@ -380,7 +380,7 @@ export default function Header(props: HeaderProps) { const dispatch = useDispatch(); const showAppSnapshot = useSelector(showAppSnapshotSelector); const {selectedSnapshot, isArchivedSnapshot} = useSelector(getSelectedAppSnapshot); - const brandingSettings = useSelector(getBrandingSettings); + const brandingSettings = useSelector(getBrandingSetting); const { appType } = useContext(ExternalEditorContext); const [editName, setEditName] = useState(false); const [editing, setEditing] = useState(false); @@ -436,8 +436,8 @@ export default function Header(props: HeaderProps) { <> history.push(ALL_APPLICATIONS_URL)}> {/* {REACT_APP_LOWCODER_SHOW_BRAND === 'true' ? REACT_APP_LOWCODER_CUSTOM_LOGO_SQUARE !== "" ? logo : : } */} - { brandingSettings?.squareLogo - ? + { brandingSettings?.config_set?.squareLogo + ? : } @@ -685,7 +685,7 @@ export default function Header(props: HeaderProps) { headerMiddle={headerMiddle} headerEnd={headerEnd} style={{ - backgroundColor: brandingSettings?.appHeaderColor + backgroundColor: brandingSettings?.config_set?.appHeaderColor }} /> ); @@ -694,13 +694,13 @@ export default function Header(props: HeaderProps) { // header in manager page export function AppHeader() { const user = useSelector(getUser); - const brandingSettings = useSelector(getBrandingSettings); + const brandingSettings = useSelector(getBrandingSetting); const headerStart = ( history.push(ALL_APPLICATIONS_URL)}> {/* {REACT_APP_LOWCODER_SHOW_BRAND === 'true' ? REACT_APP_LOWCODER_CUSTOM_LOGO !== "" ? logo : : } */} - { brandingSettings?.squareLogo - ? + { brandingSettings?.config_set?.squareLogo + ? : } @@ -711,7 +711,7 @@ export function AppHeader() { headerStart={headerStart} headerEnd={headerEnd} style={{ - backgroundColor: brandingSettings?.appHeaderColor + backgroundColor: brandingSettings?.config_set?.appHeaderColor }} /> ); diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx index a3d42c43a..3aef2d0c7 100644 --- a/client/packages/lowcoder/src/pages/editor/editorView.tsx +++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx @@ -55,9 +55,12 @@ import { } from "util/localStorageUtil"; import { isAggregationApp } from "util/appUtils"; import EditorSkeletonView from "./editorSkeletonView"; -import { getBrandingSettings, getCommonSettings } from "@lowcoder-ee/redux/selectors/commonSettingSelectors"; +import { + getCommonSettings +} from "@lowcoder-ee/redux/selectors/commonSettingSelectors"; import { isEqual, noop } from "lodash"; import { AppSettingContext, AppSettingType } from "@lowcoder-ee/comps/utils/appSettingContext"; +import { getBrandingSetting } from "@lowcoder-ee/redux/selectors/enterpriseSelectors"; // import { BottomSkeleton } from "./bottom/BottomContent"; const Header = lazy( @@ -314,7 +317,7 @@ function EditorView(props: EditorViewProps) { const locationState = useLocation().state; const showNewUserGuide = locationState?.showNewUserGuide; const showAppSnapshot = useSelector(showAppSnapshotSelector); - const brandingSettings = useSelector(getBrandingSettings); + const brandingSettings = useSelector(getBrandingSetting); const [showShortcutList, setShowShortcutList] = useState(false); const toggleShortcutList = useCallback( () => setShowShortcutList(!showShortcutList), @@ -534,10 +537,10 @@ function EditorView(props: EditorViewProps) { > [0] | undefined; - -const BrandingSettingContent = styled.div` - font-size: 14px; - color: #8b8fa3; - flex-grow: 1; - padding-top: 0px; - padding-left: 0px; - max-width: 100%; -`; - -const StyleThemeSettingsCover = styled.div` - display: flex; - flex-direction: row; - background: linear-gradient(34deg, rgba(2, 0, 36, 1) 0%, rgba(102, 9, 121, 1) 35%, rgba(0, 255, 181, 1) 100%); - padding: 15px; - height: 80px; - border-radius: 10px 10px 0 0; -`; - -const StyledRectUploadContainer = styled.div` - .avatar-uploader { - width: 240px; - height: 100px; - display: flex; - justify-content: center; - align-items: center; - border: 1px dashed #d9d9d9; - border-radius: 8px; - overflow: hidden; - } - - img { - width: 240px; - height: 100px; - object-fit: cover; - border-radius: 8px; - } -`; - -const StyledSquareUploadContainer = styled.div` - .avatar-uploader { - width: 100px; - height: 100px; - display: flex; - justify-content: center; - align-items: center; - border: 1px dashed #d9d9d9; - border-radius: 8px; - overflow: hidden; - } - - img { - width: 100px; - height: 100px; - object-fit: cover; - border-radius: 8px; - } -`; - -const getBase64 = (file: File): Promise => { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.readAsBinaryString(file); // Read file as base64 - - reader.onload = () => resolve(reader.result as string); - reader.onerror = error => reject(error); - }); -}; - -const beforeUpload = (file: RcFile) => { - const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png" || file.type === "image/svg+xml"; - if (!isJpgOrPng) { - message.error("You can only upload JPG/PNG/SVG files!"); - return Upload.LIST_IGNORE; - } - const isLt2M = file.size / 1024 / 1024 < 2; - if (!isLt2M) { - message.error("Image must be smaller than 2MB!"); - return Upload.LIST_IGNORE; - } - return true; -}; - export function AppUsage() { - const [settings, setSettings] = useState(defaultSettings); - const [loading, setLoading] = useState({ - [SettingsEnum.LOGO]: false, - [SettingsEnum.SQUARE_LOGO]: false, - [SettingsEnum.ERROR_PAGE_IMAGE]: false, - [SettingsEnum.LOGOUT_PAGE_IMAGE]: false, - [SettingsEnum.SIGNUP_PAGE_IMAGE]: false, - }); - const currentUser = useSelector(getUser); - const dispatch = useDispatch(); - const brandingSettings = useShallowEqualSelector(getBrandingSettings); - - useEffect(() => { - setSettings(brandingSettings ?? defaultSettings); - }, [brandingSettings]); - - useEffect(() => { - dispatch(fetchCommonSettings({ orgId: currentUser.currentOrgId })); - }, [currentUser.currentOrgId, dispatch]); - - const updateSettings = (key: keyof BrandingSettings, value: any) => { - setSettings((prev) => ({ ...prev, [key]: value })); - }; - - const handleUpload = async (options: any, imageType: keyof BrandingSettings) => { - const { onSuccess, onError, file } = options; - - try { - setLoading((loading) => ({ - ...loading, - [imageType]: true, - })) - const base64File = await getBase64(file); - const resp = await MaterialApi.upload( - file.name, - MaterialUploadTypeEnum.COMMON, - btoa(base64File), - ); - if (validateResponse(resp)) { - onSuccess(trans("success")); - updateSettings(imageType, resp.data.data.id); - return; - } - throw new Error("Something went wrong"); - } catch (error: any) { - onError(error); - messageInstance.error(trans("home.fileUploadError")); - } finally { - setLoading((loading) => ({ - ...loading, - [imageType]: false, - })) - } - } - - const handleSave = () => { - dispatch( - setCommonSettings({ - orgId: currentUser.currentOrgId, - data: { - key: 'branding', - value: settings, - }, - onSuccess: () => { - messageInstance.success(trans("advanced.saveSuccess")); - }, - }) - ); - } - - const uploadButton = (loading: boolean) => ( -
- {loading ? : } -
Upload
-
- ); - - return ( - -
- - {trans("branding.title")} - -
- - - - -

{trans("branding.logoSection")}

-
- -
-

{trans("branding.logo")}

- - handleUpload(options, SettingsEnum.LOGO)} - > - {Boolean(settings[SettingsEnum.LOGO]) - ? logo - : uploadButton(loading[SettingsEnum.LOGO]) - } - - {trans("branding.logoHelp")} - -
- -
-

{trans("branding.squareLogo")}

- - handleUpload(options, SettingsEnum.SQUARE_LOGO)} - > - {Boolean(settings[SettingsEnum.SQUARE_LOGO]) - ? square_logo - : uploadButton(loading[SettingsEnum.SQUARE_LOGO]) - } - - {trans("branding.squareLogoHelp")} - -
-
-
- - - -

{trans("branding.colorFontSection")}

-
- -
-

{trans("branding.mainBrandingColor")}

- node.parentNode} - value={settings.mainBrandingColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.MAIN_BRANDING_COLOR, hex)} - /> - {trans("branding.mainBrandingColorHelp")} -
- -
-

{trans("branding.editorHeaderColor")}

- node.parentNode} - value={settings.appHeaderColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.APP_HEADER_COLOR, hex)} - /> - {trans("branding.editorHeaderColorHelp")} -
- -
-

{trans("branding.adminSidebarColor")}

- node.parentNode} - value={settings.adminSidebarColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.ADMIN_SIDEBAR_COLOR, hex)} - /> - {trans("branding.adminSidebarColorHelp")} -
- -
-

{trans("branding.adminSidebarFontColor")}

- node.parentNode} - value={settings.adminSidebarFontColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.ADMIN_SIDEBAR_FONT_COLOR, hex)} - /> - {trans("branding.adminSidebarFontColorHelp")} -
- -
-

{trans("branding.adminSidebarActiveBgColor")}

- node.parentNode} - value={settings.adminSidebarActiveBgColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.ADMIN_SIDEBAR_ACTIVE_BG_COLOR, hex)} - /> - {trans("branding.adminSidebarActiveBgColorHelp")} -
- -
-

{trans("branding.adminSidebarActiveFontColor")}

- node.parentNode} - value={settings.adminSidebarActiveFontColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.ADMIN_SIDEBAR_ACTIVE_FONT_COLOR, hex)} - /> - {trans("branding.adminSidebarActiveFontColorHelp")} -
- -
-

{trans("branding.editorSidebarColor")}

- node.parentNode} - value={settings.editorSidebarColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.EDITOR_SIDEBAR_COLOR, hex)} - /> - {trans("branding.editorSidebarColorHelp")} -
- -
-

{trans("branding.editorSidebarFontColor")}

- node.parentNode} - value={settings.editorSidebarFontColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.EDITOR_SIDEBAR_FONT_COLOR, hex)} - /> - {trans("branding.editorSidebarFontColorHelp")} -
- -
-

{trans("branding.editorSidebarActiveBgColor")}

- node.parentNode} - value={settings.editorSidebarActiveBgColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.EDITOR_SIDEBAR_ACTIVE_BG_COLOR, hex)} - /> - {trans("branding.editorSidebarActiveBgColorHelp")} -
- -
-

{trans("branding.editorSidebarActiveFontColor")}

- node.parentNode} - value={settings.editorSidebarActiveFontColor} - showText - allowClear - format="hex" - onChange={(_, hex) => updateSettings(SettingsEnum.EDITOR_SIDEBAR_ACTIVE_FONT_COLOR, hex)} - /> - {trans("branding.editorSidebarActiveFontColorHelp")} -
- -
-

{trans("branding.font")}

- updateSettings(SettingsEnum.FONT, font)} - /> - {trans("branding.fontHelp")} -
-
-
- - - -

{trans("branding.textSection")}

-
- -
-

{trans("branding.errorPage")}

-