From a0917e7f1b12cbbe29c504809d56ddef3e68674f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 19:49:31 +0100 Subject: [PATCH 01/14] frontend/core: fix index import parts --- frontend/packages/core/src/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/packages/core/src/index.ts b/frontend/packages/core/src/index.ts index ccca30231a..ae3bc452d9 100644 --- a/frontend/packages/core/src/index.ts +++ b/frontend/packages/core/src/index.ts @@ -3,10 +3,10 @@ export { default as EntityLink, RelativeEntityLink, } from './components/EntityLink'; -export { default as Page } from '../src/layout/Page'; -export { gradients, theme } from '../src/layout/Page'; -export { default as Header } from '../src/layout/Header/Header'; -export { default as HeaderLabel } from '../src/layout/HeaderLabel'; -export { default as InfoCard } from '../src/layout/InfoCard'; -export { default as ErrorBoundary } from '../src/layout/ErrorBoundary'; -export { default as BackstageTheme } from '../src/theme/BackstageTheme'; +export { default as Page } from './layout/Page'; +export { gradients, theme } from './layout/Page'; +export { default as Header } from './layout/Header/Header'; +export { default as HeaderLabel } from './layout/HeaderLabel'; +export { default as InfoCard } from './layout/InfoCard'; +export { default as ErrorBoundary } from './layout/ErrorBoundary'; +export { default as BackstageTheme } from './theme/BackstageTheme'; From aec0eb0536599cec73f65b9a4f202ca3ecdf4b6d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:04:47 +0100 Subject: [PATCH 02/14] front/core/api/entityView: reorg entity view page components --- .../src/api/entityView/EntityPageBuilder.tsx | 74 +++++++++---------- .../packages/core/src/api/entityView/types.ts | 22 ++++++ 2 files changed, 55 insertions(+), 41 deletions(-) create mode 100644 frontend/packages/core/src/api/entityView/types.ts diff --git a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx index 8dbf6ba2a0..19f2e3ec8b 100644 --- a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx +++ b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx @@ -6,59 +6,51 @@ import { AppComponentBuilder, App } from '../app/types'; import { useEntity, useEntityUri, useEntityConfig } from './EntityContext'; import EntityLink from '../../components/EntityLink/EntityLink'; import BackstagePlugin from '../plugin/Plugin'; +import { Header } from '../..'; +import { + EntityPageNavbarProps, + EntityPageHeaderProps, + EntityPageProps, + EntityPageNavItem, + EntityPageView, +} from './types'; -const EntityLayout: FC<{}> = ({ children }) => { - const config = useEntityConfig(); - return ( -
{children}
- ); -}; +// type AppComponents = { +// EntityPage: ComponentType; +// EntityPageNavbar: ComponentType; +// EntityPageHeader: ComponentType; +// }; -const EntitySidebar: FC<{}> = ({ children }) => { - return {children}; -}; - -const EntitySidebarItem: FC<{ title: string; path: string }> = ({ - title, - path, -}) => { +const DefaultEntityPageNavbar: FC = ({ navItems }) => { const entityUri = useEntityUri(); return ( - - - {title} - - + + {navItems.map(({ title, target }) => ( + + + {title} + + + ))} + ); }; -type EntityPageNavItem = { - title: string; - target: string; +const DefaultEntityPageHeader: FC = () => { + const { id } = useEntity(); + const config = useEntityConfig(); + return
; }; -type EntityPageView = { - path: string; - component: ComponentType; -}; - -type Props = { - navItems: EntityPageNavItem[]; - views: EntityPageView[]; -}; - -const EntityPageComponent: FC = ({ navItems, views }) => { +const DefaultEntityPage: FC = ({ navItems, views }) => { const { kind, id } = useEntity(); const basePath = `/entity/${kind}/${id}`; return ( - - - {navItems.map(({ title, target }) => ( - - ))} - +
+ + {views.map(({ path, component }) => ( = ({ navItems, views }) => { ))} - +
); }; @@ -162,6 +154,6 @@ export default class EntityPageBuilder extends AppComponentBuilder { } } - return () => ; + return () => ; } } diff --git a/frontend/packages/core/src/api/entityView/types.ts b/frontend/packages/core/src/api/entityView/types.ts new file mode 100644 index 0000000000..5e6a5d5df7 --- /dev/null +++ b/frontend/packages/core/src/api/entityView/types.ts @@ -0,0 +1,22 @@ +import { ComponentType } from 'react'; + +export type EntityPageNavItem = { + title: string; + target: string; +}; + +export type EntityPageView = { + path: string; + component: ComponentType; +}; + +export type EntityPageProps = { + navItems: EntityPageNavItem[]; + views: EntityPageView[]; +}; + +export type EntityPageNavbarProps = { + navItems: EntityPageNavItem[]; +}; + +export type EntityPageHeaderProps = {}; From 00f1d9d8e89dbe2f98f9756971ff0086946ed4d0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:15:23 +0100 Subject: [PATCH 03/14] front/core/api/entityView: move default components out to components --- .../src/api/entityView/EntityPageBuilder.tsx | 64 ++----------------- .../DefaultEntityPage/DefaultEntityPage.tsx | 31 +++++++++ .../src/components/DefaultEntityPage/index.ts | 1 + .../DefaultEntityPageHeader.tsx | 11 ++++ .../DefaultEntityPageHeader/index.ts | 1 + .../DefaultEntityPageNavbar.tsx | 22 +++++++ .../DefaultEntityPageNavbar/index.ts | 1 + 7 files changed, 71 insertions(+), 60 deletions(-) create mode 100644 frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx create mode 100644 frontend/packages/core/src/components/DefaultEntityPage/index.ts create mode 100644 frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx create mode 100644 frontend/packages/core/src/components/DefaultEntityPageHeader/index.ts create mode 100644 frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx create mode 100644 frontend/packages/core/src/components/DefaultEntityPageNavbar/index.ts diff --git a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx index 19f2e3ec8b..da6b315534 100644 --- a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx +++ b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx @@ -1,19 +1,8 @@ -import React, { ComponentType, FC } from 'react'; -import { Route, Redirect, Switch } from 'react-router-dom'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import { AppComponentBuilder, App } from '../app/types'; -import { useEntity, useEntityUri, useEntityConfig } from './EntityContext'; -import EntityLink from '../../components/EntityLink/EntityLink'; +import React, { ComponentType } from 'react'; +import DefaultEntityPage from '../../components/DefaultEntityPage'; +import { App, AppComponentBuilder } from '../app/types'; import BackstagePlugin from '../plugin/Plugin'; -import { Header } from '../..'; -import { - EntityPageNavbarProps, - EntityPageHeaderProps, - EntityPageProps, - EntityPageNavItem, - EntityPageView, -} from './types'; +import { EntityPageNavItem, EntityPageView } from './types'; // type AppComponents = { // EntityPage: ComponentType; @@ -21,51 +10,6 @@ import { // EntityPageHeader: ComponentType; // }; -const DefaultEntityPageNavbar: FC = ({ navItems }) => { - const entityUri = useEntityUri(); - - return ( - - {navItems.map(({ title, target }) => ( - - - {title} - - - ))} - - ); -}; - -const DefaultEntityPageHeader: FC = () => { - const { id } = useEntity(); - const config = useEntityConfig(); - return
; -}; - -const DefaultEntityPage: FC = ({ navItems, views }) => { - const { kind, id } = useEntity(); - const basePath = `/entity/${kind}/${id}`; - - return ( -
- - - - {views.map(({ path, component }) => ( - - ))} - - -
- ); -}; - type EntityPageRegistration = | { type: 'page'; diff --git a/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx b/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx new file mode 100644 index 0000000000..df68484609 --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx @@ -0,0 +1,31 @@ +import React, { FC } from 'react'; +import { EntityPageProps } from '../../api/entityView/types'; +import { useEntity } from '../../api'; +import { Switch, Route, Redirect } from 'react-router-dom'; +import DefaultEntityPageHeader from '../DefaultEntityPageHeader'; +import DefaultEntityPageNavbar from '../DefaultEntityPageNavbar'; + +const DefaultEntityPage: FC = ({ navItems, views }) => { + const { kind, id } = useEntity(); + const basePath = `/entity/${kind}/${id}`; + + return ( +
+ + + + {views.map(({ path, component }) => ( + + ))} + + +
+ ); +}; + +export default DefaultEntityPage; diff --git a/frontend/packages/core/src/components/DefaultEntityPage/index.ts b/frontend/packages/core/src/components/DefaultEntityPage/index.ts new file mode 100644 index 0000000000..4f683076c4 --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPage/index.ts @@ -0,0 +1 @@ +export { default } from './DefaultEntityPage'; diff --git a/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx b/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx new file mode 100644 index 0000000000..b93f54b7e5 --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx @@ -0,0 +1,11 @@ +import React, { FC } from 'react'; +import { Header, useEntity, useEntityConfig } from '../..'; +import { EntityPageHeaderProps } from '../../api/entityView/types'; + +const DefaultEntityPageHeader: FC = () => { + const { id } = useEntity(); + const config = useEntityConfig(); + return
; +}; + +export default DefaultEntityPageHeader; diff --git a/frontend/packages/core/src/components/DefaultEntityPageHeader/index.ts b/frontend/packages/core/src/components/DefaultEntityPageHeader/index.ts new file mode 100644 index 0000000000..5c9304bad7 --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPageHeader/index.ts @@ -0,0 +1 @@ +export { default } from './DefaultEntityPageHeader'; diff --git a/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx b/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx new file mode 100644 index 0000000000..3b827cf838 --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx @@ -0,0 +1,22 @@ +import React, { FC } from 'react'; +import { EntityPageNavbarProps } from '../../api/entityView/types'; +import { useEntityUri, EntityLink } from '../..'; +import { List, ListItem } from '@material-ui/core'; + +const DefaultEntityPageNavbar: FC = ({ navItems }) => { + const entityUri = useEntityUri(); + + return ( + + {navItems.map(({ title, target }) => ( + + + {title} + + + ))} + + ); +}; + +export default DefaultEntityPageNavbar; diff --git a/frontend/packages/core/src/components/DefaultEntityPageNavbar/index.ts b/frontend/packages/core/src/components/DefaultEntityPageNavbar/index.ts new file mode 100644 index 0000000000..14a807a40f --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPageNavbar/index.ts @@ -0,0 +1 @@ +export { default } from './DefaultEntityPageNavbar'; From fab433d02fb71c0382ab3f492fc868ee370791be Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:18:34 +0100 Subject: [PATCH 04/14] front/core: add material-ui to deps --- frontend/packages/core/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/packages/core/package.json b/frontend/packages/core/package.json index d22516afe1..d7265591eb 100644 --- a/frontend/packages/core/package.json +++ b/frontend/packages/core/package.json @@ -4,6 +4,8 @@ "main": "src/index.ts", "main:src": "src/index.ts", "devDependencies": { + "@material-ui/core": "^4.9.1", + "@material-ui/icons": "^4.9.1", "@spotify/web-scripts": "^6.0.0", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", From ea4b1a52f9a5b1b49f88342a40d1dcf4b43ed140 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:24:06 +0100 Subject: [PATCH 05/14] front/core/DefaultEntityPage: use grid layout --- .../DefaultEntityPage/DefaultEntityPage.tsx | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx b/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx index df68484609..5edbea7bf0 100644 --- a/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx +++ b/frontend/packages/core/src/components/DefaultEntityPage/DefaultEntityPage.tsx @@ -1,29 +1,60 @@ import React, { FC } from 'react'; +import { makeStyles, Theme } from '@material-ui/core'; import { EntityPageProps } from '../../api/entityView/types'; import { useEntity } from '../../api'; import { Switch, Route, Redirect } from 'react-router-dom'; import DefaultEntityPageHeader from '../DefaultEntityPageHeader'; import DefaultEntityPageNavbar from '../DefaultEntityPageNavbar'; +const useStyles = makeStyles(theme => ({ + root: { + display: 'grid', + gridTemplateAreas: ` + 'header header' + 'navbar content' + `, + gridTemplateRows: 'auto 1fr', + gridTemplateColumns: 'auto 1fr', + minHeight: '100%', + paddingBottom: theme.spacing(3), + }, + header: { + gridArea: 'header', + }, + navbar: { + gridArea: 'navbar', + }, + content: { + gridArea: 'content', + }, +})); + const DefaultEntityPage: FC = ({ navItems, views }) => { + const classes = useStyles(); const { kind, id } = useEntity(); const basePath = `/entity/${kind}/${id}`; return ( -
- - - - {views.map(({ path, component }) => ( - - ))} - - +
+
+ +
+
+ +
+
+ + {views.map(({ path, component }) => ( + + ))} + + +
); }; From b69ee27d9efb28b9072f8acb862182b11d42876b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:33:03 +0100 Subject: [PATCH 06/14] front/app: move AppShell things into home-page plugin --- frontend/packages/app/src/App.tsx | 33 ++----------- .../src/components/HomePage/HomePage.tsx | 49 ++++++++++++++----- .../HomepageTimer/HomepageTimer.tsx | 0 .../src/components/HomepageTimer/index.ts | 0 4 files changed, 41 insertions(+), 41 deletions(-) rename frontend/packages/{app => plugins/home-page}/src/components/HomepageTimer/HomepageTimer.tsx (100%) rename frontend/packages/{app => plugins/home-page}/src/components/HomepageTimer/index.ts (100%) diff --git a/frontend/packages/app/src/App.tsx b/frontend/packages/app/src/App.tsx index 1936c63c98..96716298a1 100644 --- a/frontend/packages/app/src/App.tsx +++ b/frontend/packages/app/src/App.tsx @@ -1,18 +1,10 @@ -import { - BackstageTheme, - createApp, - Header, - InfoCard, - Page, - theme, -} from '@backstage/core'; +import { BackstageTheme, createApp, InfoCard } from '@backstage/core'; import HomePagePlugin from '@backstage/plugin-home-page'; //import PageHeader from './components/PageHeader'; import { LoginComponent } from '@backstage/plugin-login'; import { CssBaseline, makeStyles, ThemeProvider } from '@material-ui/core'; import React, { FC } from 'react'; import { BrowserRouter as Router } from 'react-router-dom'; -import HomePageTimer from './components/HomepageTimer'; import SideBar from './components/SideBar'; import entities from './entities'; import { LoginBarrier } from './login/LoginBarrier'; @@ -37,20 +29,10 @@ const useStyles = makeStyles(theme => ({ display: 'grid', // FIXME: Don't used a fixed width here gridTemplateColumns: '64px auto', - gridTemplateRows: 'auto 1fr', - width: '100%', + gridTemplateRows: '1fr', + width: '100vw', height: '100vh', }, - mainContentArea: { - overflowX: 'hidden', - overflowY: 'auto', - }, - pageBody: { - padding: theme.spacing(2), - }, - avatarButton: { - padding: theme.spacing(2), - }, })); const currentUser = new MockCurrentUser(); @@ -69,14 +51,7 @@ const AppShell: FC<{}> = ({ children }) => { return (
- -
-
- -
-
{children}
-
-
+ {children}
); }; diff --git a/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.tsx b/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.tsx index d84256ac42..f5d388f420 100644 --- a/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.tsx +++ b/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.tsx @@ -1,20 +1,45 @@ -import { EntityLink, InfoCard } from '@backstage/core'; -import { Typography } from '@material-ui/core'; +import { EntityLink, InfoCard, Header, Page, theme } from '@backstage/core'; +import { Typography, makeStyles, Theme } from '@material-ui/core'; import React, { FC } from 'react'; +import HomePageTimer from '../HomepageTimer'; + +const useStyles = makeStyles(theme => ({ + mainContentArea: { + overflowX: 'hidden', + overflowY: 'auto', + }, + pageBody: { + padding: theme.spacing(2), + }, + avatarButton: { + padding: theme.spacing(2), + }, +})); const HomePage: FC<{}> = () => { + const classes = useStyles(); + return ( - - Welcome to Backstage! -
- - Backstage Backend - - - Backstage LB CI/CD - + +
+
+ +
+
+ + Welcome to Backstage! +
+ + Backstage Backend + + + Backstage LB CI/CD + +
+
+
- +
); }; diff --git a/frontend/packages/app/src/components/HomepageTimer/HomepageTimer.tsx b/frontend/packages/plugins/home-page/src/components/HomepageTimer/HomepageTimer.tsx similarity index 100% rename from frontend/packages/app/src/components/HomepageTimer/HomepageTimer.tsx rename to frontend/packages/plugins/home-page/src/components/HomepageTimer/HomepageTimer.tsx diff --git a/frontend/packages/app/src/components/HomepageTimer/index.ts b/frontend/packages/plugins/home-page/src/components/HomepageTimer/index.ts similarity index 100% rename from frontend/packages/app/src/components/HomepageTimer/index.ts rename to frontend/packages/plugins/home-page/src/components/HomepageTimer/index.ts From c62f92d9126dff8f7e872f462263f7311d71b8a3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Feb 2020 20:39:56 +0100 Subject: [PATCH 07/14] front/core/DefaultEntityPageHeader: provide hard-coded service theme for now --- .../DefaultEntityPageHeader.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx b/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx index b93f54b7e5..b9e2768141 100644 --- a/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx +++ b/frontend/packages/core/src/components/DefaultEntityPageHeader/DefaultEntityPageHeader.tsx @@ -1,11 +1,18 @@ import React, { FC } from 'react'; -import { Header, useEntity, useEntityConfig } from '../..'; +import { Header, useEntity, useEntityConfig, theme } from '../..'; import { EntityPageHeaderProps } from '../../api/entityView/types'; +import { Theme } from '../../layout/Page/Page'; const DefaultEntityPageHeader: FC = () => { const { id } = useEntity(); const config = useEntityConfig(); - return
; + + // TODO(rugvip): provide theme through entity config + return ( + +
+ + ); }; export default DefaultEntityPageHeader; From f97b1b56333c138658a2db56daa2ee1f29486144 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:26:10 +0100 Subject: [PATCH 08/14] front/core: added common type for icon components and require for entity nav items --- frontend/packages/app/src/entities/index.ts | 6 ++-- .../core/src/api/entity/EntityKind.ts | 3 +- .../src/api/entityView/EntityPageBuilder.tsx | 28 +++++++++++++------ .../packages/core/src/api/entityView/types.ts | 2 ++ .../packages/core/src/api/plugin/Plugin.tsx | 6 ++-- .../packages/core/src/api/plugin/types.ts | 2 ++ frontend/packages/core/src/api/types.ts | 13 +++------ .../plugins/github-actions/src/plugin.ts | 3 +- 8 files changed, 40 insertions(+), 23 deletions(-) diff --git a/frontend/packages/app/src/entities/index.ts b/frontend/packages/app/src/entities/index.ts index 38e529d87f..01f4105902 100644 --- a/frontend/packages/app/src/entities/index.ts +++ b/frontend/packages/app/src/entities/index.ts @@ -4,6 +4,8 @@ import { createEntityPage, } from '@backstage/core'; import ComputerIcon from '@material-ui/icons/Computer'; +import WebIcon from '@material-ui/icons/Web'; +import DnsIcon from '@material-ui/icons/Dns'; import MockEntityPage from './MockEntityPage'; import MockEntityCard from './MockEntityCard'; import GithubActionsPlugin from '@backstage/plugin-github-actions'; @@ -14,9 +16,9 @@ const serviceOverviewPage = createWidgetView() .addComponent(MockEntityCard); const serviceView = createEntityPage() - .addPage('Overview', '/overview', serviceOverviewPage) + .addPage('Overview', WebIcon, '/overview', serviceOverviewPage) .register(GithubActionsPlugin) - .addComponent('Deployment', '/deployment', MockEntityPage); + .addComponent('Deployment', DnsIcon, '/deployment', MockEntityPage); const serviceEntity = createEntityKind({ kind: 'service', diff --git a/frontend/packages/core/src/api/entity/EntityKind.ts b/frontend/packages/core/src/api/entity/EntityKind.ts index 7f6447f4a6..b10a16c991 100644 --- a/frontend/packages/core/src/api/entity/EntityKind.ts +++ b/frontend/packages/core/src/api/entity/EntityKind.ts @@ -1,10 +1,11 @@ import { ComponentType } from 'react'; import { AppComponentBuilder } from '../app/types'; +import { IconComponent } from '../types'; export type EntityConfig = { kind: string; title: string; - icon: React.ComponentType<{ fontSize: number }>; + icon: IconComponent; color: { primary: string; secondary: string; diff --git a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx index da6b315534..7944b26ca7 100644 --- a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx +++ b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx @@ -10,10 +10,13 @@ import { EntityPageNavItem, EntityPageView } from './types'; // EntityPageHeader: ComponentType; // }; +type IconComponent = ComponentType<{ fontSize?: number }>; + type EntityPageRegistration = | { type: 'page'; title: string; + icon: IconComponent; path: string; page: AppComponentBuilder; } @@ -24,6 +27,7 @@ type EntityPageRegistration = | { type: 'component'; title: string; + icon: IconComponent; path: string; component: ComponentType; }; @@ -33,19 +37,27 @@ export default class EntityPageBuilder extends AppComponentBuilder { addPage( title: string, + icon: IconComponent, path: string, page: AppComponentBuilder, ): EntityPageBuilder { - this.registrations.push({ type: 'page', title, path, page }); + this.registrations.push({ type: 'page', title, icon, path, page }); return this; } addComponent( title: string, + icon: IconComponent, path: string, component: ComponentType, ): EntityPageBuilder { - this.registrations.push({ type: 'component', title, path, component }); + this.registrations.push({ + type: 'component', + title, + icon, + path, + component, + }); return this; } @@ -61,14 +73,14 @@ export default class EntityPageBuilder extends AppComponentBuilder { for (const reg of this.registrations) { switch (reg.type) { case 'page': { - const { title, path, page } = reg; - navItems.push({ title, target: path }); + const { title, icon, path, page } = reg; + navItems.push({ title, icon, target: path }); views.push({ path, component: page.build(app) }); break; } case 'component': { - const { title, path, component } = reg; - navItems.push({ title, target: path }); + const { title, icon, path, component } = reg; + navItems.push({ title, icon, target: path }); views.push({ path, component }); break; } @@ -77,8 +89,8 @@ export default class EntityPageBuilder extends AppComponentBuilder { for (const output of reg.plugin.output()) { switch (output.type) { case 'entity-page-nav-item': - const { title, target } = output; - navItems.push({ title, target }); + const { title, icon, target } = output; + navItems.push({ title, icon, target }); added = true; break; case 'entity-page-view-route': diff --git a/frontend/packages/core/src/api/entityView/types.ts b/frontend/packages/core/src/api/entityView/types.ts index 5e6a5d5df7..8708057b8a 100644 --- a/frontend/packages/core/src/api/entityView/types.ts +++ b/frontend/packages/core/src/api/entityView/types.ts @@ -1,6 +1,8 @@ import { ComponentType } from 'react'; +import { IconComponent } from '../types'; export type EntityPageNavItem = { + icon: IconComponent; title: string; target: string; }; diff --git a/frontend/packages/core/src/api/plugin/Plugin.tsx b/frontend/packages/core/src/api/plugin/Plugin.tsx index e351801047..dfe5da2993 100644 --- a/frontend/packages/core/src/api/plugin/Plugin.tsx +++ b/frontend/packages/core/src/api/plugin/Plugin.tsx @@ -27,6 +27,7 @@ export type RouterHooks = { type EntityPageSidebarItemOptions = { title: string; + icon: IconComponent; target: RoutePath; }; @@ -79,11 +80,12 @@ export default class Plugin { }, }, entityPage: { - navItem({ title, target }) { + navItem({ title, icon, target }) { outputs.push({ type: 'entity-page-nav-item', - target, title, + icon, + target, }); }, route(path, component, options) { diff --git a/frontend/packages/core/src/api/plugin/types.ts b/frontend/packages/core/src/api/plugin/types.ts index ddc6364ec5..f6efee230e 100644 --- a/frontend/packages/core/src/api/plugin/types.ts +++ b/frontend/packages/core/src/api/plugin/types.ts @@ -1,4 +1,5 @@ import { ComponentType } from 'react'; +import { IconComponent } from '../types'; export type RouteOptions = { // Whether the route path must match exactly, defaults to true. @@ -31,6 +32,7 @@ export type EntityPageViewRouteOutput = { export type EntityPageNavItemOutput = { type: 'entity-page-nav-item'; title: string; + icon: IconComponent; target: RoutePath; }; diff --git a/frontend/packages/core/src/api/types.ts b/frontend/packages/core/src/api/types.ts index 06f1570900..8462a5a1b9 100644 --- a/frontend/packages/core/src/api/types.ts +++ b/frontend/packages/core/src/api/types.ts @@ -1,10 +1,5 @@ -export type User = { - id: string; - email: string; -}; +import { ComponentType } from 'react'; -export type UserApi = { - isLoggedIn(): Promise; - - getUser(): Promise; -}; +export type IconComponent = ComponentType<{ + fontSize: 'inherit' | 'default' | 'small' | 'large'; +}>; diff --git a/frontend/packages/plugins/github-actions/src/plugin.ts b/frontend/packages/plugins/github-actions/src/plugin.ts index 6972d8d128..d95d5b5bdc 100644 --- a/frontend/packages/plugins/github-actions/src/plugin.ts +++ b/frontend/packages/plugins/github-actions/src/plugin.ts @@ -1,6 +1,7 @@ import { createPlugin } from '@backstage/core'; import BuildDetailsPage from './components/BuildDetailsPage'; import BuildListPage from './components/BuildListPage'; +import BuildIcon from '@material-ui/icons/Build'; // export const buildListRoute = createEntityRoute<[]>('/builds') // export const buildDetailsRoute = createEntityRoute<[number]>('/builds/:buildId') @@ -9,7 +10,7 @@ export default createPlugin({ id: 'github-actions', register({ entityPage }) { - entityPage.navItem({ title: 'CI/CD', target: '/builds' }); + entityPage.navItem({ title: 'CI/CD', icon: BuildIcon, target: '/builds' }); entityPage.route('/builds', BuildListPage); entityPage.route('/builds/:buildUri', BuildDetailsPage); }, From 87bdd8279b0e1ef6551ef2dfa73f0aab85875f25 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:26:30 +0100 Subject: [PATCH 09/14] front/core/EntityLink: forward props --- .../src/components/EntityLink/EntityLink.tsx | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/frontend/packages/core/src/components/EntityLink/EntityLink.tsx b/frontend/packages/core/src/components/EntityLink/EntityLink.tsx index 04b070e397..57993f8abf 100644 --- a/frontend/packages/core/src/components/EntityLink/EntityLink.tsx +++ b/frontend/packages/core/src/components/EntityLink/EntityLink.tsx @@ -1,17 +1,17 @@ import React, { FC } from 'react'; -import { Link } from 'react-router-dom'; +import { Link, LinkProps } from 'react-router-dom'; -type Props = { +type Props = Omit & { subPath?: string; } & ( - | { - kind: string; - id?: string; - } - | { - uri: string; - } -); + | { + kind: string; + id?: string; + } + | { + uri: string; + } + ); export function buildPath(kind: string, id?: string, subPath?: string) { if (id) { @@ -26,7 +26,11 @@ export function buildPath(kind: string, id?: string, subPath?: string) { const EntityLink: FC = ({ subPath, children, ...props }) => { if ('kind' in props) { const { kind, id } = props; - return {children}; + return ( + + {children} + + ); } else { const match = props.uri.match(/entity:([^:]+)(:[^:]+)?/); if (!match) { @@ -36,7 +40,11 @@ const EntityLink: FC = ({ subPath, children, ...props }) => { const [, kind, maybeId] = match; const id = maybeId ? maybeId.slice(1) : undefined; - return {children}; + return ( + + {children} + + ); } }; From 58ad9cd3228b5d74c3ef8255d20d524769f462cd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:27:04 +0100 Subject: [PATCH 10/14] front/core/DefaultEntityPageNavbar: stole styling from alunds PR --- .../DefaultEntityPageNavbar.tsx | 36 +++++++--- .../DefaultEntityPageNavbar/NavbarItem.tsx | 72 +++++++++++++++++++ 2 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 frontend/packages/core/src/components/DefaultEntityPageNavbar/NavbarItem.tsx diff --git a/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx b/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx index 3b827cf838..69aed8bd9f 100644 --- a/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx +++ b/frontend/packages/core/src/components/DefaultEntityPageNavbar/DefaultEntityPageNavbar.tsx @@ -1,21 +1,35 @@ import React, { FC } from 'react'; import { EntityPageNavbarProps } from '../../api/entityView/types'; -import { useEntityUri, EntityLink } from '../..'; -import { List, ListItem } from '@material-ui/core'; +import { useEntityUri } from '../..'; +import { List, makeStyles, Theme } from '@material-ui/core'; +import NavbarItem from './NavbarItem'; + +const useStyles = makeStyles({ + nav: { + gridArea: 'pageNav', + width: 220, + transition: 'width 0.07s, height 0s', + transitionTimingFunction: 'ease-in', + backgroundColor: '#eeeeee', + boxShadow: '0px 0 4px 0px rgba(0,0,0,0.35)', + }, + list: { + padding: 0, + }, +}); const DefaultEntityPageNavbar: FC = ({ navItems }) => { + const classes = useStyles(); const entityUri = useEntityUri(); return ( - - {navItems.map(({ title, target }) => ( - - - {title} - - - ))} - + ); }; diff --git a/frontend/packages/core/src/components/DefaultEntityPageNavbar/NavbarItem.tsx b/frontend/packages/core/src/components/DefaultEntityPageNavbar/NavbarItem.tsx new file mode 100644 index 0000000000..d75ee16f4c --- /dev/null +++ b/frontend/packages/core/src/components/DefaultEntityPageNavbar/NavbarItem.tsx @@ -0,0 +1,72 @@ +import React, { FC } from 'react'; +import { EntityLink } from '../..'; +import { + ListItem, + makeStyles, + Theme, + ListItemIcon, + ListItemText, + Typography, +} from '@material-ui/core'; +import { EntityPageNavItem } from '../../api/entityView/types'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'block', + overflow: 'hidden', + borderBottom: `1px solid #d9d9d9`, + paddingLeft: theme.spacing(1), + }, + label: { + color: '#333', + fontWeight: 'bolder', + whiteSpace: 'nowrap', + lineHeight: 1.0, + }, + iconImg: { + width: 24, + height: 24, + }, + icon: { + margin: theme.spacing(0.5, 2, 0.5, 0), + minWidth: 0, + fontSize: 24, + }, + expand: { + color: 'white', + }, +})); + +type Props = { + navItem: EntityPageNavItem; + entityUri: string; +}; + +const NavbarItem: FC = ({ navItem, entityUri }) => { + const classes = useStyles(); + const IconComponent = navItem.icon; + + return ( + + + + + + + {navItem.title} + + } + disableTypography + /> + + + ); +}; + +export default NavbarItem; From 568028dfbf2943208d2ed79a90cb311d5e569343 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:46:50 +0100 Subject: [PATCH 11/14] front/app,core: fix horizontal scroll --- frontend/packages/app/src/App.tsx | 2 +- frontend/packages/core/src/layout/Header/Header.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/packages/app/src/App.tsx b/frontend/packages/app/src/App.tsx index 96716298a1..9fbbf28dca 100644 --- a/frontend/packages/app/src/App.tsx +++ b/frontend/packages/app/src/App.tsx @@ -30,7 +30,7 @@ const useStyles = makeStyles(theme => ({ // FIXME: Don't used a fixed width here gridTemplateColumns: '64px auto', gridTemplateRows: '1fr', - width: '100vw', + width: '100%', height: '100vh', }, })); diff --git a/frontend/packages/core/src/layout/Header/Header.js b/frontend/packages/core/src/layout/Header/Header.js index 5ddb7865e4..7f715e5996 100644 --- a/frontend/packages/core/src/layout/Header/Header.js +++ b/frontend/packages/core/src/layout/Header/Header.js @@ -103,7 +103,7 @@ const styles = theme => ({ gridArea: 'pageHeader', padding: theme.spacing(3), minHeight: 118, - width: '100vw', + width: '100%', boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)', position: 'relative', zIndex: 100, From 94efef0d05304b4bf967d0cd0a9518c280b72808 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:47:28 +0100 Subject: [PATCH 12/14] front/github-actions/BuildListPage: some paddings --- .../BuildListPage/BuildListPage.tsx | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/frontend/packages/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx b/frontend/packages/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx index eaafce74c6..9096cc8f2e 100644 --- a/frontend/packages/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx +++ b/frontend/packages/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx @@ -10,6 +10,8 @@ import { LinearProgress, Typography, Tooltip, + makeStyles, + Theme, } from '@material-ui/core'; import { RelativeEntityLink } from '@backstage/core'; import { BuildsClient } from '../../apis/builds'; @@ -28,23 +30,31 @@ const LongText: FC<{ text: string; max: number }> = ({ text, max }) => { ); }; +const useStyles = makeStyles(theme => ({ + root: { + padding: theme.spacing(2), + }, + title: { + paddingBottom: theme.spacing(2), + }, +})); + const BuildListPage: FC<{}> = () => { + const classes = useStyles(); const status = useAsync(() => client.listBuilds('entity:spotify:backstage')); + let content: JSX.Element; + if (status.loading) { - return ; - } - if (status.error) { - return ( - + content = ; + } else if (status.error) { + content = ( + Failed to load builds, {status.error.message} ); - } - - return ( - <> - CI/CD Builds + } else { + content = ( @@ -86,7 +96,16 @@ const BuildListPage: FC<{}> = () => {
- + ); + } + + return ( +
+ + CI/CD Builds + + {content} +
); }; From 3014b96be32de3d728eecd09799b3082dbc8b178 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 09:50:17 +0100 Subject: [PATCH 13/14] front/app/SideBar: fixed sidebar --- frontend/packages/app/src/components/SideBar/SideBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/app/src/components/SideBar/SideBar.tsx b/frontend/packages/app/src/components/SideBar/SideBar.tsx index 395ae45410..2db9363f1d 100644 --- a/frontend/packages/app/src/components/SideBar/SideBar.tsx +++ b/frontend/packages/app/src/components/SideBar/SideBar.tsx @@ -158,7 +158,7 @@ const useStyles = makeStyles(theme => ({ display: 'flex', flexFlow: 'column nowrap', alignItems: 'flex-start', - position: 'absolute', + position: 'fixed', left: 0, top: 0, bottom: 0, From f070b8e1d03d4accb094f0e9fdda85789d46d23e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2020 10:05:48 +0100 Subject: [PATCH 14/14] front: test fixes --- .../core/src/api/entityView/EntityPageBuilder.tsx | 3 +-- frontend/packages/core/src/api/plugin/Plugin.tsx | 1 + .../home-page/src/components/HomePage/HomePage.test.tsx | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx index 7944b26ca7..fdbdef01fb 100644 --- a/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx +++ b/frontend/packages/core/src/api/entityView/EntityPageBuilder.tsx @@ -3,6 +3,7 @@ import DefaultEntityPage from '../../components/DefaultEntityPage'; import { App, AppComponentBuilder } from '../app/types'; import BackstagePlugin from '../plugin/Plugin'; import { EntityPageNavItem, EntityPageView } from './types'; +import { IconComponent } from '../types'; // type AppComponents = { // EntityPage: ComponentType; @@ -10,8 +11,6 @@ import { EntityPageNavItem, EntityPageView } from './types'; // EntityPageHeader: ComponentType; // }; -type IconComponent = ComponentType<{ fontSize?: number }>; - type EntityPageRegistration = | { type: 'page'; diff --git a/frontend/packages/core/src/api/plugin/Plugin.tsx b/frontend/packages/core/src/api/plugin/Plugin.tsx index dfe5da2993..772776e288 100644 --- a/frontend/packages/core/src/api/plugin/Plugin.tsx +++ b/frontend/packages/core/src/api/plugin/Plugin.tsx @@ -1,5 +1,6 @@ import { ComponentType } from 'react'; import { PluginOutput, RoutePath, RouteOptions } from './types'; +import { IconComponent } from '../types'; export type PluginConfig = { id: string; diff --git a/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.test.tsx b/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.test.tsx index 383bc9a5aa..fc495d3111 100644 --- a/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.test.tsx +++ b/frontend/packages/plugins/home-page/src/components/HomePage/HomePage.test.tsx @@ -1,10 +1,16 @@ import React from 'react'; import { render } from '@testing-library/react'; import HomePage from './HomePage'; +import { ThemeProvider } from '@material-ui/core'; +import { BackstageTheme } from '@backstage/core'; describe('HomePage', () => { it('should render', () => { - const rendered = render(); + const rendered = render( + + + , + ); expect(rendered.baseElement).toBeInTheDocument(); }); });