mirror of
https://github.com/collinbarrett/FilterLists.git
synced 2026-03-11 09:04:27 +00:00
wip convert ListsTable to functional with hooks
This commit is contained in:
parent
d28459d3c1
commit
8e4b3adf3d
7 changed files with 246 additions and 138 deletions
|
|
@ -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<number>(0);
|
||||
const [isNarrowWindow, setIsNarrowWindow] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<span>
|
||||
<Table<List>
|
||||
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 }}>
|
||||
<Table.Column<List>
|
||||
title="Info"
|
||||
dataIndex={nameof<List>("id")}
|
||||
className={styles.nogrow}
|
||||
fixed="left"
|
||||
render={(_text: string, record: List) => <ListInfoButton list={record} {...props} />} />
|
||||
<Table.Column<List>
|
||||
title="Name"
|
||||
dataIndex={nameof<List>("name")}
|
||||
sorter={(a, b) => a.name.localeCompare(b.name)}
|
||||
defaultSortOrder={"ascend"}
|
||||
width={isNarrowWindow ? undefined : 200}
|
||||
className={styles.nogrow}
|
||||
fixed="left"
|
||||
render={(text: string) => <div>{text}</div>} />
|
||||
{isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Description"
|
||||
dataIndex={nameof<List>("description")}
|
||||
className={styles.nogrow}
|
||||
render={(_text: string, record: List) => <Description {...record} />} />}
|
||||
{isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Software"
|
||||
dataIndex={nameof<List>("syntaxId")}
|
||||
className={styles.nogrow}
|
||||
render={(text: string) => <div>{text}</div>} />}
|
||||
{isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Languages"
|
||||
dataIndex={nameof<List>("languageIds")}
|
||||
sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, languages)}
|
||||
width={125}
|
||||
className={styles.nogrow}
|
||||
render={(languageIds: number[]) => languageIds ? <LanguageCloud languages={languages.filter((l: Language) => languageIds.includes(l.id))} /> : null} />}
|
||||
{isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Tags"
|
||||
dataIndex={nameof<List>("tagIds")}
|
||||
sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, tags)}
|
||||
width={275}
|
||||
className={styles.nogrow}
|
||||
render={(tagIds: number[]) => tagIds ? <TagCloud tags={tags.filter((t: Tag) => tagIds.includes(t.id))} /> : null} />}
|
||||
</Table>
|
||||
<Route path="/lists/:id" render={rp => {
|
||||
const list = lists.find(l => l.id === +rp.match.params.id);
|
||||
return list
|
||||
? <ListInfoDrawer
|
||||
list={list as List}
|
||||
languages={list.languageIds && languages.filter((l: Language) => 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 && <Redirect to={{ pathname: "/", }} />
|
||||
}} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export class ListsTable extends React.Component<RouteComponentProps, State> {
|
||||
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<RouteComponentProps, State> {
|
||||
// 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 (
|
||||
<span>
|
||||
<Table<List>
|
||||
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 }}>
|
||||
<Table.Column<List>
|
||||
title="Info"
|
||||
dataIndex={nameof<List>("id")}
|
||||
className={styles.nogrow}
|
||||
fixed="left"
|
||||
render={(_text: string, record: List) => <ListInfoButton list={record} {...this.props} />} />
|
||||
<Table.Column<List>
|
||||
title="Name"
|
||||
dataIndex={nameof<List>("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) => <div>{text}</div>} />
|
||||
{this.state.isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Description"
|
||||
dataIndex={nameof<List>("description")}
|
||||
className={styles.nogrow}
|
||||
render={(_text: string, record: List) => <Description {...record} />} />}
|
||||
{this.state.isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Software"
|
||||
dataIndex={nameof<List>("syntaxId")}
|
||||
className={styles.nogrow}
|
||||
render={(text: string) => <div>{text}</div>} />}
|
||||
{this.state.isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Languages"
|
||||
dataIndex={nameof<List>("languageIds")}
|
||||
sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, this.state.languages)}
|
||||
width={125}
|
||||
className={styles.nogrow}
|
||||
render={(languageIds: number[]) => languageIds ? <LanguageCloud languages={this.state.languages.filter((l: Language) => languageIds.includes(l.id))} /> : null} />}
|
||||
{this.state.isNarrowWindow
|
||||
? null
|
||||
: <Table.Column<List>
|
||||
title="Tags"
|
||||
dataIndex={nameof<List>("tagIds")}
|
||||
sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, this.state.tags)}
|
||||
width={275}
|
||||
className={styles.nogrow}
|
||||
render={(tagIds: number[]) => tagIds ? <TagCloud tags={this.state.tags.filter((t: Tag) => tagIds.includes(t.id))} /> : null} />}
|
||||
</Table>
|
||||
<Route path="/lists/:id" render={props => {
|
||||
const list = this.state.lists.find(l => l.id === +props.match.params.id);
|
||||
return list
|
||||
? <ListInfoDrawer
|
||||
list={list as List}
|
||||
languages={list.languageIds && this.state.languages.filter((l: Language) => 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 && <Redirect to={{ pathname: "/", }} />
|
||||
}} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <span>
|
||||
// <Table<List>
|
||||
// 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 }}>
|
||||
// <Table.Column<List>
|
||||
// title="Info"
|
||||
// dataIndex={nameof<List>("id")}
|
||||
// className={styles.nogrow}
|
||||
// fixed="left"
|
||||
// render={(_text: string, record: List) => <ListInfoButton list={record} {...this.props} />} />
|
||||
// <Table.Column<List>
|
||||
// title="Name"
|
||||
// dataIndex={nameof<List>("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) => <div>{text}</div>} />
|
||||
// {this.state.isNarrowWindow
|
||||
// ? null
|
||||
// : <Table.Column<List>
|
||||
// title="Description"
|
||||
// dataIndex={nameof<List>("description")}
|
||||
// className={styles.nogrow}
|
||||
// render={(_text: string, record: List) => <Description {...record} />} />}
|
||||
// {this.state.isNarrowWindow
|
||||
// ? null
|
||||
// : <Table.Column<List>
|
||||
// title="Software"
|
||||
// dataIndex={nameof<List>("syntaxId")}
|
||||
// className={styles.nogrow}
|
||||
// render={(text: string) => <div>{text}</div>} />}
|
||||
// {this.state.isNarrowWindow
|
||||
// ? null
|
||||
// : <Table.Column<List>
|
||||
// title="Languages"
|
||||
// dataIndex={nameof<List>("languageIds")}
|
||||
// sorter={(a, b) => arraySorter(a.languageIds, b.languageIds, this.state.languages)}
|
||||
// width={125}
|
||||
// className={styles.nogrow}
|
||||
// render={(languageIds: number[]) => languageIds ? <LanguageCloud languages={this.state.languages.filter((l: Language) => languageIds.includes(l.id))} /> : null} />}
|
||||
// {this.state.isNarrowWindow
|
||||
// ? null
|
||||
// : <Table.Column<List>
|
||||
// title="Tags"
|
||||
// dataIndex={nameof<List>("tagIds")}
|
||||
// sorter={(a, b) => arraySorter(a.tagIds, b.tagIds, this.state.tags)}
|
||||
// width={275}
|
||||
// className={styles.nogrow}
|
||||
// render={(tagIds: number[]) => tagIds ? <TagCloud tags={this.state.tags.filter((t: Tag) => tagIds.includes(t.id))} /> : null} />}
|
||||
// </Table>
|
||||
// <Route path="/lists/:id" render={props => {
|
||||
// const list = this.state.lists.find(l => l.id === +props.match.params.id);
|
||||
// return list
|
||||
// ? <ListInfoDrawer
|
||||
// list={list as List}
|
||||
// languages={list.languageIds && this.state.languages.filter((l: Language) => 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 && <Redirect to={{ pathname: "/", }} />
|
||||
// }} />
|
||||
// </span>
|
||||
// );
|
||||
// }
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.updatePageSize);
|
||||
}
|
||||
}
|
||||
// componentWillUnmount() {
|
||||
// window.removeEventListener('resize', this.updatePageSize);
|
||||
// }
|
||||
// }
|
||||
|
||||
interface ArraySortableEntity {
|
||||
id: number;
|
||||
|
|
|
|||
7
src/FilterLists.Web.V2/src/hooks/index.ts
Normal file
7
src/FilterLists.Web.V2/src/hooks/index.ts
Normal file
|
|
@ -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 };
|
||||
12
src/FilterLists.Web.V2/src/hooks/useApiData.tsx
Normal file
12
src/FilterLists.Web.V2/src/hooks/useApiData.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
export const useApiData = <T extends {}>(url: string) => {
|
||||
const [data, setData] = useState<T>();
|
||||
const fetchData = async () => {
|
||||
(await fetch(url))
|
||||
.json()
|
||||
.then(r => setData(r));
|
||||
};
|
||||
useEffect(() => { fetchData(); }, []);
|
||||
return data;
|
||||
};
|
||||
4
src/FilterLists.Web.V2/src/hooks/useLanguages.tsx
Normal file
4
src/FilterLists.Web.V2/src/hooks/useLanguages.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { useApiData } from '.';
|
||||
import { Language } from '../interfaces/Language';
|
||||
|
||||
export const useLanguages = () => useApiData<Language[]>("/api/v1/languages") || [];
|
||||
4
src/FilterLists.Web.V2/src/hooks/useLicenses.tsx
Normal file
4
src/FilterLists.Web.V2/src/hooks/useLicenses.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { useApiData } from '.';
|
||||
import { License } from '../interfaces/License';
|
||||
|
||||
export const useLicenses = () => useApiData<License[]>("/api/v1/licenses") || [];
|
||||
4
src/FilterLists.Web.V2/src/hooks/useLists.tsx
Normal file
4
src/FilterLists.Web.V2/src/hooks/useLists.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { useApiData } from '.';
|
||||
import { List } from '../interfaces/List';
|
||||
|
||||
export const useLists = () => useApiData<List[]>("/api/v1/lists") || [];
|
||||
4
src/FilterLists.Web.V2/src/hooks/useTags.tsx
Normal file
4
src/FilterLists.Web.V2/src/hooks/useTags.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { useApiData } from '.';
|
||||
import { Tag } from '../interfaces/Tag';
|
||||
|
||||
export const useTags = () => useApiData<Tag[]>("/api/v1/tags") || [];
|
||||
Loading…
Reference in a new issue