mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: pink v2
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
Reference in New Issue
Block a user