mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-17 19:35:02 +03:00
fix(frontend): key geo entries by page position and clear test-suite noise
Zod 4: use the `error` param instead of the deprecated `message`. lint:deprecated missed these because tsgolint's no-deprecated does not resolve object-literal properties on a `string | Params` union. Geodata: key geo entry rows by page position. antd deprecates rowKey's index argument, and kind:value repeats within a page because the reader drops domain attributes (22 pairs in geosite_IR.dat, 108 in geosite_RU). Nord/PIA: the "All cities/regions" option used a null value, which antd warns on. Map it through a sentinel at the Select boundary so form state stays null, with tests that fail when the sentinel is not mapped back. Tests: - Run the oxlint guard through node; .bin/oxlint is a sh shim Windows cannot spawn, and the swallowed error left both guard cases vacuous. - Start unit workers with --no-experimental-webstorage; msw's localStorage probe made Node 25+ warn once per forked worker. - Set IS_REACT_ACT_ENVIRONMENT, which RTL never sets with globals: false, and settle the async updates it exposed inside act(). The row-cells memo test now fails when memo is removed. - Disable antd's click wave in Storybook; it re-rendered inside the next story's act() and tripped "not configured to support act". - Assert InboundFormModal's validation log instead of leaking it, and give the rule-form test a well-formed clients/list response.
This commit is contained in:
@@ -86,6 +86,13 @@ const EMPTY: NordFormValues = {
|
||||
serverId: null,
|
||||
};
|
||||
|
||||
// antd warns on a null option value, so "All Cities" is a sentinel mapped back to null.
|
||||
const ALL_CITIES = '__all__';
|
||||
const allCitiesTransform = {
|
||||
input: (value: unknown) => value ?? ALL_CITIES,
|
||||
output: (value: unknown) => (value === ALL_CITIES ? null : value),
|
||||
};
|
||||
|
||||
function loadLevel(load: number): 'low' | 'medium' | 'high' {
|
||||
if (load < 30) return 'low';
|
||||
if (load < 70) return 'medium';
|
||||
@@ -452,12 +459,16 @@ export default function NordModal({
|
||||
</FormField>
|
||||
|
||||
{cities.length > 0 && (
|
||||
<FormField name="cityId" label={t('pages.xray.outbound.city')}>
|
||||
<FormField
|
||||
name="cityId"
|
||||
label={t('pages.xray.outbound.city')}
|
||||
transform={allCitiesTransform}
|
||||
>
|
||||
<Select
|
||||
data-testid="nord-city-select"
|
||||
showSearch={{ optionFilterProp: 'label' }}
|
||||
options={[
|
||||
{ value: null, label: t('pages.xray.outbound.allCities') },
|
||||
{ value: ALL_CITIES, label: t('pages.xray.outbound.allCities') },
|
||||
...cities.map((c) => ({ value: c.id, label: c.name })),
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -73,6 +73,13 @@ const EMPTY: PiaFormValues = {
|
||||
hostname: null,
|
||||
};
|
||||
|
||||
// antd warns on a null option value, so "All Regions" is a sentinel mapped back to null.
|
||||
const ALL_REGIONS = '__all__';
|
||||
const allRegionsTransform = {
|
||||
input: (value: unknown) => value ?? ALL_REGIONS,
|
||||
output: (value: unknown) => (value === ALL_REGIONS ? null : value),
|
||||
};
|
||||
|
||||
function piaHostnameOf(outbound: PiaOutboundRow): string {
|
||||
if (typeof outbound.piaHostname === 'string' && outbound.piaHostname.trim()) {
|
||||
return outbound.piaHostname.trim();
|
||||
@@ -389,12 +396,16 @@ export default function PiaModal({
|
||||
</FormField>
|
||||
|
||||
{regions.length > 0 && (
|
||||
<FormField name="regionId" label={t('pages.xray.pia.region')}>
|
||||
<FormField
|
||||
name="regionId"
|
||||
label={t('pages.xray.pia.region')}
|
||||
transform={allRegionsTransform}
|
||||
>
|
||||
<Select
|
||||
data-testid="pia-region-select"
|
||||
showSearch={{ optionFilterProp: 'label' }}
|
||||
options={[
|
||||
{ value: null, label: t('pages.xray.pia.allRegions') },
|
||||
{ value: ALL_REGIONS, label: t('pages.xray.pia.allRegions') },
|
||||
...regions.map((r) => ({ value: r.id, label: r.name })),
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user