mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-31 01:16:01 +02:00
feat: transparent header (#9108)
This PR adds header redesign behind a feature flag
This commit is contained in:
parent
4b3b98f263
commit
25c09c3627
@ -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<HTMLInputElement>(null);
|
||||
const searchContainerRef = useRef<HTMLInputElement>(null);
|
||||
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||
@ -293,7 +299,11 @@ export const CommandBar = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledContainer ref={searchContainerRef} active={showSuggestions}>
|
||||
<StyledContainer
|
||||
ref={searchContainerRef}
|
||||
active={showSuggestions}
|
||||
frontendHeaderRedesign={frontendHeaderRedesign}
|
||||
>
|
||||
<RecentlyVisitedRecorder />
|
||||
<StyledSearch
|
||||
sx={{
|
||||
|
@ -18,6 +18,7 @@ import { NavigationSidebar } from './NavigationSidebar/NavigationSidebar';
|
||||
import { MainLayoutEventTimeline } from './MainLayoutEventTimeline';
|
||||
import { EventTimelineProvider } from 'component/events/EventTimeline/EventTimelineProvider';
|
||||
import { NewInUnleash } from './NavigationSidebar/NewInUnleash/NewInUnleash';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
|
||||
interface IMainLayoutProps {
|
||||
children: ReactNode;
|
||||
@ -93,6 +94,7 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
||||
({ 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<HTMLDivElement, IMainLayoutProps>(
|
||||
return (
|
||||
<EventTimelineProvider>
|
||||
<SkipNavLink />
|
||||
<Header />
|
||||
<ConditionallyRender
|
||||
condition={!frontendHeaderRedesign}
|
||||
show={<Header />}
|
||||
/>
|
||||
|
||||
<SkipNavTarget />
|
||||
<MainLayoutContainer>
|
||||
@ -119,7 +124,9 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
||||
<Box
|
||||
sx={(theme) => ({
|
||||
display: 'flex',
|
||||
mt: theme.spacing(0.25),
|
||||
mt: frontendHeaderRedesign
|
||||
? 0
|
||||
: theme.spacing(0.25),
|
||||
})}
|
||||
>
|
||||
<ConditionallyRender
|
||||
@ -139,6 +146,11 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<ConditionallyRender
|
||||
condition={frontendHeaderRedesign}
|
||||
show={<Header />}
|
||||
/>
|
||||
|
||||
<MainLayoutEventTimeline />
|
||||
|
||||
<MainLayoutContent>
|
||||
|
@ -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 (
|
||||
<StretchContainer mode={mode}>
|
||||
<ConditionallyRender
|
||||
condition={frontendHeaderRedesign}
|
||||
show={
|
||||
<ConditionallyRender
|
||||
condition={mode === 'full'}
|
||||
show={
|
||||
<StyledLink to='/' sx={flexRow} aria-label='Home'>
|
||||
<ThemeMode
|
||||
darkmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={
|
||||
<CelebatoryUnleashLogoWhite />
|
||||
}
|
||||
elseShow={
|
||||
<StyledUnleashLogoWhite aria-label='Unleash logo' />
|
||||
}
|
||||
/>
|
||||
}
|
||||
lightmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={<StyledCelebatoryLogo />}
|
||||
elseShow={
|
||||
<StyledUnleashLogo aria-label='Unleash logo' />
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</StyledLink>
|
||||
}
|
||||
elseShow={
|
||||
<StyledLink to='/' sx={flexRow} aria-label='Home'>
|
||||
<ThemeMode
|
||||
darkmode={<StyledUnleashLogoOnlyWhite />}
|
||||
lightmode={<StyledUnleashLogoOnly />}
|
||||
/>
|
||||
</StyledLink>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<PrimaryNavigationList
|
||||
mode={mode}
|
||||
onClick={setActiveItem}
|
||||
|
@ -35,26 +35,32 @@ import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { CommandBar } from 'component/commandBar/CommandBar';
|
||||
import { HeaderEventTimelineButton } from './HeaderEventTimelineButton';
|
||||
|
||||
const HeaderComponent = styled(AppBar)(({ theme }) => ({
|
||||
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 (
|
||||
<HeaderComponent position='static'>
|
||||
<HeaderComponent
|
||||
position='static'
|
||||
frontendHeaderRedesign={frontendHeaderRedesign}
|
||||
>
|
||||
<ContainerComponent>
|
||||
<Tooltip title='Menu' arrow>
|
||||
<IconButton
|
||||
@ -153,30 +163,38 @@ const Header = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<HeaderComponent position='static'>
|
||||
<HeaderComponent
|
||||
frontendHeaderRedesign={frontendHeaderRedesign}
|
||||
position='static'
|
||||
>
|
||||
<ContainerComponent>
|
||||
<StyledLink to='/' sx={flexRow} aria-label='Home'>
|
||||
<ThemeMode
|
||||
darkmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={<CelebatoryUnleashLogoWhite />}
|
||||
elseShow={
|
||||
<StyledUnleashLogoWhite aria-label='Unleash logo' />
|
||||
<ConditionallyRender
|
||||
condition={!frontendHeaderRedesign}
|
||||
show={
|
||||
<StyledLink to='/' sx={flexRow} aria-label='Home'>
|
||||
<ThemeMode
|
||||
darkmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={<CelebatoryUnleashLogoWhite />}
|
||||
elseShow={
|
||||
<StyledUnleashLogoWhite aria-label='Unleash logo' />
|
||||
}
|
||||
/>
|
||||
}
|
||||
lightmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={<StyledCelebatoryLogo />}
|
||||
elseShow={
|
||||
<StyledUnleashLogo aria-label='Unleash logo' />
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
lightmode={
|
||||
<ConditionallyRender
|
||||
condition={celebatoryUnleash}
|
||||
show={<StyledCelebatoryLogo />}
|
||||
elseShow={
|
||||
<StyledUnleashLogo aria-label='Unleash logo' />
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</StyledLink>
|
||||
</StyledLink>
|
||||
}
|
||||
/>
|
||||
|
||||
<StyledNav>
|
||||
<StyledUserContainer>
|
||||
|
@ -92,6 +92,7 @@ export type UiFlags = {
|
||||
granularAdminPermissions?: boolean;
|
||||
sortProjectRoles?: boolean;
|
||||
lifecycleImprovements?: boolean;
|
||||
frontendHeaderRedesign?: boolean;
|
||||
};
|
||||
|
||||
export interface IVersionInfo {
|
||||
|
@ -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 = {
|
||||
|
@ -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: {
|
||||
|
Loading…
Reference in New Issue
Block a user