Working catalog type filter (#1267)

* WIP Working type filter

* Fixed type error

* Some interactivity between type filters and subfilters

* Revert "Some interactivity between type filters and subfilters"

This reverts commit 91a99f6c5759c33f1d35100f365af397d4ee9810.

* Rename services to entities in catalog filter menu
This commit is contained in:
Sebastian Qvarfordt
2020-06-17 12:03:23 +02:00
committed by GitHub
parent e57a2a48f5
commit 8658ea3f27
4 changed files with 68 additions and 42 deletions
+13 -3
View File
@@ -17,7 +17,7 @@
// TODO(blam): Remove this implementation when the Tabs are ready
// This is just a temporary solution to implementing tabs for now
import React from 'react';
import React, { useState } from 'react';
import { makeStyles, Tabs, Tab } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
@@ -42,9 +42,18 @@ export type Tab = {
id: string;
label: string;
};
export const HeaderTabs: React.FC<{ tabs: Tab[] }> = ({ tabs }) => {
export const HeaderTabs: React.FC<{
tabs: Tab[];
onChange?: (index: Number) => void;
}> = ({ tabs, onChange }) => {
const [selectedTab, setSelectedTab] = useState<Number>(0);
const styles = useStyles();
const handleChange = (_: React.ChangeEvent<{}>, index: Number) => {
setSelectedTab(index);
if (onChange) onChange(index);
};
return (
<div className={styles.tabsWrapper}>
<Tabs
@@ -53,7 +62,8 @@ export const HeaderTabs: React.FC<{ tabs: Tab[] }> = ({ tabs }) => {
variant="scrollable"
scrollButtons="auto"
aria-label="scrollable auto tabs example"
value={0}
onChange={handleChange}
value={selectedTab}
>
{tabs.map((tab, index) => (
<Tab
@@ -30,10 +30,15 @@ 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, useState, useMemo } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { catalogApiRef } from '../..';
import { defaultFilter, entityFilters, filterGroups } from '../../data/filters';
import {
defaultFilter,
entityFilters,
filterGroups,
EntityFilterType,
} from '../../data/filters';
import { findLocationForEntityMeta } from '../../data/utils';
import { useStarredEntities } from '../../hooks/useStarredEntites';
import {
@@ -43,6 +48,30 @@ import {
import { CatalogTable } from '../CatalogTable/CatalogTable';
import useStaleWhileRevalidate from 'swr';
// TODO: replace me with the proper tabs implemntation
const tabs = [
{
id: 'service',
label: 'Services',
},
{
id: 'website',
label: 'Websites',
},
{
id: 'lib',
label: 'Libraries',
},
{
id: 'documentation',
label: 'Documentation',
},
{
id: 'other',
label: 'Other',
},
];
const useStyles = makeStyles(theme => ({
contentWrapper: {
display: 'grid',
@@ -58,8 +87,8 @@ const useStyles = makeStyles(theme => ({
export const CatalogPage: FC<{}> = () => {
const catalogApi = useApi(catalogApiRef);
const [selectedTab, setSelectedTab] = useState<string>(tabs[0].id);
const { toggleStarredEntity, isStarredEntity } = useStarredEntities();
const [selectedFilter, setSelectedFilter] = useState<CatalogFilterItem>(
defaultFilter,
);
@@ -69,16 +98,19 @@ export const CatalogPage: FC<{}> = () => {
async () => catalogApi.getEntities(),
);
const data =
entities?.filter(e =>
entityFilters[selectedFilter.id](e, { isStarred: isStarredEntity(e) }),
) ?? [];
const onFilterSelected = useCallback(
selected => setSelectedFilter(selected),
[],
);
const filteredEntities = useMemo(() => {
const typeFilter = entityFilters[EntityFilterType.TYPE];
const leftMenuFilter = entityFilters[selectedFilter.id];
return entities
?.filter(e => leftMenuFilter(e, { isStarred: isStarredEntity(e) }))
.filter(e => typeFilter(e, { type: selectedTab }));
}, [selectedFilter.id, selectedTab, isStarredEntity, entities?.filter]);
const styles = useStyles();
const actions = [
@@ -127,33 +159,14 @@ export const CatalogPage: FC<{}> = () => {
},
];
// TODO: replace me with the proper tabs implemntation
const tabs = [
{
id: 'services',
label: 'Services',
},
{
id: 'websites',
label: 'Websites',
},
{
id: 'libs',
label: 'Libraries',
},
{
id: 'documentation',
label: 'Documentation',
},
{
id: 'other',
label: 'Other',
},
];
return (
<CatalogLayout>
<HeaderTabs tabs={tabs} />
<HeaderTabs
tabs={tabs}
onChange={index => {
setSelectedTab(tabs[index as number].id);
}}
/>
<Content>
<DismissableBanner
variant="info"
@@ -193,8 +206,8 @@ export const CatalogPage: FC<{}> = () => {
</div>
<CatalogTable
titlePreamble={selectedFilter.label}
entities={data || []}
loading={!data && !error}
entities={filteredEntities || []}
loading={!entities && !error}
error={error}
actions={actions}
/>
@@ -88,7 +88,7 @@
"Swedish": "God afton",
"Tagalog": "Magandang gabi",
"Tatar": "Xäyerle kiç",
"Telugu" : "శుభ సాయంత్రం",
"Telugu": "శుభ సాయంత్రం",
"Thai": "Sawat-dii torn khum",
"Turkish": "İyi akşamlar",
"Ukrainian": "Dobry vechir",
+6 -3
View File
@@ -28,6 +28,7 @@ export enum EntityFilterType {
ALL = 'ALL',
STARRED = 'STARRED',
OWNED = 'OWNED',
TYPE = 'TYPE',
}
export const filterGroups: CatalogFilterGroup[] = [
@@ -54,7 +55,7 @@ export const filterGroups: CatalogFilterGroup[] = [
items: [
{
id: EntityFilterType.ALL,
label: 'All Services',
label: 'All Entities',
count: AllServicesCount,
},
],
@@ -64,13 +65,15 @@ export const filterGroups: CatalogFilterGroup[] = [
type EntityFilter = (entity: Entity, options: EntityFilterOptions) => boolean;
type EntityFilterOptions = {
isStarred: boolean;
isStarred?: boolean;
type?: string;
};
export const entityFilters: Record<string, EntityFilter> = {
[EntityFilterType.OWNED]: () => false,
[EntityFilterType.ALL]: () => true,
[EntityFilterType.STARRED]: (_, { isStarred }) => isStarred,
[EntityFilterType.STARRED]: (_, { isStarred }) => !!isStarred,
[EntityFilterType.TYPE]: (e, { type }) => (e.spec as any)?.type === type,
};
export const defaultFilter: CatalogFilterItem = filterGroups[0].items[0];