fix: pink v2

This commit is contained in:
Torsten Dittmann
2025-02-24 21:47:52 +04:00
parent 322c175a58
commit e8a8277212
16 changed files with 429 additions and 227 deletions
+3 -9
View File
@@ -1,13 +1,7 @@
<script lang="ts">
import { Tooltip } from '@appwrite.io/pink-svelte';
export let alternativeTrim = false;
let container: HTMLSpanElement | null;
</script>
<Tooltip maxWidth="auto">
<span class={`text ${alternativeTrim ? 'u-trim-1' : 'u-trim'}`} bind:this={container}>
<slot />
</span>
<span slot="tooltip">{container?.innerText ?? undefined} </span>
</Tooltip>
<span class={`text ${alternativeTrim ? 'u-trim-1' : 'u-trim'}`}>
<slot />
</span>
+10 -10
View File
@@ -22,24 +22,24 @@
}
:global(.console-container) {
margin-block: var(--base-32);
margin-inline: 1rem;
@container (min-width: 360px) {
margin-inline: 2.5rem;
@media (min-width: 360px) {
margin-inline: 1rem;
}
@container (min-width: 1024px) {
margin-inline: auto;
@media (min-width: 1024px) {
margin-inline: 2.5rem;
max-width: 944px;
}
@container (min-width: 1280px) {
@media (min-width: 1280px) {
margin-inline: auto;
max-width: 1000px;
}
@container (min-width: 1440px) {
@media (min-width: 1440px) {
margin-inline: auto;
max-width: 1144px;
}
@container (min-width: 1728px) {
@media (min-width: 1728px) {
margin-inline: auto;
max-width: 1200px;
}
}
+10 -9
View File
@@ -36,22 +36,23 @@
justify-content: space-between;
block-size: 100%;
@container (min-width: 360px) {
margin-inline: 2.5rem;
@media (min-width: 360px) {
margin-inline: 1rem;
}
@container (min-width: 1024px) {
margin: 0 auto;
@media (min-width: 1024px) {
margin-inline: 2.5rem;
max-width: 944px;
}
@container (min-width: 1280px) {
@media (min-width: 1280px) {
margin-inline: auto;
max-width: 1000px;
}
@container (min-width: 1440px) {
@media (min-width: 1440px) {
margin-inline: auto;
max-width: 1144px;
}
@container (min-width: 1728px) {
@media (min-width: 1728px) {
margin-inline: auto;
max-width: 1200px;
}
}
+77 -78
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { DropList, DropListItem, Empty, Heading, Modal } from '$lib/components';
import { Empty, Modal, SearchQuery } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { onMount } from 'svelte';
import { dependencyStore, domain, typeStore } from './wizard/store';
@@ -10,16 +10,32 @@
import Create from './create.svelte';
import Delete from './delete.svelte';
import Retry from './wizard/retry.svelte';
import { Pill } from '$lib/elements';
import { canWriteRules } from '$lib/stores/roles';
import { Layout, Table, Link, Icon } from '@appwrite.io/pink-svelte';
import { IconDotsHorizontal, IconPlus } from '@appwrite.io/pink-icons-svelte';
import {
Layout,
Table,
Link,
Icon,
Badge,
Popover,
ActionMenu
} from '@appwrite.io/pink-svelte';
import {
IconCheckCircle,
IconDotsHorizontal,
IconExclamationCircle,
IconPlus,
IconRefresh,
IconTrash
} from '@appwrite.io/pink-icons-svelte';
import { page } from '$app/stores';
import { base } from '$app/paths';
export let search: string;
export let rules: Models.ProxyRuleList;
export let type: ResourceType;
export let dependency: Dependencies;
let showDomainsDropdown = [];
let showDelete = false;
let showRetry = false;
let selectedDomain: Models.ProxyRule;
@@ -34,32 +50,37 @@
wizard.start(Create);
}
function openRetry(rule: Models.ProxyRule, index?: number) {
function openRetry(rule: Models.ProxyRule) {
retryError = null;
if (index !== undefined) {
showDomainsDropdown[index] = false;
}
domain.set(rule);
selectedDomain = rule;
showRetry = true;
}
</script>
{#if $canWriteRules}
<Layout.Stack alignItems="flex-end">
<Button on:click={openWizard}>
<Icon icon={IconPlus} slot="start" size="s" />
Create domain
</Button>
<Layout.Stack direction="row" justifyContent="space-between">
<Layout.Stack direction="row" alignItems="center">
<SearchQuery {search} placeholder="Search by name" />
</Layout.Stack>
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<Button
href={`${base}/project-${$page.params.project}/settings/domains/create`}
event="create_user"
size="s">
<Icon size="s" icon={IconPlus} slot="start" />
<span class="text">Create domain</span>
</Button>
</Layout.Stack>
</Layout.Stack>
{/if}
{#if rules.total}
<Table.Root>
<svelte:fragment slot="header">
<Table.Header.Cell>Name</Table.Header.Cell>
<Table.Header.Cell>Verification Status</Table.Header.Cell>
<Table.Header.Cell>Certificate Status</Table.Header.Cell>
<Table.Header.Cell>Verification status</Table.Header.Cell>
<Table.Header.Cell>Certificate status</Table.Header.Cell>
{#if $canWriteRules}
<Table.Header.Cell width="40" />
<Table.Header.Cell width="20px" />
{/if}
</svelte:fragment>
{#each rules.rules as domain, index}
@@ -74,46 +95,34 @@
<Table.Cell>
{#if domain.status === 'created'}
<Layout.Stack direction="row" alignItems="center">
<Pill danger>
<span
class="icon-exclamation-circle u-color-text-danger"
aria-hidden="true" />
<span class="u-text">failed</span>
</Pill>
<button type="button" on:click={() => openRetry(domain)}>
<span class="link">Retry</span>
</button>
<Badge variant="secondary" content="failed" type="error">
<Icon slot="start" size="s" icon={IconExclamationCircle} />
</Badge>
<Link.Button variant="muted" on:click={() => openRetry(domain)}>
Retry
</Link.Button>
</Layout.Stack>
{:else}
<Pill success>
<span
class="icon-check-circle u-color-text-success"
aria-hidden="true" />
<p class="text">verified</p>
</Pill>
<Badge content="verified" variant="secondary" type="success">
<Icon slot="start" size="s" icon={IconCheckCircle} />
</Badge>
{/if}
</Table.Cell>
<Table.Cell>
{#if domain.status === 'unverified'}
<Layout.Stack direction="row" alignItems="center">
<Pill danger>
<span
class="icon-exclamation-circle u-color-text-danger"
aria-hidden="true" />
<span class="u-text">failed</span>
</Pill>
<button type="button" on:click={() => openRetry(domain)}>
<span class="link">Retry</span>
</button>
<Badge variant="secondary" content="failed" type="error">
<Icon slot="start" size="s" icon={IconExclamationCircle} />
</Badge>
<Link.Button variant="muted" on:click={() => openRetry(domain)}>
Retry
</Link.Button>
</Layout.Stack>
{:else if domain.status === 'verified'}
<Layout.Stack direction="row" alignItems="center">
<Pill success>
<span
class="icon-check-circle u-color-text-success"
aria-hidden="true" />
<span>generated</span>
</Pill>
<Badge content="generated" variant="secondary" type="success">
<Icon slot="start" size="s" icon={IconCheckCircle} />
</Badge>
{#if domain.renewAt}
<span class="u-text-color-gray">
Auto-renewal: {toLocaleDate(domain.renewAt)}
@@ -121,47 +130,37 @@
{/if}
</Layout.Stack>
{:else}
<Pill warning>
<span class="icon-clock u-text-color-gray" aria-hidden="true" />
<p class="text">blocked by verification</p>
</Pill>
<Badge content="blocked by verification" variant="secondary" type="warning">
<Icon slot="start" size="s" icon={IconExclamationCircle} />
</Badge>
{/if}
</Table.Cell>
{#if $canWriteRules}
<Table.Cell>
<DropList
bind:show={showDomainsDropdown[index]}
placement="bottom-start"
noArrow>
<Button
text
icon
ariaLabel="more options"
on:click={() =>
(showDomainsDropdown[index] = !showDomainsDropdown[index])}>
<Popover let:toggle placement="bottom-start" padding="none">
<Button text icon ariaLabel="more options" on:click={toggle}>
<Icon icon={IconDotsHorizontal} size="s" />
</Button>
<svelte:fragment slot="list">
<ActionMenu.Root slot="tooltip">
{#if domain.status !== 'verified'}
<DropListItem
icon="refresh"
on:click={() => openRetry(domain, index)}>
<ActionMenu.Item.Button
leadingIcon={IconRefresh}
on:click={() => openRetry(domain)}>
{domain.status === 'unverified'
? 'Retry generation'
: 'Retry verification'}
</DropListItem>
</ActionMenu.Item.Button>
{/if}
<DropListItem
icon="trash"
<ActionMenu.Item.Button
leadingIcon={IconTrash}
on:click={() => {
selectedDomain = domain;
showDelete = true;
showDomainsDropdown[index] = false;
}}>
Delete
</DropListItem>
</svelte:fragment>
</DropList>
</ActionMenu.Item.Button>
</ActionMenu.Root>
</Popover>
</Table.Cell>
{/if}
</Table.Row>
@@ -176,11 +175,11 @@
{/if}
<Delete bind:showDelete bind:selectedDomain {dependency} />
<Modal bind:show={showRetry} bind:error={retryError}>
<svelte:fragment slot="title">
Retry {$domain.status === 'unverified' ? 'certificate generation' : 'verification'}
</svelte:fragment>
<Retry on:error={(e) => (retryError = e.detail)} />
<Modal
bind:show={showRetry}
bind:error={retryError}
title={`Retry ${selectedDomain?.status === 'unverified' ? 'certificate generation' : 'verification'}`}>
<Retry domain={selectedDomain} on:error={(e) => (retryError = e.detail)} />
<svelte:fragment slot="footer">
<Button secondary on:click={() => (showRetry = false)}>Close</Button>
</svelte:fragment>
+28 -36
View File
@@ -1,44 +1,36 @@
<script lang="ts">
import { Copy } from '$lib/components';
import { Button } from '$lib/elements/forms';
import {
Table,
TableBody,
TableCell,
TableCellHead,
TableCellText,
TableHeader,
TableRow
} from '$lib/elements/table';
import { domain } from './store';
import { Table } from '@appwrite.io/pink-svelte';
import type { Models } from '@appwrite.io/console';
export let domain: Models.ProxyRule;
const target = window?.location.hostname ?? '';
$: parts = $domain.domain.split('.');
$: parts = domain.domain.split('.');
$: registerable = [parts[parts.length - 2], parts[parts.length - 1]].join('.');
$: cnameValue = $domain.domain.replace('.' + registerable, '');
$: cnameValue = domain.domain.replace('.' + registerable, '');
</script>
<Table noMargin noStyles style="--p-table-bg-color: var(--transparent);">
<TableHeader>
<TableCellHead>Type</TableCellHead>
<TableCellHead>Name</TableCellHead>
<TableCellHead>Value</TableCellHead>
<TableCellHead width={50} />
</TableHeader>
<TableBody>
<TableRow>
<TableCellText title="Type">CNAME</TableCellText>
<TableCellText title="Name">{cnameValue}</TableCellText>
<TableCellText title="Value">
{target}
</TableCellText>
<TableCell>
<Button text>
<Copy value={target}>
<span class="icon-duplicate" aria-hidden="true" />
</Copy>
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
<Table.Root>
<svelte:fragment slot="header">
<Table.Header.Cell>Type</Table.Header.Cell>
<Table.Header.Cell>Name</Table.Header.Cell>
<Table.Header.Cell>Value</Table.Header.Cell>
<Table.Header.Cell width="40px" />
</svelte:fragment>
<Table.Row>
<Table.Cell>CNAME</Table.Cell>
<Table.Cell>{cnameValue}</Table.Cell>
<Table.Cell>
{target}
</Table.Cell>
<Table.Cell>
<Button text>
<Copy value={target}>
<span class="icon-duplicate" aria-hidden="true" />
</Copy>
</Button>
</Table.Cell>
</Table.Row>
</Table.Root>
+53 -60
View File
@@ -1,28 +1,31 @@
<script lang="ts">
import { Button } from '$lib/elements/forms';
import { sdk } from '$lib/stores/sdk';
import { domain } from './store';
import CnameTable from './cnameTable.svelte';
import { createEventDispatcher } from 'svelte';
import { Box, Code, Trim } from '$lib/components';
import { Code, Trim } from '$lib/components';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import type { Models } from '@appwrite.io/console';
import { Card, Icon, Layout, Link, Typography } from '@appwrite.io/pink-svelte';
import { IconExclamationCircle } from '@appwrite.io/pink-icons-svelte';
let retrying = false;
export let showTitle = true;
export let domain: Models.ProxyRule;
const dispatch = createEventDispatcher();
async function retry() {
try {
retrying = true;
$domain = await sdk.forProject.proxy.updateRuleVerification($domain.$id);
domain = await sdk.forProject.proxy.updateRuleVerification(domain.$id);
invalidate(Dependencies.FUNCTION_DOMAINS);
addNotification({
message:
$domain.status === 'unverified'
domain.status === 'unverified'
? 'Domain certificate has been generated successfully'
: 'Domain has been verified successfully',
type: 'success'
@@ -37,60 +40,50 @@
}
</script>
{#if showTitle}
<Trim alternativeTrim><b>{$domain.domain}</b></Trim>
{/if}
{#if $domain.status === 'created'}
<Box radius="small">
<div class="u-flex u-gap-8 u-cross-center">
<span class="icon-exclamation-circle u-color-text-danger" aria-hidden="true" />
<p class="u-stretch">Verification failed</p>
<Button secondary on:click={retry} disabled={retrying}>
{#if retrying}
<div class="loader u-text-color-gray" />
{:else}
Retry
{/if}
</Button>
</div>
<p class="text u-margin-block-start-24">
In order to continue, set the following record on your DNS provider. DNS records may
take up to 48 hours to propagate. Please retry over the next 48 hours, but if
verification still fails, please <a
href="https://appwrite.io/discord"
target="_blank"
rel="noopener noreferrer">contact support</a
>.
</p>
<div class="u-margin-block-start-24">
<CnameTable />
</div>
</Box>
{:else if $domain.status === 'unverified'}
<Box radius="small">
<div class="u-flex u-gap-8 u-cross-center">
<span class="icon-exclamation-circle u-color-text-danger" aria-hidden="true" />
<p class="u-stretch">Generation failed</p>
<Button secondary on:click={retry} disabled={retrying}>
{#if retrying}
<div class="loader u-text-color-gray" />
{:else}
Retry
{/if}
</Button>
</div>
<p class="text u-margin-block-start-24">
In order to continue, set the following record on your DNS provider. DNS records may
take up to 48 hours to propagate. Please retry over the next 48 hours, but if
verification still fails, please <a
href="https://appwrite.io/discord"
target="_blank"
rel="noopener noreferrer">contact support</a
>.
</p>
{#if $domain?.logs}
<Code language="sh" withCopy code={$domain.logs} />
{/if}
</Box>
{#if domain.status === 'created'}
<Card.Base variant="secondary" padding="s">
<Layout.Stack gap="s" direction="row" justifyContent="space-between" wrap="wrap">
{#if showTitle}
<b>{domain.domain}</b>
{/if}
<Layout.Stack direction="row" gap="s" inline alignItems="center">
<Icon color="--web-red-500" size="s" icon={IconExclamationCircle} />
<Typography.Text>Verification failed</Typography.Text>
</Layout.Stack>
</Layout.Stack>
</Card.Base>
<Typography.Text>
In order to continue, set the following record on your DNS provider. DNS records may take up
to 48 hours to propagate. Please retry over the next 48 hours, but if verification still
fails, please <Link.Anchor
href="https://appwrite.io/discord"
target="_blank"
rel="noopener noreferrer">contact support</Link.Anchor
>.
</Typography.Text>
<CnameTable bind:domain />
{:else if domain.status === 'unverified'}
<div class="u-flex u-gap-8 u-cross-center">
<span class="icon-exclamation-circle u-color-text-danger" aria-hidden="true" />
<p class="u-stretch">Generation failed</p>
<Button secondary on:click={retry} disabled={retrying}>
{#if retrying}
<div class="loader u-text-color-gray" />
{:else}
Retry
{/if}
</Button>
</div>
<Typography.Text>
In order to continue, set the following record on your DNS provider. DNS records may take up
to 48 hours to propagate. Please retry over the next 48 hours, but if verification still
fails, please <Link.Anchor
href="https://appwrite.io/discord"
target="_blank"
rel="noopener noreferrer">contact support</Link.Anchor
>.
</Typography.Text>
{#if domain?.logs}
<Code language="sh" withCopy code={domain.logs} />
{/if}
{/if}
@@ -62,7 +62,7 @@
confirmExit>
<Form bind:this={formComponent} onSubmit={create} bind:isSubmitting>
<Layout.Stack gap="xxl">
<Fieldset legend="Settings">
<Fieldset legend="Configuration">
<Layout.Stack>
<InputText
id="name"
@@ -180,10 +180,8 @@ APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject.client.config.endpoint}"
{#if isChangingFramework}
<Button.Button
disabled={!selectedFramework}
on:click={() => {
isChangingFramework = false;
}}>
Change framework instructions</Button.Button>
on:click={() => (isChangingFramework = false)}>
Save</Button.Button>
{:else}
<Button.Button type="submit" disabled={!selectedFramework}
>Create platform</Button.Button>
@@ -9,7 +9,11 @@
</script>
<Container>
<ProxyRulesPage rules={data.rules} type={ResourceType.Api} dependency={Dependencies.DOMAINS}>
<ProxyRulesPage
search={data.search}
rules={data.rules}
type={ResourceType.Api}
dependency={Dependencies.DOMAINS}>
<svelte:fragment slot="heading">Custom domains</svelte:fragment>
</ProxyRulesPage>
</Container>
@@ -2,14 +2,19 @@ import { Dependencies } from '$lib/constants';
import { sdk } from '$lib/stores/sdk';
import { Query, ResourceType } from '@appwrite.io/console';
import type { PageLoad } from './$types';
import { getSearch } from '$lib/helpers/load';
export const load: PageLoad = async ({ depends, url }) => {
depends(Dependencies.DOMAINS);
const search = getSearch(url);
return {
rules: await sdk.forProject.proxy.listRules([
Query.equal('resourceType', ResourceType.Site)
]),
search,
rules: await sdk.forProject.proxy.listRules(
[Query.equal('resourceType', [ResourceType.Site, ResourceType.Api])],
search || undefined
),
create: url.searchParams.get('create') !== null
};
};
@@ -0,0 +1,73 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Wizard } from '$lib/layout';
import { Fieldset, Layout } from '@appwrite.io/pink-svelte';
import Button from '$lib/elements/forms/button.svelte';
import Form from '$lib/elements/forms/form.svelte';
import { writable } from 'svelte/store';
import { InputDomain } from '$lib/elements/forms';
import { goto } from '$app/navigation';
import { sdk } from '$lib/stores/sdk';
import { ResourceType } from '@appwrite.io/console';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
let showExitModal = false;
let formComponent: Form;
let isSubmitting = writable(false);
export let data;
let domain = data.domain;
async function create() {
try {
if (data.$id) {
await sdk.forProject.proxy.deleteRule(data.$id);
}
const value = await sdk.forProject.proxy.createRule(domain, ResourceType.Api);
trackEvent(Submit.DomainCreate);
goto(`${base}/project-${$page.params.project}/settings/domains/create/${value.$id}`);
} catch (e) {
trackError(e.message, Submit.DomainCreate);
throw new Error(e.message);
}
}
</script>
<Wizard
title="Create custom domain"
href={`${base}/project-${$page.params.project}/settings/domains`}
bind:showExitModal
column
hideFooter
confirmExit>
<Form bind:this={formComponent} onSubmit={create} bind:isSubmitting>
<Layout.Stack gap="xxl">
<Fieldset legend="Configuration">
<Layout.Stack gap="l" alignItems="flex-end">
<Layout.Stack gap="s">
<InputDomain
id="domain"
label="Domain"
placeholder="appwrite.example.com"
autocomplete={false}
required
bind:value={domain} />
</Layout.Stack>
<Button
fullWidthMobile
size="s"
submit
forceShowLoader
on:click={() => formComponent.triggerSubmit()}
disabled={$isSubmitting}>
Create domain
</Button>
</Layout.Stack>
</Fieldset>
</Layout.Stack>
</Form>
</Wizard>
@@ -0,0 +1,6 @@
export const load = async ({ url }) => {
const domain = url.searchParams.get('domain');
const $id = url.searchParams.get('$id');
return { domain, $id };
};
@@ -0,0 +1,131 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Wizard } from '$lib/layout';
import {
Alert,
Card,
Fieldset,
Icon,
Layout,
Spinner,
Status,
Typography
} from '@appwrite.io/pink-svelte';
import Button from '$lib/elements/forms/button.svelte';
import Form from '$lib/elements/forms/form.svelte';
import { sdk } from '$lib/stores/sdk';
import { onboarding } from '$routes/(console)/project-[project]/store';
import { goto, invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { addNotification } from '$lib/stores/notifications';
import { writable } from 'svelte/store';
import Retry from '$lib/pages/domains/wizard/retry.svelte';
import Box from '$lib/components/box.svelte';
import { IconClock } from '@appwrite.io/pink-icons-svelte';
let retrying = false;
let showExitModal = false;
let isSubmitting = writable(false);
export let data;
let domain = data.domain;
function onSubmit() {}
async function retry() {
try {
retrying = true;
domain = await sdk.forProject.proxy.updateRuleVerification(domain.$id);
invalidate(Dependencies.FUNCTION_DOMAINS);
addNotification({
message:
domain.status === 'unverified'
? 'Domain certificate has been generated successfully'
: 'Domain has been verified successfully',
type: 'success'
});
trackEvent(Submit.DomainUpdateVerification);
} catch (error) {
addNotification({
message: error.message,
type: 'error'
});
trackError(error, Submit.DomainUpdateVerification);
} finally {
retrying = false;
}
}
</script>
<Wizard
title={data.domain.domain}
href={`${base}/project-${$page.params.project}/settings/domains/`}
bind:showExitModal
column>
<Form {onSubmit} bind:isSubmitting>
<Layout.Stack gap="xxl">
<Card.Base padding="s"
><Layout.Stack direction="row" justifyContent="space-between" alignItems="center">
<Layout.Stack gap="xxs" direction="row">
<Typography.Text variant="m-500">{data.domain.domain}</Typography.Text>
</Layout.Stack>
<Button
secondary
size="s"
href={`${base}/project-${$page.params.project}/settings/domains/create?domain=${data.domain.domain}&$id=${data.domain.$id}`}
>Change</Button>
</Layout.Stack></Card.Base>
<Fieldset legend="DNS">
<Layout.Stack gap="l" alignItems="flex-end">
<Layout.Stack>
{#if data.domain.status === 'created'}
<Retry bind:domain showTitle={false} />
{:else}
<div class="u-flex u-gap-8 u-cross-center">
<span class="icon-check u-color-text-success" aria-hidden="true" />
<p class="u-stretch">Domain verified</p>
</div>
{/if}
<Card.Base variant="secondary" padding="s">
<Layout.Stack direction="row" gap="s" alignItems="center">
{#if domain.status === 'verifying'}
<Spinner size="s" />
<p class="u-stretch">Generating certificate</p>
{:else if domain.status === 'verified'}
<Status status="complete" label="Certificate generated" />
{:else}
<Icon icon={IconClock} size="s" />
Certificate generation will begin after domain verification
{/if}
</Layout.Stack>
</Card.Base>
</Layout.Stack>
{#if data.domain.status === 'created'}
<Button
fullWidthMobile
size="s"
submit
secondary
forceShowLoader
on:click={retry}
disabled={retrying}>
Retry
</Button>
{/if}
</Layout.Stack>
</Fieldset>
</Layout.Stack>
</Form>
<svelte:fragment slot="footer">
<Button
fullWidthMobile
secondary
href={`${base}/project-${$page.params.project}/settings/domains`}>
Go to Domains
</Button>
</svelte:fragment>
</Wizard>
@@ -0,0 +1,6 @@
import { sdk } from '$lib/stores/sdk';
export const load = async ({ params }) => {
const domain = await sdk.forProject.proxy.getRule(params.domain);
return { domain };
};