From 70228ee35356aabfa52aeaa604b12b4d5947e384 Mon Sep 17 00:00:00 2001 From: "Collin M. Barrett" Date: Sun, 25 Aug 2019 17:08:31 -0500 Subject: [PATCH] get routing to list details working, misc. component folder cleanup --- src/FilterLists.Web.V2/src/App.tsx | 10 +- .../src/components/ListDetailsButton.tsx | 16 ++ .../src/components/ListDetailsDrawer.tsx | 19 ++ .../allListsTable/AllListsTable.tsx | 159 ---------------- .../src/components/allListsTable/index.ts | 3 - .../src/components/buttons/index.ts | 3 - .../src/components/index.ts | 9 +- .../components/listDetails/ListDetails.tsx | 41 ----- .../src/components/listDetails/index.ts | 3 - .../ListsTable.module.css} | 0 .../src/components/listsTable/ListsTable.tsx | 172 ++++++++++++++++++ .../src/components/listsTable/index.ts | 3 + .../SubscribeButton.module.css | 0 .../SubscribeButton.tsx | 0 .../subscribe => subscribeButton}/index.ts | 0 15 files changed, 217 insertions(+), 221 deletions(-) create mode 100644 src/FilterLists.Web.V2/src/components/ListDetailsButton.tsx create mode 100644 src/FilterLists.Web.V2/src/components/ListDetailsDrawer.tsx delete mode 100644 src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.tsx delete mode 100644 src/FilterLists.Web.V2/src/components/allListsTable/index.ts delete mode 100644 src/FilterLists.Web.V2/src/components/buttons/index.ts delete mode 100644 src/FilterLists.Web.V2/src/components/listDetails/ListDetails.tsx delete mode 100644 src/FilterLists.Web.V2/src/components/listDetails/index.ts rename src/FilterLists.Web.V2/src/components/{allListsTable/AllListsTable.module.css => listsTable/ListsTable.module.css} (100%) create mode 100644 src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx create mode 100644 src/FilterLists.Web.V2/src/components/listsTable/index.ts rename src/FilterLists.Web.V2/src/components/{buttons/subscribe => subscribeButton}/SubscribeButton.module.css (100%) rename src/FilterLists.Web.V2/src/components/{buttons/subscribe => subscribeButton}/SubscribeButton.tsx (100%) rename src/FilterLists.Web.V2/src/components/{buttons/subscribe => subscribeButton}/index.ts (100%) diff --git a/src/FilterLists.Web.V2/src/App.tsx b/src/FilterLists.Web.V2/src/App.tsx index fb2e3d3ed..73523b53e 100644 --- a/src/FilterLists.Web.V2/src/App.tsx +++ b/src/FilterLists.Web.V2/src/App.tsx @@ -1,13 +1,13 @@ import { Layout, Menu } from 'antd'; import React from 'react'; -import { BrowserRouter, Route, RouteComponentProps, Switch } from 'react-router-dom'; +import { BrowserRouter as Router, Route, RouteComponentProps, Switch } from 'react-router-dom'; -import { AllListsTable } from './components'; +import { ListsTable } from './components'; const { Header, Content, Footer } = Layout; export const App: React.FC = () => - +
@@ -16,7 +16,7 @@ export const App: React.FC = () =>
- +
@@ -25,7 +25,7 @@ export const App: React.FC = () => | | | | - ; + ; const Logo = (): JSX.Element => + ; \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/ListDetailsDrawer.tsx b/src/FilterLists.Web.V2/src/components/ListDetailsDrawer.tsx new file mode 100644 index 000000000..92ce66130 --- /dev/null +++ b/src/FilterLists.Web.V2/src/components/ListDetailsDrawer.tsx @@ -0,0 +1,19 @@ +import { Drawer } from 'antd'; +import React from 'react'; +import { RouteComponentProps } from 'react-router-dom'; + +import { List } from '../interfaces/List'; +import { Description } from './Description'; +import { SubscribeButton } from './subscribeButton'; + +interface Props { + list: List; +}; + +export const ListDetailsDrawer = (props: RouteComponentProps & Props) => + props.history.push("/")}> + + + ; \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.tsx b/src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.tsx deleted file mode 100644 index 36c927aab..000000000 --- a/src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import { Table } from 'antd'; -import React from 'react'; - -import { Description, LanguageCloud, ListDetails, TagCloud } from '..'; -import { Language } from '../../interfaces/Language'; -import { List } from '../../interfaces/List'; -import { Tag } from '../../interfaces/Tag'; -import { nameof } from '../../utils'; -import styles from './AllListsTable.module.css'; - -interface State { - lists: List[]; - languages: Language[]; - tags: Tag[]; - pageSize: number; - pageSizeOptions: string[]; - isNarrowWindow: boolean; -} - -export class AllListsTable extends React.Component<{}, State> { - constructor(props: any) { - super(props); - this.state = { - lists: [], - languages: [], - tags: [], - pageSize: 0, - pageSizeOptions: [], - isNarrowWindow: false - }; - this.updatePageSize = this.updatePageSize.bind(this); - } - - componentDidMount() { - this.fetchData(); - this.updatePageSize(); - window.addEventListener('resize', this.updatePageSize); - } - - private fetchData() { - 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 }); }) - - 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 }); }) - - 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 updatePageSize() { - const pageSize = Math.floor((window.innerHeight - 211.5) / 56); - this.setState({ - pageSize: pageSize, - pageSizeOptions: [pageSize, 200, 2000].sort((a, b) => a - b).map(String), - 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", - pageSize: this.state.pageSize, - showSizeChanger: true, - pageSizeOptions: this.state.pageSizeOptions - }} - scroll={{ x: this.state.isNarrowWindow ? undefined : 1200 }}> - - 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} />} - - title="Details" - dataIndex={nameof("viewUrl")} - className={styles.nogrow} - fixed="right" - render={(_text: string, record: List) => } /> - - ); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.updatePageSize); - } -} - -interface ArraySortableEntity { - id: number; - name: string; -} - -const arraySorter = (a: number[], b: number[], entities: ArraySortableEntity[]): number => - a && a.length - ? b && b.length - ? a.length === b.length - ? entities.filter((e: ArraySortableEntity) => a.indexOf(e.id) > -1).map((e: ArraySortableEntity) => e.name).join().toLowerCase() - > entities.filter((e: ArraySortableEntity) => b.indexOf(e.id) > -1).map((e: ArraySortableEntity) => e.name).join().toLowerCase() - ? 1 - : -1 - : a.length > b.length - ? -1 - : 1 - : -1 - : 1; \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/allListsTable/index.ts b/src/FilterLists.Web.V2/src/components/allListsTable/index.ts deleted file mode 100644 index 35e7597f6..000000000 --- a/src/FilterLists.Web.V2/src/components/allListsTable/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AllListsTable } from './AllListsTable'; - -export { AllListsTable } \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/buttons/index.ts b/src/FilterLists.Web.V2/src/components/buttons/index.ts deleted file mode 100644 index a551734b5..000000000 --- a/src/FilterLists.Web.V2/src/components/buttons/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { SubscribeButton } from './subscribe'; - -export { SubscribeButton } \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/index.ts b/src/FilterLists.Web.V2/src/components/index.ts index a14e1b807..654f34a7d 100644 --- a/src/FilterLists.Web.V2/src/components/index.ts +++ b/src/FilterLists.Web.V2/src/components/index.ts @@ -1,8 +1,3 @@ -import { AllListsTable } from './allListsTable'; -import { SubscribeButton } from './buttons'; -import { Description } from './Description'; -import { LanguageCloud } from './languageCloud'; -import { ListDetails } from './listDetails'; -import { TagCloud } from './tagCloud'; +import { ListsTable } from './listsTable'; -export { SubscribeButton, Description, LanguageCloud, TagCloud, AllListsTable, ListDetails }; +export { ListsTable }; diff --git a/src/FilterLists.Web.V2/src/components/listDetails/ListDetails.tsx b/src/FilterLists.Web.V2/src/components/listDetails/ListDetails.tsx deleted file mode 100644 index 7a1bb5131..000000000 --- a/src/FilterLists.Web.V2/src/components/listDetails/ListDetails.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Button, Drawer } from 'antd'; -import React from 'react'; - -import { Description } from '..'; -import { List } from '../../interfaces/List'; -import { SubscribeButton } from '../buttons'; - -interface State { - visible: boolean; -} - -interface Props { - list: List; -}; - -export class ListDetails extends React.Component { - constructor(props: any) { - super(props); - this.state = { - visible: false - }; - } - - render() { - return ( - - - this.setState({ visible: false, })}> - - - - - ) - } -} \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/listDetails/index.ts b/src/FilterLists.Web.V2/src/components/listDetails/index.ts deleted file mode 100644 index d1f027755..000000000 --- a/src/FilterLists.Web.V2/src/components/listDetails/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ListDetails } from './ListDetails'; - -export { ListDetails }; diff --git a/src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.module.css b/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.module.css similarity index 100% rename from src/FilterLists.Web.V2/src/components/allListsTable/AllListsTable.module.css rename to src/FilterLists.Web.V2/src/components/listsTable/ListsTable.module.css diff --git a/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx b/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx new file mode 100644 index 000000000..d55644291 --- /dev/null +++ b/src/FilterLists.Web.V2/src/components/listsTable/ListsTable.tsx @@ -0,0 +1,172 @@ +import { Table } from 'antd'; +import React from 'react'; +import { Route, RouteComponentProps } from 'react-router-dom'; + +import { Language } from '../../interfaces/Language'; +import { List } from '../../interfaces/List'; +import { Tag } from '../../interfaces/Tag'; +import { nameof } from '../../utils'; +import { Description } from '../Description'; +import { LanguageCloud } from '../languageCloud'; +import { ListDetailsButton } from '../ListDetailsButton'; +import { ListDetailsDrawer } from '../ListDetailsDrawer'; +import { TagCloud } from '../tagCloud'; +import styles from './ListsTable.module.css'; + +interface State { + lists: List[]; + languages: Language[]; + tags: Tag[]; + pageSize: number; + pageSizeOptions: string[]; + isNarrowWindow: boolean; +} + +export class ListsTable extends React.Component { + constructor(props: any) { + super(props); + this.state = { + lists: [], + languages: [], + tags: [], + pageSize: 0, + pageSizeOptions: [], + isNarrowWindow: false + }; + this.updatePageSize = this.updatePageSize.bind(this); + } + + componentDidMount() { + this.fetchData(); + this.updatePageSize(); + window.addEventListener('resize', this.updatePageSize); + } + + private fetchData() { + 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 }); }) + + 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 }); }) + + 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 updatePageSize() { + const pageSize = Math.floor((window.innerHeight - 211.5) / 56); + this.setState({ + pageSize: pageSize, + pageSizeOptions: [pageSize, 200, 2000].sort((a, b) => a - b).map(String), + 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", + pageSize: this.state.pageSize, + showSizeChanger: true, + pageSizeOptions: this.state.pageSizeOptions + }} + scroll={{ x: this.state.isNarrowWindow ? undefined : 1200 }}> + + 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} />} + + title="Details" + dataIndex={nameof("viewUrl")} + className={styles.nogrow} + fixed="right" + render={(_text: string, record: List) => } /> + + { + const list = this.state.lists.find(l => l.id === +props.match.params.id); + return list + ? + : null //TODO: redirect or 404 for invalid list id + }} /> +
+ ); + } + + componentWillUnmount() { + window.removeEventListener('resize', this.updatePageSize); + } +} + +interface ArraySortableEntity { + id: number; + name: string; +} + +const arraySorter = (a: number[], b: number[], entities: ArraySortableEntity[]): number => + a && a.length + ? b && b.length + ? a.length === b.length + ? entities.filter((e: ArraySortableEntity) => a.indexOf(e.id) > -1).map((e: ArraySortableEntity) => e.name).join().toLowerCase() + > entities.filter((e: ArraySortableEntity) => b.indexOf(e.id) > -1).map((e: ArraySortableEntity) => e.name).join().toLowerCase() + ? 1 + : -1 + : a.length > b.length + ? -1 + : 1 + : -1 + : 1; \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/listsTable/index.ts b/src/FilterLists.Web.V2/src/components/listsTable/index.ts new file mode 100644 index 000000000..ad67ef839 --- /dev/null +++ b/src/FilterLists.Web.V2/src/components/listsTable/index.ts @@ -0,0 +1,3 @@ +import { ListsTable } from './ListsTable'; + +export { ListsTable } \ No newline at end of file diff --git a/src/FilterLists.Web.V2/src/components/buttons/subscribe/SubscribeButton.module.css b/src/FilterLists.Web.V2/src/components/subscribeButton/SubscribeButton.module.css similarity index 100% rename from src/FilterLists.Web.V2/src/components/buttons/subscribe/SubscribeButton.module.css rename to src/FilterLists.Web.V2/src/components/subscribeButton/SubscribeButton.module.css diff --git a/src/FilterLists.Web.V2/src/components/buttons/subscribe/SubscribeButton.tsx b/src/FilterLists.Web.V2/src/components/subscribeButton/SubscribeButton.tsx similarity index 100% rename from src/FilterLists.Web.V2/src/components/buttons/subscribe/SubscribeButton.tsx rename to src/FilterLists.Web.V2/src/components/subscribeButton/SubscribeButton.tsx diff --git a/src/FilterLists.Web.V2/src/components/buttons/subscribe/index.ts b/src/FilterLists.Web.V2/src/components/subscribeButton/index.ts similarity index 100% rename from src/FilterLists.Web.V2/src/components/buttons/subscribe/index.ts rename to src/FilterLists.Web.V2/src/components/subscribeButton/index.ts