From 190f11c8f721bb78b2b2aa632f6453df753a8d8e Mon Sep 17 00:00:00 2001 From: Sebastian Qvarfordt Date: Mon, 4 May 2020 11:10:35 +0200 Subject: [PATCH] Table component with filter and search (#600) * Initial table component with storybook example * Moved dependencies to package/core * Removed dependency to @backstage/core from base package.json * Clean up some examples and remove type from columns, replacing with property align instead * Removed more unused stuff and added toggle for filter input * Fixed some lint issues * Added example with material-table * Convert column array passed into MaterialTable Backstage component into MT column array. Allow multiple values in one cell * Removed subheader from MT * Nicer double value cell * Added custom sorting to example * Cleaned up stories a bit * Setting field instead of customSort * Improve styling. Still needs better theme integration * Using more colors from theme * Fixed typing issue * Removed react-table implementation and cleaned up material-table implementation * Fixed some type issues * Fixed lint issues --- packages/app/src/components/Root/Root.tsx | 2 +- packages/core/package.json | 1 + packages/core/src/api/app/AppBuilder.tsx | 2 +- .../core/src/components/Status/Status.tsx | 16 +- .../src/components/Table/SubvalueCell.tsx | 47 +++++ .../src/components/Table/Table.stories.tsx | 143 +++++++++++++ .../core/src/components/Table/Table.test.tsx | 50 +++++ packages/core/src/components/Table/Table.tsx | 192 ++++++++++++++++++ packages/core/src/components/Table/index.ts | 18 ++ .../core/src/layout/ErrorPage/ErrorPage.tsx | 2 +- .../core/src/layout/InfoCard/InfoCard.tsx | 8 +- packages/storybook/.storybook/main.js | 2 +- .../explore/src/components/ExploreCard.tsx | 2 +- .../src/components/ExplorePluginPage.tsx | 2 +- .../GraphiQLBrowser/GraphiQLBrowser.tsx | 2 +- .../src/inventory/AggregatorInventory.ts | 4 +- .../src/inventory/StaticInventory.ts | 2 +- plugins/inventory-backend/src/run.ts | 2 +- .../src/components/Audit/AuditRow.tsx | 19 +- .../components/AuditList/AuditListTable.tsx | 13 +- .../src/components/CreateAudit/index.tsx | 9 +- plugins/lighthouse/src/utils.ts | 8 +- .../src/pages/_document.tsx | 2 +- .../src/components/ScaffolderPage/index.tsx | 2 +- yarn.lock | 151 +++++++++++++- 25 files changed, 649 insertions(+), 52 deletions(-) create mode 100644 packages/core/src/components/Table/SubvalueCell.tsx create mode 100644 packages/core/src/components/Table/Table.stories.tsx create mode 100644 packages/core/src/components/Table/Table.test.tsx create mode 100644 packages/core/src/components/Table/Table.tsx create mode 100644 packages/core/src/components/Table/index.ts diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index a8c4cd3382..7ef3a5a22f 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -84,7 +84,7 @@ const Root: FC<{}> = ({ children }) => ( - + diff --git a/packages/core/package.json b/packages/core/package.json index 1d4372f15c..107cba0196 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -45,6 +45,7 @@ "classnames": "^2.2.6", "clsx": "^1.1.0", "lodash": "^4.17.15", + "material-table": "^1.57.2", "prop-types": "^15.7.2", "rc-progress": "^2.5.2", "react": "^16.12.0", diff --git a/packages/core/src/api/app/AppBuilder.tsx b/packages/core/src/api/app/AppBuilder.tsx index 0af21f5c8d..94d6df1b3d 100644 --- a/packages/core/src/api/app/AppBuilder.tsx +++ b/packages/core/src/api/app/AppBuilder.tsx @@ -118,7 +118,7 @@ export default class AppBuilder { {routes} ( + render={(props) => ( )} /> diff --git a/packages/core/src/components/Status/Status.tsx b/packages/core/src/components/Status/Status.tsx index 99109bfa21..a232aceb62 100644 --- a/packages/core/src/components/Status/Status.tsx +++ b/packages/core/src/components/Status/Status.tsx @@ -19,7 +19,7 @@ import { BackstageTheme } from '@backstage/theme'; import classNames from 'classnames'; import React, { FC } from 'react'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ status: { width: 12, height: 12, @@ -55,7 +55,7 @@ const useStyles = makeStyles(theme => ({ }, })); -export const StatusOK: FC<{}> = props => { +export const StatusOK: FC<{}> = (props) => { const classes = useStyles(props); return ( = props => { ); }; -export const StatusWarning: FC<{}> = props => { +export const StatusWarning: FC<{}> = (props) => { const classes = useStyles(props); return ( = props => { ); }; -export const StatusError: FC<{}> = props => { +export const StatusError: FC<{}> = (props) => { const classes = useStyles(props); return ( = props => { ); }; -export const StatusNA: FC<{}> = props => ( +export const StatusNA: FC<{}> = (props) => ( N/A ); -export const StatusPending: FC<{}> = props => { +export const StatusPending: FC<{}> = (props) => { const classes = useStyles(props); return ( = props => { ); }; -export const StatusRunning: FC<{}> = props => { +export const StatusRunning: FC<{}> = (props) => { const classes = useStyles(props); return ( = props => { ); }; -export const StatusFailed: FC<{}> = props => { +export const StatusFailed: FC<{}> = (props) => { const classes = useStyles(props); return ( (theme => ({ + value: { + marginBottom: '6px', + }, + subvalue: { + color: theme.palette.textSubtle, + fontWeight: 'normal', + }, +})); + +type SubvalueCellProps = { + value: React.ReactNode; + subvalue: React.ReactNode; +}; + +const SubvalueCell: FC = ({ value, subvalue }) => { + const classes = useSubvalueCellStyles(); + + return ( + <> +
{value}
+
{subvalue}
+ + ); +}; + +export default SubvalueCell; diff --git a/packages/core/src/components/Table/Table.stories.tsx b/packages/core/src/components/Table/Table.stories.tsx new file mode 100644 index 0000000000..b1a886ddc8 --- /dev/null +++ b/packages/core/src/components/Table/Table.stories.tsx @@ -0,0 +1,143 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 Table, { SubvalueCell, TableColumn } from './'; + +export default { + title: 'Table', + component: Table, +}; + +const generateTestData: (number: number) => Array<{}> = (rows = 20) => { + const data: Array<{}> = []; + while (data.length <= rows) { + data.push({ + col1: `Some value ${data.length}`, + col2: `More data ${data.length}`, + subvalue: `Subvalue ${data.length}`, + number: Math.floor(Math.random() * 1000), + date: new Date(Math.random() * 10000000000000), + }); + } + + return data; +}; + +const testData100 = generateTestData(100); + +export const DefaultTable = () => { + const columns: TableColumn[] = [ + { + title: 'Column 1', + field: 'col1', + highlight: true, + }, + { + title: 'Column 2', + field: 'col2', + }, + { + title: 'Numeric value', + field: 'number', + type: 'numeric', + }, + { + title: 'A Date', + field: 'date', + type: 'date', + }, + ]; + + return ( + + ); +}; + +export const HiddenSearchTable = () => { + const columns: TableColumn[] = [ + { + title: 'Column 1', + field: 'col1', + highlight: true, + }, + { + title: 'Column 2', + field: 'col2', + }, + { + title: 'Numeric value', + field: 'number', + type: 'numeric', + }, + { + title: 'A Date', + field: 'date', + type: 'date', + }, + ]; + + return ( +
+ ); +}; + +export const SubvalueTable = () => { + const columns: TableColumn[] = [ + { + title: 'Column 1', + customFilterAndSearch: ( + query, + row: any, // Only needed if you want subvalue searchable + ) => + `${row.col1} ${row.subvalue}` + .toUpperCase() + .includes(query.toUpperCase()), + field: 'col1', + highlight: true, + render: (row: any): React.ReactNode => ( + + ), + }, + { + title: 'Column 2', + field: 'col2', + }, + { + title: 'Numeric value', + field: 'number', + type: 'numeric', + }, + { + title: 'A Date', + field: 'date', + type: 'date', + }, + ]; + + return ( +
+ ); +}; diff --git a/packages/core/src/components/Table/Table.test.tsx b/packages/core/src/components/Table/Table.test.tsx new file mode 100644 index 0000000000..f6801359eb --- /dev/null +++ b/packages/core/src/components/Table/Table.test.tsx @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 } from '@testing-library/react'; +import { wrapInTestApp } from '@backstage/test-utils'; +import Table from './'; + +const minProps = { + columns: [ + { + title: 'Column 1', + field: 'col1', + }, + { + title: 'Column 2', + field: 'col2', + }, + ], + data: [ + { + col1: 'first value, first row', + col2: 'second value, first row', + }, + { + col1: 'first value, second row', + col2: 'second value, second row', + }, + ], +}; + +describe('
', () => { + it('renders without exploding', () => { + const rendered = render(wrapInTestApp(
)); + expect(rendered.getByText('second value, second row')).toBeInTheDocument(); + }); +}); diff --git a/packages/core/src/components/Table/Table.tsx b/packages/core/src/components/Table/Table.tsx new file mode 100644 index 0000000000..a9a55ae763 --- /dev/null +++ b/packages/core/src/components/Table/Table.tsx @@ -0,0 +1,192 @@ +/* + * Copyright 2020 Spotify AB + * + * 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, { FC, forwardRef } from 'react'; +import MTable, { + MTableCell, + MTableHeader, + MTableToolbar, + MaterialTableProps, + Options, + Column, +} from 'material-table'; +import { BackstageTheme } from '@backstage/theme'; +import { makeStyles } from '@material-ui/core'; + +// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51 +import { + AddBox, + ArrowUpward, + Check, + ChevronLeft, + ChevronRight, + Clear, + DeleteOutline, + Edit, + FilterList, + FirstPage, + LastPage, + Remove, + SaveAlt, + Search, + ViewColumn, +} from '@material-ui/icons'; + +const tableIcons = { + Add: forwardRef((props, ref: React.Ref) => ( + + )), + Check: forwardRef((props, ref: React.Ref) => ( + + )), + Clear: forwardRef((props, ref: React.Ref) => ( + + )), + Delete: forwardRef((props, ref: React.Ref) => ( + + )), + DetailPanel: forwardRef((props, ref: React.Ref) => ( + + )), + Edit: forwardRef((props, ref: React.Ref) => ( + + )), + Export: forwardRef((props, ref: React.Ref) => ( + + )), + Filter: forwardRef((props, ref: React.Ref) => ( + + )), + FirstPage: forwardRef((props, ref: React.Ref) => ( + + )), + LastPage: forwardRef((props, ref: React.Ref) => ( + + )), + NextPage: forwardRef((props, ref: React.Ref) => ( + + )), + PreviousPage: forwardRef((props, ref: React.Ref) => ( + + )), + ResetSearch: forwardRef((props, ref: React.Ref) => ( + + )), + Search: forwardRef((props, ref: React.Ref) => ( + + )), + SortArrow: forwardRef((props, ref: React.Ref) => ( + + )), + ThirdStateCheck: forwardRef((props, ref: React.Ref) => ( + + )), + ViewColumn: forwardRef((props, ref: React.Ref) => ( + + )), +}; + +const useCellStyles = makeStyles(theme => ({ + root: { + color: theme.palette.grey[500], + padding: theme.spacing(0, 2, 0, 2.5), + height: '56px', + }, +})); + +const useHeaderStyles = makeStyles(theme => ({ + header: { + padding: theme.spacing(1, 2, 1, 2.5), + borderTop: `1px solid ${theme.palette.grey.A100}`, + borderBottom: `1px solid ${theme.palette.grey.A100}`, + color: theme.palette.textSubtle, + fontWeight: 'bold', + position: 'static', + }, +})); + +const useToolbarStyles = makeStyles(theme => ({ + root: { + padding: theme.spacing(3, 0, 2.5, 2.5), + }, + title: { + '& > h6': { + fontWeight: 'bold', + }, + }, +})); + +const convertColumns = (columns: TableColumn[]): TableColumn[] => { + return columns.map(column => { + const headerStyle: React.CSSProperties = {}; + const cellStyle: React.CSSProperties = {}; + + if (column.highlight) { + headerStyle.color = '#000000'; + cellStyle.fontWeight = 'bold'; + } + + return { + ...column, + headerStyle, + cellStyle, + }; + }); +}; + +export interface TableColumn extends Column<{}> { + highlight?: boolean; +} + +export interface TableProps extends MaterialTableProps<{}> { + columns: TableColumn[]; +} + +const Table: FC = ({ columns, options, ...props }) => { + const cellClasses = useCellStyles(); + const headerClasses = useHeaderStyles(); + const toolbarClasses = useToolbarStyles(); + + const MTColumns = convertColumns(columns); + + const defaultOptions: Options = { + headerStyle: { + textTransform: 'uppercase', + }, + }; + + return ( + ( + + ), + Header: headerProps => ( + + ), + Toolbar: toolbarProps => ( + + ), + }} + options={{ ...defaultOptions, ...options }} + columns={MTColumns} + icons={tableIcons} + {...props} + /> + ); +}; + +export default Table; diff --git a/packages/core/src/components/Table/index.ts b/packages/core/src/components/Table/index.ts new file mode 100644 index 0000000000..e85aac3a01 --- /dev/null +++ b/packages/core/src/components/Table/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { default, TableColumn } from './Table'; +export { default as SubvalueCell } from './SubvalueCell'; diff --git a/packages/core/src/layout/ErrorPage/ErrorPage.tsx b/packages/core/src/layout/ErrorPage/ErrorPage.tsx index ea593dbb49..49b79ef925 100644 --- a/packages/core/src/layout/ErrorPage/ErrorPage.tsx +++ b/packages/core/src/layout/ErrorPage/ErrorPage.tsx @@ -28,7 +28,7 @@ interface IErrorPageProps { }; } -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ container: { padding: theme.spacing(8), }, diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx index fe2bbfa1ce..7077167828 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.tsx @@ -27,18 +27,18 @@ import { import ErrorBoundary from 'layout/ErrorBoundary/ErrorBoundary'; import BottomLink, { Props as BottomLinkProps } from '../BottomLink'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ header: { padding: theme.spacing(2, 2, 2, 2.5), }, })); -const BoldHeader = withStyles(theme => ({ +const BoldHeader = withStyles((theme) => ({ title: { fontWeight: 700 }, subheader: { paddingTop: theme.spacing(1) }, }))(CardHeader); -const CardActionsTopRight = withStyles(theme => ({ +const CardActionsTopRight = withStyles((theme) => ({ root: { display: 'inline-block', padding: theme.spacing(8, 8, 0, 0), @@ -154,7 +154,7 @@ const InfoCard: FC = ({ if (variant) { const variants = variant.split(/[\s]+/g); - variants.forEach(name => { + variants.forEach((name) => { calculatedStyle = { ...calculatedStyle, ...VARIANT_STYLES.card[name as keyof typeof VARIANT_STYLES['card']], diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js index 5a3eafa532..c187dc5f56 100644 --- a/packages/storybook/.storybook/main.js +++ b/packages/storybook/.storybook/main.js @@ -11,7 +11,7 @@ module.exports = { '@storybook/addon-storysource', 'storybook-dark-mode/register', ], - webpackFinal: async config => { + webpackFinal: async (config) => { const coreSrc = path.resolve(__dirname, '../../core/src'); config.resolve.alias = { diff --git a/plugins/explore/src/components/ExploreCard.tsx b/plugins/explore/src/components/ExploreCard.tsx index 9c61e9bea8..af6eca61b7 100644 --- a/plugins/explore/src/components/ExploreCard.tsx +++ b/plugins/explore/src/components/ExploreCard.tsx @@ -28,7 +28,7 @@ import { } from '@material-ui/core'; import { BackstageTheme } from '@backstage/theme'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ card: { display: 'flex', flexDirection: 'column', diff --git a/plugins/explore/src/components/ExplorePluginPage.tsx b/plugins/explore/src/components/ExplorePluginPage.tsx index 7b5fc81a30..48a0f90c32 100644 --- a/plugins/explore/src/components/ExplorePluginPage.tsx +++ b/plugins/explore/src/components/ExplorePluginPage.tsx @@ -27,7 +27,7 @@ import { import ExploreCard, { CardData } from './ExploreCard'; import { BackstageTheme } from '@backstage/theme'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ container: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, 296px)', diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx index c5a003a496..5885183b01 100644 --- a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx +++ b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx @@ -24,7 +24,7 @@ import { BackstageTheme } from '@backstage/theme'; const GraphiQL = React.lazy(() => import('graphiql')); -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ root: { height: '100%', display: 'flex', diff --git a/plugins/inventory-backend/src/inventory/AggregatorInventory.ts b/plugins/inventory-backend/src/inventory/AggregatorInventory.ts index 3f1ca0f5de..babea8c7b9 100644 --- a/plugins/inventory-backend/src/inventory/AggregatorInventory.ts +++ b/plugins/inventory-backend/src/inventory/AggregatorInventory.ts @@ -20,13 +20,13 @@ export class AggregatorInventory implements Inventory { inventories: Inventory[] = []; list(): Promise> { - return Promise.all(this.inventories.map(i => i.list())).then(lists => + return Promise.all(this.inventories.map((i) => i.list())).then((lists) => lists.flat(), ); } item(id: string): Promise { - return this.list().then(items => items.find(i => i.id === id)); + return this.list().then((items) => items.find((i) => i.id === id)); } enlist(inventory: Inventory) { diff --git a/plugins/inventory-backend/src/inventory/StaticInventory.ts b/plugins/inventory-backend/src/inventory/StaticInventory.ts index cd4fa2b7d5..fdfc2afde7 100644 --- a/plugins/inventory-backend/src/inventory/StaticInventory.ts +++ b/plugins/inventory-backend/src/inventory/StaticInventory.ts @@ -24,6 +24,6 @@ export class StaticInventory implements Inventory { } item(id: string): Promise { - return this.list().then(items => items.find(i => i.id === id)); + return this.list().then((items) => items.find((i) => i.id === id)); } } diff --git a/plugins/inventory-backend/src/run.ts b/plugins/inventory-backend/src/run.ts index 979827c40f..9694a60c33 100644 --- a/plugins/inventory-backend/src/run.ts +++ b/plugins/inventory-backend/src/run.ts @@ -23,7 +23,7 @@ startServer({ ? Boolean(process.env.PLUGIN_CORS) : false, logger: getRootLogger(), -}).catch(err => { +}).catch((err) => { getRootLogger().error(err); process.exit(1); }); diff --git a/plugins/lighthouse/src/components/Audit/AuditRow.tsx b/plugins/lighthouse/src/components/Audit/AuditRow.tsx index c42e6a8538..71668138f4 100644 --- a/plugins/lighthouse/src/components/Audit/AuditRow.tsx +++ b/plugins/lighthouse/src/components/Audit/AuditRow.tsx @@ -14,17 +14,16 @@ * limitations under the License. */ import React, { FC } from 'react'; -import { - Link, - TableCell, - TableRow, -} from '@material-ui/core'; +import { Link, TableCell, TableRow } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import { TrendLine } from '@backstage/core'; +import { Website } from '../../api'; import { - Website, -} from '../../api'; -import { formatTime, CATEGORIES, CATEGORY_LABELS, SparklinesDataByCategory } from '../../utils'; + formatTime, + CATEGORIES, + CATEGORY_LABELS, + SparklinesDataByCategory, +} from '../../utils'; import AuditStatusIcon from '../AuditStatusIcon'; const useStyles = makeStyles(theme => ({ @@ -76,9 +75,7 @@ export const AuditRow: FC<{ {website.lastAudit.status.toLowerCase()} - - {formatTime(website.lastAudit.timeCreated)} - + {formatTime(website.lastAudit.timeCreated)} ); }; diff --git a/plugins/lighthouse/src/components/AuditList/AuditListTable.tsx b/plugins/lighthouse/src/components/AuditList/AuditListTable.tsx index 778eb71fb5..082433a550 100644 --- a/plugins/lighthouse/src/components/AuditList/AuditListTable.tsx +++ b/plugins/lighthouse/src/components/AuditList/AuditListTable.tsx @@ -23,11 +23,14 @@ import { TableRow, } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; +import { Website } from '../../api'; import { - Website, -} from '../../api'; -import { CATEGORIES, CATEGORY_LABELS, SparklinesDataByCategory, buildSparklinesDataForItem } from '../../utils'; -import Audit from '../Audit' + CATEGORIES, + CATEGORY_LABELS, + SparklinesDataByCategory, + buildSparklinesDataForItem, +} from '../../utils'; +import Audit from '../Audit'; const useStyles = makeStyles(theme => ({ table: { @@ -51,7 +54,7 @@ export const AuditListTable: FC<{ items: Website[] }> = ({ items }) => { () => items.reduce( (res, item) => ({ - ...res, + ...res, [item.url]: buildSparklinesDataForItem(item), }), {}, diff --git a/plugins/lighthouse/src/components/CreateAudit/index.tsx b/plugins/lighthouse/src/components/CreateAudit/index.tsx index 8ff0ce5ea8..19db33791b 100644 --- a/plugins/lighthouse/src/components/CreateAudit/index.tsx +++ b/plugins/lighthouse/src/components/CreateAudit/index.tsx @@ -84,7 +84,14 @@ const CreateAudit: FC<{}> = () => { } finally { setSubmitting(false); } - }, [url, emulatedFormFactor, lighthouseApi, setSubmitting, errorApi, history]); + }, [ + url, + emulatedFormFactor, + lighthouseApi, + setSubmitting, + errorApi, + history, + ]); return ( diff --git a/plugins/lighthouse/src/utils.ts b/plugins/lighthouse/src/utils.ts index 1546521083..cc09b52f4f 100644 --- a/plugins/lighthouse/src/utils.ts +++ b/plugins/lighthouse/src/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { useLocation } from 'react-router-dom'; -import {Website, Audit, LighthouseCategoryId, AuditCompleted} from './api' +import { Website, Audit, LighthouseCategoryId, AuditCompleted } from './api'; export function useQuery(): URLSearchParams { return new URLSearchParams(useLocation().search); } @@ -45,7 +45,9 @@ export const CATEGORY_LABELS: Record = { }; export type SparklinesDataByCategory = Record; -export function buildSparklinesDataForItem(item: Website): SparklinesDataByCategory { +export function buildSparklinesDataForItem( + item: Website, +): SparklinesDataByCategory { return item.audits .filter( (audit: Audit): audit is AuditCompleted => audit.status === 'COMPLETED', @@ -63,4 +65,4 @@ export function buildSparklinesDataForItem(item: Website): SparklinesDataByCateg return scores; }, {} as SparklinesDataByCategory); -} \ No newline at end of file +} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.componentId}}/src/pages/_document.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.componentId}}/src/pages/_document.tsx index 210de6412c..9b01a6a74c 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.componentId}}/src/pages/_document.tsx +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.componentId}}/src/pages/_document.tsx @@ -20,7 +20,7 @@ export default class MyDocument extends Document { try { ctx.renderPage = () => originalRenderPage({ - enhanceApp: (App: any) => props => + enhanceApp: (App: any) => (props) => sheet.collectStyles(), }); diff --git a/plugins/scaffolder/src/components/ScaffolderPage/index.tsx b/plugins/scaffolder/src/components/ScaffolderPage/index.tsx index e6adaca099..5cfeb122ce 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/index.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/index.tsx @@ -33,7 +33,7 @@ const ScaffolderPage: React.FC<{}> = () => {
- {STATIC_DATA.map(item => { + {STATIC_DATA.map((item) => { return (