From 1712d0c81dd8f72929a68087e971dc79eac2eae3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 7 Dec 2022 16:07:14 +0100 Subject: [PATCH] Continue to work on Svelte migration --- ui/src/lib/api/provider_specs.ts | 18 +++++ ui/src/lib/api/user.ts | 12 +-- ui/src/lib/components/Home.svelte | 79 +++++++++++++++++++ ui/src/lib/components/ZoneList.svelte | 52 ++++++++++++ .../components/providers/ImgProvider.svelte | 12 +++ .../lib/components/providers/Selector.svelte | 50 ++++++++++++ ui/src/lib/locales/en.json | 5 +- ui/src/lib/locales/fr.json | 5 +- ui/src/lib/model/domain.ts | 8 ++ ui/src/lib/model/golang.ts | 3 + ui/src/lib/model/provider.ts | 26 ++++++ ui/src/lib/model/service.ts | 11 +++ ui/src/lib/model/source.ts | 6 ++ ui/src/lib/model/zone.ts | 9 +++ ui/src/lib/stores/providers.ts | 16 ++++ ui/src/routes/+page.svelte | 5 ++ ui/src/routes/+page.ts | 4 +- ui/src/routes/providers/new/+layout.svelte | 25 ++++++ ui/src/routes/providers/new/+page.svelte | 18 +++++ 19 files changed, 355 insertions(+), 9 deletions(-) create mode 100644 ui/src/lib/api/provider_specs.ts create mode 100644 ui/src/lib/components/Home.svelte create mode 100644 ui/src/lib/components/ZoneList.svelte create mode 100644 ui/src/lib/components/providers/ImgProvider.svelte create mode 100644 ui/src/lib/components/providers/Selector.svelte create mode 100644 ui/src/lib/model/domain.ts create mode 100644 ui/src/lib/model/golang.ts create mode 100644 ui/src/lib/model/provider.ts create mode 100644 ui/src/lib/model/service.ts create mode 100644 ui/src/lib/model/source.ts create mode 100644 ui/src/lib/model/zone.ts create mode 100644 ui/src/lib/stores/providers.ts create mode 100644 ui/src/routes/+page.svelte create mode 100644 ui/src/routes/providers/new/+layout.svelte create mode 100644 ui/src/routes/providers/new/+page.svelte diff --git a/ui/src/lib/api/provider_specs.ts b/ui/src/lib/api/provider_specs.ts new file mode 100644 index 0000000..9c98841 --- /dev/null +++ b/ui/src/lib/api/provider_specs.ts @@ -0,0 +1,18 @@ +import { handleApiResponse } from '$lib/errors'; +import type { Provider, ProviderList } from '$lib/model/provider'; + +export async function listProviders(): Promise { + const res = await fetch('/api/providers/_specs', { + method: 'GET', + headers: {'Accept': 'application/json'}, + }); + return await handleApiResponse(res); +} + +export async function getProviderSpec(psid: string): Promise { + const res = await fetch(`/api/providers/_specs/` + psid, { + method: 'GET', + headers: {'Accept': 'application/json'}, + }); + return new Provider(await handleApiResponse(res)); +} diff --git a/ui/src/lib/api/user.ts b/ui/src/lib/api/user.ts index ed3045f..fb7ab9c 100644 --- a/ui/src/lib/api/user.ts +++ b/ui/src/lib/api/user.ts @@ -2,7 +2,7 @@ import { handleApiResponse } from '$lib/errors'; import type { SignUpForm, LoginForm } from '$lib/model/user'; export async function registerUser(form: SignUpForm): Promise { - const res = await fetch('api/users', { + const res = await fetch('/api/users', { method: 'POST', headers: {'Accept': 'application/json'}, body: JSON.stringify(form), @@ -11,7 +11,7 @@ export async function registerUser(form: SignUpForm): Promise { } export async function authUser(form: LoginForm): Promise { - const res = await fetch('api/auth', { + const res = await fetch('/api/auth', { method: 'POST', headers: {'Accept': 'application/json'}, body: JSON.stringify(form), @@ -20,7 +20,7 @@ export async function authUser(form: LoginForm): Promise { } export async function logout(): Promise { - const res = await fetch('api/auth/logout', { + const res = await fetch('/api/auth/logout', { method: 'POST', headers: {'Accept': 'application/json'}, }); @@ -28,7 +28,7 @@ export async function logout(): Promise { } export async function specialUserOperations(email: string, kind: "recovery"|"validation"): Promise { - const res = await fetch('api/users', { + const res = await fetch('/api/users', { method: 'PATCH', headers: {'Accept': 'application/json'}, body: JSON.stringify({ @@ -49,7 +49,7 @@ export async function resendValidationEmail(email: string): Promise { export async function recoverAccount(userid: string, key: string, password: string): Promise { userid = encodeURIComponent(userid); - const res = await fetch(`api/users/${userid}/recovery`, { + const res = await fetch(`/api/users/${userid}/recovery`, { method: 'POST', headers: {'Accept': 'application/json'}, body: JSON.stringify({ @@ -62,7 +62,7 @@ export async function recoverAccount(userid: string, key: string, password: stri export async function validateEmail(userid: string, key: string): Promise { userid = encodeURIComponent(userid); - const res = await fetch(`api/users/${userid}/email`, { + const res = await fetch(`/api/users/${userid}/email`, { method: 'POST', headers: {'Accept': 'application/json'}, body: JSON.stringify({ diff --git a/ui/src/lib/components/Home.svelte b/ui/src/lib/components/Home.svelte new file mode 100644 index 0000000..df1db85 --- /dev/null +++ b/ui/src/lib/components/Home.svelte @@ -0,0 +1,79 @@ + + + +

+ {$t('common.welcome.start')} + + {$t('common.welcome.end')} +

+ + + + + + OK + + + {#if filteredProvider} +
0}> + {#if !noDomainsList} + + {$t("provider.provider")} + {filteredProvider._comment} + + + {/if} + +
+ {/if} + {#if !filteredProvider || noDomainsList} + + {/if} + +
+
diff --git a/ui/src/lib/components/ZoneList.svelte b/ui/src/lib/components/ZoneList.svelte new file mode 100644 index 0000000..fea9910 --- /dev/null +++ b/ui/src/lib/components/ZoneList.svelte @@ -0,0 +1,52 @@ + + +
+ {#if domains.length === 0} + + {:else} + {#each Objects.keys(groups) as gname} + {@const gdomains = groups[gname]} +
+ {#if Object.keys(groups).length != 1} +
+

+ {#if group === undefined} + {$t("domaingroups.no-group")} + {:else} + {gname} + {/if} +

+
+ {/if} + dispatch('click', event.details)} + let:item={item} + > +
+
+ +
+ {item.domain} +
+ +
+
+ {/each} + {/if} +
diff --git a/ui/src/lib/components/providers/ImgProvider.svelte b/ui/src/lib/components/providers/ImgProvider.svelte new file mode 100644 index 0000000..8c608a6 --- /dev/null +++ b/ui/src/lib/components/providers/ImgProvider.svelte @@ -0,0 +1,12 @@ + + +{#if providers_getAll[id_provider]} + {providers_getAll[id_provider]._srctype} +{/if} diff --git a/ui/src/lib/components/providers/Selector.svelte b/ui/src/lib/components/providers/Selector.svelte new file mode 100644 index 0000000..913afef --- /dev/null +++ b/ui/src/lib/components/providers/Selector.svelte @@ -0,0 +1,50 @@ + + + + {#if isLoading} + + Retrieving usable providers... + + {/if} + {#each Object.keys(providers) as ptype (ptype)} + {@const provider = providers[ptype]} + value = provider.id} + > +
+ +
+
+ {provider.name} – + {provider.description} +
+
+ {/each} +
diff --git a/ui/src/lib/locales/en.json b/ui/src/lib/locales/en.json index 9f0768b..44dbc49 100644 --- a/ui/src/lib/locales/en.json +++ b/ui/src/lib/locales/en.json @@ -44,7 +44,10 @@ "run": "Run the request!", "survey": "A remark? a comment to share? Don't hesitate to write us!", "spinning": "Spinning", - "welcome": "Welcome to {{0}}!", + "welcome": { + "start": "Welcome to ", + "end": "!" + }, "help": "Help!", "records": "{{number:eq; 0:no {{type}} record; 1:{{type}} record; default:{{type}} records}}" }, diff --git a/ui/src/lib/locales/fr.json b/ui/src/lib/locales/fr.json index fa9d6ed..430d077 100644 --- a/ui/src/lib/locales/fr.json +++ b/ui/src/lib/locales/fr.json @@ -43,7 +43,10 @@ "resolver": "Résolveur", "run": "Lancer l'opération !", "spinning": "Chargement", - "welcome": "Bienvenue sur {{0}} !", + "welcome": { + "start": "Bienvenue sur ", + "end": " !" + }, "help": "Besoin d'aide ?", "records": "{{number:eq; 0:aucun enregistrement {{type}}; 1:enregistrement {{type}}; default:enregistrements {{type}}}}", "survey": "Une remarque ? un commentaire à partager ? N'hésitez pas à nous écrire !" diff --git a/ui/src/lib/model/domain.ts b/ui/src/lib/model/domain.ts new file mode 100644 index 0000000..6991d57 --- /dev/null +++ b/ui/src/lib/model/domain.ts @@ -0,0 +1,8 @@ +export interface Domain { + id: string; + id_owner: string; + id_provider: string; + domain: string; + group: string; + zone_history: Array; +}; diff --git a/ui/src/lib/model/golang.ts b/ui/src/lib/model/golang.ts new file mode 100644 index 0000000..e75387e --- /dev/null +++ b/ui/src/lib/model/golang.ts @@ -0,0 +1,3 @@ +export interface Map { + [key: T1]: T2; +}; diff --git a/ui/src/lib/model/provider.ts b/ui/src/lib/model/provider.ts new file mode 100644 index 0000000..7a922c8 --- /dev/null +++ b/ui/src/lib/model/provider.ts @@ -0,0 +1,26 @@ +import type Map from '$lib/model/golang'; + +export class ProviderInfos { + name: string; + description: string; + capabilites: Array; + + constructor({ name, description, capabilites }: ProviderInfos) { + this.name = name; + this.description = description; + this.capabilites = capabilites; + } +}; + +export type ProviderList = Map; + +export interface ProviderMeta { + _srctype: string; + _id: string; + _ownerid: string; + _comment: string; +}; + +export interface Provider extends ProviderMeta { + +}; diff --git a/ui/src/lib/model/service.ts b/ui/src/lib/model/service.ts new file mode 100644 index 0000000..530704d --- /dev/null +++ b/ui/src/lib/model/service.ts @@ -0,0 +1,11 @@ +export interface ServiceMeta { + _svctype: string; + _id: string; + _ownerid: string; + _domain: string; + _ttl: number; + _comment: string; + _mycomment: string; + _aliases: Array; + _tmp_hint_nb: number; +}; diff --git a/ui/src/lib/model/source.ts b/ui/src/lib/model/source.ts new file mode 100644 index 0000000..779fc85 --- /dev/null +++ b/ui/src/lib/model/source.ts @@ -0,0 +1,6 @@ +export interface SourceMeta { + _srctype: string; + _id: string; + _ownerid: string; + _comment: string; +}; diff --git a/ui/src/lib/model/zone.ts b/ui/src/lib/model/zone.ts new file mode 100644 index 0000000..a9e20b4 --- /dev/null +++ b/ui/src/lib/model/zone.ts @@ -0,0 +1,9 @@ +export interface ZoneMeta { + id: string; + id_author: string; + default_ttl: Number; + last_modified: Date; + commit_message?: string; + commit_date?: Date; + published?: Date; +}; diff --git a/ui/src/lib/stores/providers.ts b/ui/src/lib/stores/providers.ts new file mode 100644 index 0000000..09d78f5 --- /dev/null +++ b/ui/src/lib/stores/providers.ts @@ -0,0 +1,16 @@ +import { writable, type Writable } from 'svelte/store'; +import type { User } from '$lib/model/user'; + +export const userSession: Writable = writable(null); + +export async function refreshUserSession() { + const res = await fetch('/api/auth', {headers: {'Accept': 'application/json'}}) + if (res.status == 200) { + const user = new User(await res.json()); + userSession.set(user); + return user + } else { + userSession.set(null); + throw new Error((await res.json()).errmsg); + } +} diff --git a/ui/src/routes/+page.svelte b/ui/src/routes/+page.svelte new file mode 100644 index 0000000..131e73c --- /dev/null +++ b/ui/src/routes/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/ui/src/routes/+page.ts b/ui/src/routes/+page.ts index 57ca5ba..7c423c4 100644 --- a/ui/src/routes/+page.ts +++ b/ui/src/routes/+page.ts @@ -5,7 +5,9 @@ import { get_store_value } from 'svelte/internal'; import { userSession } from '$lib/stores/usersession'; import { config as tsConfig, locale } from '$lib/translations'; -export const load: Load = async() => { +export const load: Load = async({ parent }) => { + await parent(); + // If not connected, redirect to main website in the right language if (!get_store_value(userSession)) { const initLocale = locale.get() || window.navigator.language || window.navigator.languages[0] || tsConfig.fallbackLocale; diff --git a/ui/src/routes/providers/new/+layout.svelte b/ui/src/routes/providers/new/+layout.svelte new file mode 100644 index 0000000..58abe3f --- /dev/null +++ b/ui/src/routes/providers/new/+layout.svelte @@ -0,0 +1,25 @@ + + + +

+ + {$t("provider.select-provider")} +

+
+ +
diff --git a/ui/src/routes/providers/new/+page.svelte b/ui/src/routes/providers/new/+page.svelte new file mode 100644 index 0000000..ce5f9a3 --- /dev/null +++ b/ui/src/routes/providers/new/+page.svelte @@ -0,0 +1,18 @@ + + + + + + +