Merge branch 'blam/react-router' of github.com:spotify/backstage into blam/react-router

* 'blam/react-router' of github.com:spotify/backstage:
  chore(catalog/swr): Removing superfluous import for useEffect
  feat(catalog/swr): simplify the code significantly. now we are talking. this library is the nutz
  feat(catalog/swr): Added a nice stale-while-revalidate pattern for fetching data
  chore(swr): Updating the yarn.lock
This commit is contained in:
blam
2020-06-12 02:25:40 +02:00
4 changed files with 23 additions and 38 deletions
+2 -2
View File
@@ -30,12 +30,12 @@
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"node-cache": "^5.1.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router": "^6.0.0-alpha.5",
"react-router-dom": "^6.0.0-alpha.5",
"react-use": "^14.2.0"
"react-use": "^14.2.0",
"swr": "^0.2.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.7",
-11
View File
@@ -19,14 +19,9 @@ import {
Location,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import Cache from 'node-cache';
import { CatalogApi, EntityCompoundName } from './types';
export class CatalogClient implements CatalogApi {
// TODO(blam): This cache is just temporary until we have GraphQL.
// And client side caching using things like React Apollo or Relay.
// There's a lot of loading states that cause flickering around the app which aren't needed.
private cache: Cache;
private apiOrigin: string;
private basePath: string;
@@ -39,7 +34,6 @@ export class CatalogClient implements CatalogApi {
}) {
this.apiOrigin = apiOrigin;
this.basePath = basePath;
this.cache = new Cache({ stdTTL: 10 });
}
private async getRequired(path: string): Promise<any> {
@@ -79,11 +73,6 @@ export class CatalogClient implements CatalogApi {
async getEntities(
filter?: Record<string, string | string[]>,
): Promise<Entity[]> {
const cachedValue = this.cache.get<Entity[]>(
`get:${JSON.stringify(filter)}`,
);
if (cachedValue) return cachedValue;
let path = `/entities`;
if (filter) {
const params = new URLSearchParams();
@@ -35,7 +35,6 @@ import Star from '@material-ui/icons/Star';
import StarOutline from '@material-ui/icons/StarBorder';
import React, { FC, useCallback, useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { useAsync } from 'react-use';
import { catalogApiRef } from '../..';
import { defaultFilter, entityFilters, filterGroups } from '../../data/filters';
import { findLocationForEntityMeta } from '../../data/utils';
@@ -45,6 +44,7 @@ import {
CatalogFilterItem,
} from '../CatalogFilter/CatalogFilter';
import { CatalogTable } from '../CatalogTable/CatalogTable';
import useStaleWhileRevalidate from 'swr';
const useStyles = makeStyles(theme => ({
contentWrapper: {
@@ -61,20 +61,21 @@ const useStyles = makeStyles(theme => ({
export const CatalogPage: FC<{}> = () => {
const catalogApi = useApi(catalogApiRef);
const {
starredEntities,
toggleStarredEntity,
isStarredEntity,
} = useStarredEntities();
const { toggleStarredEntity, isStarredEntity } = useStarredEntities();
const [selectedFilter, setSelectedFilter] = useState<CatalogFilterItem>(
defaultFilter,
);
const { value, error, loading } = useAsync(async () => {
const filter = entityFilters[selectedFilter.id];
const all = await catalogApi.getEntities();
return all.filter(e => filter(e, { isStarred: isStarredEntity(e) }));
}, [selectedFilter.id, starredEntities.size]);
const { data: entities, error } = useStaleWhileRevalidate(
['catalog/all', entityFilters[selectedFilter.id]],
async () => catalogApi.getEntities(),
);
const data =
entities?.filter(e =>
entityFilters[selectedFilter.id](e, { isStarred: isStarredEntity(e) }),
) ?? [];
const onFilterSelected = useCallback(
selected => setSelectedFilter(selected),
@@ -195,8 +196,8 @@ export const CatalogPage: FC<{}> = () => {
</div>
<CatalogTable
titlePreamble={selectedFilter.label}
entities={value || []}
loading={loading}
entities={data || []}
loading={!data && !error}
error={error}
actions={actions}
/>
+7 -12
View File
@@ -6204,11 +6204,6 @@ clone-response@^1.0.2:
dependencies:
mimic-response "^1.0.0"
clone@2.x:
version "2.1.2"
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
@@ -13254,13 +13249,6 @@ nocache@2.1.0:
resolved "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f"
integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
node-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/node-cache/-/node-cache-5.1.1.tgz#5fcc887176b23bdcd19cd1461b9544d2d501e786"
integrity sha512-bJ9nH25Z51HG2QIu66K4dMVyMs6o8bNQpviDnXzG+O/gfNxPU9IpIig0j4pzlO707GcGZ6QA4rWhlRxjJsjnZw==
dependencies:
clone "2.x"
node-cleanup@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
@@ -17706,6 +17694,13 @@ svgo@^1.0.0, svgo@^1.2.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
swr@^0.2.2:
version "0.2.2"
resolved "https://registry.npmjs.org/swr/-/swr-0.2.2.tgz#6e1b3e5c0e545c4fdb36ae3aa38cd94d0f9a88b7"
integrity sha512-D/z+PTUchZhoUA0tNC8TNJivf7Hc61WPxbUdXPi+VxRloddWYNP1ZicaEgyAph42ZnKl1L7twcZr4q6d0UMXcg==
dependencies:
fast-deep-equal "2.0.1"
symbol-observable@^1.1.0, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"