feat(catalog): extract useEntitiesStore
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { FC } from 'react';
|
||||
import {
|
||||
Card,
|
||||
List,
|
||||
@@ -27,11 +27,12 @@ import {
|
||||
} from '@material-ui/core';
|
||||
import type { IconComponent } from '@backstage/core';
|
||||
import { EntityFilterType } from '../../data/filters';
|
||||
|
||||
export type CatalogFilterItem = {
|
||||
id: EntityFilterType;
|
||||
label: string;
|
||||
icon?: IconComponent;
|
||||
count?: number | React.FC;
|
||||
count?: number | FC;
|
||||
};
|
||||
|
||||
export type CatalogFilterGroup = {
|
||||
@@ -71,7 +72,7 @@ const useStyles = makeStyles<Theme>(theme => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export const CatalogFilter: React.FC<CatalogFilterProps> = ({
|
||||
export const CatalogFilter: FC<CatalogFilterProps> = ({
|
||||
groups,
|
||||
selectedId,
|
||||
onSelectedChange,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 } from 'react';
|
||||
import { useStarredEntities } from '../../hooks/useStarredEntites';
|
||||
|
||||
export const StarredCount: FC<{}> = () => {
|
||||
const { starredEntities } = useStarredEntities();
|
||||
return <span>{starredEntities.size}</span>;
|
||||
};
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { FC } from 'react';
|
||||
import { useStarredEntities } from '../../hooks/useStarredEntites';
|
||||
|
||||
export const StarredCount: React.FC<{}> = () => {
|
||||
export const StarredCount: FC<{}> = () => {
|
||||
const { starredEntities } = useStarredEntities();
|
||||
return <span>{starredEntities.size}</span>;
|
||||
};
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
DismissableBanner,
|
||||
HeaderTabs,
|
||||
SupportButton,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import CatalogLayout from './CatalogLayout';
|
||||
import { rootRoute as scaffolderRootRoute } from '@backstage/plugin-scaffolder';
|
||||
@@ -30,18 +29,13 @@ 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, useState } from 'react';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { catalogApiRef } from '../..';
|
||||
import { defaultFilter, entityFilters, filterGroups } from '../../data/filters';
|
||||
import { findLocationForEntityMeta } from '../../data/utils';
|
||||
import { useStarredEntities } from '../../hooks/useStarredEntites';
|
||||
import {
|
||||
CatalogFilter,
|
||||
CatalogFilterItem,
|
||||
} from '../CatalogFilter/CatalogFilter';
|
||||
import { CatalogFilter } from '../CatalogFilter/CatalogFilter';
|
||||
import { CatalogTable } from '../CatalogTable/CatalogTable';
|
||||
import useStaleWhileRevalidate from 'swr';
|
||||
import { useEntitiesStore } from '../../hooks/useEntitiesStore';
|
||||
import { findLocationForEntityMeta } from '../../data/utils';
|
||||
import { filterGroups } from '../../data/filters';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
contentWrapper: {
|
||||
@@ -57,26 +51,18 @@ const useStyles = makeStyles(theme => ({
|
||||
}));
|
||||
|
||||
export const CatalogPage: FC<{}> = () => {
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const { toggleStarredEntity, isStarredEntity } = useStarredEntities();
|
||||
|
||||
const [selectedFilter, setSelectedFilter] = useState<CatalogFilterItem>(
|
||||
defaultFilter,
|
||||
);
|
||||
|
||||
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 {
|
||||
filteredEntities: data,
|
||||
selectedFilter,
|
||||
setSelectedFilter,
|
||||
error,
|
||||
toggleStarredEntity,
|
||||
isStarredEntity,
|
||||
} = useEntitiesStore();
|
||||
|
||||
const onFilterSelected = useCallback(
|
||||
selected => setSelectedFilter(selected),
|
||||
[],
|
||||
[setSelectedFilter],
|
||||
);
|
||||
|
||||
const styles = useStyles();
|
||||
|
||||
@@ -63,14 +63,22 @@ export const filterGroups: CatalogFilterGroup[] = [
|
||||
|
||||
type EntityFilter = (entity: Entity, options: EntityFilterOptions) => boolean;
|
||||
|
||||
type EntityFilterOptions = {
|
||||
type EntityFilterOptions = Partial<{
|
||||
isStarred: boolean;
|
||||
userId: string;
|
||||
}>;
|
||||
|
||||
type Owned = {
|
||||
owner: string;
|
||||
};
|
||||
|
||||
export const entityFilters: Record<string, EntityFilter> = {
|
||||
[EntityFilterType.OWNED]: () => false,
|
||||
[EntityFilterType.OWNED]: (e, { userId }) => {
|
||||
const owner = (e.spec! as Owned).owner;
|
||||
return owner === userId;
|
||||
},
|
||||
[EntityFilterType.ALL]: () => true,
|
||||
[EntityFilterType.STARRED]: (_, { isStarred }) => isStarred,
|
||||
[EntityFilterType.STARRED]: (_, { isStarred }) => isStarred ?? false,
|
||||
};
|
||||
|
||||
export const defaultFilter: CatalogFilterItem = filterGroups[0].items[0];
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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