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:
committed by
GitHub
parent
e57a2a48f5
commit
8658ea3f27
@@ -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",
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user