mirror of
https://github.com/idanoo/autobrr
synced 2025-07-24 01:09:13 +00:00
feat(filters): regex validation for supported fields (#773)
* initial commit * minor visual improvements * lock validation to golang flavor * made a new field called regexfield reverted old textfield to be up2date with develop * added Formik Validation * removed yup as its not needed * improvements * refactor: simplify and make more generic --------- Co-authored-by: ze0s <ze0s@riseup.net>
This commit is contained in:
parent
59f41be3ef
commit
8a0c6e8180
5 changed files with 130 additions and 18 deletions
|
@ -1,21 +1,21 @@
|
|||
import { Field, FieldProps } from "formik";
|
||||
import { classNames } from "../../utils";
|
||||
import { EyeIcon, EyeSlashIcon } from "@heroicons/react/24/solid";
|
||||
import { EyeIcon, EyeSlashIcon, CheckCircleIcon, XCircleIcon } from "@heroicons/react/24/solid";
|
||||
import { useToggle } from "../../hooks/hooks";
|
||||
import { CustomTooltip } from "../tooltips/CustomTooltip";
|
||||
|
||||
type COL_WIDTHS = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
||||
|
||||
interface TextFieldProps {
|
||||
name: string;
|
||||
defaultValue?: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
columns?: COL_WIDTHS;
|
||||
autoComplete?: string;
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
tooltip?: JSX.Element;
|
||||
name: string;
|
||||
defaultValue?: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
columns?: COL_WIDTHS;
|
||||
autoComplete?: string;
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
tooltip?: JSX.Element;
|
||||
}
|
||||
|
||||
export const TextField = ({
|
||||
|
@ -75,6 +75,113 @@ export const TextField = ({
|
|||
</div>
|
||||
);
|
||||
|
||||
interface RegexFieldProps {
|
||||
name: string;
|
||||
defaultValue?: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
columns?: COL_WIDTHS;
|
||||
autoComplete?: string;
|
||||
useRegex?: boolean;
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
tooltip?: JSX.Element;
|
||||
}
|
||||
|
||||
export const RegexField = ({
|
||||
name,
|
||||
defaultValue,
|
||||
label,
|
||||
placeholder,
|
||||
columns,
|
||||
autoComplete,
|
||||
useRegex,
|
||||
hidden,
|
||||
tooltip,
|
||||
disabled
|
||||
}: RegexFieldProps) => {
|
||||
const golangRegex = /^((\\\*|\\\?|\\[^\s\\])+|\(\?i\))(\|((\\\*|\\\?|\\[^\s\\])+|\(\?i\)))*$/;
|
||||
|
||||
const validRegex = (pattern: string) => {
|
||||
try {
|
||||
new RegExp(golangRegex.source + pattern);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const validateRegexp = (val: string) => {
|
||||
let error = "";
|
||||
|
||||
if (!validRegex(val)) {
|
||||
error = "Invalid regex";
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
hidden ? "hidden" : "",
|
||||
columns ? `col-span-${columns}` : "col-span-12"
|
||||
)}
|
||||
>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className="flex float-left mb-2 text-xs font-bold text-gray-700 dark:text-gray-200 uppercase tracking-wide"
|
||||
>
|
||||
<div className="flex">
|
||||
{label}
|
||||
{tooltip && <CustomTooltip anchorId={name}>{tooltip}</CustomTooltip>}
|
||||
</div>
|
||||
</label>
|
||||
)}
|
||||
<Field
|
||||
name={name}
|
||||
validate={useRegex && validateRegexp}
|
||||
>
|
||||
{({ field, meta }: FieldProps) => (
|
||||
<div className="relative">
|
||||
<input
|
||||
{...field}
|
||||
name={name}
|
||||
type="text"
|
||||
defaultValue={defaultValue}
|
||||
autoComplete={autoComplete}
|
||||
className={classNames(
|
||||
meta.touched && meta.error
|
||||
? "focus:ring-red-500 focus:border-red-500 border-red-500"
|
||||
: "focus:ring-blue-500 dark:focus:ring-blue-500 focus:border-blue-500 dark:focus:border-blue-500 border-gray-300 dark:border-gray-700",
|
||||
disabled
|
||||
? "bg-gray-100 dark:bg-gray-700 cursor-not-allowed"
|
||||
: "dark:bg-gray-800",
|
||||
"mt-2 block w-full dark:text-gray-100 rounded-md"
|
||||
)}
|
||||
disabled={disabled}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
{useRegex && (
|
||||
<div className="relative">
|
||||
<div className="flex float-right items-center">
|
||||
{meta.touched && !meta.error ? (
|
||||
<CheckCircleIcon className="dark:bg-gray-800 bg-white h-8 w-8 mb-2.5 pl-1 text-green-500 right-2 absolute transform -translate-y-1/2" aria-hidden="true" style={{ overflow: "hidden" }} />
|
||||
) : (
|
||||
<XCircleIcon className="dark:bg-gray-800 bg-white h-8 w-8 mb-2.5 pl-1 text-red-500 right-2 absolute transform -translate-y-1/2" aria-hidden="true" style={{ overflow: "hidden" }} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface TextAreaProps {
|
||||
name: string;
|
||||
defaultValue?: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue