🏗️ Adding fields to the settings form
This commit is contained in:
@@ -12,11 +12,12 @@ import {
|
|||||||
} from "../constants/endpoints";
|
} from "../constants/endpoints";
|
||||||
|
|
||||||
export const saveSettings =
|
export const saveSettings =
|
||||||
(settingsPayload, settingsObjectId?: string) => async (dispatch) => {
|
(settingsPayload, settingsKey: string, settingsObjectId?: string) =>
|
||||||
|
async (dispatch) => {
|
||||||
const result = await axios({
|
const result = await axios({
|
||||||
url: `${SETTINGS_SERVICE_BASE_URI}/saveSettings`,
|
url: `${SETTINGS_SERVICE_BASE_URI}/saveSettings`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: { settingsPayload, settingsObjectId },
|
data: { settingsPayload, settingsKey, settingsObjectId },
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: SETTINGS_OBJECT_FETCHED,
|
type: SETTINGS_OBJECT_FETCHED,
|
||||||
@@ -70,18 +71,20 @@ export const flushDb = () => async (dispatch) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getQBitTorrentClientInfo = (hostInfo) => async (dispatch) => {
|
||||||
|
|
||||||
export const getQBitTorrentClientInfo = () => async (dispatch) => {
|
|
||||||
|
|
||||||
const foo = await axios.request({
|
const foo = await axios.request({
|
||||||
url: `${QBITTORRENT_SERVICE_BASE_URI}/getList`,
|
url: `${QBITTORRENT_SERVICE_BASE_URI}/connect`,
|
||||||
|
method: "POST",
|
||||||
|
data: hostInfo,
|
||||||
|
});
|
||||||
|
const bar = await axios.request({
|
||||||
|
url: `${QBITTORRENT_SERVICE_BASE_URI}/getClientInfo`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(bar);
|
||||||
dispatch({
|
dispatch({
|
||||||
type: SETTINGS_QBITTORRENT_TORRENTS_LIST_FETCHED,
|
type: SETTINGS_QBITTORRENT_TORRENTS_LIST_FETCHED,
|
||||||
data: foo,
|
data: foo,
|
||||||
})
|
});
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React, { ReactElement } from "react";
|
|||||||
|
|
||||||
export const AirDCPPSettingsConfirmation = (settingsObject): ReactElement => {
|
export const AirDCPPSettingsConfirmation = (settingsObject): ReactElement => {
|
||||||
const { settings } = settingsObject;
|
const { settings } = settingsObject;
|
||||||
console.log(settings);
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-4 is-clearfix">
|
<div className="mt-4 is-clearfix">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
|
|||||||
@@ -8,32 +8,16 @@ import {
|
|||||||
import { AirDCPPSettingsConfirmation } from "./AirDCPPSettingsConfirmation";
|
import { AirDCPPSettingsConfirmation } from "./AirDCPPSettingsConfirmation";
|
||||||
import { AirDCPPSocketContext } from "../../../context/AirDCPPSocket";
|
import { AirDCPPSocketContext } from "../../../context/AirDCPPSocket";
|
||||||
import { isUndefined, isEmpty, isNil } from "lodash";
|
import { isUndefined, isEmpty, isNil } from "lodash";
|
||||||
|
import { hostNameValidator } from "../../../shared/utils/validator.utils";
|
||||||
|
|
||||||
export const AirDCPPSettingsForm = (): ReactElement => {
|
export const AirDCPPSettingsForm = (): ReactElement => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const airDCPPSettings = useContext(AirDCPPSocketContext);
|
const airDCPPSettings = useContext(AirDCPPSocketContext);
|
||||||
|
|
||||||
const hostValidator = (hostname: string): string | undefined => {
|
|
||||||
const hostnameRegex =
|
|
||||||
/^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/;
|
|
||||||
|
|
||||||
if (!isUndefined(hostname)) {
|
|
||||||
const matches = hostname.match(hostnameRegex);
|
|
||||||
console.log(matches);
|
|
||||||
return !isNil(matches) && matches.length > 0
|
|
||||||
? undefined
|
|
||||||
: "Enter a valid hostname";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = useCallback(async (values) => {
|
const onSubmit = useCallback(async (values) => {
|
||||||
try {
|
try {
|
||||||
airDCPPSettings.setSettings(values);
|
airDCPPSettings.setSettings(values);
|
||||||
dispatch(
|
dispatch(saveSettings(values, "directConnect"));
|
||||||
saveSettings({
|
|
||||||
host: values,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -70,7 +54,7 @@ export const AirDCPPSettingsForm = (): ReactElement => {
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<div className="control is-expanded">
|
<div className="control is-expanded">
|
||||||
<Field name="hostname" validate={hostValidator}>
|
<Field name="hostname" validate={hostNameValidator}>
|
||||||
{({ input, meta }) => (
|
{({ input, meta }) => (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
@@ -125,9 +109,6 @@ export const AirDCPPSettingsForm = (): ReactElement => {
|
|||||||
<span className="icon is-small is-left">
|
<span className="icon is-small is-left">
|
||||||
<i className="fa-solid fa-lock"></i>
|
<i className="fa-solid fa-lock"></i>
|
||||||
</span>
|
</span>
|
||||||
<span className="icon is-small is-right">
|
|
||||||
<i className="fas fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import React, { ReactElement, useCallback, useEffect } from "react";
|
|||||||
import { Form, Field } from "react-final-form";
|
import { Form, Field } from "react-final-form";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { getQBitTorrentClientInfo } from "../../../actions/settings.actions";
|
import { getQBitTorrentClientInfo } from "../../../actions/settings.actions";
|
||||||
|
import { hostNameValidator } from "../../../shared/utils/validator.utils";
|
||||||
|
import { saveSettings } from "../../../actions/settings.actions";
|
||||||
|
import { isUndefined } from "lodash";
|
||||||
|
|
||||||
export const QbittorrentConnectionForm = (): ReactElement => {
|
export const QbittorrentConnectionForm = (): ReactElement => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -9,18 +12,34 @@ export const QbittorrentConnectionForm = (): ReactElement => {
|
|||||||
(state: RootState) => state.settings.torrentsList,
|
(state: RootState) => state.settings.torrentsList,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const qBittorrentSettings = useSelector((state: RootState) => {
|
||||||
|
if (!isUndefined(state.settings.data.bittorrent)) {
|
||||||
|
return state.settings.data.bittorrent.client.host;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(getQBitTorrentClientInfo());
|
if (!isUndefined(qBittorrentSettings)) {
|
||||||
|
dispatch(getQBitTorrentClientInfo(qBittorrentSettings));
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
const handleSubmit = () => {};
|
|
||||||
|
const onSubmit = useCallback(async (values) => {
|
||||||
|
try {
|
||||||
|
dispatch(saveSettings(values, "bittorrent"));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<pre> {JSON.stringify(torrents, null, 4)} </pre>
|
<pre> {JSON.stringify(torrents, null, 4)} </pre>
|
||||||
|
|
||||||
<Form
|
<Form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={onSubmit}
|
||||||
// validate={}
|
// validate={}
|
||||||
/* initialValues={} */
|
initialValues={qBittorrentSettings}
|
||||||
render={({ handleSubmit }) => (
|
render={({ handleSubmit }) => (
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<h2>Configure Qbittorrent</h2>
|
<h2>Configure Qbittorrent</h2>
|
||||||
@@ -36,7 +55,7 @@ export const QbittorrentConnectionForm = (): ReactElement => {
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<div className="control is-expanded">
|
<div className="control is-expanded">
|
||||||
<Field name="hostname">
|
<Field name="hostname" validate={hostNameValidator}>
|
||||||
{({ input, meta }) => (
|
{({ input, meta }) => (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
@@ -92,13 +111,18 @@ export const QbittorrentConnectionForm = (): ReactElement => {
|
|||||||
<span className="icon is-small is-left">
|
<span className="icon is-small is-left">
|
||||||
<i className="fa-solid fa-lock"></i>
|
<i className="fa-solid fa-lock"></i>
|
||||||
</span>
|
</span>
|
||||||
<span className="icon is-small is-right">
|
|
||||||
<i className="fas fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="field is-grouped">
|
||||||
|
<p className="control">
|
||||||
|
<button type="submit" className="button is-primary">
|
||||||
|
Connect
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
14
src/client/shared/utils/validator.utils.ts
Normal file
14
src/client/shared/utils/validator.utils.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { isNil, isUndefined } from "lodash";
|
||||||
|
|
||||||
|
export const hostNameValidator = (hostname: string): string | undefined => {
|
||||||
|
// https://stackoverflow.com/a/3824105/656708
|
||||||
|
const hostnameRegex =
|
||||||
|
/^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/;
|
||||||
|
|
||||||
|
if (!isUndefined(hostname)) {
|
||||||
|
const matches = hostname.match(hostnameRegex);
|
||||||
|
return !isNil(matches) && matches.length > 0
|
||||||
|
? undefined
|
||||||
|
: "Enter a valid hostname";
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user