Skip to content

Commit 12bb302

Browse files
feat(global-header): added config for default header components (#2263)
* feat(global-header): added config for default header components Signed-off-by: Yi Cai <[email protected]> * prettier fix Signed-off-by: Yi Cai <[email protected]> * hide header items in sidebar Signed-off-by: Yi Cai <[email protected]> * resolve failed ci checks Signed-off-by: Yi Cai <[email protected]> * resolve failed ci checks Signed-off-by: Yi Cai <[email protected]> * updated header component mp name Signed-off-by: Yi Cai <[email protected]> * added icons and updated global header config Signed-off-by: Yi Cai <[email protected]> * addressed review comments Signed-off-by: Yi Cai <[email protected]> * updated global header wrapper to take the latest release Signed-off-by: Yi Cai <[email protected]> * removed default support button url Signed-off-by: Yi Cai <[email protected]> * resolved merging conflicts Signed-off-by: Yi Cai <[email protected]> * addressed review comments Signed-off-by: Yi Cai <[email protected]> * updated theme package to pick up changes for global header Signed-off-by: Yi Cai <[email protected]> * fix: align application header mountpoint with other mount points Signed-off-by: Christoph Jerolimov <[email protected]> * fixed double scrollbar issue Signed-off-by: Yi Cai <[email protected]> * small pickup Signed-off-by: Yi Cai <[email protected]> * prettier fix Signed-off-by: Yi Cai <[email protected]> * updated default global header config Signed-off-by: Yi Cai <[email protected]> * fixed global header version Signed-off-by: Yi Cai <[email protected]> * fixed default global header config Signed-off-by: Yi Cai <[email protected]> * updated header package.json dependency Signed-off-by: Yi Cai <[email protected]> * ignore the problematic link Signed-off-by: Yi Cai <[email protected]> * updated yarn.lock Signed-off-by: Yi Cai <[email protected]> * code clean Signed-off-by: Yi Cai <[email protected]> * code clean Signed-off-by: Yi Cai <[email protected]> * added config to hide search and settings when header is enabled Signed-off-by: Yi Cai <[email protected]> * feat(global-header): use global-header 1.0.0 * feat(global-header): add optional layout config option for the header itself * docs(global-header): small fix * feat(global-header): enable new global-header plugin by default * fix(global-header): fix duplicate scrollbar issues (incl. RHIDP-4637) * chore(global-header): disable header in e2e tests for now * fix(global-header): fix duplicate scrollbar issues (incl. RHIDP-4637) * fix(global-header): fix duplicate scrollbar issues (incl. RHIDP-4637) * fix(global-header): fix duplicate scrollbar issues (incl. RHIDP-4637) * hide notifications from sidebar by default Signed-off-by: Yi Cai <[email protected]> --------- Signed-off-by: Yi Cai <[email protected]> Signed-off-by: Christoph Jerolimov <[email protected]> Co-authored-by: Christoph Jerolimov <[email protected]>
1 parent d5fc240 commit 12bb302

File tree

16 files changed

+250
-494
lines changed

16 files changed

+250
-494
lines changed

.github/workflows/link-checker.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
with:
1919
config-file: '.github/workflows/link-checker.config.json'
2020
folder-path: 'docs/'
21+
ignore: "https://code.visualstudio.com/docs/nodejs/nodejs-debugging" # Ignores known false positives
2122

2223
- name: Check markdown files in root
2324
uses: gaurav-nelson/github-action-markdown-link-check@v1

.ibm/pipelines/value_files/values_showcase-rbac.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ global:
9696
disabled: false
9797
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
9898
disabled: false
99+
# Disable global header plugin for now. See https://issues.redhat.com/browse/RHIDP-5474
100+
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
101+
disabled: true
99102
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page
100103
disabled: false
101104
# Enable tech-radar plugin.

.ibm/pipelines/value_files/values_showcase.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ global:
9494
disabled: false
9595
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
9696
disabled: false
97+
# Disable global header plugin for now. See https://issues.redhat.com/browse/RHIDP-5474
98+
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
99+
disabled: true
97100
# Enable tech-radar plugins.
98101
- package: ./dynamic-plugins/dist/backstage-community-plugin-tech-radar
99102
disabled: false

app-config.dynamic-plugins.yaml

+1-2
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ dynamicPlugins:
256256
- mountPoint: application/header
257257
importName: GlobalHeader
258258
config:
259-
layout:
260-
position: above-main-content
259+
position: above-main-content # above-main-content | above-sidebar
261260
red-hat-developer-hub.backstage-plugin-global-floating-action-button:
262261
mountPoints:
263262
- mountPoint: application/listener

docs/dynamic-plugins/frontend-plugin-wiring.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -386,15 +386,14 @@ dynamicPlugins:
386386
- mountPoint: application/header # mount point for a global header
387387
importName: <header_component> # e.g., `GlobalHeader` for `red-hat-developer-hub.backstage-plugin-global-header`
388388
config:
389-
layout:
390-
position: above-main-content # options: `above-main-content` or `above-sidebar`
389+
position: above-main-content # options: `above-main-content` or `above-sidebar`
391390
```
392391
393392
Each global header entry requires the following attributes:
394393
395394
- `mountPoint`: Defines where the header will be added. Use `application/header` to specify it as a global header.
396395
- `importName`: Specifies the component exported by the global header plugin (e.g., `GlobalHeader`).
397-
- `config.layout.position`: Determines the header's position. Supported values are:
396+
- `config.position`: Determines the header's position. Supported values are:
398397
- `above-main-content`: Positions the header above the main content area.
399398
- `above-sidebar`: Positions the header above the sidebar.
400399

dynamic-plugins.default.yaml

+60-3
Original file line numberDiff line numberDiff line change
@@ -524,17 +524,74 @@ plugins:
524524
text: Bulk import
525525
# Global Header
526526
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
527-
disabled: true
527+
disabled: false
528528
pluginConfig:
529+
app:
530+
sidebar:
531+
search: false
532+
settings: false
529533
dynamicPlugins:
530534
frontend:
535+
default.main-menu-items:
536+
menuItems:
537+
default.create:
538+
title: ''
539+
backstage.plugin-notifications:
540+
dynamicRoutes:
541+
- importName: NotificationsPage
542+
path: /notifications
531543
red-hat-developer-hub.backstage-plugin-global-header:
532544
mountPoints:
533545
- mountPoint: application/header
534546
importName: GlobalHeader
535547
config:
536-
layout:
537-
position: above-main-content
548+
position: above-main-content # above-main-content | above-sidebar
549+
- mountPoint: global.header/component
550+
importName: SearchComponent
551+
config:
552+
priority: 100
553+
- mountPoint: global.header/component
554+
importName: Spacer
555+
config:
556+
priority: 99
557+
props:
558+
growFactor: 0
559+
- mountPoint: global.header/component
560+
importName: HeaderIconButton
561+
config:
562+
priority: 90
563+
props:
564+
title: Create...
565+
icon: add
566+
to: create
567+
- mountPoint: global.header/component
568+
importName: SupportButton
569+
config:
570+
priority: 80
571+
- mountPoint: global.header/component
572+
importName: NotificationButton
573+
config:
574+
priority: 70
575+
- mountPoint: global.header/component
576+
importName: Divider
577+
config:
578+
priority: 50
579+
- mountPoint: global.header/component
580+
importName: ProfileDropdown
581+
config:
582+
priority: 10
583+
- mountPoint: global.header/profile
584+
importName: MenuItemLink
585+
config:
586+
priority: 100
587+
props:
588+
title: Settings
589+
link: /settings
590+
icon: manageAccounts
591+
- mountPoint: global.header/profile
592+
importName: LogoutButton
593+
config:
594+
priority: 10
538595

539596
# Group: Global floating action button
540597
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
1+
module.exports = require("@backstage/cli/config/eslint-factory")(__dirname);

dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "red-hat-developer-hub-backstage-plugin-global-header",
3-
"version": "0.0.2",
3+
"version": "1.0.0",
44
"main": "src/index.ts",
55
"types": "src/index.ts",
66
"license": "Apache-2.0",
@@ -29,7 +29,7 @@
2929
},
3030
"dependencies": {
3131
"@mui/material": "5.16.14",
32-
"@red-hat-developer-hub/backstage-plugin-global-header": "0.0.2"
32+
"@red-hat-developer-hub/backstage-plugin-global-header": "1.0.0"
3333
},
3434
"devDependencies": {
3535
"@backstage/cli": "0.29.6",
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from '@red-hat-developer-hub/backstage-plugin-global-header';
1+
export * from "@red-hat-developer-hub/backstage-plugin-global-header";

packages/app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@mui/icons-material": "5.16.14",
4646
"@mui/material": "5.16.14",
4747
"@mui/styled-engine": "5.16.14",
48-
"@redhat-developer/red-hat-developer-hub-theme": "0.4.0",
48+
"@redhat-developer/red-hat-developer-hub-theme": "0.5.0",
4949
"@scalprum/core": "0.8.1",
5050
"@scalprum/react-core": "0.9.3",
5151
"lodash": "4.17.21",

packages/app/src/components/DynamicRoot/CommonIcons.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ import Extension from '@mui/icons-material/ExtensionOutlined';
77
import Favorite from '@mui/icons-material/Favorite';
88
import FolderOpen from '@mui/icons-material/FolderOpenOutlined';
99
import GppGood from '@mui/icons-material/GppGoodOutlined';
10+
import Help from '@mui/icons-material/HelpOutline';
1011
import Home from '@mui/icons-material/HomeOutlined';
1112
import InsertChart from '@mui/icons-material/InsertChartOutlined';
1213
import Layers from '@mui/icons-material/Layers';
1314
import List from '@mui/icons-material/List';
15+
import Logout from '@mui/icons-material/LogoutOutlined';
16+
import ManageAccounts from '@mui/icons-material/ManageAccountsOutlined';
1417
import MonitorHeart from '@mui/icons-material/MonitorHeartOutlined';
18+
import Notifications from '@mui/icons-material/NotificationsOutlined';
1519
import People from '@mui/icons-material/People';
1620
import QueryStats from '@mui/icons-material/QueryStatsOutlined';
1721
import Rule from '@mui/icons-material/RuleOutlined';
@@ -44,6 +48,10 @@ const CommonIcons: {
4448
feedback: Textsms,
4549
validate: Rule,
4650
security: GppGood,
51+
support: Help,
52+
notifications: Notifications,
53+
manageAccounts: ManageAccounts,
54+
logout: Logout,
4755
};
4856

4957
export default CommonIcons;

packages/app/src/components/DynamicRoot/DynamicRootContext.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export type ResolvedDynamicRoute = DynamicModuleEntry & {
5454
};
5555
};
5656

57-
type ScalprumMountPointConfigBase = {
57+
export type ScalprumMountPointConfigBase = {
5858
layout?: Record<string, string>;
5959
props?: Record<string, any>;
6060
};
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,47 @@
1-
import React, { useContext } from 'react';
1+
import React, { useContext, useMemo } from 'react';
22

33
import { ErrorBoundary } from '@backstage/core-components';
44

5-
import DynamicRootContext from '../DynamicRoot/DynamicRootContext';
5+
import DynamicRootContext, {
6+
ScalprumMountPoint,
7+
ScalprumMountPointConfigBase,
8+
} from '../DynamicRoot/DynamicRootContext';
69

7-
export const ApplicationHeaders = ({ position }: { position: string }) => {
10+
type Position = 'above-main-content' | 'above-sidebar';
11+
12+
type ApplicationHeaderMountPointConfig = ScalprumMountPointConfigBase & {
13+
position: Position;
14+
layout?: React.CSSProperties;
15+
};
16+
17+
type ApplicationHeaderMountPoint = ScalprumMountPoint & {
18+
Component: React.ComponentType<
19+
React.PropsWithChildren<{
20+
position: Position;
21+
layout?: React.CSSProperties;
22+
}>
23+
>;
24+
config?: ApplicationHeaderMountPointConfig;
25+
};
26+
27+
export const ApplicationHeaders = ({ position }: { position: Position }) => {
828
const { mountPoints } = useContext(DynamicRootContext);
9-
const appHeaderMountPoints = mountPoints['application/header'] ?? [];
10-
return appHeaderMountPoints
11-
?.filter(({ config }) => config?.layout?.position === position)
12-
.map(({ Component, config }, index) => (
13-
// eslint-disable-next-line react/no-array-index-key
14-
<ErrorBoundary key={index}>
15-
<Component {...config?.props} />
16-
</ErrorBoundary>
17-
));
29+
30+
const appHeaderMountPoints = useMemo(() => {
31+
const appHeaderMP = (mountPoints['application/header'] ??
32+
[]) as ApplicationHeaderMountPoint[];
33+
34+
return appHeaderMP.filter(({ config }) => config?.position === position);
35+
}, [mountPoints, position]);
36+
37+
return appHeaderMountPoints.map(({ Component, config }, index) => (
38+
// eslint-disable-next-line react/no-array-index-key
39+
<ErrorBoundary key={index}>
40+
<Component
41+
position={position}
42+
{...config?.props}
43+
layout={config?.layout}
44+
/>
45+
</ErrorBoundary>
46+
));
1847
};

packages/app/src/components/Root/Root.tsx

+75-8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,65 @@ import { MenuIcon } from './MenuIcon';
3636
import { SidebarLogo } from './SidebarLogo';
3737

3838
const useStyles = makeStyles()({
39+
/**
40+
* This is a workaround to remove the fix height of the Page component
41+
* to support the application headers (and the global header plugin)
42+
* without having multiple scrollbars.
43+
*
44+
* This solves also the duplicate scrollbar issues in tech docs:
45+
* https://issues.redhat.com/browse/RHIDP-4637 (Scrollbar for docs behaves weirdly if there are over a page of headings)
46+
*
47+
* Which was also reported and tried to fix upstream:
48+
* https://github.com/backstage/backstage/issues/13717
49+
* https://github.com/backstage/backstage/pull/14138
50+
* https://github.com/backstage/backstage/issues/19427
51+
* https://github.com/backstage/backstage/issues/22745
52+
*
53+
* See also
54+
* https://github.com/backstage/backstage/blob/v1.35.0/packages/core-components/src/layout/Page/Page.tsx#L31-L34
55+
*
56+
* The following rules are based on the current DOM structure
57+
*
58+
* ```
59+
* <body>
60+
* <div id="root">
61+
* // snackbars and toasts
62+
* <div className="pageWithoutFixHeight">
63+
* <nav /> // Optional nav(s) if a header with position: above-sidebar is configured
64+
* <div> // Backstage SidebarPage component
65+
* <nav /> // Optional nav(s) if a header with position: above-main-content is configured
66+
* <nav aria-label="sidebar nav" /> // Sidebar content
67+
* <main /> // Backstage Page component
68+
* </div>
69+
* </div>
70+
* </div>
71+
* // some modals and other overlays
72+
* </body>
73+
* ```
74+
*/
75+
pageWithoutFixHeight: {
76+
// Use 100vh for the complete viewport (similar to how Backstage does it)
77+
// and makes the page content part scrollable below...
78+
// But instead of using 100vh on the content below,
79+
// we use it here so that it includes the header.
80+
'> div': {
81+
height: '100vh',
82+
display: 'flex',
83+
flexDirection: 'column',
84+
},
85+
86+
// But we unset the Backstage default 100vh value here and use flex box
87+
// to grow to the full height of the parent container.
88+
'> div > main': {
89+
height: 'unset',
90+
flexGrow: 1,
91+
},
92+
// This solves the same issue for techdocs, which was reported as
93+
// https://issues.redhat.com/browse/RHIDP-4637
94+
'.techdocs-reader-page > main': {
95+
height: 'unset',
96+
},
97+
},
3998
sidebarItem: {
4099
textDecorationLine: 'none',
41100
},
@@ -51,7 +110,7 @@ const SideBarItemWrapper = (props: SidebarItemProps) => {
51110
return (
52111
<SidebarItem
53112
{...props}
54-
className={`${sidebarItem}${props.className ?? ''}`}
113+
className={`${sidebarItem} ${props.className ?? ''}`}
55114
/>
56115
);
57116
};
@@ -103,6 +162,10 @@ const getMenuItem = (menuItem: ResolvedMenuItem, isNestedMenuItem = false) => {
103162
};
104163

105164
export const Root = ({ children }: PropsWithChildren<{}>) => {
165+
const {
166+
classes: { pageWithoutFixHeight },
167+
} = useStyles();
168+
106169
const { dynamicRoutes, menuItems } = useContext(DynamicRootContext);
107170

108171
const configApi = useApi(configApiRef);
@@ -260,18 +323,22 @@ export const Root = ({ children }: PropsWithChildren<{}>) => {
260323
};
261324

262325
return (
263-
<>
326+
<div className={pageWithoutFixHeight}>
264327
<ApplicationHeaders position="above-sidebar" />
265328
<SidebarPage>
266329
<ApplicationHeaders position="above-main-content" />
267330
<Sidebar>
268331
{showLogo && <SidebarLogo />}
269-
{showSearch && (
270-
<SidebarGroup label="Search" icon={<SearchIcon />} to="/search">
271-
<SidebarSearchModal />
272-
</SidebarGroup>
332+
{showSearch ? (
333+
<>
334+
<SidebarGroup label="Search" icon={<SearchIcon />} to="/search">
335+
<SidebarSearchModal />
336+
</SidebarGroup>
337+
<SidebarDivider />
338+
</>
339+
) : (
340+
<Box sx={{ height: '1.2rem' }} />
273341
)}
274-
{(showLogo || showSearch) && <SidebarDivider />}
275342
<SidebarGroup label="Menu" icon={<MuiMenuIcon />}>
276343
{/* Global nav, not org-specific */}
277344
{renderMenuItems(true, false)}
@@ -317,6 +384,6 @@ export const Root = ({ children }: PropsWithChildren<{}>) => {
317384
</Sidebar>
318385
{children}
319386
</SidebarPage>
320-
</>
387+
</div>
321388
);
322389
};

packages/app/src/components/Root/SidebarLogo.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const SidebarLogo = () => {
5555
<LogoRender
5656
base64Logo={logoFullBase64URI}
5757
defaultLogo={<LogoFull />}
58-
width={fullLogoWidth ?? 110}
58+
width={fullLogoWidth ?? 170}
5959
/>
6060
) : (
6161
<LogoRender

0 commit comments

Comments
 (0)