mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-24 00:58:22 +03:00
Don't allow # in face name
This commit is contained in:
parent
aaa61ae2e0
commit
ac6dda370d
@ -2,7 +2,8 @@
|
|||||||
"description": {
|
"description": {
|
||||||
"addFace": "Add a new collection to the Face Library by uploading your first image.",
|
"addFace": "Add a new collection to the Face Library by uploading your first image.",
|
||||||
"placeholder": "Enter a name for this collection",
|
"placeholder": "Enter a name for this collection",
|
||||||
"invalidName": "Invalid name. Names can only include letters, numbers, spaces, apostrophes, underscores, and hyphens."
|
"invalidName": "Invalid name. Names can only include letters, numbers, spaces, apostrophes, underscores, and hyphens.",
|
||||||
|
"nameCannotContainHash": "Name cannot contain #."
|
||||||
},
|
},
|
||||||
"details": {
|
"details": {
|
||||||
"timestamp": "Timestamp",
|
"timestamp": "Timestamp",
|
||||||
|
|||||||
@ -20,6 +20,8 @@ type TextEntryProps = {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
regexPattern?: RegExp;
|
regexPattern?: RegExp;
|
||||||
regexErrorMessage?: string;
|
regexErrorMessage?: string;
|
||||||
|
forbiddenPattern?: RegExp;
|
||||||
|
forbiddenErrorMessage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TextEntry({
|
export default function TextEntry({
|
||||||
@ -30,11 +32,16 @@ export default function TextEntry({
|
|||||||
children,
|
children,
|
||||||
regexPattern,
|
regexPattern,
|
||||||
regexErrorMessage = "Input does not match the required format",
|
regexErrorMessage = "Input does not match the required format",
|
||||||
|
forbiddenPattern,
|
||||||
|
forbiddenErrorMessage = "Input contains invalid characters",
|
||||||
}: TextEntryProps) {
|
}: TextEntryProps) {
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
text: z
|
text: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
|
.refine((val) => !val || !forbiddenPattern?.test(val), {
|
||||||
|
message: forbiddenErrorMessage,
|
||||||
|
})
|
||||||
.refine(
|
.refine(
|
||||||
(val) => {
|
(val) => {
|
||||||
if (!allowEmpty && !val) return false;
|
if (!allowEmpty && !val) return false;
|
||||||
|
|||||||
@ -128,6 +128,8 @@ export default function CreateFaceWizardDialog({
|
|||||||
}}
|
}}
|
||||||
regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u}
|
regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u}
|
||||||
regexErrorMessage={t("description.invalidName")}
|
regexErrorMessage={t("description.invalidName")}
|
||||||
|
forbiddenPattern={/#/}
|
||||||
|
forbiddenErrorMessage={t("description.nameCannotContainHash")}
|
||||||
>
|
>
|
||||||
<div className="flex justify-end py-2">
|
<div className="flex justify-end py-2">
|
||||||
<Button variant="select" type="submit">
|
<Button variant="select" type="submit">
|
||||||
|
|||||||
@ -22,6 +22,8 @@ type TextEntryDialogProps = {
|
|||||||
allowEmpty?: boolean;
|
allowEmpty?: boolean;
|
||||||
regexPattern?: RegExp;
|
regexPattern?: RegExp;
|
||||||
regexErrorMessage?: string;
|
regexErrorMessage?: string;
|
||||||
|
forbiddenPattern?: RegExp;
|
||||||
|
forbiddenErrorMessage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TextEntryDialog({
|
export default function TextEntryDialog({
|
||||||
@ -34,6 +36,8 @@ export default function TextEntryDialog({
|
|||||||
allowEmpty = false,
|
allowEmpty = false,
|
||||||
regexPattern,
|
regexPattern,
|
||||||
regexErrorMessage,
|
regexErrorMessage,
|
||||||
|
forbiddenPattern,
|
||||||
|
forbiddenErrorMessage,
|
||||||
}: TextEntryDialogProps) {
|
}: TextEntryDialogProps) {
|
||||||
const { t } = useTranslation("common");
|
const { t } = useTranslation("common");
|
||||||
|
|
||||||
@ -50,6 +54,8 @@ export default function TextEntryDialog({
|
|||||||
onSave={onSave}
|
onSave={onSave}
|
||||||
regexPattern={regexPattern}
|
regexPattern={regexPattern}
|
||||||
regexErrorMessage={regexErrorMessage}
|
regexErrorMessage={regexErrorMessage}
|
||||||
|
forbiddenPattern={forbiddenPattern}
|
||||||
|
forbiddenErrorMessage={forbiddenErrorMessage}
|
||||||
>
|
>
|
||||||
<DialogFooter className={cn("pt-4", isMobile && "gap-2")}>
|
<DialogFooter className={cn("pt-4", isMobile && "gap-2")}>
|
||||||
<Button type="button" onClick={() => setOpen(false)}>
|
<Button type="button" onClick={() => setOpen(false)}>
|
||||||
|
|||||||
@ -560,6 +560,8 @@ function LibrarySelector({
|
|||||||
defaultValue={renameFace || ""}
|
defaultValue={renameFace || ""}
|
||||||
regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u}
|
regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u}
|
||||||
regexErrorMessage={t("description.invalidName")}
|
regexErrorMessage={t("description.invalidName")}
|
||||||
|
forbiddenPattern={/#/}
|
||||||
|
forbiddenErrorMessage={t("description.nameCannotContainHash")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DropdownMenu modal={false}>
|
<DropdownMenu modal={false}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user