Introduce initial TemplateTypePicker component in scaffolder

Co-authored-by: Tim Hansen <timbonicus@gmail.com>
Co-authored-by: Chase Rutherford-Jenkins <chaseajen@users.noreply.github.com>
Co-authored-by: Himanshu Mishra <himanshum@spotify.com>
Co-authored-by: Joe Porpeglia <josephp@spotify.com>
Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
Mike Lewis
2021-06-28 18:29:24 +01:00
parent 77186cf637
commit 2669b41f2f
4 changed files with 249 additions and 0 deletions
+1
View File
@@ -51,6 +51,7 @@
"humanize-duration": "^3.25.1",
"immer": "^9.0.1",
"json-schema": "^0.3.0",
"lodash": "^4.17.21",
"luxon": "^1.25.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
@@ -0,0 +1,134 @@
/*
* 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 { fireEvent, render, waitFor } from '@testing-library/react';
import { capitalize } from 'lodash';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { EntityTypePicker } from './EntityTypePicker';
import { MockEntityListContextProvider } from '../../testUtils/providers';
import { catalogApiRef } from '../../api';
import { EntityKindFilter, EntityTypeFilter } from '../../filters';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
const entities: Entity[] = [
{
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'component-1',
},
spec: {
type: 'service',
},
},
{
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'component-2',
},
spec: {
type: 'website',
},
},
{
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'component-3',
},
spec: {
type: 'library',
},
},
];
const apis = ApiRegistry.from([
[
catalogApiRef,
({
getEntities: jest
.fn()
.mockImplementation(() => Promise.resolve({ items: entities })),
} as unknown) as CatalogApi,
],
[
alertApiRef,
({
post: jest.fn(),
} as unknown) as AlertApi,
],
]);
describe('<EntityTypePicker/>', () => {
it('renders available entity types', async () => {
const rendered = render(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{ filters: { kind: new EntityKindFilter('component') } }}
>
<EntityTypePicker />
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(rendered.getByText('Type')).toBeInTheDocument();
const input = rendered.getByTestId('select');
fireEvent.click(input);
await waitFor(() => rendered.getByText('Service'));
entities.forEach(entity => {
expect(
rendered.getByText(capitalize(entity.spec!.type as string)),
).toBeInTheDocument();
});
});
it('sets the selected type filter', async () => {
const updateFilters = jest.fn();
const rendered = render(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{
filters: { kind: new EntityKindFilter('component') },
updateFilters,
}}
>
<EntityTypePicker />
</MockEntityListContextProvider>
</ApiProvider>,
);
const input = rendered.getByTestId('select');
fireEvent.click(input);
await waitFor(() => rendered.getByText('Service'));
fireEvent.click(rendered.getByText('Service'));
expect(updateFilters).toHaveBeenLastCalledWith({
type: new EntityTypeFilter('service'),
});
fireEvent.click(input);
fireEvent.click(rendered.getByText('All'));
expect(updateFilters).toHaveBeenLastCalledWith({ type: undefined });
});
});
@@ -0,0 +1,97 @@
/*
* 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 {
Typography,
List,
ListItem,
makeStyles,
Theme,
Checkbox,
ListItemText,
} from '@material-ui/core';
import { useEntityTypeFilter } from '@backstage/plugin-catalog-react';
import { alertApiRef, useApi } from '@backstage/core-plugin-api';
const useStyles = makeStyles<Theme>(theme => ({
checkbox: {
padding: theme.spacing(0, 1, 0, 1),
},
}));
export const TemplateTypePicker = () => {
const classes = useStyles();
const alertApi = useApi(alertApiRef);
// TODO(timbonicus): Use new setTypes returned from the hook
const { error, types, selectedType } = useEntityTypeFilter();
if (!types) return null;
if (error) {
alertApi.post({
message: `Failed to load entity types`,
severity: 'error',
});
return null;
}
return (
<>
<Typography variant="button">Categories</Typography>
<List disablePadding dense>
{types.map(type => {
const labelId = `checkbox-list-label-${type}`;
return (
<ListItem
key={type}
dense
button
onClick={() => {}}
// TODO(timbonicus): Update to use setTypes
// setSelectedCategories(
// selectedCategories.includes(type)
// ? selectedCategories.filter(
// selectedCategory => selectedCategory !== type,
// )
// : [...selectedCategories, type],
// )
// }
>
<Checkbox
edge="start"
color="primary"
// TODO: Fix me
// checked={selectedTypes.includes(type)}
checked={type === selectedType}
tabIndex={-1}
disableRipple
className={classes.checkbox}
inputProps={{ 'aria-labelledby': labelId }}
/>
<ListItemText
id={labelId}
primary={
type.charAt(0).toLocaleUpperCase('en-US') + type.slice(1)
}
/>
</ListItem>
);
})}
</List>
</>
);
};
@@ -0,0 +1,17 @@
/*
* 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.
*/
export { TemplateTypePicker } from './TemplateTypePicker';