mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: update functions domains
This commit is contained in:
+8
-10
@@ -21,18 +21,16 @@
|
||||
|
||||
const routeBase = `${base}/project-${page.params.project}/functions/function-${page.params.function}/domains`;
|
||||
|
||||
export let data;
|
||||
let { data } = $props();
|
||||
|
||||
let formComponent: Form;
|
||||
let isSubmitting = writable(false);
|
||||
|
||||
let showConnectRepo = false;
|
||||
|
||||
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = 'ACTIVE';
|
||||
let domainName = '';
|
||||
let redirect: string = null;
|
||||
let statusCode = 307;
|
||||
let branch = null;
|
||||
let isSubmitting = $state(writable(false));
|
||||
let showConnectRepo = $state(false);
|
||||
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = $state('ACTIVE');
|
||||
let domainName = $state('');
|
||||
let redirect: string = $state(null);
|
||||
let statusCode = $state(307);
|
||||
let branch: string = $state(null);
|
||||
|
||||
onMount(() => {
|
||||
if (
|
||||
|
||||
+3
-1
@@ -1,9 +1,11 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import { RuleTrigger, RuleType } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
|
||||
export const load = async ({ parent }) => {
|
||||
export const load = async ({ parent, depends }) => {
|
||||
const { function: func } = await parent();
|
||||
depends(Dependencies.DOMAINS, Dependencies.FUNCTION_DOMAINS);
|
||||
|
||||
const [domains, installations] = await Promise.all([
|
||||
sdk.forProject.proxy.listRules([
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<script lang="ts">
|
||||
import { IconGlobeAlt } from '@appwrite.io/pink-icons-svelte';
|
||||
import {
|
||||
Card,
|
||||
Divider,
|
||||
Fieldset,
|
||||
Icon,
|
||||
Layout,
|
||||
Tabs,
|
||||
Typography
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Button, Form } from '$lib/elements/forms';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { goto, invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { page } from '$app/state';
|
||||
import Wizard from '$lib/layout/wizard.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { writable } from 'svelte/store';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
|
||||
import RecordTable from '$lib/components/domains/recordTable.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
|
||||
const ruleId = page.url.searchParams.get('rule');
|
||||
let isSubDomain = $derived(page.params.domain?.split('.')?.length >= 3);
|
||||
|
||||
let selectedTab: 'cname' | 'nameserver' | 'a' | 'aaaa' = $state(
|
||||
!!$consoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain
|
||||
? 'cname'
|
||||
: !!$consoleVariables._APP_DOMAIN_TARGET_A
|
||||
? 'a'
|
||||
: !!$consoleVariables._APP_DOMAIN_TARGET_AAAA
|
||||
? 'aaaa'
|
||||
: 'nameserver'
|
||||
);
|
||||
let verified = $state(false);
|
||||
|
||||
let routeBase = `${base}/project-${page.params.project}/functions/function-${page.params.function}/domains`;
|
||||
let isSubmitting = $state(writable(false));
|
||||
|
||||
async function verify() {
|
||||
const isNewDomain =
|
||||
data.domainsList.domains.findIndex((rule) => rule.domain === page.params.domain) === -1;
|
||||
try {
|
||||
if (selectedTab !== 'nameserver') {
|
||||
const ruleData = await sdk.forProject.proxy.updateRuleVerification(ruleId);
|
||||
verified = ruleData.status === 'verified';
|
||||
} else if (isNewDomain && isCloud) {
|
||||
const domainData = await sdk.forConsole.domains.create(
|
||||
$organization.$id,
|
||||
page.params.domain
|
||||
);
|
||||
verified = domainData.nameservers.toLocaleLowerCase() === 'appwrite';
|
||||
}
|
||||
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Domain added successfully'
|
||||
});
|
||||
await goto(routeBase);
|
||||
await invalidate(Dependencies.DOMAINS);
|
||||
await invalidate(Dependencies.FUNCTION_DOMAINS);
|
||||
} catch (error) {
|
||||
verified = false;
|
||||
isSubmitting.set(false);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function back() {
|
||||
if (ruleId) {
|
||||
await sdk.forProject.proxy.deleteRule(ruleId);
|
||||
}
|
||||
await goto(`${routeBase}/add-domain?domain=${page.params.domain}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Wizard title="Add domain" href={routeBase} column columnSize="s">
|
||||
<Form onSubmit={verify} bind:isSubmitting>
|
||||
<Layout.Stack gap="xxl">
|
||||
<Card.Base radius="s" padding="s">
|
||||
<Layout.Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap="xs">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="xs">
|
||||
<Icon icon={IconGlobeAlt} color="--fgcolor-neutral-primary" />
|
||||
|
||||
<Typography.Text variation="m-500" color="--fgcolor-neutral-primary">
|
||||
{page.params.domain}
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
<Button secondary on:click={back}>Change</Button>
|
||||
</Layout.Stack>
|
||||
</Card.Base>
|
||||
|
||||
<Fieldset legend="Verification">
|
||||
<Layout.Stack gap="xl">
|
||||
<div>
|
||||
<Tabs.Root variant="secondary" let:root>
|
||||
{#if isSubDomain && !!$consoleVariables._APP_DOMAIN_TARGET_CNAME && $consoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'}
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'cname')}
|
||||
active={selectedTab === 'cname'}>
|
||||
CNAME
|
||||
</Tabs.Item.Button>
|
||||
{/if}
|
||||
{#if isCloud}
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'nameserver')}
|
||||
active={selectedTab === 'nameserver'}>
|
||||
Nameservers
|
||||
</Tabs.Item.Button>
|
||||
{/if}
|
||||
{#if !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'a')}
|
||||
active={selectedTab === 'a'}>
|
||||
A
|
||||
</Tabs.Item.Button>
|
||||
{/if}
|
||||
{#if !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'aaaa')}
|
||||
active={selectedTab === 'aaaa'}>
|
||||
AAAA
|
||||
</Tabs.Item.Button>
|
||||
{/if}
|
||||
</Tabs.Root>
|
||||
<Divider />
|
||||
</div>
|
||||
{#if selectedTab === 'nameserver'}
|
||||
<NameserverTable domain={page.params.domain} {verified} />
|
||||
{:else}
|
||||
<RecordTable domain={page.params.domain} {verified} variant={selectedTab} />
|
||||
{/if}
|
||||
<Divider />
|
||||
<Layout.Stack direction="row" justifyContent="flex-end">
|
||||
<div>
|
||||
<Button submit disabled={$isSubmitting}>Verify</Button>
|
||||
</div>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
</Wizard>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants.js';
|
||||
import { isCloud } from '$lib/system';
|
||||
import type { Domain, DomainsList } from '$lib/sdk/domains.js';
|
||||
|
||||
export const load = async ({ parent, depends, params }) => {
|
||||
depends(Dependencies.DOMAINS);
|
||||
|
||||
let domain: Domain;
|
||||
let domainsList: DomainsList;
|
||||
if (isCloud) {
|
||||
[domain, domainsList] = await Promise.all([
|
||||
sdk.forConsole.domains.get(params.domain),
|
||||
sdk.forConsole.domains.list()
|
||||
]);
|
||||
}
|
||||
|
||||
return {
|
||||
domain,
|
||||
domainsList
|
||||
};
|
||||
};
|
||||
-182
@@ -1,182 +0,0 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Badge,
|
||||
Divider,
|
||||
Fieldset,
|
||||
Icon,
|
||||
InteractiveText,
|
||||
Layout,
|
||||
Table,
|
||||
Tabs,
|
||||
Typography
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Card } from '$lib/components';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Link } from '$lib/elements';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
|
||||
const backPage = `${base}/project-${page.params.project}/sites/site-${page.params.site}/domains`;
|
||||
|
||||
let nameservers = $consoleVariables?._APP_DOMAINS_NAMESERVERS
|
||||
? $consoleVariables?._APP_DOMAINS_NAMESERVERS.split(',')
|
||||
: ['ns1.appwrite.io', 'ns2.appwrite.io'];
|
||||
|
||||
export let data;
|
||||
async function verifyStatus() {
|
||||
try {
|
||||
await sdk.forProject.proxy.updateRuleVerification(data.domain.$id);
|
||||
console.log(data.domain);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let selectedTab: 'cname' | 'nameserver' = 'cname';
|
||||
|
||||
$: isVerified = data.domain?.nameservers?.toLocaleLowerCase() === 'appwrite';
|
||||
</script>
|
||||
|
||||
<Wizard title="Add custom domain" href={backPage} column columnSize="s" hideFooter>
|
||||
{#if isVerified}
|
||||
<Card radius="s">
|
||||
<Layout.Stack gap="s" direction="row" alignItems="center">
|
||||
<Typography.Text variant="l-500">{data.domain.domain}</Typography.Text>
|
||||
<Badge variant="secondary" type="success" content="Verified" />
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
{:else}
|
||||
<Fieldset legend="Verification">
|
||||
<Layout.Stack gap="xl">
|
||||
<div>
|
||||
<Tabs.Root variant="secondary" let:root>
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'cname')}
|
||||
active={selectedTab === 'cname'}>
|
||||
CNAME
|
||||
</Tabs.Item.Button>
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'nameserver')}
|
||||
active={selectedTab === 'nameserver'}>
|
||||
Nameservers
|
||||
</Tabs.Item.Button>
|
||||
</Tabs.Root>
|
||||
<Divider />
|
||||
</div>
|
||||
{#if selectedTab === 'cname'}
|
||||
<Layout.Stack gap="s">
|
||||
<Layout.Stack gap="s" direction="row" alignItems="center">
|
||||
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary"
|
||||
>{data.domain?.domain}</Typography.Text>
|
||||
{#if isVerified}
|
||||
<Badge variant="secondary" type="success" content="Verified" />
|
||||
{:else}
|
||||
<Badge
|
||||
variant="secondary"
|
||||
type="warning"
|
||||
size="xs"
|
||||
content="Pending verification" />
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
<Typography.Text variant="m-400">
|
||||
Add the following record on your DNS provider. Note that DNS changes may
|
||||
take time to propagate fully.
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
|
||||
<Table.Root columns={3} let:root>
|
||||
<svelte:fragment slot="header" let:root>
|
||||
<Table.Header.Cell {root}>Type</Table.Header.Cell>
|
||||
<Table.Header.Cell {root}>Name</Table.Header.Cell>
|
||||
<Table.Header.Cell {root}>Value</Table.Header.Cell>
|
||||
</svelte:fragment>
|
||||
<Table.Row.Base {root}>
|
||||
<Table.Cell {root}>CNAME</Table.Cell>
|
||||
<Table.Cell {root}>{data.domain?.domain}</Table.Cell>
|
||||
<Table.Cell {root}>
|
||||
<InteractiveText
|
||||
variant="copy"
|
||||
isVisible
|
||||
text={globalThis?.location?.origin}>
|
||||
{globalThis?.location?.origin}</InteractiveText>
|
||||
</Table.Cell>
|
||||
</Table.Row.Base>
|
||||
</Table.Root>
|
||||
<Layout.Stack gap="s" direction="row" alignItems="center">
|
||||
<Icon icon={IconInfo} size="s" color="--fgcolor-neutral-secondary" />
|
||||
<Typography.Text variant="m-400" color="--fgcolor-neutral-secondary">
|
||||
A list of all domain providers and their DNS setting is available <Link
|
||||
variant="muted"
|
||||
external
|
||||
href="https://appwrite.io/docs/advanced/platform/custom-domains"
|
||||
>here</Link
|
||||
>.
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
|
||||
<Divider />
|
||||
<Layout.Stack direction="row" justifyContent="flex-end">
|
||||
<Button on:click={verifyStatus}>Verify</Button>
|
||||
</Layout.Stack>
|
||||
{:else}
|
||||
<Layout.Stack gap="s">
|
||||
<Layout.Stack gap="s" direction="row" alignItems="center">
|
||||
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary"
|
||||
>{data.domain?.domain}</Typography.Text>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
type="warning"
|
||||
size="xs"
|
||||
content="Pending verification" />
|
||||
</Layout.Stack>
|
||||
<Typography.Text variant="m-400">
|
||||
Add the following nameservers on your DNS provider. Note that DNS
|
||||
changes may take time to propagate fully.
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
|
||||
<Table.Root columns={2} let:root>
|
||||
<svelte:fragment slot="header" let:root>
|
||||
<Table.Header.Cell {root}>Type</Table.Header.Cell>
|
||||
<Table.Header.Cell {root}>Value</Table.Header.Cell>
|
||||
</svelte:fragment>
|
||||
{#each nameservers as nameserver}
|
||||
<Table.Row.Base {root}>
|
||||
<Table.Cell {root}>NS</Table.Cell>
|
||||
<Table.Cell {root}>
|
||||
<InteractiveText variant="copy" isVisible text={nameserver}>
|
||||
{nameserver}</InteractiveText>
|
||||
</Table.Cell>
|
||||
</Table.Row.Base>
|
||||
{/each}
|
||||
</Table.Root>
|
||||
<!-- <Layout.Stack gap="s" direction="row" alignItems="center">
|
||||
<Icon icon={IconInfo} size="s" color="--fgcolor-neutral-secondary" />
|
||||
<Typography.Text variant="m-400" color="--fgcolor-neutral-secondary">
|
||||
A list of all domain providers and their DNS setting is available <Link
|
||||
variant="muted"
|
||||
href="https://appwrite.io/docs/advanced/platform/custom-domains"
|
||||
>here</Link
|
||||
>.
|
||||
</Typography.Text>
|
||||
</Layout.Stack> -->
|
||||
|
||||
<Divider />
|
||||
<Layout.Stack direction="row" justifyContent="flex-end">
|
||||
<Button on:click={verifyStatus}>Verify</Button>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{/if}
|
||||
</Wizard>
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
// import { sdk } from '$lib/stores/sdk';
|
||||
import { isCloud } from '$lib/system';
|
||||
|
||||
export const load = async (/*{ params }*/) => {
|
||||
if (isCloud) {
|
||||
// if (params?.id) {
|
||||
// return {
|
||||
// domain: await sdk.forConsole.domains.get(params.id)
|
||||
// };
|
||||
// }
|
||||
} else {
|
||||
return {
|
||||
domain: undefined
|
||||
};
|
||||
}
|
||||
};
|
||||
+8
-10
@@ -26,18 +26,16 @@
|
||||
|
||||
const routeBase = `${base}/project-${page.params.project}/sites/site-${page.params.site}/domains`;
|
||||
|
||||
export let data;
|
||||
let { data } = $props();
|
||||
|
||||
let formComponent: Form;
|
||||
let isSubmitting = writable(false);
|
||||
|
||||
let showConnectRepo = false;
|
||||
|
||||
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = 'ACTIVE';
|
||||
let domainName = '';
|
||||
let redirect: string = null;
|
||||
let statusCode = 307;
|
||||
let branch = null;
|
||||
let isSubmitting = $state(writable(false));
|
||||
let showConnectRepo = $state(false);
|
||||
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = $state('ACTIVE');
|
||||
let domainName = $state('');
|
||||
let redirect: string = $state(null);
|
||||
let statusCode = $state(307);
|
||||
let branch: string = $state(null);
|
||||
|
||||
onMount(() => {
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user