Merge pull request #6635 from tudi2d/catalog-fully-responsive

ContentHeader responsiveness
This commit is contained in:
Ben Lambert
2021-08-03 19:57:58 +02:00
committed by GitHub
14 changed files with 121 additions and 86 deletions
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/core-components': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-scaffolder': patch
---
Move the `CreateComponentButton` from the catalog plugin to the `core-components` & rename it to `CreateButton` to be reused inside the api-docs plugin & scaffolder plugin, but also future plugins. Additionally, improve responsiveness of `CreateButton` & `SupportButton` by shrinking them to `IconButtons` on smaller screens.
@@ -36,7 +36,7 @@ export const CustomCatalogPage = ({
<PageWithHeader title={`${orgName} Catalog`} themeId="home">
<Content>
<ContentHeader title="Components">
<CreateComponentButton />
<CreateButton title="Create Component" to={link} />
<SupportButton>All your software catalog entities</SupportButton>
</ContentHeader>
<EntityListProvider>
+9
View File
@@ -467,6 +467,15 @@ export const CopyTextButton: {
};
};
// Warning: (ae-forgotten-export) The symbol "CreateButtonProps" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "CreateButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const CreateButton: ({
title,
to,
}: CreateButtonProps) => JSX.Element | null;
// Warning: (ae-missing-release-tag) "DashboardIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -0,0 +1,51 @@
/*
* Copyright 2021 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 { BackstageTheme } from '@backstage/theme';
import { Button, IconButton, useMediaQuery } from '@material-ui/core';
import React from 'react';
import { Link as RouterLink, LinkProps } from 'react-router-dom';
import AddCircleOutline from '@material-ui/icons/AddCircleOutline';
type CreateButtonProps = {
title: string;
} & Partial<Pick<LinkProps, 'to'>>;
export const CreateButton = ({ title, to }: CreateButtonProps) => {
const isXSScreen = useMediaQuery<BackstageTheme>(theme =>
theme.breakpoints.down('xs'),
);
if (!to) {
return null;
}
return isXSScreen ? (
<IconButton
component={RouterLink}
color="primary"
title={title}
size="small"
to={to}
>
<AddCircleOutline />
</IconButton>
) : (
<Button component={RouterLink} variant="contained" color="primary" to={to}>
{title}
</Button>
);
};
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { CreateComponentButton } from './CreateComponentButton';
export { CreateButton } from './CreateButton';
@@ -15,21 +15,24 @@
*/
import { useApp } from '@backstage/core-plugin-api';
import { HelpIcon } from '../../icons';
import { BackstageTheme } from '@backstage/theme';
import {
Box,
Button,
DialogActions,
IconButton,
List,
ListItem,
ListItemIcon,
ListItemText,
Typography,
makeStyles,
Popover,
Typography,
useMediaQuery,
} from '@material-ui/core';
import React, { MouseEventHandler, useState } from 'react';
import { SupportItem, SupportItemLink, useSupportConfig } from '../../hooks';
import { HelpIcon } from '../../icons';
import { Link } from '../Link';
type SupportButtonProps = {
@@ -83,6 +86,9 @@ export const SupportButton = ({ title, children }: SupportButtonProps) => {
const [popoverOpen, setPopoverOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
const classes = useStyles();
const isSmallScreen = useMediaQuery<BackstageTheme>(theme =>
theme.breakpoints.down('sm'),
);
const onClickHandler: MouseEventHandler = event => {
setAnchorEl(event.currentTarget);
@@ -95,15 +101,26 @@ export const SupportButton = ({ title, children }: SupportButtonProps) => {
return (
<>
<Box ml={1}>
<Button
data-testid="support-button"
color="primary"
onClick={onClickHandler}
startIcon={<HelpIcon />}
>
Support
</Button>
<Box display="flex" ml={1}>
{isSmallScreen ? (
<IconButton
color="primary"
size="small"
onClick={onClickHandler}
data-testid="support-button"
>
<HelpIcon />
</IconButton>
) : (
<Button
data-testid="support-button"
color="primary"
onClick={onClickHandler}
startIcon={<HelpIcon />}
>
Support
</Button>
)}
</Box>
<Popover
data-testid="support-button-popover"
@@ -19,6 +19,7 @@ export * from './Avatar';
export * from './Button';
export * from './CodeSnippet';
export * from './CopyTextButton';
export * from './CreateButton';
export * from './DependencyGraph';
export * from './DismissableBanner';
export * from './EmptyState';
@@ -31,12 +31,11 @@ const useStyles = (props: ContentHeaderProps) =>
flexWrap: 'wrap',
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: theme.spacing(1),
marginBottom: theme.spacing(2),
textAlign: props.textAlign,
},
leftItemsBox: {
flex: '1 1 auto',
marginBottom: theme.spacing(1),
minWidth: 0,
overflow: 'visible',
},
@@ -47,13 +46,13 @@ const useStyles = (props: ContentHeaderProps) =>
flexWrap: 'wrap',
alignItems: 'center',
marginLeft: theme.spacing(1),
marginBottom: theme.spacing(1),
minWidth: 0,
overflow: 'visible',
},
description: {},
title: {
display: 'inline-flex',
marginBottom: 0,
},
}));
@@ -17,6 +17,7 @@
import {
Content,
ContentHeader,
CreateButton,
PageWithHeader,
SupportButton,
TableColumn,
@@ -39,9 +40,7 @@ import {
UserListFilterKind,
UserListPicker,
} from '@backstage/plugin-catalog-react';
import { Button } from '@material-ui/core';
import React from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { createComponentRouteRef } from '../../routes';
const defaultColumns: TableColumn<CatalogTableRow>[] = [
@@ -63,11 +62,11 @@ export const ApiExplorerPage = ({
initiallySelectedFilter = 'all',
columns,
}: ApiExplorerPageProps) => {
const createComponentLink = useRouteRef(createComponentRouteRef);
const configApi = useApi(configApiRef);
const generatedSubtitle = `${
configApi.getOptionalString('organization.name') ?? 'Backstage'
} API Explorer`;
const createComponentLink = useRouteRef(createComponentRouteRef);
return (
<PageWithHeader
@@ -78,16 +77,10 @@ export const ApiExplorerPage = ({
>
<Content>
<ContentHeader title="">
{createComponentLink && (
<Button
variant="contained"
color="primary"
component={RouterLink}
to={createComponentLink()}
>
Register Existing API
</Button>
)}
<CreateButton
title="Register Existing API"
to={createComponentLink?.()}
/>
<SupportButton>All your APIs</SupportButton>
</ContentHeader>
<EntityListProvider>
-5
View File
@@ -160,11 +160,6 @@ export type CatalogTableRow = {
};
};
// Warning: (ae-missing-release-tag) "CreateComponentButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const CreateComponentButton: () => JSX.Element | null;
// Warning: (ae-missing-release-tag) "createMetadataDescriptionColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -17,12 +17,13 @@
import {
Content,
ContentHeader,
CreateButton,
PageWithHeader,
SupportButton,
TableColumn,
TableProps,
} from '@backstage/core-components';
import { configApiRef, useApi } from '@backstage/core-plugin-api';
import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
import {
EntityKindPicker,
EntityLifecyclePicker,
@@ -34,9 +35,9 @@ import {
UserListPicker,
} from '@backstage/plugin-catalog-react';
import React from 'react';
import { createComponentRouteRef } from '../../routes';
import { CatalogTable } from '../CatalogTable';
import { EntityRow } from '../CatalogTable/types';
import { CreateComponentButton } from '../CreateComponentButton';
import {
FilteredEntityLayout,
EntityListContainer,
@@ -56,12 +57,16 @@ export const CatalogPage = ({
}: CatalogPageProps) => {
const orgName =
useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';
const createComponentLink = useRouteRef(createComponentRouteRef);
return (
<PageWithHeader title={`${orgName} Catalog`} themeId="home">
<Content>
<ContentHeader title="Components">
<CreateComponentButton />
<CreateButton
title="Create Component"
to={createComponentLink && createComponentLink()}
/>
<SupportButton>All your software catalog entities</SupportButton>
</ContentHeader>
<EntityListProvider>
@@ -1,36 +0,0 @@
/*
* Copyright 2021 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 React from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { Button } from '@material-ui/core';
import { createComponentRouteRef } from '../../routes';
import { useRouteRef } from '@backstage/core-plugin-api';
export const CreateComponentButton = () => {
const createComponentLink = useRouteRef(createComponentRouteRef);
return createComponentLink ? (
<Button
component={RouterLink}
variant="contained"
color="primary"
to={createComponentLink()}
>
Create Component
</Button>
) : null;
};
-1
View File
@@ -20,7 +20,6 @@ export * from './components/CatalogResultListItem';
export { CatalogTable } from './components/CatalogTable';
export type { EntityRow as CatalogTableRow } from './components/CatalogTable';
export * from './components/CatalogTable/columns';
export * from './components/CreateComponentButton';
export * from './components/EntityLayout';
export * from './components/EntityOrphanWarning';
export * from './components/EntityProcessingErrorsPanel';
@@ -17,6 +17,7 @@
import {
Content,
ContentHeader,
CreateButton,
Header,
Lifecycle,
Page,
@@ -30,9 +31,8 @@ import {
EntityTagPicker,
UserListPicker,
} from '@backstage/plugin-catalog-react';
import { Button, makeStyles } from '@material-ui/core';
import { makeStyles } from '@material-ui/core';
import React from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { registerComponentRouteRef } from '../../routes';
import { TemplateList } from '../TemplateList';
import { TemplateTypePicker } from '../TemplateTypePicker';
@@ -64,16 +64,10 @@ export const ScaffolderPageContents = () => {
/>
<Content>
<ContentHeader title="Available Templates">
{registerComponentLink && (
<Button
component={RouterLink}
variant="contained"
color="primary"
to={registerComponentLink()}
>
Register Existing Component
</Button>
)}
<CreateButton
title="Register Existing Component"
to={registerComponentLink && registerComponentLink()}
/>
<SupportButton>
Create new software components using standard templates. Different
templates create different kinds of components (services, websites,