fix(catalog): starred entities count

This commit is contained in:
Nikita Nek Dudnik
2020-06-15 17:45:05 +02:00
parent bb09898b51
commit c8797d6d7a
5 changed files with 46 additions and 117 deletions
@@ -14,13 +14,13 @@
* limitations under the License.
*/
import React from 'react';
import React, { FC } from 'react';
import { useApi } from '@backstage/core';
import { catalogApiRef } from '../../api/types';
import { useAsync } from 'react-use';
import { CircularProgress, useTheme } from '@material-ui/core';
export const AllServicesCount: React.FC<{}> = () => {
export const AllServicesCount: FC<{}> = () => {
const theme = useTheme();
const catalogApi = useApi(catalogApiRef);
const { value, loading } = useAsync(() => catalogApi.getEntities());
@@ -26,7 +26,8 @@ import {
makeStyles,
} from '@material-ui/core';
import type { IconComponent } from '@backstage/core';
import { EntityFilterType } from '../../data/filters';
import { EntityFilterType, filterGroups } from '../../data/filters';
import { EntitiesByFilter } from '../../hooks/useEntities';
export type CatalogFilterItem = {
id: EntityFilterType;
@@ -40,12 +41,6 @@ export type CatalogFilterGroup = {
items: CatalogFilterItem[];
};
export type CatalogFilterProps = {
groups: CatalogFilterGroup[];
selectedId?: string;
onSelectedChange?: (item: CatalogFilterItem) => void;
};
const useStyles = makeStyles<Theme>(theme => ({
root: {
backgroundColor: 'rgba(0, 0, 0, .11)',
@@ -72,11 +67,16 @@ const useStyles = makeStyles<Theme>(theme => ({
},
}));
export const CatalogFilter: FC<CatalogFilterProps> = ({
groups,
selectedId,
onSelectedChange,
export const CatalogFilter: FC<{
selectedFilter: EntityFilterType;
onFilterChange: (type: EntityFilterType) => void;
entitiesByFilter: EntitiesByFilter;
}> = ({
selectedFilter: selectedId,
onFilterChange: setSelectedFilter,
entitiesByFilter,
}) => {
const groups = filterGroups;
const classes = useStyles();
return (
<Card className={classes.root}>
@@ -92,7 +92,9 @@ export const CatalogFilter: FC<CatalogFilterProps> = ({
key={item.id}
button
divider
onClick={() => onSelectedChange?.(item)}
onClick={() => {
setSelectedFilter(item.id);
}}
selected={item.id === selectedId}
className={classes.menuItem}
>
@@ -106,11 +108,7 @@ export const CatalogFilter: FC<CatalogFilterProps> = ({
{item.label}
</Typography>
</ListItemText>
{typeof item.count === 'function' ? (
<item.count />
) : (
item.count
)}
{entitiesByFilter[item.id]?.length ?? 0}
</MenuItem>
))}
</List>
@@ -29,13 +29,16 @@ import Edit from '@material-ui/icons/Edit';
import GitHub from '@material-ui/icons/GitHub';
import Star from '@material-ui/icons/Star';
import StarOutline from '@material-ui/icons/StarBorder';
import React, { FC, useCallback } from 'react';
import React, { FC } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { CatalogFilter } from '../CatalogFilter/CatalogFilter';
import { CatalogTable } from '../CatalogTable/CatalogTable';
import { useEntitiesStore } from '../../hooks/useEntitiesStore';
import { useEntities } from '../../hooks/useEntities';
import { findLocationForEntityMeta } from '../../data/utils';
import { filterGroups } from '../../data/filters';
import {
getCatalogFilterItemByType,
EntityFilterType,
} from '../../data/filters';
const useStyles = makeStyles(theme => ({
contentWrapper: {
@@ -52,19 +55,15 @@ const useStyles = makeStyles(theme => ({
export const CatalogPage: FC<{}> = () => {
const {
filteredEntities: data,
selectedFilter,
setSelectedFilter,
entitiesByFilter,
selectedFilter: selectedId,
error,
toggleStarredEntity,
isStarredEntity,
} = useEntitiesStore();
const onFilterSelected = useCallback(
selected => setSelectedFilter(selected),
[setSelectedFilter],
);
setSelectedFilter,
} = useEntities();
const data = entitiesByFilter[selectedId ?? EntityFilterType.ALL];
const styles = useStyles();
const actions = [
@@ -172,13 +171,16 @@ export const CatalogPage: FC<{}> = () => {
<div className={styles.contentWrapper}>
<div>
<CatalogFilter
groups={filterGroups}
selectedId={selectedFilter.id}
onSelectedChange={onFilterSelected}
selectedFilter={selectedId ?? EntityFilterType.ALL}
onFilterChange={setSelectedFilter}
entitiesByFilter={entitiesByFilter}
/>
</div>
<CatalogTable
titlePreamble={selectedFilter.label}
titlePreamble={
getCatalogFilterItemByType(selectedId ?? EntityFilterType.ALL)
?.label ?? ''
}
entities={data || []}
loading={!data && !error}
error={error}
+11
View File
@@ -61,6 +61,17 @@ export const filterGroups: CatalogFilterGroup[] = [
},
];
export const getCatalogFilterItemByType = (filterType: EntityFilterType) => {
for (const group of filterGroups) {
for (const filter of group.items) {
if (filter.id === filterType) {
return filter;
}
}
}
return null;
};
type EntityFilter = (entity: Entity, options: EntityFilterOptions) => boolean;
type EntityFilterOptions = Partial<{
@@ -1,82 +0,0 @@
/*
* 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 { useState, useEffect } from 'react';
import { CatalogFilterItem } from '../components/CatalogFilter/CatalogFilter';
import {
defaultFilter,
EntityFilterType,
entityFilters,
} from '../data/filters';
import { useApi } from '@backstage/core';
import { catalogApiRef } from '..';
import { useStarredEntities } from './useStarredEntites';
import { Entity } from '@backstage/catalog-model';
import useStaleWhileRevalidate from 'swr';
export const useEntitiesStore = () => {
const [selectedFilter, setSelectedFilter] = useState<CatalogFilterItem>(
defaultFilter,
);
const catalogApi = useApi(catalogApiRef);
const { toggleStarredEntity, isStarredEntity } = useStarredEntities();
const { data: entities, error } = useStaleWhileRevalidate(
['catalog/all', entityFilters[selectedFilter.id]],
async () => catalogApi.getEntities(),
);
const useUser = () => {
const [user] = useState('tools@example.com');
return user;
};
const userId = useUser();
const [filteredEntities, setFilteredEntities] = useState<Entity[]>([]);
const [entitiesByFilter] = useState<Record<string, Entity[]>>(
// Create an empty result for every filter by default
Object.keys(EntityFilterType).reduce(
(res, key) => ({ ...res, [key]: [] }),
{},
),
);
useEffect(() => {
// const dataByFilter = Object.keys(EntityFilterType).reduce(
// ,{});
const data =
entities?.filter((e: Entity) =>
entityFilters[selectedFilter.id](e, {
isStarred: isStarredEntity(e),
userId,
}),
) ?? [];
setFilteredEntities(data);
}, [
entities,
selectedFilter.id,
isStarredEntity,
userId,
setFilteredEntities,
]);
return {
filteredEntities,
selectedFilter,
setSelectedFilter,
error,
toggleStarredEntity,
isStarredEntity,
entitiesByFilter,
};
};