summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAnderson Shindy Oki <[email protected]>2024-12-03 15:05:19 +0900
committerGitHub <[email protected]>2024-12-03 15:05:19 +0900
commitd79bc09b7c9715dd2eb016ac6782a16a755bb67c (patch)
tree84da3bb6f7f89b5d9b3facf2f37e7f6818462abd
parent8dc686e902df6a0b421f5c6fb36f24661e09db8a (diff)
downloadbazarr-d79bc09b7c9715dd2eb016ac6782a16a755bb67c.tar.gz
bazarr-d79bc09b7c9715dd2eb016ac6782a16a755bb67c.zip
Added opensubtitlescom provider validation (#2770)
-rw-r--r--frontend/src/pages/Settings/Providers/components.tsx107
-rw-r--r--frontend/src/pages/Settings/Providers/list.ts16
2 files changed, 90 insertions, 33 deletions
diff --git a/frontend/src/pages/Settings/Providers/components.tsx b/frontend/src/pages/Settings/Providers/components.tsx
index 5c37188a2..d50f0c93c 100644
--- a/frontend/src/pages/Settings/Providers/components.tsx
+++ b/frontend/src/pages/Settings/Providers/components.tsx
@@ -1,4 +1,5 @@
import {
+ Fragment,
FunctionComponent,
useCallback,
useMemo,
@@ -42,7 +43,7 @@ import {
} from "@/pages/Settings/utilities/SettingsProvider";
import { BuildKey, useSelectorOptions } from "@/utilities";
import { ASSERT } from "@/utilities/console";
-import { ProviderInfo } from "./list";
+import { ProviderInfo, ProviderList } from "./list";
type SettingsKey =
| "settings-general-enabled_providers"
@@ -151,6 +152,27 @@ const SelectItem: AutocompleteProps["renderOption"] = ({ option }) => {
);
};
+const validation = ProviderList.map((provider) => {
+ return provider.inputs
+ ?.map((input) => {
+ if (input.validation === undefined) {
+ return null;
+ }
+
+ return {
+ [`settings-${provider.key}-${input.key}`]: input.validation?.rule,
+ };
+ })
+ .filter((input) => input && Object.keys(input).length > 0)
+ .reduce((acc, curr) => {
+ return { ...acc, ...curr };
+ }, {});
+})
+ .filter((provider) => provider && Object.keys(provider).length > 0)
+ .reduce((acc, item) => {
+ return { ...acc, ...item };
+ }, {});
+
const ProviderTool: FunctionComponent<ProviderToolProps> = ({
payload,
enabledProviders,
@@ -172,6 +194,9 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
settings: staged,
hooks: {},
},
+ validate: {
+ settings: validation!,
+ },
});
const deletePayload = useCallback(() => {
@@ -188,6 +213,12 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
const submit = useCallback(
(values: FormValues) => {
+ const result = form.validate();
+
+ if (result.hasErrors) {
+ return;
+ }
+
if (info && enabledProviders) {
const changes = { ...values.settings };
const hooks = values.hooks;
@@ -204,7 +235,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
modals.closeAll();
}
},
- [info, enabledProviders, modals, settingsKey],
+ [info, enabledProviders, modals, settingsKey, form],
);
const canSave = info !== null;
@@ -249,43 +280,57 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
const label = value.name ?? capitalize(value.key);
const options = value.options ?? [];
+ const error = form.errors[`settings.settings-${itemKey}-${key}`] ? (
+ <MantineText c="red" component="span" size="xs">
+ {form.errors[`settings.settings-${itemKey}-${key}`]}
+ </MantineText>
+ ) : null;
+
switch (value.type) {
case "text":
elements.push(
- <Text
- key={BuildKey(itemKey, key)}
- label={label}
- settingKey={`settings-${itemKey}-${key}`}
- ></Text>,
+ <Fragment key={BuildKey(itemKey, key)}>
+ <Text
+ label={label}
+ settingKey={`settings-${itemKey}-${key}`}
+ ></Text>
+ {error}
+ </Fragment>,
);
return;
case "password":
elements.push(
- <Password
- key={BuildKey(itemKey, key)}
- label={label}
- settingKey={`settings-${itemKey}-${key}`}
- ></Password>,
+ <Fragment key={BuildKey(itemKey, key)}>
+ <Password
+ label={label}
+ settingKey={`settings-${itemKey}-${key}`}
+ ></Password>
+ {error}
+ </Fragment>,
);
return;
case "switch":
elements.push(
- <Check
- key={key}
- inline
- label={label}
- settingKey={`settings-${itemKey}-${key}`}
- ></Check>,
+ <Fragment key={BuildKey(itemKey, key)}>
+ <Check
+ inline
+ label={label}
+ settingKey={`settings-${itemKey}-${key}`}
+ ></Check>
+ {error}
+ </Fragment>,
);
return;
case "select":
elements.push(
- <GlobalSelector
- key={key}
- label={label}
- settingKey={`settings-${itemKey}-${key}`}
- options={options}
- ></GlobalSelector>,
+ <Fragment key={BuildKey(itemKey, key)}>
+ <GlobalSelector
+ label={label}
+ settingKey={`settings-${itemKey}-${key}`}
+ options={options}
+ ></GlobalSelector>
+ {error}
+ </Fragment>,
);
return;
case "testbutton":
@@ -295,11 +340,13 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
return;
case "chips":
elements.push(
- <Chips
- key={key}
- label={label}
- settingKey={`settings-${itemKey}-${key}`}
- ></Chips>,
+ <Fragment key={BuildKey(itemKey, key)}>
+ <Chips
+ label={label}
+ settingKey={`settings-${itemKey}-${key}`}
+ ></Chips>
+ {error}
+ </Fragment>,
);
return;
default:
@@ -308,7 +355,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
});
return <Stack gap="xs">{elements}</Stack>;
- }, [info]);
+ }, [info, form]);
return (
<SettingsProvider value={settings}>
diff --git a/frontend/src/pages/Settings/Providers/list.ts b/frontend/src/pages/Settings/Providers/list.ts
index 9d663a1d5..d2217bb6d 100644
--- a/frontend/src/pages/Settings/Providers/list.ts
+++ b/frontend/src/pages/Settings/Providers/list.ts
@@ -1,6 +1,7 @@
-import { ReactText } from "react";
import { SelectorOption } from "@/components";
+type Text = string | number;
+
type Input<T, N> = {
type: N;
key: string;
@@ -8,15 +9,18 @@ type Input<T, N> = {
name?: string;
description?: string;
options?: SelectorOption<string>[];
+ validation?: {
+ rule: (value: string) => string | null;
+ };
};
type AvailableInput =
- | Input<ReactText, "text">
+ | Input<Text, "text">
| Input<string, "password">
| Input<boolean, "switch">
| Input<string, "select">
| Input<string, "testbutton">
- | Input<ReactText[], "chips">;
+ | Input<Text[], "chips">;
export interface ProviderInfo {
key: string;
@@ -391,6 +395,12 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
{
type: "text",
key: "username",
+ validation: {
+ rule: (value: string) =>
+ /^.\S+@\S+$/.test(value)
+ ? "Invalid Username. Do not use your e-mail."
+ : null,
+ },
},
{
type: "password",