From 4516dde1f4fd86125691f407bf99966043824cec Mon Sep 17 00:00:00 2001 From: Larvey Date: Thu, 16 Jun 2022 15:38:50 -0400 Subject: [PATCH 1/6] Reworked AddAppShelfItem Adds: - Advanced Options tab - Changed which ping status codes identify as "Online" - Change if service opens in new tab or not Fixes: - Deluge and Transmission Password requirement --- src/components/AppShelf/AddAppShelfItem.tsx | 274 +++++++++++------- src/components/AppShelf/AppShelfItem.tsx | 13 +- src/components/AppShelf/AppShelfMenu.tsx | 2 + .../modules/ping/PingModule.story.tsx | 1 + src/components/modules/ping/PingModule.tsx | 31 +- src/pages/api/modules/downloads.ts | 4 +- src/pages/api/modules/ping.ts | 4 +- src/tools/types.ts | 28 ++ 8 files changed, 235 insertions(+), 122 deletions(-) diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index 1106bb0db..e1d70382d 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -12,6 +12,8 @@ import { Title, Anchor, Text, + Tabs, + MultiSelect, } from '@mantine/core'; import { useForm } from '@mantine/form'; import { useEffect, useState } from 'react'; @@ -19,7 +21,7 @@ import { IconApps as Apps } from '@tabler/icons'; import { v4 as uuidv4 } from 'uuid'; import { useDebouncedValue } from '@mantine/hooks'; import { useConfig } from '../../tools/state'; -import { ServiceTypeList } from '../../tools/types'; +import { ServiceTypeList, statusCodes, targets } from '../../tools/types'; export function AddItemShelfButton(props: any) { const [opened, setOpened] = useState(false); @@ -113,6 +115,8 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & username: props.username ?? (undefined as unknown as string), password: props.password ?? (undefined as unknown as string), openedUrl: props.openedUrl ?? (undefined as unknown as string), + status: props.status ?? ['200'], + target: props.target ?? '_blank', }, validate: { apiKey: () => null, @@ -133,6 +137,12 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & } return null; }, + status: (value: string[]) => { + if (!value.length) { + return 'Please select a status code'; + } + return null; + }, }, }); @@ -191,117 +201,165 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & form.reset(); })} > - - - - - - - { - e.preventDefault(); - }} - getCreateLabel={(query) => `+ Create "${query}"`} - onCreate={(query) => {}} - {...form.getInputProps('category')} - /> - - {(form.values.type === 'Sonarr' || - form.values.type === 'Radarr' || - form.values.type === 'Lidarr' || - form.values.type === 'Readarr') && ( - <> + + + { - form.setFieldValue('apiKey', event.currentTarget.value); - }} - error={form.errors.apiKey && 'Invalid API key'} + label="Service name" + placeholder="Plex" + {...form.getInputProps('name')} /> - - Tip: Get your API key{' '} - - here. - - - - )} - {(form.values.type === 'Deluge' || - form.values.type === 'Transmission' || - form.values.type === 'qBittorrent') && ( - <> - { - form.setFieldValue('username', event.currentTarget.value); - }} - error={form.errors.username && 'Invalid username'} - /> - { - form.setFieldValue('password', event.currentTarget.value); - }} - error={form.errors.password && 'Invalid password'} - /> - - )} - + + + + { + e.preventDefault(); + }} + getCreateLabel={(query) => `+ Create "${query}"`} + onCreate={(query) => {}} + {...form.getInputProps('category')} + /> + + {(form.values.type === 'Sonarr' || + form.values.type === 'Radarr' || + form.values.type === 'Lidarr' || + form.values.type === 'Readarr') && ( + <> + { + form.setFieldValue('apiKey', event.currentTarget.value); + }} + error={form.errors.apiKey && 'Invalid API key'} + /> + + Tip: Get your API key{' '} + + here. + + + + )} + {form.values.type === 'qBittorrent' && ( + <> + { + form.setFieldValue('username', event.currentTarget.value); + }} + error={form.errors.username && 'Invalid username'} + /> + { + form.setFieldValue('password', event.currentTarget.value); + }} + error={form.errors.password && 'Invalid password'} + /> + + )} + {(form.values.type === 'Deluge' || + form.values.type === 'Transmission' || + form.values.type === 'qBittorrent') && ( + <> + { + form.setFieldValue('username', event.currentTarget.value); + }} + error={form.errors.username && 'Invalid username'} + /> + { + form.setFieldValue('password', event.currentTarget.value); + }} + error={form.errors.password && 'Invalid password'} + /> + + )} + + + + + Date: Thu, 16 Jun 2022 16:54:07 -0400 Subject: [PATCH 3/6] declutter config file --- src/components/AppShelf/AddAppShelfItem.tsx | 145 ++++++++++-------- .../modules/ping/PingModule.story.tsx | 1 + 2 files changed, 80 insertions(+), 66 deletions(-) diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index 50013e639..e8fa39730 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -178,6 +178,12 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } &
{ + if (JSON.stringify(form.values.status) === JSON.stringify(['200'])) { + form.values.status = undefined; + } + if (form.values.target === '_blank') { + form.values.target = undefined; + } // If service already exists, update it. if (config.services && config.services.find((s) => s.id === form.values.id)) { setConfig({ @@ -202,7 +208,7 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & form.reset(); })} > - + @@ -213,70 +219,77 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & {...form.getInputProps('name')} /> - - - - { - e.preventDefault(); - }} - getCreateLabel={(query) => `+ Create "${query}"`} - onCreate={(query) => {}} - {...form.getInputProps('category')} - /> - - {(form.values.type === 'Sonarr' || - form.values.type === 'Radarr' || - form.values.type === 'Lidarr' || - form.values.type === 'Readarr') && ( - <> - { - form.setFieldValue('apiKey', event.currentTarget.value); - }} - error={form.errors.apiKey && 'Invalid API key'} - /> - + + + { + e.preventDefault(); + }} + getCreateLabel={(query) => `+ Create "${query}"`} + onCreate={(query) => {}} + {...form.getInputProps('category')} + /> + + {(form.values.type === 'Sonarr' || + form.values.type === 'Radarr' || + form.values.type === 'Lidarr' || + form.values.type === 'Readarr') && ( + <> + { + form.setFieldValue('apiKey', event.currentTarget.value); + }} + error={form.errors.apiKey && 'Invalid API key'} + /> + + Tip: Get your API key{' '} + here. @@ -332,12 +345,12 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & placeholder="Select valid status codes" clearButtonLabel="Clear selection" nothingFound="Nothing found" + defaultValue={['200']} clearable searchable {...form.getInputProps('status')} /> Date: Mon, 20 Jun 2022 09:52:05 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=94=A7=20Tweak=20UI=20and=20change=20?= =?UTF-8?q?the=20name=20of=20the=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/AppShelf/AddAppShelfItem.tsx | 288 ++++++++++---------- src/components/AppShelf/AppShelfItem.tsx | 12 +- src/components/AppShelf/AppShelfMenu.tsx | 13 +- src/pages/api/modules/ping.ts | 6 +- src/tools/types.ts | 4 +- 5 files changed, 156 insertions(+), 167 deletions(-) diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index 0c8071c83..cff74d57a 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -15,6 +15,7 @@ import { Tabs, MultiSelect, ScrollArea, + Switch, } from '@mantine/core'; import { useForm } from '@mantine/form'; import { useEffect, useState } from 'react'; @@ -22,7 +23,7 @@ import { IconApps as Apps } from '@tabler/icons'; import { v4 as uuidv4 } from 'uuid'; import { useDebouncedValue } from '@mantine/hooks'; import { useConfig } from '../../tools/state'; -import { ServiceTypeList, StatusCodes, Targets } from '../../tools/types'; +import { ServiceTypeList, StatusCodes } from '../../tools/types'; export function AddItemShelfButton(props: any) { const [opened, setOpened] = useState(false); @@ -117,7 +118,7 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & password: props.password ?? (undefined as unknown as string), openedUrl: props.openedUrl ?? (undefined as unknown as string), status: props.status ?? ['200'], - target: props.target ?? '_blank', + newTab: props.newTab ?? true, }, validate: { apiKey: () => null, @@ -181,8 +182,8 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & if (JSON.stringify(form.values.status) === JSON.stringify(['200'])) { form.values.status = undefined; } - if (form.values.target === '_blank') { - form.values.target = undefined; + if (form.values.newTab === true) { + form.values.newTab = undefined; } // If service already exists, update it. if (config.services && config.services.find((s) => s.id === form.values.id)) { @@ -208,155 +209,154 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & form.reset(); })} > - - - - - + + + + + - - - - { - e.preventDefault(); - }} - getCreateLabel={(query) => `+ Create "${query}"`} - onCreate={(query) => {}} - {...form.getInputProps('category')} - /> - - {(form.values.type === 'Sonarr' || - form.values.type === 'Radarr' || - form.values.type === 'Lidarr' || - form.values.type === 'Readarr') && ( - <> { - form.setFieldValue('apiKey', event.currentTarget.value); - }} - error={form.errors.apiKey && 'Invalid API key'} - /> - - Tip: Get your API key{' '} - - here. - - - - )} - {form.values.type === 'qBittorrent' && ( - <> - { - form.setFieldValue('username', event.currentTarget.value); - }} - error={form.errors.username && 'Invalid username'} + label="Icon URL" + placeholder="/favicon.svg" + {...form.getInputProps('icon')} /> { - form.setFieldValue('password', event.currentTarget.value); - }} - error={form.errors.password && 'Invalid password'} + label="Service URL" + placeholder="http://localhost:7575" + {...form.getInputProps('url')} /> - - )} - {(form.values.type === 'Deluge' || form.values.type === 'Transmission') && ( - <> { - form.setFieldValue('password', event.currentTarget.value); - }} - error={form.errors.password && 'Invalid password'} + label="On Click URL" + placeholder="http://sonarr.example.com" + {...form.getInputProps('openedUrl')} /> - - )} - - - - - - - +