Skip to content

Commit f3c3789

Browse files
fix the behaviour when we are sending the request even though value is not changed and use tanstack/query
1 parent 16e5695 commit f3c3789

File tree

2 files changed

+172
-70
lines changed

2 files changed

+172
-70
lines changed

src/components/settings-panel/server-settings.tsx

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState } from 'react';
2+
import { useMutation } from '@tanstack/react-query';
23
import { Button } from '@/components/ui/button';
34
import { Input } from '@/components/ui/input';
45
import {
@@ -20,58 +21,70 @@ import {
2021

2122
export const ServerSettings = () => {
2223
const [baseUrl, setBaseUrlState] = useState<string>(() => getBaseUrl());
23-
const [baseUrlError, setBaseUrlError] = useState<string | null>(null);
24-
const [isTestingConnection, setIsTestingConnection] = useState(false);
2524
const [isOpen, setIsOpen] = useState(false);
2625

26+
const connectionMutation = useMutation({
27+
mutationFn: testConnection,
28+
onSuccess: (result, url) => {
29+
if (result.reachable) {
30+
const normalizedUrl = normalizeBaseUrl(url);
31+
setBaseUrl(normalizedUrl);
32+
setBaseUrlState(normalizedUrl);
33+
}
34+
},
35+
});
36+
37+
const getErrorMessage = (): string | null => {
38+
if (connectionMutation.error) {
39+
return connectionMutation.error.message || 'Connection failed';
40+
}
41+
if (connectionMutation.data && !connectionMutation.data.reachable) {
42+
return connectionMutation.data.error || 'Server unreachable';
43+
}
44+
return null;
45+
};
46+
47+
const errorMessage = getErrorMessage();
48+
2749
const handleBaseUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2850
setBaseUrlState(e.target.value);
29-
setBaseUrlError(null);
51+
connectionMutation.reset();
3052
};
3153

32-
const handleBaseUrlBlur = async () => {
54+
const handleBaseUrlBlur = () => {
3355
const currentStoredUrl = getBaseUrl();
3456
const trimmedUrl = baseUrl.trim();
3557

3658
if (trimmedUrl === currentStoredUrl) {
3759
return;
3860
}
3961

62+
const lastTestedUrl = connectionMutation.variables;
63+
if (lastTestedUrl === trimmedUrl && errorMessage) {
64+
return;
65+
}
66+
4067
if (trimmedUrl === '' || trimmedUrl === getDefaultBaseUrl()) {
4168
setBaseUrl(trimmedUrl);
4269
setBaseUrlState(trimmedUrl || getDefaultBaseUrl());
43-
setBaseUrlError(null);
70+
connectionMutation.reset();
4471
return;
4572
}
4673

4774
const validation = validateBaseUrl(trimmedUrl);
4875
if (!validation.valid) {
49-
setBaseUrlError(validation.error || 'Invalid URL');
76+
connectionMutation.mutate(trimmedUrl);
5077
return;
5178
}
5279

53-
setIsTestingConnection(true);
54-
setBaseUrlError(null);
55-
56-
const result = await testConnection(trimmedUrl);
57-
58-
setIsTestingConnection(false);
59-
60-
if (result.reachable) {
61-
const normalizedUrl = normalizeBaseUrl(trimmedUrl);
62-
setBaseUrl(normalizedUrl);
63-
setBaseUrlState(normalizedUrl);
64-
setBaseUrlError(null);
65-
} else {
66-
setBaseUrlError(result.error || 'Server unreachable');
67-
}
80+
connectionMutation.mutate(trimmedUrl);
6881
};
6982

7083
const handleResetBaseUrl = () => {
7184
const defaultUrl = getDefaultBaseUrl();
7285
setBaseUrlState(defaultUrl);
7386
setBaseUrl(defaultUrl);
74-
setBaseUrlError(null);
87+
connectionMutation.reset();
7588
};
7689

7790
return (
@@ -82,7 +95,7 @@ export const ServerSettings = () => {
8295
onOpenChange={setIsOpen}
8396
>
8497
<div className="space-y-2">
85-
<Field data-invalid={!!baseUrlError}>
98+
<Field data-invalid={!!errorMessage}>
8699
<FieldLabel htmlFor="base-url-input">Base URL</FieldLabel>
87100
<FieldDescription>
88101
The Valhalla server URL for routing and isochrone requests
@@ -96,29 +109,29 @@ export const ServerSettings = () => {
96109
value={baseUrl}
97110
onChange={handleBaseUrlChange}
98111
onBlur={handleBaseUrlBlur}
99-
disabled={isTestingConnection}
100-
aria-invalid={!!baseUrlError}
112+
disabled={connectionMutation.isPending}
113+
aria-invalid={!!errorMessage}
101114
className={
102-
baseUrlError
115+
errorMessage
103116
? 'border-destructive focus-visible:ring-destructive/50'
104117
: ''
105118
}
106119
/>
107-
{isTestingConnection && (
120+
{connectionMutation.isPending && (
108121
<div className="absolute right-3 top-1/2 -translate-y-1/2">
109122
<Loader2 className="size-4 animate-spin text-muted-foreground" />
110123
</div>
111124
)}
112125
</div>
113126
</div>
114-
<FieldError>{baseUrlError}</FieldError>
127+
<FieldError>{errorMessage}</FieldError>
115128
</Field>
116129
<Button
117130
variant="outline"
118131
size="sm"
119132
onClick={handleResetBaseUrl}
120133
disabled={
121-
isTestingConnection ||
134+
connectionMutation.isPending ||
122135
normalizeBaseUrl(baseUrl) === getDefaultBaseUrl()
123136
}
124137
className="w-full"

0 commit comments

Comments
 (0)