Adding title prop to customHomePage
Signed-off-by: gerson <tnii.gerson@gmail.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'example-app': minor
|
||||
'@backstage/plugin-home': minor
|
||||
---
|
||||
|
||||
Added optional title prop to customHomePageGrid and improved the example app homepage to add the custom one
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
RELATION_PROVIDES_API,
|
||||
} from '@backstage/catalog-model';
|
||||
import { createApp } from '@backstage/app-defaults';
|
||||
import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
|
||||
import { AppRouter, FeatureFlagged, FlatRoutes } from '@backstage/core-app-api';
|
||||
import {
|
||||
AlertDisplay,
|
||||
OAuthRequestDialog,
|
||||
@@ -66,7 +66,6 @@ import AlarmIcon from '@material-ui/icons/Alarm';
|
||||
import { Navigate, Route } from 'react-router-dom';
|
||||
import { apis } from './apis';
|
||||
import { entityPage } from './components/catalog/EntityPage';
|
||||
import { homePage } from './components/home/HomePage';
|
||||
import { Root } from './components/Root';
|
||||
import { DelayingComponentFieldExtension } from './components/scaffolder/customScaffolderExtensions';
|
||||
import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate';
|
||||
@@ -84,6 +83,8 @@ import {
|
||||
NotificationsPage,
|
||||
UserNotificationSettingsCard,
|
||||
} from '@backstage/plugin-notifications';
|
||||
import { CustomizableHomePage } from './components/home/CustomizableHomePage';
|
||||
import { HomePage } from './components/home/HomePage';
|
||||
|
||||
const app = createApp({
|
||||
apis,
|
||||
@@ -115,10 +116,20 @@ const app = createApp({
|
||||
const routes = (
|
||||
<FlatRoutes>
|
||||
<Route path="/" element={<Navigate to="catalog" />} />
|
||||
|
||||
{/* TODO(rubenl): Move this to / once its more mature and components exist */}
|
||||
<Route path="/home" element={<HomepageCompositionRoot />}>
|
||||
{homePage}
|
||||
</Route>
|
||||
|
||||
<FeatureFlagged with="customizable-home-page-preview">
|
||||
<Route path="/home" element={<HomepageCompositionRoot />}>
|
||||
<CustomizableHomePage />
|
||||
</Route>
|
||||
</FeatureFlagged>
|
||||
<FeatureFlagged without="customizable-home-page-preview">
|
||||
<Route path="/home" element={<HomepageCompositionRoot />}>
|
||||
<HomePage />
|
||||
</Route>
|
||||
</FeatureFlagged>
|
||||
|
||||
<Route
|
||||
path="/catalog"
|
||||
element={<CatalogIndexPage pagination={{ mode: 'offset', limit: 20 }} />}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Page, Content } from '@backstage/core-components';
|
||||
import {
|
||||
HomePageCompanyLogo,
|
||||
TemplateBackstageLogo,
|
||||
HomePageStarredEntities,
|
||||
HomePageToolkit,
|
||||
CustomHomepageGrid,
|
||||
HomePageRandomJoke,
|
||||
HomePageTopVisited,
|
||||
HomePageRecentlyVisited,
|
||||
} from '@backstage/plugin-home';
|
||||
import { HomePageSearchBar } from '@backstage/plugin-search';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
|
||||
import { tools, useLogoStyles } from './shared';
|
||||
|
||||
const defaultConfig = [
|
||||
{
|
||||
component: 'HomePageSearchBar',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 24,
|
||||
height: 2,
|
||||
},
|
||||
{
|
||||
component: 'HomePageRecentlyVisited',
|
||||
x: 0,
|
||||
y: 1,
|
||||
width: 5,
|
||||
height: 4,
|
||||
},
|
||||
{
|
||||
component: 'HomePageTopVisited',
|
||||
x: 5,
|
||||
y: 1,
|
||||
width: 5,
|
||||
height: 4,
|
||||
},
|
||||
{
|
||||
component: 'HomePageStarredEntities',
|
||||
x: 0,
|
||||
y: 2,
|
||||
width: 6,
|
||||
height: 4,
|
||||
},
|
||||
{
|
||||
component: 'HomePageToolkit',
|
||||
x: 6,
|
||||
y: 6,
|
||||
width: 4,
|
||||
height: 4,
|
||||
},
|
||||
];
|
||||
|
||||
export const CustomizableHomePage = () => {
|
||||
const { svg, path, container } = useLogoStyles();
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
<Content>
|
||||
<Grid container justifyContent="center">
|
||||
<HomePageCompanyLogo
|
||||
className={container}
|
||||
logo={<TemplateBackstageLogo classes={{ svg, path }} />}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<CustomHomepageGrid config={defaultConfig}>
|
||||
<HomePageSearchBar />
|
||||
<HomePageRecentlyVisited />
|
||||
<HomePageTopVisited />
|
||||
<HomePageToolkit tools={tools} />
|
||||
<HomePageStarredEntities />
|
||||
<HomePageRandomJoke />
|
||||
</CustomHomepageGrid>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
@@ -14,21 +14,37 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Page, Content, Header } from '@backstage/core-components';
|
||||
import {
|
||||
ClockConfig,
|
||||
CustomHomepageGrid,
|
||||
HeaderWorldClock,
|
||||
HomePageCompanyLogo,
|
||||
HomePageRandomJoke,
|
||||
TemplateBackstageLogo,
|
||||
HomePageStarredEntities,
|
||||
HomePageToolkit,
|
||||
HomePageTopVisited,
|
||||
HomePageRecentlyVisited,
|
||||
WelcomeTitle,
|
||||
HeaderWorldClock,
|
||||
ClockConfig,
|
||||
} from '@backstage/plugin-home';
|
||||
import { Content, Header, Page } from '@backstage/core-components';
|
||||
import { HomePageSearchBar } from '@backstage/plugin-search';
|
||||
import HomeIcon from '@material-ui/icons/Home';
|
||||
import { SearchContextProvider } from '@backstage/plugin-search-react';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
import { tools, useLogoStyles } from './shared';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
searchBarInput: {
|
||||
maxWidth: '60vw',
|
||||
margin: 'auto',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderRadius: '50px',
|
||||
boxShadow: theme.shadows[1],
|
||||
},
|
||||
searchBarOutline: {
|
||||
borderStyle: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
const clockConfigs: ClockConfig[] = [
|
||||
{
|
||||
@@ -55,60 +71,55 @@ const timeFormat: Intl.DateTimeFormatOptions = {
|
||||
hour12: false,
|
||||
};
|
||||
|
||||
const defaultConfig = [
|
||||
{
|
||||
component: 'CompanyLogo',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 12,
|
||||
height: 1,
|
||||
movable: false,
|
||||
resizable: false,
|
||||
deletable: false,
|
||||
},
|
||||
{
|
||||
component: 'WelcomeTitle',
|
||||
x: 0,
|
||||
y: 1,
|
||||
width: 12,
|
||||
height: 1,
|
||||
},
|
||||
{
|
||||
component: 'HomePageSearchBar',
|
||||
x: 0,
|
||||
y: 2,
|
||||
width: 12,
|
||||
height: 2,
|
||||
},
|
||||
];
|
||||
export const HomePage = () => {
|
||||
const classes = useStyles();
|
||||
const { svg, path, container } = useLogoStyles();
|
||||
|
||||
export const homePage = (
|
||||
<Page themeId="home">
|
||||
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
|
||||
<HeaderWorldClock
|
||||
clockConfigs={clockConfigs}
|
||||
customTimeFormat={timeFormat}
|
||||
/>
|
||||
</Header>
|
||||
<Content>
|
||||
<CustomHomepageGrid config={defaultConfig}>
|
||||
<HomePageSearchBar />
|
||||
<HomePageRandomJoke />
|
||||
<HomePageStarredEntities />
|
||||
<HomePageCompanyLogo />
|
||||
<WelcomeTitle />
|
||||
<HomePageToolkit
|
||||
tools={[
|
||||
{
|
||||
url: 'https://backstage.io',
|
||||
label: 'Backstage Homepage',
|
||||
icon: <HomeIcon />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<HomePageTopVisited />
|
||||
<HomePageRecentlyVisited />
|
||||
</CustomHomepageGrid>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
return (
|
||||
<SearchContextProvider>
|
||||
<Page themeId="home">
|
||||
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
|
||||
<HeaderWorldClock
|
||||
clockConfigs={clockConfigs}
|
||||
customTimeFormat={timeFormat}
|
||||
/>
|
||||
</Header>
|
||||
<Content>
|
||||
<Grid container justifyContent="center" spacing={2}>
|
||||
<HomePageCompanyLogo
|
||||
className={container}
|
||||
logo={<TemplateBackstageLogo classes={{ svg, path }} />}
|
||||
/>
|
||||
<Grid container item xs={12} justifyContent="center">
|
||||
<HomePageSearchBar
|
||||
InputProps={{
|
||||
classes: {
|
||||
root: classes.searchBarInput,
|
||||
notchedOutline: classes.searchBarOutline,
|
||||
},
|
||||
}}
|
||||
placeholder="Search"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<HomePageTopVisited />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<HomePageRecentlyVisited />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={7}>
|
||||
<HomePageStarredEntities />
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<HomePageToolkit tools={tools} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
</Page>
|
||||
</SearchContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TemplateBackstageLogoIcon } from '@backstage/plugin-home';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useLogoStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
margin: theme.spacing(5, 0),
|
||||
},
|
||||
svg: {
|
||||
width: 'auto',
|
||||
height: 100,
|
||||
},
|
||||
path: {
|
||||
fill: '#7df3e1',
|
||||
},
|
||||
}));
|
||||
|
||||
export const tools = [
|
||||
{
|
||||
url: 'https://backstage.io/docs',
|
||||
label: 'Docs',
|
||||
icon: <TemplateBackstageLogoIcon />,
|
||||
},
|
||||
{
|
||||
url: 'https://github.com/backstage/backstage',
|
||||
label: 'GitHub',
|
||||
icon: <TemplateBackstageLogoIcon />,
|
||||
},
|
||||
{
|
||||
url: 'https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md',
|
||||
label: 'Contributing',
|
||||
icon: <TemplateBackstageLogoIcon />,
|
||||
},
|
||||
{
|
||||
url: 'https://backstage.io/plugins',
|
||||
label: 'Plugins Directory',
|
||||
icon: <TemplateBackstageLogoIcon />,
|
||||
},
|
||||
{
|
||||
url: 'https://github.com/backstage/backstage/issues/new/choose',
|
||||
label: 'Submit New Issue',
|
||||
icon: <TemplateBackstageLogoIcon />,
|
||||
},
|
||||
];
|
||||
@@ -107,6 +107,9 @@ export const homePage = (
|
||||
);
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> You can provide a title to the grid by passing it as a prop: `<CustomHomepageGrid title="Your Dashboard" />`. This will be displayed as a header above the grid layout.
|
||||
|
||||
### Creating Customizable Components
|
||||
|
||||
The custom home page can use the default components created by using the default `createCardExtension` method but if you
|
||||
|
||||
@@ -89,6 +89,7 @@ export const CustomHomepageGrid: (
|
||||
export type CustomHomepageGridProps = {
|
||||
children?: ReactNode;
|
||||
config?: LayoutConfiguration[];
|
||||
title?: string;
|
||||
rowHeight?: number;
|
||||
breakpoints?: Record<Breakpoint, number>;
|
||||
cols?: Record<Breakpoint, number>;
|
||||
|
||||
@@ -321,7 +321,7 @@ export const CustomHomepageGrid = (props: CustomHomepageGridProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentHeader title="">
|
||||
<ContentHeader title={props.title}>
|
||||
<CustomHomepageButtons
|
||||
editMode={editMode}
|
||||
numWidgets={widgets.length}
|
||||
|
||||
@@ -45,6 +45,10 @@ export type CustomHomepageGridProps = {
|
||||
* Default layout for the homepage before users have modified it.
|
||||
*/
|
||||
config?: LayoutConfiguration[];
|
||||
/**
|
||||
* Title displayed in the header of the grid. If not provided, no title will be shown.
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* Height of grid row in pixels.
|
||||
* @defaultValue 60
|
||||
|
||||
Reference in New Issue
Block a user