Reorganize Drawer & move drawer state to EntityListProvider

Signed-off-by: Philipp Hugenroth <philipph@spotify.com>
This commit is contained in:
Philipp Hugenroth
2021-07-14 11:10:08 +02:00
parent 2934eb3a50
commit f3b58ecd8e
7 changed files with 97 additions and 94 deletions
@@ -84,6 +84,9 @@ export type EntityListContextProps<
*/
queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;
showFiltersDrawer: boolean;
toggleFiltersDrawer: (showFiltersDrawer: boolean) => void;
loading: boolean;
error?: Error;
};
@@ -108,6 +111,8 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>({
const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(
{} as EntityFilters,
);
// Show
const [showFiltersDrawer, toggleFiltersDrawer] = useState<boolean>(false);
const [outputState, setOutputState] = useState<OutputState<EntityFilters>>({
appliedFilters: {} as EntityFilters,
entities: [],
@@ -203,6 +208,8 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>({
updateFilters,
queryParameters: outputState.queryParameters,
loading,
showFiltersDrawer,
toggleFiltersDrawer,
error,
}}
>
@@ -16,8 +16,6 @@
import {
Content,
ContentHeader,
ContentHeaderTitle,
PageWithHeader,
SupportButton,
TableColumn,
@@ -34,15 +32,16 @@ import {
UserListFilterKind,
UserListPicker,
} from '@backstage/plugin-catalog-react';
import { BackstageTheme } from '@backstage/theme';
import { Box, Grid, IconButton, useMediaQuery } from '@material-ui/core';
import FilterListIcon from '@material-ui/icons/FilterList';
import React, { useState } from 'react';
import React from 'react';
import { CatalogTable } from '../CatalogTable';
import { EntityRow } from '../CatalogTable/types';
import { CreateComponentButton } from '../CreateComponentButton/CreateComponentButton';
import { FilterContainer } from '../FilterContainer';
import { FilteredTableLayout } from '../FilteredTableLayout';
import {
FilteredTableLayout,
TableContainer,
FilterContainer,
} from '../FilteredTableLayout';
import { CatalogPageHeader } from './CatalogPageHeader';
export type CatalogPageProps = {
initiallySelectedFilter?: UserListFilterKind;
@@ -50,74 +49,24 @@ export type CatalogPageProps = {
actions?: TableProps<EntityRow>['actions'];
};
const CatalogPageHeaderAction = ({
showFilter,
toggleFilter,
isMidSizeScreen,
}: {
showFilter: boolean;
toggleFilter: (showFilter: boolean) => void;
isMidSizeScreen: boolean;
}) =>
isMidSizeScreen ? (
<Box display="flex" alignItems="center">
<ContentHeaderTitle title="Components" />
<IconButton onClick={() => toggleFilter(!showFilter)}>
<FilterListIcon />
</IconButton>
</Box>
) : (
<ContentHeaderTitle title="Components" />
);
const CatalogPageHeader = ({
children,
...props
}: React.PropsWithChildren<{
showFilter: boolean;
toggleFilter: (showFilter: boolean) => void;
isMidSizeScreen: boolean;
}>) => {
return (
<ContentHeader
titleComponent={() => <CatalogPageHeaderAction {...props} />}
>
{children}
</ContentHeader>
);
};
export const CatalogPage = ({
columns,
actions,
initiallySelectedFilter = 'owned',
}: CatalogPageProps) => {
const [showFilter, toggleFilter] = useState<boolean>(false);
const isMidSizeScreen = useMediaQuery<BackstageTheme>(theme =>
theme.breakpoints.down('md'),
);
const orgName =
useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';
return (
<PageWithHeader title={`${orgName} Catalog`} themeId="home">
<Content>
<CatalogPageHeader
showFilter={showFilter}
toggleFilter={toggleFilter}
isMidSizeScreen={isMidSizeScreen}
>
<CreateComponentButton />
<SupportButton>All your software catalog entities</SupportButton>
</CatalogPageHeader>
<EntityListProvider>
<CatalogPageHeader>
<CreateComponentButton />
<SupportButton>All your software catalog entities</SupportButton>
</CatalogPageHeader>
<FilteredTableLayout>
<FilterContainer
showFilter={showFilter}
toggleFilter={toggleFilter}
isMidSizeScreen={isMidSizeScreen}
>
<FilterContainer>
<EntityKindPicker initialFilter="component" hidden />
<EntityTypePicker />
<UserListPicker initialFilter={initiallySelectedFilter} />
@@ -125,9 +74,9 @@ export const CatalogPage = ({
<EntityLifecyclePicker />
<EntityTagPicker />
</FilterContainer>
<Grid id="drawer-container" item xs={12} lg={10}>
<TableContainer>
<CatalogTable columns={columns} actions={actions} />
</Grid>
</TableContainer>
</FilteredTableLayout>
</EntityListProvider>
</Content>
@@ -0,0 +1,50 @@
/*
* 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 { ContentHeader, ContentHeaderTitle } from '@backstage/core-components';
import { useEntityListProvider } from '@backstage/plugin-catalog-react';
import { BackstageTheme } from '@backstage/theme';
import { Box, IconButton, useMediaQuery } from '@material-ui/core';
import FilterListIcon from '@material-ui/icons/FilterList';
import React from 'react';
const CatalogPageHeaderAction = () => {
const isMidSizeScreen = useMediaQuery<BackstageTheme>(theme =>
theme.breakpoints.down('md'),
);
const { showFiltersDrawer, toggleFiltersDrawer } = useEntityListProvider();
return isMidSizeScreen ? (
<Box display="flex" alignItems="center">
<ContentHeaderTitle title="Components" />
<IconButton onClick={() => toggleFiltersDrawer(!showFiltersDrawer)}>
<FilterListIcon />
</IconButton>
</Box>
) : (
<ContentHeaderTitle title="Components" />
);
};
export const CatalogPageHeader = ({
children,
}: React.PropsWithChildren<{}>) => {
return (
<ContentHeader titleComponent={() => <CatalogPageHeaderAction />}>
{children}
</ContentHeader>
);
};
@@ -23,9 +23,7 @@ import { useRouteRef } from '@backstage/core-plugin-api';
export const CreateComponentButton = () => {
const createComponentLink = useRouteRef(createComponentRouteRef);
if (!createComponentLink) return null;
return (
return !createComponentLink ? null : (
<Button
component={RouterLink}
variant="contained"
@@ -14,44 +14,34 @@
* limitations under the License.
*/
import { Box, Drawer, Grid } from '@material-ui/core';
import { Box, Drawer, Grid, useMediaQuery } from '@material-ui/core';
import { useEntityListProvider } from '@backstage/plugin-catalog-react';
import { BackstageTheme } from '@backstage/theme';
import React from 'react';
interface IProps {
showFilter: boolean;
toggleFilter: (showFilter: boolean) => void;
isMidSizeScreen: boolean;
}
export const FilterContainer = ({ children }: React.PropsWithChildren<{}>) => {
const isMidSizeScreen = useMediaQuery<BackstageTheme>(theme =>
theme.breakpoints.down('md'),
);
const { showFiltersDrawer, toggleFiltersDrawer } = useEntityListProvider();
export const FilterContainer = ({
children,
showFilter,
toggleFilter,
isMidSizeScreen,
}: React.PropsWithChildren<IProps>) =>
isMidSizeScreen ? (
return isMidSizeScreen ? (
<Drawer
open={showFilter}
open={showFiltersDrawer}
onClose={() => {
toggleFilter(false);
toggleFiltersDrawer(false);
}}
elevation={0}
anchor="left"
disableAutoFocus
PaperProps={{
style: { position: 'absolute', width: '250px' },
}}
BackdropProps={{ style: { position: 'absolute' } }}
ModalProps={{
container: document.getElementById('drawer-container'),
disableEnforceFocus: true,
style: { position: 'absolute' },
}}
keepMounted
variant="temporary"
>
<Box m={1}>{children}</Box>
<Box m={2}>{children}</Box>
</Drawer>
) : (
<Grid item lg={2}>
{children}
</Grid>
);
};
@@ -14,4 +14,11 @@
* limitations under the License.
*/
export { FilterContainer } from './FilterContainer';
import { Grid } from '@material-ui/core';
import React from 'react';
export const TableContainer = ({ children }: React.PropsWithChildren<{}>) => (
<Grid item xs={12} lg={10}>
{children}
</Grid>
);
@@ -15,3 +15,5 @@
*/
export { FilteredTableLayout } from './FilteredTableLayout';
export { FilterContainer } from './FilterContainer';
export { TableContainer } from './TableContainer';