2023-08-24 04:20:53 +08:00
|
|
|
import { createForm } from '@felte/solid'
|
|
|
|
import { validator } from '@felte/validator-zod'
|
2023-09-02 00:32:27 +08:00
|
|
|
import { useI18n } from '@solid-primitives/i18n'
|
2023-08-24 04:20:53 +08:00
|
|
|
import { useNavigate } from '@solidjs/router'
|
|
|
|
import { IconX } from '@tabler/icons-solidjs'
|
|
|
|
import ky from 'ky'
|
2023-09-02 15:43:42 +08:00
|
|
|
import { For, onMount } from 'solid-js'
|
2023-08-24 04:20:53 +08:00
|
|
|
import { v4 as uuid } from 'uuid'
|
|
|
|
import { z } from 'zod'
|
2023-09-03 03:26:29 +08:00
|
|
|
import { Button } from '~/components'
|
2023-09-04 13:34:20 +08:00
|
|
|
import {
|
|
|
|
endpointList,
|
|
|
|
selectedEndpoint,
|
|
|
|
setEndpointList,
|
|
|
|
setSelectedEndpoint,
|
|
|
|
} from '~/signals'
|
2023-08-24 04:20:53 +08:00
|
|
|
|
|
|
|
const schema = z.object({
|
|
|
|
url: z.string().url().nonempty(),
|
|
|
|
secret: z.string(),
|
|
|
|
})
|
|
|
|
|
2023-08-29 14:44:49 +08:00
|
|
|
export default () => {
|
2023-09-02 00:32:27 +08:00
|
|
|
const [t] = useI18n()
|
2023-08-24 04:20:53 +08:00
|
|
|
const navigate = useNavigate()
|
|
|
|
|
2023-08-30 17:50:28 +08:00
|
|
|
const onSetupSuccess = (id: string) => {
|
|
|
|
setSelectedEndpoint(id)
|
|
|
|
navigate('/overview')
|
|
|
|
}
|
|
|
|
|
2023-08-30 18:03:05 +08:00
|
|
|
const checkEndpoint = (url: string, secret: string) =>
|
2023-08-30 18:01:48 +08:00
|
|
|
ky
|
|
|
|
.get(url, {
|
2023-08-30 15:49:53 +08:00
|
|
|
headers: secret
|
2023-08-30 10:55:12 +08:00
|
|
|
? {
|
2023-08-30 15:49:53 +08:00
|
|
|
Authorization: `Bearer ${secret}`,
|
2023-08-30 10:55:12 +08:00
|
|
|
}
|
|
|
|
: {},
|
|
|
|
})
|
2023-08-30 18:01:48 +08:00
|
|
|
.then(({ ok }) => ok)
|
|
|
|
.catch(() => false)
|
2023-08-30 17:50:28 +08:00
|
|
|
|
|
|
|
const onEndpointSelect = async (id: string) => {
|
|
|
|
const endpoint = endpointList().find((e) => e.id === id)
|
|
|
|
|
|
|
|
if (!endpoint) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-08-30 18:03:05 +08:00
|
|
|
if (!(await checkEndpoint(endpoint.url, endpoint.secret))) {
|
2023-08-30 17:50:28 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
onSetupSuccess(id)
|
|
|
|
}
|
|
|
|
|
2023-09-02 15:43:42 +08:00
|
|
|
const onSubmit = async ({ url, secret }: { url: string; secret: string }) => {
|
2023-09-04 13:34:20 +08:00
|
|
|
if (!(await checkEndpoint(url, secret))) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const id = uuid()
|
2023-09-02 15:43:42 +08:00
|
|
|
const list = endpointList().slice()
|
|
|
|
const point = list.find((history) => history.url === url)
|
2023-08-30 17:50:28 +08:00
|
|
|
|
2023-09-04 13:34:20 +08:00
|
|
|
if (!point) {
|
|
|
|
// new host and secret
|
|
|
|
setEndpointList([{ id, url, secret }, ...list])
|
2023-08-30 17:50:28 +08:00
|
|
|
onSetupSuccess(id)
|
2023-09-03 15:30:56 +08:00
|
|
|
|
2023-09-02 15:43:42 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-09-04 13:55:37 +08:00
|
|
|
// exist host we update secret and id no matter if secret is equal or not
|
2023-09-04 13:34:20 +08:00
|
|
|
point.secret = secret
|
|
|
|
point.id = id
|
2023-09-02 15:43:42 +08:00
|
|
|
|
2023-09-04 13:34:20 +08:00
|
|
|
setEndpointList(list)
|
2023-09-02 15:43:42 +08:00
|
|
|
onSetupSuccess(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
const { form } = createForm<z.infer<typeof schema>>({
|
|
|
|
extend: validator({ schema }),
|
2023-09-04 01:12:29 +08:00
|
|
|
onSubmit,
|
2023-08-24 04:20:53 +08:00
|
|
|
})
|
|
|
|
|
2023-09-04 13:34:20 +08:00
|
|
|
const onRemove = (id: string) => {
|
|
|
|
if (selectedEndpoint() === id) {
|
|
|
|
setSelectedEndpoint('')
|
|
|
|
}
|
|
|
|
|
2023-08-24 04:20:53 +08:00
|
|
|
setEndpointList(endpointList().filter((e) => e.id !== id))
|
2023-09-04 13:34:20 +08:00
|
|
|
}
|
2023-08-24 04:20:53 +08:00
|
|
|
|
2023-09-02 15:43:42 +08:00
|
|
|
onMount(() => {
|
|
|
|
const query = new URLSearchParams(window.location.search)
|
|
|
|
|
|
|
|
if (query.has('hostname')) {
|
2023-09-04 01:12:29 +08:00
|
|
|
void onSubmit({
|
2023-09-02 15:43:42 +08:00
|
|
|
url: `http://${query.get('hostname')}${
|
|
|
|
query.get('port') && ':' + query.get('port')
|
|
|
|
}`,
|
|
|
|
secret: query.get('secret') ?? '',
|
|
|
|
})
|
2023-09-04 13:51:29 +08:00
|
|
|
} else if (endpointList().length === 0) {
|
|
|
|
/**
|
|
|
|
we only try auto login when there is nothing in endpoint list
|
2023-09-04 13:55:37 +08:00
|
|
|
or user who is using default config wont be able to switch to another endpoint ever
|
2023-09-04 13:51:29 +08:00
|
|
|
*/
|
|
|
|
void onSubmit({
|
|
|
|
url: 'http://127.0.0.1:9090',
|
|
|
|
secret: '',
|
|
|
|
})
|
2023-09-02 15:43:42 +08:00
|
|
|
}
|
|
|
|
})
|
2023-09-03 15:30:56 +08:00
|
|
|
|
2023-08-24 04:20:53 +08:00
|
|
|
return (
|
2023-08-27 22:25:41 +08:00
|
|
|
<div class="mx-auto flex flex-col items-center gap-4 py-10 sm:w-2/3">
|
2023-08-24 04:20:53 +08:00
|
|
|
<form class="contents" use:form={form}>
|
2023-08-27 22:25:41 +08:00
|
|
|
<div class="flex w-full flex-col gap-4">
|
2023-08-24 04:20:53 +08:00
|
|
|
<input
|
|
|
|
name="url"
|
|
|
|
type="url"
|
2023-08-27 22:25:41 +08:00
|
|
|
class="input input-bordered"
|
2023-09-02 15:43:42 +08:00
|
|
|
placeholder="host url"
|
2023-08-24 04:20:53 +08:00
|
|
|
list="defaultEndpoints"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<datalist id="defaultEndpoints">
|
2023-09-01 12:16:37 +08:00
|
|
|
<option value="http://127.0.0.1:9090" />
|
2023-08-24 04:20:53 +08:00
|
|
|
</datalist>
|
|
|
|
|
|
|
|
<input
|
|
|
|
name="secret"
|
|
|
|
type="password"
|
2023-08-27 22:25:41 +08:00
|
|
|
class="input input-bordered"
|
2023-08-24 04:20:53 +08:00
|
|
|
placeholder="secret"
|
|
|
|
/>
|
|
|
|
|
2023-09-03 02:31:06 +08:00
|
|
|
<Button type="submit" class="btn-primary join-item uppercase">
|
2023-09-02 00:32:27 +08:00
|
|
|
{t('add')}
|
2023-09-03 02:31:06 +08:00
|
|
|
</Button>
|
2023-08-24 04:20:53 +08:00
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
|
|
|
|
<div class="flex w-full flex-col gap-4">
|
|
|
|
<For each={endpointList()}>
|
|
|
|
{({ id, url }) => (
|
|
|
|
<div
|
|
|
|
class="badge badge-info flex w-full cursor-pointer items-center gap-4 py-4"
|
2023-08-30 17:50:28 +08:00
|
|
|
onClick={() => onEndpointSelect(id)}
|
2023-08-24 04:20:53 +08:00
|
|
|
>
|
|
|
|
{url}
|
|
|
|
|
2023-09-03 02:31:06 +08:00
|
|
|
<Button
|
|
|
|
class="btn-circle btn-ghost btn-xs text-white"
|
2023-08-24 04:20:53 +08:00
|
|
|
onClick={(e) => {
|
|
|
|
e.stopPropagation()
|
|
|
|
onRemove(id)
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<IconX />
|
2023-09-03 02:31:06 +08:00
|
|
|
</Button>
|
2023-08-24 04:20:53 +08:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</For>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|