mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-14 00:55:01 +03:00
129f50d92a
* feat(settings): add subscription format controls
* feat(sub): auto-detect subscription formats
* fix(xray): validate balancer regexes before save
* Revert "fix(xray): validate balancer regexes before save"
This reverts commit 8a208ce71b.
* doc(endpoints): align indent spaces
* doc(settings): improve error message formatting in validateSubUserAgentRegex
- Use NewErrorf with proper formatting instead of NewError with string concatenation
- Add comment explaining the rationale for returning original pattern value
- This preserves the intentional design where empty input is stored as empty
in the DB and inherited as the runtime default at read time
---------
Co-authored-by: Tomilla <5007859+Tomilla@users.noreply.github.com>
Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import { useRef, useState } from 'react';
|
|
import { Input, Typography } from 'antd';
|
|
|
|
import { HttpUtil } from '@/utils';
|
|
|
|
interface GoRegexInputProps {
|
|
value: string;
|
|
ariaLabel?: string;
|
|
placeholder?: string;
|
|
maxLength?: number;
|
|
onChange: (value: string) => void;
|
|
externalError?: string;
|
|
}
|
|
|
|
export async function validateGoRegex(value: string): Promise<string> {
|
|
const result = await HttpUtil.post(
|
|
'/panel/api/setting/validateRegex',
|
|
{ regex: value },
|
|
{ silent: true },
|
|
);
|
|
return result.success ? '' : result.msg || 'Invalid Go RE2 regular expression';
|
|
}
|
|
|
|
export default function GoRegexInput({
|
|
value,
|
|
ariaLabel,
|
|
placeholder,
|
|
maxLength = 2048,
|
|
onChange,
|
|
externalError,
|
|
}: GoRegexInputProps) {
|
|
const [error, setError] = useState('');
|
|
const validationSequence = useRef(0);
|
|
|
|
async function validate() {
|
|
const sequence = ++validationSequence.current;
|
|
const nextError = await validateGoRegex(value);
|
|
if (sequence === validationSequence.current) {
|
|
setError(nextError);
|
|
}
|
|
}
|
|
|
|
const displayError = externalError ?? error;
|
|
|
|
return (
|
|
<div style={{ width: '100%' }}>
|
|
<Input
|
|
value={value}
|
|
aria-label={ariaLabel}
|
|
placeholder={placeholder}
|
|
maxLength={maxLength}
|
|
status={displayError ? 'error' : undefined}
|
|
onChange={(event) => {
|
|
validationSequence.current += 1;
|
|
setError('');
|
|
onChange(event.target.value);
|
|
}}
|
|
onBlur={() => void validate()}
|
|
/>
|
|
{displayError && <Typography.Text type="danger">{displayError}</Typography.Text>}
|
|
</div>
|
|
);
|
|
}
|