Make route organization RESTful

This commit is contained in:
Alexis Sellier
2021-05-19 12:15:49 +02:00
parent 73b00be0af
commit b61c336dca
19 changed files with 66 additions and 43 deletions
+6 -6
View File
@@ -4,11 +4,11 @@
import { getConfig } from '@app/config';
import { session } from '@app/session';
import Home from '@app/base/home/Home.svelte';
import Vesting from '@app/base/vesting/Vesting.svelte';
import Register from '@app/base/register/Routes.svelte';
import Home from '@app/base/home/Index.svelte';
import Vesting from '@app/base/vesting/Index.svelte';
import Registrations from '@app/base/registrations/Routes.svelte';
import Orgs from '@app/base/orgs/Routes.svelte';
import Resolve from '@app/base/resolve/Routes.svelte';
import Resolver from '@app/base/resolver/Routes.svelte';
import Header from '@app/Header.svelte';
function handleKeydown(event: KeyboardEvent) {
@@ -43,9 +43,9 @@
<Route path="vesting">
<Vesting {config} session={$session} />
</Route>
<Register {config} session={$session} />
<Registrations {config} session={$session} />
<Orgs {config} />
<Resolve {config} />
<Resolver {config} />
</Router>
</div>
</div>
+3 -1
View File
@@ -24,7 +24,9 @@
</span>
<span slot="body">
<strong>Error:</strong> {body}
<slot>
<strong>Error:</strong> {body}
</slot>
</span>
<span slot="actions">
+1 -1
View File
@@ -88,7 +88,7 @@
<div class="left">
<a use:link href="/"><Logo /></a>
<div class="nav">
<a use:link href="/register/">Register</a>
<a use:link href="/registrations">Register</a>
<a use:link href="/vesting/">Vesting</a>
{#if config.network.name === 'ropsten'}
<a use:link href="/orgs/">Orgs</a>
@@ -3,7 +3,7 @@
let input: string = "";
const search = () => {
navigate(`/resolve?${
navigate(`/resolver/query?${
new URLSearchParams({ q: input })
}`);
};
+4 -4
View File
@@ -1,16 +1,16 @@
<script lang="typescript">
import { Route } from "svelte-routing";
import Orgs from '@app/base/orgs/Orgs.svelte';
import Profile from '@app/base/orgs/Profile.svelte';
import Index from '@app/base/orgs/Index.svelte';
import View from '@app/base/orgs/View.svelte';
import type { Config } from '@app/config';
export let config: Config;
</script>
<Route path="/orgs">
<Orgs {config} />
<Index {config} />
</Route>
<Route path="/orgs/:address" let:params>
<Profile {config} address={params.address} />
<View {config} address={params.address} />
</Route>
@@ -4,8 +4,8 @@
import type { SvelteComponent } from 'svelte';
import { navigate } from 'svelte-routing';
import type { Config } from '@app/config';
import type { Registration } from '@app/base/register/registrar';
import { getRegistration } from '@app/base/register/registrar';
import type { Registration } from '@app/base/registrations/registrar';
import { getRegistration } from '@app/base/registrations/registrar';
import { parseEnsLabel, explorerLink } from '@app/utils';
import { Org } from './Org';
import { session } from '@app/session';
@@ -14,6 +14,7 @@
import Error from '@app/Error.svelte';
import Icon from '@app/Icon.svelte';
import SetName from '@app/ens/SetName.svelte';
import * as utils from '@app/utils';
export let address: string;
export let config: Config;
@@ -144,10 +145,12 @@
<span slot="body">
<p class="highlight"><strong>{address}</strong></p>
<p>Sorry, there is no Org at this address.</p>
<p>
<a href={explorerLink(address, config)} target="_blank">View in explorer</a>
<span class="faded">↗</span>
</p>
{#if utils.isAddress(address)}
<p>
<a href={explorerLink(address, config)} target="_blank">View in explorer</a>
<span class="faded">↗</span>
</p>
{/if}
</span>
<span slot="actions">
<button on:click={back}>
@@ -24,7 +24,7 @@
registrar(config).available(name).then((isAvailable: boolean) => {
if (isAvailable) {
state = State.NameAvailable;
navigate(`/register/${name}`);
navigate(`/registrations/${name}/form`);
} else {
state = State.NameUnavailable;
}
@@ -3,13 +3,14 @@
// Perhaps the availability check should be moved out of the 'submit' step then.
import { navigate } from 'svelte-routing';
import { formatAddress } from '@app/utils';
import { registrar } from '../registrar';
import { session } from '@app/session';
import type { Config } from '@app/config';
import Connect from '@app/Connect.svelte';
import Modal from '@app/Modal.svelte';
import { registrar } from './registrar';
enum State {
Initial,
CheckingAvailability,
@@ -27,7 +28,7 @@
state = State.CheckingAvailability;
if (await registrar(config).available(subdomain)) {
navigate(`/register/${subdomain}/submit?${
navigate(`/registrations/${subdomain}/submit?${
registrationOwner ? new URLSearchParams({ owner: registrationOwner }) : ''
}`);
} else {
@@ -63,7 +64,7 @@
Checking availability...
</button>
{:else if state === State.NameUnavailable}
<button on:click={() => navigate("/register")} class="">
<button on:click={() => navigate("/registrations")} class="">
Back
</button>
{:else}
@@ -75,7 +76,7 @@
<Connect caption="Connect to register" className="primary" {config} />
{/if}
<button on:click={() => navigate("/register")} class="text">
<button on:click={() => navigate("/registrations")} class="text">
Cancel
</button>
{/if}
@@ -1,9 +1,9 @@
<script lang="typescript">
import { Route, navigate } from "svelte-routing";
import Register from '@app/base/register/Register.svelte';
import Begin from '@app/base/register/steps/Begin.svelte';
import Submit from '@app/base/register/steps/Submit.svelte';
import Registration from '@app/base/register/Registration.svelte';
import Index from '@app/base/registrations/Index.svelte';
import New from '@app/base/registrations/New.svelte';
import Submit from '@app/base/registrations/Submit.svelte';
import View from '@app/base/registrations/View.svelte';
import Error from '@app/Error.svelte';
import type { Config } from '@app/config';
import type { Session } from '@app/session';
@@ -13,25 +13,25 @@
export let config: Config;
</script>
<Route path="register">
<Register {config} />
<Route path="registrations">
<Index {config} />
</Route>
<Route path="register/:name" let:params let:location>
<Begin {config} subdomain={params.name} owner={getSearchParam("owner", location)} />
<Route path="registrations/:name/form" let:params let:location>
<New {config} subdomain={params.name} owner={getSearchParam("owner", location)} />
</Route>
<Route path="register/:name/submit" let:params let:location>
<Route path="registrations/:name/submit" let:params let:location>
{#if session}
<Submit {config} subdomain={params.name} owner={getSearchParam("owner", location)} {session} />
{:else}
<Error
message={"You must connect your wallet to register"}
on:close={() => navigate("/register")}
on:close={() => navigate("/registrations")}
/>
{/if}
</Route>
<Route path="registrations/:name" let:params>
<Registration {config} subdomain={params.name} />
<View {config} subdomain={params.name} />
</Route>
@@ -3,14 +3,15 @@
// TODO: When transfering name, warn about transfering to org.
import { onMount } from 'svelte';
import { navigate } from 'svelte-routing';
import { registerName } from '../registrar';
import { State, state } from '../state';
import type { Session } from '@app/session';
import type { Config } from '@app/config';
import Loading from '@app/Loading.svelte';
import Modal from '@app/Modal.svelte';
import Err from '@app/Error.svelte';
import { registerName } from './registrar';
import { State, state } from './state';
export let config: Config;
export let subdomain: string;
export let owner: string | null;
@@ -39,7 +40,7 @@
<Err
title="Transaction failed"
message={error.message}
on:close={() => navigate('/register')}
on:close={() => navigate('/registrations')}
/>
{:else}
<Modal>
@@ -29,6 +29,7 @@
let registration: Registration | null = null;
let name = `${subdomain}.${config.registrar.domain}`;
// TODO: Handle failure (network error)
const loadRegistration = getRegistration(name, config)
.then(r => {
if (r) {
@@ -141,7 +142,7 @@
</span>
<span slot="actions">
<Link to={`/register/${subdomain}`} primary>Register &rarr;</Link>
<Link to={`/registrations/${subdomain}/form`} primary>Register &rarr;</Link>
</span>
</Modal>
{/if}
@@ -4,10 +4,13 @@
import { navigate } from 'svelte-routing';
import type { Config } from '@app/config';
import * as utils from '@app/utils';
import Error from '@app/Error.svelte';
export let config: Config;
export let query: string | null;
let error = false;
onMount(() => {
if (query) {
if (ethers.utils.isAddress(query)) {
@@ -18,10 +21,22 @@
alert("Radicle IDs are not yet supported");
} else {
let label = utils.parseEnsLabel(query, config);
navigate(`/registrations/${label}`, { replace: true });
if (label.includes(".")) {
error = true;
} else {
navigate(`/registrations/${label}`, { replace: true });
}
}
} else {
navigate('/');
}
});
</script>
<main>
{#if error}
<Error on:close={() => navigate('/')}>
Invalid query string “{query}”
</Error>
{/if}
</main>
@@ -1,12 +1,12 @@
<script lang="typescript">
import { Route } from "svelte-routing";
import Resolve from '@app/base/resolve/Resolve.svelte';
import Resolve from '@app/base/resolver/Query.svelte';
import type { Config } from '@app/config';
import * as utils from '@app/utils';
export let config: Config;
</script>
<Route path="/resolve" let:location>
<Route path="/resolver/query" let:location>
<Resolve {config} query={utils.getSearchParam("q", location)} />
</Route>
+1 -1
View File
@@ -19,7 +19,7 @@ export function capitalize(s: string) {
// Takes a domain name, eg. 'cloudhead.radicle.eth' and
// returns the label, eg. 'cloudhead', otherwise `null`.
export function parseEnsLabel(name: string, config: Config): string | null {
export function parseEnsLabel(name: string, config: Config): string {
let domain = config.registrar.domain.replace(".", "\\.");
let label = name.replace(new RegExp(`\\.${domain}$`), "");