From 9ea29d02a2d4adbc5c29e8363bcd6f1f95e5afb8 Mon Sep 17 00:00:00 2001 From: stacksmash76 <98354295+stacksmash76@users.noreply.github.com> Date: Fri, 4 Mar 2022 21:13:46 +0100 Subject: [PATCH] refactor: releases table-related code and fix for #158 (#159) * refactor(APIClient): updated the newly added findQuery function to use URLSearchParams instead of manually crafting the URI string itself. * refactor: moved duplicate dashboard/release code to a separate folder: components/data-table. * refactor(SlideOver): added proper typings to the SlideOver component and added a sanity check to prevent passing of null/undefined values to the child component before rendering. * refactor: removed the redundant Network and Channel typings and updated relevant typings to match the backend. adapted relevant code to match these changes. * fix(ChannelsFieldArray): fixed a bug where it was unable to add a new irc network due to the validation object being initialized as non-empty (formik requires that successful validated entries return empty objects) * refactor(screens/settings/Irc): replaced incorrect typings, sanitized potentially null values and cleaned up the code. * fix: included changes should fix issue #158 as well. * feat: send chan empty array --- internal/irc/service.go | 1 + web/src/api/APIClient.ts | 43 +- web/src/components/Icons.tsx | 17 + web/src/components/data-table/Buttons.tsx | 34 + web/src/components/data-table/Cells.tsx | 76 ++ web/src/components/data-table/index.tsx | 2 + web/src/components/emptystates/index.tsx | 2 +- web/src/components/panels/index.tsx | 35 +- web/src/forms/settings/IndexerForms.tsx | 23 +- web/src/forms/settings/IrcForms.tsx | 226 ++--- web/src/screens/Base.tsx | 4 +- web/src/screens/Logs.tsx | 2 +- web/src/screens/Releases.tsx | 781 ------------------ web/src/screens/Settings.tsx | 4 +- .../ActivityTable.tsx} | 158 +--- web/src/screens/dashboard/Stats.tsx | 48 ++ web/src/screens/dashboard/index.tsx | 11 + web/src/screens/releases/Filters.tsx | 142 ++++ web/src/screens/releases/ReleaseTable.tsx | 319 +++++++ web/src/screens/releases/index.tsx | 14 + web/src/screens/settings/Irc.tsx | 126 ++- web/src/types/Irc.d.ts | 86 +- web/src/types/Release.d.ts | 7 +- 23 files changed, 974 insertions(+), 1187 deletions(-) create mode 100644 web/src/components/Icons.tsx create mode 100644 web/src/components/data-table/Buttons.tsx create mode 100644 web/src/components/data-table/Cells.tsx create mode 100644 web/src/components/data-table/index.tsx delete mode 100644 web/src/screens/Releases.tsx rename web/src/screens/{Dashboard.tsx => dashboard/ActivityTable.tsx} (59%) create mode 100644 web/src/screens/dashboard/Stats.tsx create mode 100644 web/src/screens/dashboard/index.tsx create mode 100644 web/src/screens/releases/Filters.tsx create mode 100644 web/src/screens/releases/ReleaseTable.tsx create mode 100644 web/src/screens/releases/index.tsx diff --git a/internal/irc/service.go b/internal/irc/service.go index 18381b0..a4d260f 100644 --- a/internal/irc/service.go +++ b/internal/irc/service.go @@ -396,6 +396,7 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor InviteCommand: n.InviteCommand, NickServ: n.NickServ, Connected: false, + Channels: []domain.ChannelWithHealth{}, } handler, ok := s.handlers[handlerKey{n.Server, n.NickServ.Account}] diff --git a/web/src/api/APIClient.ts b/web/src/api/APIClient.ts index 5294988..6255257 100644 --- a/web/src/api/APIClient.ts +++ b/web/src/api/APIClient.ts @@ -87,9 +87,9 @@ export const APIClient = { delete: (id: number) => appClient.Delete(`api/indexer/${id}`), }, irc: { - getNetworks: () => appClient.Get("api/irc"), - createNetwork: (network: Network) => appClient.Post("api/irc", network), - updateNetwork: (network: Network) => appClient.Put(`api/irc/network/${network.id}`, network), + getNetworks: () => appClient.Get("api/irc"), + createNetwork: (network: IrcNetwork) => appClient.Post("api/irc", network), + updateNetwork: (network: IrcNetwork) => appClient.Put(`api/irc/network/${network.id}`, network), deleteNetwork: (id: number) => appClient.Delete(`api/irc/network/${id}`), }, events: { @@ -97,28 +97,25 @@ export const APIClient = { }, release: { find: (query?: string) => appClient.Get(`api/release${query}`), - findQuery: (offset?: number, limit?: number, filters?: any[]) => { - let queryString = "?" + findQuery: (offset?: number, limit?: number, filters?: Array) => { + const params = new URLSearchParams(); + if (offset !== undefined) + params.append("offset", offset.toString()); - if (offset != 0) { - queryString += `offset=${offset}` - } - if (limit != 0) { - queryString += `&limit=${limit}` - } - if (filters && filters?.length > 0) { - filters?.map((filter) => { - if (filter.id === "indexer" && filter.value != "") { - queryString += `&indexer=${filter.value}` - } - // using action_status instead of push_status because thats the column accessor - if (filter.id === "action_status" && filter.value != "") { - queryString += `&push_status=${filter.value}` - } - }) - } + if (limit !== undefined) + params.append("limit", limit.toString()); - return appClient.Get(`api/release${queryString}`) + filters?.forEach((filter) => { + if (!filter.value) + return; + + if (filter.id == "indexer") + params.append("indexer", filter.value); + else if (filter.id === "action_status") + params.append("push_status", filter.value); + }); + + return appClient.Get(`api/release?${params.toString()}`) }, indexerOptions: () => appClient.Get(`api/release/indexers`), stats: () => appClient.Get("api/release/stats") diff --git a/web/src/components/Icons.tsx b/web/src/components/Icons.tsx new file mode 100644 index 0000000..26bdac9 --- /dev/null +++ b/web/src/components/Icons.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +interface IconProps { + className?: string; +} + +export const SortIcon = ({ className }: IconProps) => ( + +); + +export const SortUpIcon = ({ className }: IconProps) => ( + +); + +export const SortDownIcon = ({ className }: IconProps) => ( + +); diff --git a/web/src/components/data-table/Buttons.tsx b/web/src/components/data-table/Buttons.tsx new file mode 100644 index 0000000..2b3e961 --- /dev/null +++ b/web/src/components/data-table/Buttons.tsx @@ -0,0 +1,34 @@ +import { classNames } from "../../utils" + +interface ButtonProps { + className?: string; + children: any; + [rest: string]: any; +} + +export const Button = ({ children, className, ...rest }: ButtonProps) => ( + +); + + +export const PageButton = ({ children, className, ...rest }: ButtonProps) => ( + +); \ No newline at end of file diff --git a/web/src/components/data-table/Cells.tsx b/web/src/components/data-table/Cells.tsx new file mode 100644 index 0000000..bbe3c85 --- /dev/null +++ b/web/src/components/data-table/Cells.tsx @@ -0,0 +1,76 @@ +import * as React from "react"; +import { formatDistanceToNowStrict } from "date-fns"; +import { CheckIcon } from "@heroicons/react/solid"; +import { ClockIcon, BanIcon, ExclamationCircleIcon } from "@heroicons/react/outline"; + +import { classNames, simplifyDate } from "../../utils"; + +interface CellProps { + value: string; +} + +export const AgeCell = ({ value }: CellProps) => ( +
+ {formatDistanceToNowStrict(new Date(value), { addSuffix: true })} +
+); + +export const ReleaseCell = ({ value }: CellProps) => ( +
+ {value} +
+); + +export const IndexerCell = ({ value }: CellProps) => ( +
+ {value} +
+); + +interface ReleaseStatusCellProps { + value: ReleaseActionStatus[]; + column: any; + row: any; +} + +interface StatusCellMapEntry { + colors: string; + icon: React.ReactElement; +} + +const StatusCellMap: Record = { + "PUSH_ERROR": { + colors: "bg-pink-100 text-pink-800 hover:bg-pink-300", + icon: