-
Settings
+
+
Settings
diff --git a/web/src/screens/dashboard/ActivityTable.tsx b/web/src/screens/dashboard/ActivityTable.tsx
index f73cc2e..76783e9 100644
--- a/web/src/screens/dashboard/ActivityTable.tsx
+++ b/web/src/screens/dashboard/ActivityTable.tsx
@@ -1,11 +1,11 @@
import * as React from "react";
import { useQuery } from "react-query";
import {
- useTable,
- useFilters,
- useGlobalFilter,
- useSortBy,
- usePagination
+ useTable,
+ useFilters,
+ useGlobalFilter,
+ useSortBy,
+ usePagination
} from "react-table";
import { APIClient } from "../../api/APIClient";
@@ -17,185 +17,178 @@ import * as DataTable from "../../components/data-table";
// This is a custom filter UI for selecting
// a unique option from a list
function SelectColumnFilter({
- column: { filterValue, setFilter, preFilteredRows, id, render },
+ column: { filterValue, setFilter, preFilteredRows, id, render },
}: any) {
- // Calculate the options for filtering
- // using the preFilteredRows
- const options = React.useMemo(() => {
- const options: any = new Set()
- preFilteredRows.forEach((row: { values: { [x: string]: unknown } }) => {
- options.add(row.values[id])
- })
- return [...options.values()]
- }, [id, preFilteredRows])
+ // Calculate the options for filtering
+ // using the preFilteredRows
+ const options = React.useMemo(() => {
+ const options: any = new Set()
+ preFilteredRows.forEach((row: { values: { [x: string]: unknown } }) => {
+ options.add(row.values[id])
+ })
+ return [...options.values()]
+ }, [id, preFilteredRows])
- // Render a multi-select box
- return (
-
- {render("Header")}:
- {
- setFilter(e.target.value || undefined)
- }}
- >
- All
- {options.map((option, i) => (
-
- {option}
-
- ))}
-
-
- )
+ // Render a multi-select box
+ return (
+
+ {render("Header")}:
+ {
+ setFilter(e.target.value || undefined)
+ }}
+ >
+ All
+ {options.map((option, i) => (
+
+ {option}
+
+ ))}
+
+
+ )
}
function Table({ columns, data }: any) {
- // Use the state and functions returned from useTable to build your UI
- const {
- getTableProps,
- getTableBodyProps,
- headerGroups,
- prepareRow,
- page, // Instead of using 'rows', we'll use page,
- } = useTable(
- { columns, data },
- useFilters,
- useGlobalFilter,
- useSortBy,
- usePagination
- );
+ // Use the state and functions returned from useTable to build your UI
+ const {
+ getTableProps,
+ getTableBodyProps,
+ headerGroups,
+ prepareRow,
+ page, // Instead of using 'rows', we'll use page,
+ } = useTable(
+ { columns, data },
+ useFilters,
+ useGlobalFilter,
+ useSortBy,
+ usePagination
+ );
- if (!page.length)
- return
;
+ if (!page.length)
+ return
;
- // Render the UI for your table
- return (
-
-
-
-
-
-
- {headerGroups.map((headerGroup) => {
- const { key: rowKey, ...rowRest } = headerGroup.getHeaderGroupProps();
- return (
-
- {headerGroup.headers.map((column) => {
- const { key: columnKey, ...columnRest } = column.getHeaderProps(column.getSortByToggleProps());
- return (
- // Add the sorting props to control sorting. For this example
- // we can add them into the header props
-
-
- {column.render('Header')}
- {/* Add a sort direction indicator */}
-
- {column.isSorted ? (
- column.isSortedDesc ? (
-
- ) : (
-
- )
- ) : (
-
- )}
-
-
-
- );
- })}
-
- );
- })}
-
-
- {page.map((row: any) => {
- prepareRow(row);
- const { key: bodyRowKey, ...bodyRowRest } = row.getRowProps();
- return (
-
- {row.cells.map((cell: any) => {
- const { key: cellRowKey, ...cellRowRest } = cell.getCellProps();
- return (
-
- {cell.column.Cell.name === "defaultRenderer"
- ? {cell.render('Cell')}
- : cell.render('Cell')
- }
-
- )
- })}
-
- )
- })}
-
-
-
-
-
-
- );
+ // Render the UI for your table
+ return (
+
+
+
+
+ {headerGroups.map((headerGroup) => {
+ const { key: rowKey, ...rowRest } = headerGroup.getHeaderGroupProps();
+ return (
+
+ {headerGroup.headers.map((column) => {
+ const { key: columnKey, ...columnRest } = column.getHeaderProps(column.getSortByToggleProps());
+ return (
+ // Add the sorting props to control sorting. For this example
+ // we can add them into the header props
+
+
+ {column.render('Header')}
+ {/* Add a sort direction indicator */}
+
+ {column.isSorted ? (
+ column.isSortedDesc ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ )}
+
+
+
+ );
+ })}
+
+ );
+ })}
+
+
+ {page.map((row: any) => {
+ prepareRow(row);
+ const { key: bodyRowKey, ...bodyRowRest } = row.getRowProps();
+ return (
+
+ {row.cells.map((cell: any) => {
+ const { key: cellRowKey, ...cellRowRest } = cell.getCellProps();
+ return (
+
+ {cell.render('Cell')}
+
+ )
+ })}
+
+ )
+ })}
+
+
+
+
+ );
}
export const ActivityTable = () => {
- const columns = React.useMemo(() => [
- {
- Header: "Age",
- accessor: 'timestamp',
- Cell: DataTable.AgeCell,
- },
- {
- Header: "Release",
- accessor: 'torrent_name',
- Cell: DataTable.ReleaseCell,
- },
- {
- Header: "Actions",
- accessor: 'action_status',
- Cell: DataTable.ReleaseStatusCell,
- },
- {
- Header: "Indexer",
- accessor: 'indexer',
- Cell: DataTable.IndexerCell,
- Filter: SelectColumnFilter,
- filter: 'includes',
- },
- ], [])
+ const columns = React.useMemo(() => [
+ {
+ Header: "Age",
+ accessor: 'timestamp',
+ Cell: DataTable.AgeCell,
+ },
+ {
+ Header: "Release",
+ accessor: 'torrent_name',
+ Cell: DataTable.TitleCell,
+ },
+ {
+ Header: "Actions",
+ accessor: 'action_status',
+ Cell: DataTable.ReleaseStatusCell,
+ },
+ {
+ Header: "Indexer",
+ accessor: 'indexer',
+ Cell: DataTable.TitleCell,
+ Filter: SelectColumnFilter,
+ filter: 'includes',
+ },
+ ], [])
- const { isLoading, data } = useQuery(
- 'dash_release',
- () => APIClient.release.find("?limit=10"),
- { refetchOnWindowFocus: false }
- );
+ const { isLoading, data } = useQuery(
+ 'dash_release',
+ () => APIClient.release.find("?limit=10"),
+ { refetchOnWindowFocus: false }
+ );
- if (isLoading)
- return null;
+ if (isLoading)
+ return null;
- return (
-
-
- Recent activity
-
+ return (
+
+
+ Recent activity
+
-
-
- );
+
+
+ );
}
diff --git a/web/src/screens/dashboard/Stats.tsx b/web/src/screens/dashboard/Stats.tsx
index 80ea9c1..10689ed 100644
--- a/web/src/screens/dashboard/Stats.tsx
+++ b/web/src/screens/dashboard/Stats.tsx
@@ -8,15 +8,15 @@ interface StatsItemProps {
const StatsItem = ({ name, value }: StatsItemProps) => (
{name}
-
- {value}
+
+ {value}
)
diff --git a/web/src/screens/dashboard/index.tsx b/web/src/screens/dashboard/index.tsx
index 46b78bc..a706418 100644
--- a/web/src/screens/dashboard/index.tsx
+++ b/web/src/screens/dashboard/index.tsx
@@ -3,7 +3,7 @@ import { ActivityTable } from "./ActivityTable";
export const Dashboard = () => (
-
+
diff --git a/web/src/screens/filters/details.tsx b/web/src/screens/filters/details.tsx
index bc4988c..8fe08dc 100644
--- a/web/src/screens/filters/details.tsx
+++ b/web/src/screens/filters/details.tsx
@@ -205,17 +205,17 @@ export default function FilterDetails() {
return (
-
-
+
+
Filters
- {filter.name}
+ {filter.name}
-
+
diff --git a/web/src/screens/filters/list.tsx b/web/src/screens/filters/list.tsx
index 3c9f260..ca6100a 100644
--- a/web/src/screens/filters/list.tsx
+++ b/web/src/screens/filters/list.tsx
@@ -39,9 +39,10 @@ export default function Filters() {
-
-
Filters
-
+
+
+ Filters
+
-
+
{data && data.length > 0 ? (
) : (
diff --git a/web/src/screens/releases/ReleaseTable.tsx b/web/src/screens/releases/ReleaseTable.tsx
index a40b9cf..e6964a4 100644
--- a/web/src/screens/releases/ReleaseTable.tsx
+++ b/web/src/screens/releases/ReleaseTable.tsx
@@ -62,7 +62,7 @@ export const ReleaseTable = () => {
{
Header: "Release",
accessor: 'torrent_name',
- Cell: DataTable.ReleaseCell,
+ Cell: DataTable.TitleCell,
},
{
Header: "Actions",
@@ -73,7 +73,7 @@ export const ReleaseTable = () => {
{
Header: "Indexer",
accessor: 'indexer',
- Cell: DataTable.IndexerCell,
+ Cell: DataTable.TitleCell,
Filter: IndexerSelectColumnFilter,
filter: 'equal',
},
@@ -177,8 +177,7 @@ export const ReleaseTable = () => {
))
)}
-
-
+
{headerGroups.map((headerGroup) => {
@@ -193,7 +192,7 @@ export const ReleaseTable = () => {
@@ -233,14 +232,11 @@ export const ReleaseTable = () => {
return (
- {cell.column.Cell.name === "defaultRenderer"
- ? {cell.render('Cell')}
- : cell.render('Cell')
- }
+ {cell.render('Cell')}
);
})}
diff --git a/web/src/screens/releases/index.tsx b/web/src/screens/releases/index.tsx
index 00a347c..1935736 100644
--- a/web/src/screens/releases/index.tsx
+++ b/web/src/screens/releases/index.tsx
@@ -3,11 +3,11 @@ import { ReleaseTable } from "./ReleaseTable";
export const Releases = () => (
)
diff --git a/web/src/screens/settings/Irc.tsx b/web/src/screens/settings/Irc.tsx
index 12fa995..0176aea 100644
--- a/web/src/screens/settings/Irc.tsx
+++ b/web/src/screens/settings/Irc.tsx
@@ -18,7 +18,11 @@ export const IrcSettings = () => {
const { data } = useQuery(
"networks",
APIClient.irc.getNetworks,
- { refetchOnWindowFocus: false }
+ {
+ refetchOnWindowFocus: false,
+ // Refetch every 3 seconds
+ refetchInterval: 3000
+ }
);
return (
diff --git a/web/src/setupProxy.js b/web/src/setupProxy.js
new file mode 100644
index 0000000..340738c
--- /dev/null
+++ b/web/src/setupProxy.js
@@ -0,0 +1,11 @@
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+module.exports = function(app) {
+ app.use(
+ '/api',
+ createProxyMiddleware({
+ target: 'http://127.0.0.1:7474',
+ changeOrigin: true,
+ })
+ );
+};
\ No newline at end of file
diff --git a/web/yarn.lock b/web/yarn.lock
index 4ab5d97..52f78d5 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -2543,6 +2543,13 @@ array.prototype.flatmap@^1.2.5:
define-properties "^1.1.3"
es-abstract "^1.19.0"
+as-table@^1.0.36:
+ version "1.0.55"
+ resolved "https://registry.yarnpkg.com/as-table/-/as-table-1.0.55.tgz#dc984da3937745de902cea1d45843c01bdbbec4f"
+ integrity sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==
+ dependencies:
+ printable-characters "^1.0.42"
+
asap@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
@@ -3466,6 +3473,11 @@ damerau-levenshtein@^1.0.7:
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
+data-uri-to-buffer@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz#d296973d5a4897a5dbe31716d118211921f04770"
+ integrity sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==
+
data-urls@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
@@ -4532,6 +4544,14 @@ get-package-type@^0.1.0:
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
+get-source@^2.0.12:
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/get-source/-/get-source-2.0.12.tgz#0b47d57ea1e53ce0d3a69f4f3d277eb8047da944"
+ integrity sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==
+ dependencies:
+ data-uri-to-buffer "^2.0.0"
+ source-map "^0.6.1"
+
get-stream@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
@@ -4818,6 +4838,17 @@ http-proxy-middleware@^2.0.3:
is-plain-obj "^3.0.0"
micromatch "^4.0.2"
+http-proxy-middleware@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f"
+ integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
+ dependencies:
+ "@types/http-proxy" "^1.17.8"
+ http-proxy "^1.18.1"
+ is-glob "^4.0.1"
+ is-plain-obj "^3.0.0"
+ micromatch "^4.0.2"
+
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
@@ -7151,6 +7182,11 @@ pretty-format@^27.5.1:
ansi-styles "^5.0.0"
react-is "^17.0.1"
+printable-characters@^1.0.42:
+ version "1.0.42"
+ resolved "https://registry.yarnpkg.com/printable-characters/-/printable-characters-1.0.42.tgz#3f18e977a9bd8eb37fcc4ff5659d7be90868b3d8"
+ integrity sha1-Pxjpd6m9jrN/zE/1ZZ176Qhos9g=
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -7307,6 +7343,13 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"
+react-error-boundary@^3.1.4:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
+ integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+
react-error-overlay@^6.0.10:
version "6.0.10"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6"
@@ -8062,6 +8105,14 @@ stackframe@^1.1.1:
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1"
integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==
+stacktracey@^2.1.8:
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/stacktracey/-/stacktracey-2.1.8.tgz#bf9916020738ce3700d1323b32bd2c91ea71199d"
+ integrity sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==
+ dependencies:
+ as-table "^1.0.36"
+ get-source "^2.0.12"
+
"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"