diff --git a/server/getDynamicIndex.ts b/server/getDynamicIndex.ts index 3be5d00..6044490 100644 --- a/server/getDynamicIndex.ts +++ b/server/getDynamicIndex.ts @@ -2,6 +2,33 @@ export const getDynamicIndex = (baseprefix: string): string => { try { const mainJs = 'index-react.js' const mainCss = 'style.css' + const titleText = process.env.TITLE_TEXT || 'OpenAPI UI' + const iconSvg = process.env.ICON_SVG || '' + + // Create environment variables object + const envVars = { + VITE_LOGO_SVG: process.env.LOGO_SVG || '', + VITE_LOGO_TEXT: process.env.LOGO_TEXT || '', + VITE_TENANT_TEXT: process.env.TENANT_TEXT || '', + VITE_TITLE_TEXT: process.env.TITLE_TEXT || 'OpenAPI UI', + VITE_FOOTER_TEXT: process.env.FOOTER_TEXT || 'PRO Robotech', + VITE_ICON_SVG: iconSvg + } + + // Generate favicon from SVG if provided + const generateFavicon = () => { + if (!iconSvg) { + return '' + } + try { + const decodedSvg = Buffer.from(iconSvg, 'base64').toString('utf-8') + const dataUri = `data:image/svg+xml;base64,${iconSvg}` + return `` + } catch (error) { + console.error('Error processing icon SVG:', error) + return '' + } + } return ` @@ -14,7 +41,11 @@ export const getDynamicIndex = (baseprefix: string): string => { href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet" /> - OpenAPI UI + ${titleText} + ${generateFavicon()} + diff --git a/src/components/organisms/Footer/Footer.tsx b/src/components/organisms/Footer/Footer.tsx index c302c01..8a0cd43 100644 --- a/src/components/organisms/Footer/Footer.tsx +++ b/src/components/organisms/Footer/Footer.tsx @@ -1,11 +1,14 @@ import React, { FC } from 'react' import { Typography } from 'antd' +import { getFooterText } from 'utils/env' import { Styled } from './styled' export const Footer: FC = () => { + const footerText = getFooterText() + return ( - PRO Robotech © {new Date().getFullYear()} + {footerText} © {new Date().getFullYear()} ) } diff --git a/src/components/organisms/Header/organisms/Logo/Logo.tsx b/src/components/organisms/Header/organisms/Logo/Logo.tsx index 7823147..2125325 100644 --- a/src/components/organisms/Header/organisms/Logo/Logo.tsx +++ b/src/components/organisms/Header/organisms/Logo/Logo.tsx @@ -3,6 +3,7 @@ import { Flex, theme as antdtheme } from 'antd' import { useNavigate } from 'react-router-dom' import { useSelector } from 'react-redux' import { RootState } from 'store/store' +import { getLogo, getLogoText, getTenantText } from 'utils/env' import { Styled } from './styled' export const Logo: FC = () => { @@ -13,18 +14,47 @@ export const Logo: FC = () => { const { token } = antdtheme.useToken() const tenant = clusterList?.find(item => item.name === cluster)?.tenant + const customLogo = getLogo() + const customLogoText = getLogoText() + const customTenantText = getTenantText() + + const renderLogo = () => { + if (customLogo) { + // Decode base64 SVG and replace all fill placeholders + try { + const decodedSvg = atob(customLogo) + // Replace all instances of {token.colorText} with actual color + const svgWithFill = decodedSvg.replace(/\{token\.colorText\}/g, `"${token.colorText}"`) + return
+ } catch (error) { + console.error('Error decoding custom logo:', error) + return renderDefaultLogo() + } + } + return renderDefaultLogo() + } + + const renderDefaultLogo = () => ( + + + + ) return ( - - - - navigate(`${baseprefix}`)}>In-Cloud - {tenant} + {renderLogo()} + {customLogoText !== false && ( + navigate(`${baseprefix}`)}> + {customLogoText} + + )} + + {customTenantText || tenant} + ) diff --git a/src/global.d.ts b/src/global.d.ts index d3e90f9..c0bb011 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,6 +1,14 @@ declare global { interface Window { _env_: Record + __ENV__: { + VITE_LOGO_SVG?: string + VITE_LOGO_TEXT?: string + VITE_TENANT_TEXT?: string + VITE_TITLE_TEXT?: string + VITE_FOOTER_TEXT?: string + VITE_ICON_SVG?: string + } } } export {} diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 0000000..f43ea1f --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1,38 @@ +// Environment variables for UI customization +export const getEnvVar = (key: string, defaultValue: string = ''): string => { + // Try to get from window.__ENV__ first (runtime variables) + if (typeof window !== 'undefined' && (window as any).__ENV__) { + return (window as any).__ENV__[key] || defaultValue + } + + // Fallback to import.meta.env (build-time variables) + return import.meta.env[key] || defaultValue +} + +export const getLogo = (): string => { + return getEnvVar('VITE_LOGO_SVG') +} + +export const getLogoText = (): string | false => { + const logoText = getEnvVar('VITE_LOGO_TEXT') + if (logoText === 'false') { + return false + } + return logoText || 'In-Cloud' +} + +export const getTenantText = (): string => { + return getEnvVar('VITE_TENANT_TEXT') +} + +export const getTitleText = (): string => { + return getEnvVar('VITE_TITLE_TEXT', 'OpenAPI UI') +} + +export const getFooterText = (): string => { + return getEnvVar('VITE_FOOTER_TEXT', 'PRO Robotech') +} + +export const getIconSvg = (): string => { + return getEnvVar('VITE_ICON_SVG') +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..12aec9d --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,6 @@ +export * from './env' +export * from './getBacklink' +export * from './getBaseprefix' +export * from './getBreadcrumbsIdPrefix' +export * from './getSidebarIdPrefix' +export * from './getTableCustomizationIdPrefix'