diff --git a/.changeset/honest-states-repeat.md b/.changeset/honest-states-repeat.md new file mode 100644 index 0000000000..99d094b4c1 --- /dev/null +++ b/.changeset/honest-states-repeat.md @@ -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 diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 3927992fd4..5ac9052d2a 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -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 = ( } /> + {/* TODO(rubenl): Move this to / once its more mature and components exist */} - }> - {homePage} - + + + }> + + + + + }> + + + + } diff --git a/packages/app/src/components/home/CustomizableHomePage.tsx b/packages/app/src/components/home/CustomizableHomePage.tsx new file mode 100644 index 0000000000..8998538e54 --- /dev/null +++ b/packages/app/src/components/home/CustomizableHomePage.tsx @@ -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 ( + + + + } + /> + + + + + + + + + + + + + ); +}; diff --git a/packages/app/src/components/home/HomePage.tsx b/packages/app/src/components/home/HomePage.tsx index f0f49ab34e..ca555280dd 100644 --- a/packages/app/src/components/home/HomePage.tsx +++ b/packages/app/src/components/home/HomePage.tsx @@ -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 = ( - -
} pageTitleOverride="Home"> - -
- - - - - - - - , - }, - ]} - /> - - - - -
-); + return ( + + +
} pageTitleOverride="Home"> + +
+ + + } + /> + + + + + + + + + + + + + + + + + + + + + +
+
+ ); +}; diff --git a/packages/app/src/components/home/shared.tsx b/packages/app/src/components/home/shared.tsx new file mode 100644 index 0000000000..c8b9764c83 --- /dev/null +++ b/packages/app/src/components/home/shared.tsx @@ -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: , + }, + { + url: 'https://github.com/backstage/backstage', + label: 'GitHub', + icon: , + }, + { + url: 'https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md', + label: 'Contributing', + icon: , + }, + { + url: 'https://backstage.io/plugins', + label: 'Plugins Directory', + icon: , + }, + { + url: 'https://github.com/backstage/backstage/issues/new/choose', + label: 'Submit New Issue', + icon: , + }, +]; diff --git a/plugins/home/README.md b/plugins/home/README.md index 50b422a3dc..3498d6700f 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -107,6 +107,9 @@ export const homePage = ( ); ``` +> [!NOTE] +> You can provide a title to the grid by passing it as a prop: ``. 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 diff --git a/plugins/home/report.api.md b/plugins/home/report.api.md index 7c7f55fd47..07e54757e6 100644 --- a/plugins/home/report.api.md +++ b/plugins/home/report.api.md @@ -89,6 +89,7 @@ export const CustomHomepageGrid: ( export type CustomHomepageGridProps = { children?: ReactNode; config?: LayoutConfiguration[]; + title?: string; rowHeight?: number; breakpoints?: Record; cols?: Record; diff --git a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx index da55ccc5f4..675e17357e 100644 --- a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx +++ b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx @@ -321,7 +321,7 @@ export const CustomHomepageGrid = (props: CustomHomepageGridProps) => { return ( <> - +