From 6caeae5d911f543c90100a9665720953855474b1 Mon Sep 17 00:00:00 2001 From: "Collin M. Barrett" Date: Tue, 3 Sep 2019 15:23:05 -0500 Subject: [PATCH] show count of lists matching each filter option closes #556, closes #551 --- .../src/components/listsTable/ListsTable.tsx | 256 +++++++++--------- 1 file changed, 134 insertions(+), 122 deletions(-) diff --git a/src/FilterLists.Web/src/components/listsTable/ListsTable.tsx b/src/FilterLists.Web/src/components/listsTable/ListsTable.tsx index 1e84e9f51..fc3ddce9d 100644 --- a/src/FilterLists.Web/src/components/listsTable/ListsTable.tsx +++ b/src/FilterLists.Web/src/components/listsTable/ListsTable.tsx @@ -1,5 +1,6 @@ import { Table, Tag } from 'antd'; -import React from 'react'; +import { PaginationConfig, SorterResult, TableCurrentDataSource } from 'antd/lib/table'; +import React, { useEffect, useState } from 'react'; import { RouteComponentProps } from 'react-router'; import { useSearchColumnFilter, useTablePageSizer } from '../../hooks'; @@ -18,128 +19,139 @@ import { arraySorter } from './arraySorter'; import styles from './ListsTable.module.css'; interface Props { - lists: List[]; - languages: Language[]; - licenses: License[]; - software: Software[]; - tags: TagInterface[]; + lists: List[]; + languages: Language[]; + licenses: License[]; + software: Software[]; + tags: TagInterface[]; }; export const ListsTable = (props: RouteComponentProps & Props) => { - const { lists, languages, licenses, software, tags, ...routeComponentProps } = props; - const tablePageSize = useTablePageSizer(); - const searchNameColumn = useSearchColumnFilter(nameof("name")); - const searchDescriptionColumn = useSearchColumnFilter(nameof("description")); - return ( - - dataSource={lists} - rowKey={record => record.id.toString()} - loading={lists.length ? false : true} - size="small" - pagination={{ - size: "small", - simple: true, - style: { float: "left" }, - pageSize: tablePageSize.pageSize - }} - scroll={{ x: tablePageSize.isNarrowWindow ? undefined : 1200 }}> - - title="Info" - dataIndex={nameof("id")} - className={styles.nogrow} - fixed="left" - render={(_id: number, list: List) => - } /> - - title="Name" - dataIndex={nameof("name")} - sorter={(a, b) => a.name.localeCompare(b.name)} - defaultSortOrder={"ascend"} - width={tablePageSize.isNarrowWindow ? undefined : 200} - className={styles.nogrow} - fixed="left" - filterDropdown={searchNameColumn.filterDropdown} - filterIcon={searchNameColumn.filterIcon} - onFilter={searchNameColumn.onFilter} - render={(name: string) => -
{name}
} /> - {tablePageSize.isNarrowWindow - ? null - : - title="Description" - dataIndex={nameof("description")} - className={styles.nogrow} - filterDropdown={searchDescriptionColumn.filterDropdown} - filterIcon={searchDescriptionColumn.filterIcon} - onFilter={searchDescriptionColumn.onFilter} - render={(description: string, list: List) => - } />} - {tablePageSize.isNarrowWindow - ? null - : - title="Software" - dataIndex={nameof("syntaxId")} - sorter={(a, b) => { - const getSoftwareIds = (l: List) => software.filter((s: Software) => s.syntaxIds.includes(l.syntaxId)).map(s => s.id); - return arraySorter(getSoftwareIds(a), getSoftwareIds(b), software); - }} - width={143} - className={styles.nogrow} - filters={software.map(s => ({ - text: <> -   - {s.name} - , - value: s.name - }))} - onFilter={(value, record) => software.filter((s: Software) => s.name === value).flatMap(s => s.syntaxIds).includes(record.syntaxId)} - render={(syntaxId: number) => - syntaxId - ? s.syntaxIds.includes(syntaxId))} /> - : null} />} - {tablePageSize.isNarrowWindow - ? null - : - title="Languages" - dataIndex={nameof("languageIds")} - sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, languages)} - width={125} - className={styles.nogrow} - filters={languages.map(l => ({ - text: <> - {l.iso6391}  - {l.name} - , - value: l.id.toString() - }))} - onFilter={(value, record) => record.languageIds - ? record.languageIds.includes(+value) - : false} - render={(languageIds: number[]) => - languageIds - ? languageIds.includes(l.id))} /> - : null} />} - {tablePageSize.isNarrowWindow - ? null - : - title="Tags" - dataIndex={nameof("tagIds")} - sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, tags)} - width={275} - className={styles.nogrow} - filters={tags.map(t => ({ - text: {t.name}, - value: t.id.toString() - }))} - onFilter={(value, record) => record.tagIds - ? record.tagIds.includes(+value) - : false} - render={(tagIds: number[]) => - tagIds - ? tagIds.includes(t.id))} /> - : null} />} - - ); + const { lists, languages, licenses, software, tags, ...routeComponentProps } = props; + const tablePageSize = useTablePageSizer(); + const searchNameColumn = useSearchColumnFilter(nameof("name")); + const searchDescriptionColumn = useSearchColumnFilter(nameof("description")); + const [visibleLists, setVisibleLists] = useState(lists); + useEffect(() => { + setVisibleLists(lists); + }, [lists]); + return ( + + dataSource={lists} + rowKey={record => record.id.toString()} + loading={lists.length ? false : true} + size="small" + pagination={{ + size: "small", + simple: true, + style: { float: "left" }, + pageSize: tablePageSize.pageSize + }} + scroll={{ x: tablePageSize.isNarrowWindow ? undefined : 1200 }} + onChange={(_pagination: PaginationConfig, _filters: Record, _sorter: SorterResult, extra: TableCurrentDataSource) => + setVisibleLists(extra.currentDataSource)}> + + title="Info" + dataIndex={nameof("id")} + className={styles.nogrow} + fixed="left" + render={(_id: number, list: List) => + } /> + + title="Name" + dataIndex={nameof("name")} + sorter={(a, b) => a.name.localeCompare(b.name)} + defaultSortOrder={"ascend"} + width={tablePageSize.isNarrowWindow ? undefined : 200} + className={styles.nogrow} + fixed="left" + filterDropdown={searchNameColumn.filterDropdown} + filterIcon={searchNameColumn.filterIcon} + onFilter={searchNameColumn.onFilter} + render={(name: string) => +
{name}
} /> + {tablePageSize.isNarrowWindow + ? null + : + title="Description" + dataIndex={nameof("description")} + className={styles.nogrow} + filterDropdown={searchDescriptionColumn.filterDropdown} + filterIcon={searchDescriptionColumn.filterIcon} + onFilter={searchDescriptionColumn.onFilter} + render={(description: string, list: List) => + } />} + {tablePageSize.isNarrowWindow + ? null + : + title="Software" + dataIndex={nameof("syntaxId")} + sorter={(a, b) => { + const getSoftwareIds = (l: List) => software.filter((s: Software) => s.syntaxIds.includes(l.syntaxId)).map(s => s.id); + return arraySorter(getSoftwareIds(a), getSoftwareIds(b), software); + }} + width={143} + className={styles.nogrow} + filters={software.map(s => ({ + text: <> +   + {s.name}  + ({visibleLists.filter(l => s.syntaxIds && s.syntaxIds.includes(l.syntaxId)).length}) + , + value: s.name + }))} + onFilter={(value, record) => software.filter((s: Software) => s.name === value).flatMap(s => s.syntaxIds).includes(record.syntaxId)} + render={(syntaxId: number) => + syntaxId + ? s.syntaxIds.includes(syntaxId))} /> + : null} />} + {tablePageSize.isNarrowWindow + ? null + : + title="Languages" + dataIndex={nameof("languageIds")} + sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, languages)} + width={125} + className={styles.nogrow} + filters={languages.map(l => ({ + text: <> + {l.iso6391}  + {l.name}  + ({visibleLists.filter(li => li.languageIds && li.languageIds.includes(l.id)).length}) + , + value: l.id.toString() + }))} + onFilter={(value, record) => record.languageIds + ? record.languageIds.includes(+value) + : false} + render={(languageIds: number[]) => + languageIds + ? languageIds.includes(l.id))} /> + : null} />} + {tablePageSize.isNarrowWindow + ? null + : + title="Tags" + dataIndex={nameof("tagIds")} + sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, tags)} + width={275} + className={styles.nogrow} + filters={tags.map(t => ({ + text: <> + {t.name}  + ({visibleLists.filter(l => l.tagIds && l.tagIds.includes(t.id)).length}) + , + value: t.id.toString() + }))} + onFilter={(value, record) => record.tagIds + ? record.tagIds.includes(+value) + : false} + render={(tagIds: number[]) => + tagIds + ? tagIds.includes(t.id))} /> + : null} />} + + ); }; \ No newline at end of file