diff --git a/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx b/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx index de1e12069..d0e2f6cbb 100644 --- a/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx +++ b/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx @@ -1,7 +1,8 @@ import { Table } from 'antd'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Redirect, Route, RouteComponentProps } from 'react-router-dom'; +import { useLanguages, useLicenses, useLists, useTags } from '../../hooks'; import { Language } from '../../interfaces/Language'; import { License } from '../../interfaces/License'; import { List } from '../../interfaces/List'; @@ -14,154 +15,226 @@ import { ListInfoDrawer } from '../ListInfoDrawer'; import { TagCloud } from '../tagCloud'; import styles from './ListsTable.module.css'; -interface State { - lists: List[]; - languages: Language[]; - licenses: License[]; - tags: Tag[]; - pageSize: number; - isNarrowWindow: boolean; +export const ListsTable = (props: RouteComponentProps) => { + const lists = useLists(); + const languages = useLanguages(); + const licenses = useLicenses(); + const tags = useTags(); + + const [pageSize, setPageSize] = useState(0); + const [isNarrowWindow, setIsNarrowWindow] = useState(false); + + return ( + + + dataSource={lists} + rowKey={record => record.id.toString()} + loading={lists.length ? false : true} + size="small" + pagination={{ size: "small", simple: true, style: { float: "left" }, pageSize: pageSize }} + scroll={{ x: isNarrowWindow ? undefined : 1200 }}> + + title="Info" + dataIndex={nameof("id")} + className={styles.nogrow} + fixed="left" + render={(_text: string, record: List) => } /> + + title="Name" + dataIndex={nameof("name")} + sorter={(a, b) => a.name.localeCompare(b.name)} + defaultSortOrder={"ascend"} + width={isNarrowWindow ? undefined : 200} + className={styles.nogrow} + fixed="left" + render={(text: string) =>
{text}
} /> + {isNarrowWindow + ? null + : + title="Description" + dataIndex={nameof("description")} + className={styles.nogrow} + render={(_text: string, record: List) => } />} + {isNarrowWindow + ? null + : + title="Software" + dataIndex={nameof("syntaxId")} + className={styles.nogrow} + render={(text: string) =>
{text}
} />} + {isNarrowWindow + ? null + : + title="Languages" + dataIndex={nameof("languageIds")} + sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, languages)} + width={125} + className={styles.nogrow} + render={(languageIds: number[]) => languageIds ? languageIds.includes(l.id))} /> : null} />} + {isNarrowWindow + ? null + : + title="Tags" + dataIndex={nameof("tagIds")} + sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, tags)} + width={275} + className={styles.nogrow} + render={(tagIds: number[]) => tagIds ? tagIds.includes(t.id))} /> : null} />} + + { + const list = lists.find(l => l.id === +rp.match.params.id); + return list + ? list.languageIds.includes(l.id))} + license={list.licenseId ? licenses.find((l: License) => list.licenseId === l.id) : undefined} + tags={list.tagIds && tags.filter((t: Tag) => list.tagIds.includes(t.id))} + {...props} /> + : lists && lists.length && + }} /> +
+ ); } -export class ListsTable extends React.Component { - constructor(props: any) { - super(props); - this.state = { - lists: [], - languages: [], - licenses: [], - tags: [], - pageSize: 0, - isNarrowWindow: false - }; - this.updatePageSize = this.updatePageSize.bind(this); - } +// export class ListsTable extends React.Component { +// constructor(props: any) { +// super(props); +// this.state = { +// lists: [], +// languages: [], +// licenses: [], +// tags: [], +// pageSize: 0, +// isNarrowWindow: false +// }; +// this.updatePageSize = this.updatePageSize.bind(this); +// } - componentDidMount() { - this.fetchData(); - this.updatePageSize(); - window.addEventListener('resize', this.updatePageSize); - } +// componentDidMount() { +// this.fetchData(); +// this.updatePageSize(); +// window.addEventListener('resize', this.updatePageSize); +// } - private fetchData() { - this.fetchLists(); - this.fetchLanguages(); - this.fetchTags(); - this.fetchLicenses(); - } +// private fetchData() { +// this.fetchLists(); +// this.fetchLanguages(); +// this.fetchTags(); +// this.fetchLicenses(); +// } - private fetchLists() { - fetch("/api/v1/lists") - .then(response => response.json()) - .then(json => (json as List[]).sort((a, b) => a.name.localeCompare(b.name))) - .then(lists => { this.setState({ lists: lists }); }); - } +// private fetchLists() { +// fetch("/api/v1/lists") +// .then(response => response.json()) +// .then(json => (json as List[]).sort((a, b) => a.name.localeCompare(b.name))) +// .then(lists => { this.setState({ lists: lists }); }); +// } - private fetchLanguages() { - fetch("/api/v1/languages") - .then(response => response.json()) - .then(json => (json as Language[]).sort((a, b) => a.name.localeCompare(b.name))) - .then(languages => { this.setState({ languages: languages }); }); - } +// private fetchLanguages() { +// fetch("/api/v1/languages") +// .then(response => response.json()) +// .then(json => (json as Language[]).sort((a, b) => a.name.localeCompare(b.name))) +// .then(languages => { this.setState({ languages: languages }); }); +// } - private fetchTags() { - fetch("/api/v1/tags") - .then(response => response.json()) - .then(json => (json as Tag[]).sort((a, b) => a.name.localeCompare(b.name))) - .then(tags => { this.setState({ tags: tags }); }); - } +// private fetchTags() { +// fetch("/api/v1/tags") +// .then(response => response.json()) +// .then(json => (json as Tag[]).sort((a, b) => a.name.localeCompare(b.name))) +// .then(tags => { this.setState({ tags: tags }); }); +// } - private fetchLicenses() { - fetch("/api/v1/licenses") - .then(response => response.json()) - .then(json => (json as License[]).sort((a, b) => a.name.localeCompare(b.name))) - .then(licenses => { this.setState({ licenses: licenses }); }); - } +// private fetchLicenses() { +// fetch("/api/v1/licenses") +// .then(response => response.json()) +// .then(json => (json as License[]).sort((a, b) => a.name.localeCompare(b.name))) +// .then(licenses => { this.setState({ licenses: licenses }); }); +// } - private updatePageSize() { - this.setState({ - pageSize: Math.floor((window.innerHeight - 211.5) / 56), - isNarrowWindow: window.innerWidth < 576 ? true : false - }); - } +// private updatePageSize() { +// this.setState({ +// pageSize: Math.floor((window.innerHeight - 211.5) / 56), +// isNarrowWindow: window.innerWidth < 576 ? true : false +// }); +// } - render() { - return ( - - - dataSource={this.state.lists} - rowKey={record => record.id.toString()} - loading={this.state.lists.length ? false : true} - size="small" - pagination={{ size: "small", simple: true, style: { float: "left" }, pageSize: this.state.pageSize }} - scroll={{ x: this.state.isNarrowWindow ? undefined : 1200 }}> - - title="Info" - dataIndex={nameof("id")} - className={styles.nogrow} - fixed="left" - render={(_text: string, record: List) => } /> - - title="Name" - dataIndex={nameof("name")} - sorter={(a, b) => a.name.localeCompare(b.name)} - defaultSortOrder={"ascend"} - width={this.state.isNarrowWindow ? undefined : 200} - className={styles.nogrow} - fixed="left" - render={(text: string) =>
{text}
} /> - {this.state.isNarrowWindow - ? null - : - title="Description" - dataIndex={nameof("description")} - className={styles.nogrow} - render={(_text: string, record: List) => } />} - {this.state.isNarrowWindow - ? null - : - title="Software" - dataIndex={nameof("syntaxId")} - className={styles.nogrow} - render={(text: string) =>
{text}
} />} - {this.state.isNarrowWindow - ? null - : - title="Languages" - dataIndex={nameof("languageIds")} - sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, this.state.languages)} - width={125} - className={styles.nogrow} - render={(languageIds: number[]) => languageIds ? languageIds.includes(l.id))} /> : null} />} - {this.state.isNarrowWindow - ? null - : - title="Tags" - dataIndex={nameof("tagIds")} - sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, this.state.tags)} - width={275} - className={styles.nogrow} - render={(tagIds: number[]) => tagIds ? tagIds.includes(t.id))} /> : null} />} - - { - const list = this.state.lists.find(l => l.id === +props.match.params.id); - return list - ? list.languageIds.includes(l.id))} - license={list.licenseId ? this.state.licenses.find((l: License) => list.licenseId === l.id) : undefined} - tags={list.tagIds && this.state.tags.filter((t: Tag) => list.tagIds.includes(t.id))} - {...this.props} /> - : this.state.lists && this.state.lists.length && - }} /> -
- ); - } +// render() { +// return ( +// +// +// dataSource={this.state.lists} +// rowKey={record => record.id.toString()} +// loading={this.state.lists.length ? false : true} +// size="small" +// pagination={{ size: "small", simple: true, style: { float: "left" }, pageSize: this.state.pageSize }} +// scroll={{ x: this.state.isNarrowWindow ? undefined : 1200 }}> +// +// title="Info" +// dataIndex={nameof("id")} +// className={styles.nogrow} +// fixed="left" +// render={(_text: string, record: List) => } /> +// +// title="Name" +// dataIndex={nameof("name")} +// sorter={(a, b) => a.name.localeCompare(b.name)} +// defaultSortOrder={"ascend"} +// width={this.state.isNarrowWindow ? undefined : 200} +// className={styles.nogrow} +// fixed="left" +// render={(text: string) =>
{text}
} /> +// {this.state.isNarrowWindow +// ? null +// : +// title="Description" +// dataIndex={nameof("description")} +// className={styles.nogrow} +// render={(_text: string, record: List) => } />} +// {this.state.isNarrowWindow +// ? null +// : +// title="Software" +// dataIndex={nameof("syntaxId")} +// className={styles.nogrow} +// render={(text: string) =>
{text}
} />} +// {this.state.isNarrowWindow +// ? null +// : +// title="Languages" +// dataIndex={nameof("languageIds")} +// sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, this.state.languages)} +// width={125} +// className={styles.nogrow} +// render={(languageIds: number[]) => languageIds ? languageIds.includes(l.id))} /> : null} />} +// {this.state.isNarrowWindow +// ? null +// : +// title="Tags" +// dataIndex={nameof("tagIds")} +// sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, this.state.tags)} +// width={275} +// className={styles.nogrow} +// render={(tagIds: number[]) => tagIds ? tagIds.includes(t.id))} /> : null} />} +// +// { +// const list = this.state.lists.find(l => l.id === +props.match.params.id); +// return list +// ? list.languageIds.includes(l.id))} +// license={list.licenseId ? this.state.licenses.find((l: License) => list.licenseId === l.id) : undefined} +// tags={list.tagIds && this.state.tags.filter((t: Tag) => list.tagIds.includes(t.id))} +// {...this.props} /> +// : this.state.lists && this.state.lists.length && +// }} /> +//
+// ); +// } - componentWillUnmount() { - window.removeEventListener('resize', this.updatePageSize); - } -} +// componentWillUnmount() { +// window.removeEventListener('resize', this.updatePageSize); +// } +// } interface ArraySortableEntity { id: number; diff --git a/src/FilterLists.Web.V2/src/hooks/index.ts b/src/FilterLists.Web.V2/src/hooks/index.ts new file mode 100644 index 000000000..695ceab13 --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/index.ts @@ -0,0 +1,7 @@ +import { useApiData } from './useApiData'; +import { useLanguages } from './useLanguages'; +import { useLicenses } from './useLicenses'; +import { useLists } from './useLists'; +import { useTags } from './useTags'; + +export { useLists, useLanguages, useLicenses, useTags, useApiData }; diff --git a/src/FilterLists.Web.V2/src/hooks/useApiData.tsx b/src/FilterLists.Web.V2/src/hooks/useApiData.tsx new file mode 100644 index 000000000..7b3f9074d --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/useApiData.tsx @@ -0,0 +1,12 @@ +import { useEffect, useState } from 'react'; + +export const useApiData = (url: string) => { + const [data, setData] = useState(); + const fetchData = async () => { + (await fetch(url)) + .json() + .then(r => setData(r)); + }; + useEffect(() => { fetchData(); }, []); + return data; +}; diff --git a/src/FilterLists.Web.V2/src/hooks/useLanguages.tsx b/src/FilterLists.Web.V2/src/hooks/useLanguages.tsx new file mode 100644 index 000000000..496521992 --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/useLanguages.tsx @@ -0,0 +1,4 @@ +import { useApiData } from '.'; +import { Language } from '../interfaces/Language'; + +export const useLanguages = () => useApiData("/api/v1/languages") || []; diff --git a/src/FilterLists.Web.V2/src/hooks/useLicenses.tsx b/src/FilterLists.Web.V2/src/hooks/useLicenses.tsx new file mode 100644 index 000000000..9f1b45584 --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/useLicenses.tsx @@ -0,0 +1,4 @@ +import { useApiData } from '.'; +import { License } from '../interfaces/License'; + +export const useLicenses = () => useApiData("/api/v1/licenses") || []; diff --git a/src/FilterLists.Web.V2/src/hooks/useLists.tsx b/src/FilterLists.Web.V2/src/hooks/useLists.tsx new file mode 100644 index 000000000..a528c33ed --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/useLists.tsx @@ -0,0 +1,4 @@ +import { useApiData } from '.'; +import { List } from '../interfaces/List'; + +export const useLists = () => useApiData("/api/v1/lists") || []; diff --git a/src/FilterLists.Web.V2/src/hooks/useTags.tsx b/src/FilterLists.Web.V2/src/hooks/useTags.tsx new file mode 100644 index 000000000..cd1a72b76 --- /dev/null +++ b/src/FilterLists.Web.V2/src/hooks/useTags.tsx @@ -0,0 +1,4 @@ +import { useApiData } from '.'; +import { Tag } from '../interfaces/Tag'; + +export const useTags = () => useApiData("/api/v1/tags") || [];