forked from SignalK/signalk-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHistoryProviderSettings.tsx
More file actions
163 lines (153 loc) · 5.15 KB
/
Copy pathHistoryProviderSettings.tsx
File metadata and controls
163 lines (153 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import React, { useState, useEffect, useCallback } from 'react'
import Alert from 'react-bootstrap/Alert'
import Card from 'react-bootstrap/Card'
import Col from 'react-bootstrap/Col'
import Form from 'react-bootstrap/Form'
import Row from 'react-bootstrap/Row'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faClockRotateLeft } from '@fortawesome/free-solid-svg-icons/faClockRotateLeft'
const PROVIDERS_PATH = '/signalk/v2/api/history/_providers'
interface ProvidersState {
ids: string[]
/** Provider currently serving unqualified History API requests */
defaultId: string | null
/** Provider persisted in server settings; may not be registered */
configuredId: string | null
}
const HistoryProviderSettings: React.FC = () => {
const [providers, setProviders] = useState<ProvidersState | null>(null)
const [saveError, setSaveError] = useState<string | null>(null)
const [saved, setSaved] = useState(false)
const fetchProviders = useCallback(async () => {
try {
const [providersRes, defaultRes] = await Promise.all([
fetch(PROVIDERS_PATH, { credentials: 'include' }),
fetch(`${PROVIDERS_PATH}/_default`, { credentials: 'include' })
])
if (!providersRes.ok || !defaultRes.ok) {
return
}
const providersBody = (await providersRes.json()) as Record<
string,
{ isDefault: boolean }
>
const defaultBody = (await defaultRes.json()) as {
id?: string
configured?: string
}
setProviders({
ids: Object.keys(providersBody),
defaultId: defaultBody.id ?? null,
configuredId: defaultBody.configured ?? null
})
} catch (e) {
console.error('Failed to fetch history providers:', e)
}
}, [])
useEffect(() => {
fetchProviders()
}, [fetchProviders])
const handleChange = useCallback(
async (id: string) => {
setSaveError(null)
setSaved(false)
try {
const res = await fetch(`${PROVIDERS_PATH}/_default/${id}`, {
method: 'POST',
credentials: 'include'
})
if (res.ok) {
setSaved(true)
setTimeout(() => setSaved(false), 3000)
} else {
const body = await res.json()
setSaveError(body.message || `Save failed (HTTP ${res.status})`)
}
} catch (e) {
setSaveError(e instanceof Error ? e.message : 'Save failed')
}
await fetchProviders()
},
[fetchProviders]
)
if (providers === null) {
return null
}
const configuredButUnavailable =
providers.configuredId !== null &&
!providers.ids.includes(providers.configuredId)
return (
<Card>
<Card.Header>
<FontAwesomeIcon icon={faClockRotateLeft} />{' '}
<strong>History Provider</strong>
</Card.Header>
<Card.Body>
<Form.Group as={Row} className="mb-0">
<Col md={2}>
<Form.Label>Default Provider</Form.Label>
</Col>
<Col xs="12" md={10}>
{providers.ids.length === 0 ? (
<Form.Text className="text-muted">
No history providers are registered. Enable a plugin that
provides the History API to select a default.
</Form.Text>
) : (
<>
<Form.Select
value={providers.defaultId ?? ''}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
handleChange(e.target.value)
}
style={{ maxWidth: '300px' }}
>
{providers.ids.map((id) => (
<option key={id} value={id}>
{id}
</option>
))}
</Form.Select>
<Form.Text className="text-muted">
Serves History API requests that do not specify a provider.
The setting persists across restarts and does not depend on
plugin load order.
</Form.Text>
</>
)}
{configuredButUnavailable && (
<Alert
variant="warning"
style={{ marginTop: '10px', marginBottom: 0 }}
>
The configured default provider "{providers.configuredId}
" is not currently available
{providers.defaultId
? ` — using "${providers.defaultId}" as fallback`
: ''}
. It will become the default again when its plugin is enabled.
</Alert>
)}
{saved && (
<Alert
variant="success"
style={{ marginTop: '10px', marginBottom: 0 }}
>
Default history provider saved.
</Alert>
)}
{saveError && (
<Alert
variant="danger"
style={{ marginTop: '10px', marginBottom: 0 }}
>
{saveError}
</Alert>
)}
</Col>
</Form.Group>
</Card.Body>
</Card>
)
}
export default HistoryProviderSettings