wip convert ListsTable to functional with hooks

This commit is contained in:
Collin M. Barrett 2019-08-30 21:35:16 -05:00
parent d28459d3c1
commit 8e4b3adf3d
7 changed files with 246 additions and 138 deletions

View file

@ -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;

View 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 };

View 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;
};

View file

@ -0,0 +1,4 @@
import { useApiData } from '.';
import { Language } from '../interfaces/Language';
export const useLanguages = () => useApiData<Language[]>("/api/v1/languages") || [];

View file

@ -0,0 +1,4 @@
import { useApiData } from '.';
import { License } from '../interfaces/License';
export const useLicenses = () => useApiData<License[]>("/api/v1/licenses") || [];

View file

@ -0,0 +1,4 @@
import { useApiData } from '.';
import { List } from '../interfaces/List';
export const useLists = () => useApiData<List[]>("/api/v1/lists") || [];

View file

@ -0,0 +1,4 @@
import { useApiData } from '.';
import { Tag } from '../interfaces/Tag';
export const useTags = () => useApiData<Tag[]>("/api/v1/tags") || [];