diff --git a/frontend/src/component/commandBar/CommandBar.tsx b/frontend/src/component/commandBar/CommandBar.tsx index e7434139e3..c263b76112 100644 --- a/frontend/src/component/commandBar/CommandBar.tsx +++ b/frontend/src/component/commandBar/CommandBar.tsx @@ -30,6 +30,7 @@ import { CommandQuickSuggestions } from './CommandQuickSuggestions'; import { CommandSearchPages } from './CommandSearchPages'; import { CommandBarFeedback } from './CommandBarFeedback'; import { RecentlyVisitedRecorder } from './RecentlyVisitedRecorder'; +import { useUiFlag } from 'hooks/useUiFlag'; export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ position: 'absolute', @@ -50,16 +51,20 @@ export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ })); const StyledContainer = styled('div', { - shouldForwardProp: (prop) => prop !== 'active', + shouldForwardProp: (prop) => + prop !== 'active' && prop !== 'frontendHeaderRedesign', })<{ active: boolean | undefined; -}>(({ theme, active }) => ({ + frontendHeaderRedesign?: boolean; +}>(({ theme, active, frontendHeaderRedesign }) => ({ border: `1px solid transparent`, display: 'flex', flexGrow: 1, alignItems: 'center', position: 'relative', - backgroundColor: theme.palette.background.paper, + backgroundColor: frontendHeaderRedesign + ? theme.palette.background.application + : theme.palette.background.paper, maxWidth: active ? '100%' : '400px', [theme.breakpoints.down('md')]: { marginTop: theme.spacing(1), @@ -97,6 +102,7 @@ interface IPageRouteInfo { export const CommandBar = () => { const { trackEvent } = usePlausibleTracker(); + const frontendHeaderRedesign = useUiFlag('frontendHeaderRedesign'); const searchInputRef = useRef(null); const searchContainerRef = useRef(null); const [showSuggestions, setShowSuggestions] = useState(false); @@ -293,7 +299,11 @@ export const CommandBar = () => { }; return ( - + ( ({ children }, ref) => { const { uiConfig } = useUiConfig(); const projectId = useOptionalPathParam('projectId'); + const frontendHeaderRedesign = useUiFlag('frontendHeaderRedesign'); const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled( projectId || '', ); @@ -103,7 +105,10 @@ export const MainLayout = forwardRef( return ( -
+ } + /> @@ -119,7 +124,9 @@ export const MainLayout = forwardRef( ({ display: 'flex', - mt: theme.spacing(0.25), + mt: frontendHeaderRedesign + ? 0 + : theme.spacing(0.25), })} > ( minWidth: 0, }} > + } + /> + diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx index b72e90db3c..d728695552 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx @@ -16,6 +16,17 @@ import { useInitialPathname } from './useInitialPathname'; import { useLastViewedProject } from 'hooks/useLastViewedProject'; import { useLastViewedFlags } from 'hooks/useLastViewedFlags'; import type { NewInUnleash } from './NewInUnleash/NewInUnleash'; +import { ThemeMode } from 'component/common/ThemeMode/ThemeMode'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { flexRow, focusable } from 'themes/themeStyles'; +import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg'; +import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText.svg'; +import { ReactComponent as CelebatoryUnleashLogo } from 'assets/img/unleashHoliday.svg'; +import { ReactComponent as CelebatoryUnleashLogoWhite } from 'assets/img/unleashHolidayDark.svg'; +import { ReactComponent as LogoOnlyWhite } from 'assets/img/logo.svg'; +import { ReactComponent as LogoOnly } from 'assets/img/logoDark.svg'; +import { useUiFlag } from 'hooks/useUiFlag'; +import { Link } from 'react-router-dom'; export const MobileNavigationSidebar: FC<{ onClick: () => void; @@ -57,6 +68,26 @@ export const StretchContainer = styled(Box)<{ mode: string }>( }), ); +const StyledLink = styled(Link)(({ theme }) => focusable(theme)); + +const StyledUnleashLogoWhite = styled(UnleashLogoWhite)({ width: '150px' }); + +const StyledUnleashLogo = styled(UnleashLogo)({ width: '150px' }); + +const StyledCelebatoryLogo = styled(CelebatoryUnleashLogo)({ width: '150px' }); + +const StyledUnleashLogoOnly = styled(LogoOnly)(({ theme }) => ({ + width: '58px', + marginTop: theme.spacing(0.5), + margin: '0 auto', +})); + +const StyledUnleashLogoOnlyWhite = styled(LogoOnlyWhite)(({ theme }) => ({ + width: '37px', + marginTop: theme.spacing(1), + margin: '0 auto', +})); + // This component is needed when the sticky item could overlap with nav items. You can replicate it on a short screen. const StickyContainer = styled(Box)(({ theme }) => ({ position: 'sticky', @@ -71,6 +102,8 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({ NewInUnleash, }) => { const { routes } = useRoutes(); + const celebatoryUnleash = useUiFlag('celebrateUnleash'); + const frontendHeaderRedesign = useUiFlag('frontendHeaderRedesign'); const [mode, setMode] = useNavigationMode(); const [expanded, changeExpanded] = useExpanded<'configure' | 'admin'>(); @@ -90,6 +123,49 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({ return ( + + + } + elseShow={ + + } + /> + } + lightmode={ + } + elseShow={ + + } + /> + } + /> + + } + elseShow={ + + } + lightmode={} + /> + + } + /> + } + /> + ({ - backgroundColor: theme.palette.background.paper, - padding: theme.spacing(1), - boxShadow: 'none', - position: 'relative', - zIndex: 300, - paddingRight: theme.spacing(9), - [theme.breakpoints.down('lg')]: { - paddingLeft: theme.spacing(1), - paddingRight: theme.spacing(1), - }, - [theme.breakpoints.down(1024)]: { - marginLeft: 0, - marginRight: 0, - }, - [theme.breakpoints.down('sm')]: { - minWidth: '100%', - }, - margin: '0 auto', -})); +const HeaderComponent = styled(AppBar, { + shouldForwardProp: (prop) => prop !== 'frontendHeaderRedesign', +})<{ frontendHeaderRedesign?: boolean }>( + ({ theme, frontendHeaderRedesign }) => ({ + backgroundColor: frontendHeaderRedesign + ? theme.palette.background.application + : theme.palette.background.paper, + padding: theme.spacing(1), + boxShadow: 'none', + position: 'relative', + zIndex: 300, + paddingRight: theme.spacing(9), + [theme.breakpoints.down('lg')]: { + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), + }, + [theme.breakpoints.down(1024)]: { + marginLeft: 0, + marginRight: 0, + }, + [theme.breakpoints.down('sm')]: { + minWidth: '100%', + }, + margin: '0 auto', + }), +); const ContainerComponent = styled(Box)(() => ({ display: 'flex', @@ -107,6 +113,7 @@ const Header = () => { const [openDrawer, setOpenDrawer] = useState(false); const toggleDrawer = () => setOpenDrawer((prev) => !prev); const celebatoryUnleash = useUiFlag('celebrateUnleash'); + const frontendHeaderRedesign = useUiFlag('frontendHeaderRedesign'); const routes = getRoutes(); const adminRoutes = useAdminRoutes(); @@ -123,7 +130,10 @@ const Header = () => { if (smallScreen) { return ( - + { } return ( - + - - } - elseShow={ - + + } + elseShow={ + + } + /> + } + lightmode={ + } + elseShow={ + + } + /> } /> - } - lightmode={ - } - elseShow={ - - } - /> - } - /> - + + } + /> diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index 2586131734..1410afbe84 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -92,6 +92,7 @@ export type UiFlags = { granularAdminPermissions?: boolean; sortProjectRoles?: boolean; lifecycleImprovements?: boolean; + frontendHeaderRedesign?: boolean; }; export interface IVersionInfo { diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index a217eba9bc..ae4620749f 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -62,7 +62,8 @@ export type IFlagKey = | 'deltaApi' | 'uniqueSdkTracking' | 'sortProjectRoles' - | 'lifecycleImprovements'; + | 'lifecycleImprovements' + | 'frontendHeaderRedesign'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -295,6 +296,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_LIFECYCLE_IMPROVEMENTS, false, ), + frontendHeaderRedesign: parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_FRONTEND_HEADER_REDESIGN, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = { diff --git a/src/server-dev.ts b/src/server-dev.ts index 073d8a8595..72d9c3e04f 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -40,7 +40,6 @@ process.nextTick(async () => { embedProxyFrontend: true, anonymiseEventLog: false, responseTimeWithAppNameKillSwitch: false, - celebrateUnleash: true, userAccessUIEnabled: true, outdatedSdksBanner: true, disableShowContextFieldSelectionValues: false, @@ -58,6 +57,7 @@ process.nextTick(async () => { deltaApi: true, uniqueSdkTracking: true, lifecycleImprovements: true, + frontendHeaderRedesign: true, }, }, authentication: {