Added SearchBar and ScrollBar on Techradar
Signed-off-by: lmejbar <42239917+lmejbar@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/core-components': minor
|
||||
'@backstage/plugin-tech-radar': minor
|
||||
---
|
||||
|
||||
Added SearchBar to allow filtering and a scrollbar to display hidden tech
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2020 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 {
|
||||
render,
|
||||
act,
|
||||
RenderResult,
|
||||
waitFor,
|
||||
fireEvent,
|
||||
screen,
|
||||
} from '@testing-library/react';
|
||||
import { wrapInTestApp, renderInTestApp } from '@backstage/test-utils';
|
||||
import { InputTextFilter } from './InputTextFilter';
|
||||
|
||||
const SUPPORT_BUTTON_ID = 'support-button';
|
||||
const POPOVER_ID = 'support-button-popover';
|
||||
|
||||
describe('<InputTextFilter />', () => {
|
||||
// it('renders without exploding', async () => {
|
||||
// let renderResult: RenderResult;
|
||||
// await act(async () => {
|
||||
// renderResult = render(wrapInTestApp(<InputTextFilter />));
|
||||
// });
|
||||
// await waitFor(() =>
|
||||
// expect(renderResult.getByTestId(SUPPORT_BUTTON_ID)).toBeInTheDocument(),
|
||||
// );
|
||||
// });
|
||||
// it('supports passing a title', async () => {
|
||||
// await renderInTestApp(<InputTextFilter title="Custom title" />);
|
||||
// fireEvent.click(screen.getByTestId(SUPPORT_BUTTON_ID));
|
||||
// expect(screen.getByText('Custom title')).toBeInTheDocument();
|
||||
// });
|
||||
// it('shows popover on click', async () => {
|
||||
// let renderResult: RenderResult;
|
||||
// await act(async () => {
|
||||
// renderResult = render(wrapInTestApp(<InputTextFilter />));
|
||||
// });
|
||||
// let button: HTMLElement;
|
||||
// await waitFor(() => {
|
||||
// expect(renderResult.getByTestId(SUPPORT_BUTTON_ID)).toBeInTheDocument();
|
||||
// button = renderResult.getByTestId(SUPPORT_BUTTON_ID);
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(button);
|
||||
// });
|
||||
// await waitFor(() => {
|
||||
// expect(renderResult.getByTestId(POPOVER_ID)).toBeInTheDocument();
|
||||
// });
|
||||
// });
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2020 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 { makeStyles } from '@material-ui/core/styles';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
'& > *': {
|
||||
width: '50ch',
|
||||
'margin-right': '40ch',
|
||||
'margin-bottom': '1ch',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export const InputTextFilter = ({
|
||||
searchCategory,
|
||||
}: {
|
||||
searchCategory: any;
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
|
||||
const [, setSearchCategory] = React.useState('');
|
||||
|
||||
const setSearchCategoryValue = event => {
|
||||
setSearchCategory(event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<form className={classes.root} noValidate autoComplete="off">
|
||||
<TextField
|
||||
id="standard-basic"
|
||||
label="Search"
|
||||
onChange={e => {
|
||||
searchCategory(e);
|
||||
setSearchCategoryValue(e);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
export { InputTextFilter } from './InputTextFilter';
|
||||
@@ -28,6 +28,7 @@ export * from './ResponseErrorPanel';
|
||||
export * from './FeatureDiscovery';
|
||||
export * from './HeaderIconLinkRow';
|
||||
export * from './HorizontalScrollGrid';
|
||||
export * from './InputTextFilter';
|
||||
export * from './Lifecycle';
|
||||
export * from './Link';
|
||||
export * from './MarkdownContent';
|
||||
|
||||
@@ -22,7 +22,7 @@ const useStyles = makeStyles((theme: Theme) => ({
|
||||
root: {
|
||||
gridArea: 'pageContent',
|
||||
minWidth: 0,
|
||||
paddingTop: theme.spacing(3),
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingBottom: theme.spacing(3),
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(2),
|
||||
|
||||
@@ -53,6 +53,7 @@ const useStyles = (props: ContentHeaderProps) =>
|
||||
title: {
|
||||
display: 'inline-flex',
|
||||
marginBottom: 0,
|
||||
color: '#0082C3',
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -81,4 +81,5 @@ export interface TechRadarComponentProps {
|
||||
width: number;
|
||||
height: number;
|
||||
svgProps?: object;
|
||||
searchText?: string;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,29 @@ const useTechRadarLoader = (id: string | undefined) => {
|
||||
return { loading, value, error };
|
||||
};
|
||||
|
||||
const RadarComponent = (props: TechRadarComponentProps): JSX.Element => {
|
||||
const RadarComponent = (
|
||||
props: TechRadarComponentProps,
|
||||
searchText: string,
|
||||
): JSX.Element => {
|
||||
const { loading, error, value: data } = useTechRadarLoader(props.id);
|
||||
|
||||
const mapToEntries = (
|
||||
loaderResponse: TechRadarLoaderResponse | undefined,
|
||||
): Array<Entry> => {
|
||||
return loaderResponse!.entries.map(entry => {
|
||||
let filteredArray = loaderResponse!.entries;
|
||||
if (!(props.searchText === '')) {
|
||||
// Compare the name or the description with the search input text
|
||||
filteredArray = loaderResponse!.entries.filter(
|
||||
element =>
|
||||
element.title
|
||||
.toLowerCase()
|
||||
.includes(props.searchText.toLowerCase()) ||
|
||||
element.timeline[0].description
|
||||
?.toLowerCase()
|
||||
.includes(props.searchText.toLowerCase()),
|
||||
);
|
||||
}
|
||||
return filteredArray.map(entry => {
|
||||
return {
|
||||
id: entry.key,
|
||||
quadrant: loaderResponse!.quadrants.find(q => q.id === entry.quadrant)!,
|
||||
|
||||
@@ -32,21 +32,25 @@ export type Props = {
|
||||
};
|
||||
|
||||
const useStyles = makeStyles<Theme>(theme => ({
|
||||
foreignObject: {
|
||||
overflowY: 'visible',
|
||||
},
|
||||
quadrant: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
overflowY: 'visible',
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
quadrantHeading: {
|
||||
pointerEvents: 'none',
|
||||
userSelect: 'none',
|
||||
color: '#0082C3',
|
||||
marginTop: 0,
|
||||
marginBottom: theme.spacing(8 / (18 * 0.375)),
|
||||
fontSize: '18px',
|
||||
},
|
||||
rings: {
|
||||
columns: 3,
|
||||
columns: 2,
|
||||
},
|
||||
ring: {
|
||||
breakInside: 'avoid-column',
|
||||
@@ -66,6 +70,9 @@ const useStyles = makeStyles<Theme>(theme => ({
|
||||
listStylePosition: 'inside',
|
||||
marginTop: 0,
|
||||
paddingLeft: 0,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'scroll',
|
||||
fontVariantNumeric: 'proportional-nums',
|
||||
'-moz-font-feature-settings': 'pnum',
|
||||
'-webkit-font-feature-settings': 'pnum',
|
||||
@@ -221,6 +228,7 @@ const RadarLegend = (props: Props): JSX.Element => {
|
||||
y={quadrant.legendY}
|
||||
width={quadrant.legendWidth}
|
||||
height={quadrant.legendHeight}
|
||||
className={classes.foreignObject}
|
||||
data-testid="radar-quadrant"
|
||||
>
|
||||
<div className={classes.quadrant}>
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
Page,
|
||||
Header,
|
||||
SupportButton,
|
||||
InputTextFilter,
|
||||
} from '@backstage/core-components';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
@@ -45,11 +46,18 @@ export const RadarPage = ({
|
||||
...props
|
||||
}: TechRadarPageProps): JSX.Element => {
|
||||
const classes = useStyles();
|
||||
const [searchText, setSearchText] = React.useState('');
|
||||
|
||||
const searchInput = event => {
|
||||
setSearchText(event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Page themeId="tool">
|
||||
<Header title={title} subtitle={subtitle} />
|
||||
{/* <Header title={title} subtitle={subtitle} /> */}
|
||||
<Content className={classes.overflowXScroll}>
|
||||
<ContentHeader title={pageTitle}>
|
||||
<InputTextFilter searchCategory={searchInput} />
|
||||
<SupportButton>
|
||||
This is used for visualizing the official guidelines of different
|
||||
areas of software development such as languages, frameworks,
|
||||
@@ -58,7 +66,7 @@ export const RadarPage = ({
|
||||
</ContentHeader>
|
||||
<Grid container spacing={3} direction="row">
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<RadarComponent {...props} />
|
||||
<RadarComponent {...props} searchText={searchText} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
|
||||
Reference in New Issue
Block a user