fix(catalog): starred entities count
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user