Merge branch 'feat-pink-v2' into 'clean-checks'.

This commit is contained in:
Darshan
2025-03-19 19:53:51 +05:30
10 changed files with 361 additions and 450 deletions
+22
View File
@@ -0,0 +1,22 @@
export const statusCodeOptions = [
{
label: '301 Moved permanently',
value: 301
},
{
label: '302 Found',
value: 302
},
{
label: '303 See other',
value: 303
},
{
label: '307 Temporary redirect',
value: 307
},
{
label: '308 Permanent redirect',
value: 308
}
];
@@ -3,41 +3,16 @@
import { page } from '$app/stores';
import { EmptySearch, PaginationWithLimit } from '$lib/components/index.js';
import { Button } from '$lib/elements/forms';
import Link from '$lib/elements/link.svelte';
import Container from '$lib/layout/container.svelte';
import { protocol } from '$routes/(console)/store.js';
import type { Models } from '@appwrite.io/console';
import {
IconDotsHorizontal,
IconExternalLink,
IconPlus,
IconRefresh,
IconTrash
} from '@appwrite.io/pink-icons-svelte';
import {
ActionMenu,
Card,
Empty,
Icon,
Layout,
Popover,
Table
} from '@appwrite.io/pink-svelte';
import DeleteDomainModal from './deleteDomainModal.svelte';
import RetryDomainModal from './retryDomainModal.svelte';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import { Card, Empty, Icon, Layout } from '@appwrite.io/pink-svelte';
import SearchQuery from '$lib/components/searchQuery.svelte';
import { app } from '$lib/stores/app';
import { Click, trackEvent } from '$lib/actions/analytics';
import CreatePreviewDomainModal from './createPreviewDomainModal.svelte';
import type { Domain } from '$lib/sdk/domains.js';
import Table from './table.svelte';
export let data;
let showDelete = false;
let showRetry = false;
let showPreviewDomainModal = false;
let selectedDomain: Domain | Models.ProxyRule = null;
$: console.log(data.domains);
</script>
@@ -57,80 +32,7 @@
</Layout.Stack>
{#if data.domains.total}
<Table.Root columns={4} let:root>
<svelte:fragment slot="header" let:root>
<Table.Header.Cell {root}>Domain</Table.Header.Cell>
<Table.Header.Cell {root}>Redirect to</Table.Header.Cell>
<Table.Header.Cell {root}>Production branch</Table.Header.Cell>
<Table.Header.Cell {root} />
</svelte:fragment>
{#each data.domains.rules as domain}
<Table.Row.Base {root}>
<Table.Cell {root}>
<Link external href={`${$protocol}${domain.domain}`} variant="quiet">
<Layout.Stack direction="row" alignItems="center" gap="xs">
{domain.domain}
<Icon icon={IconExternalLink} size="s" />
</Layout.Stack>
</Link>
</Table.Cell>
<!-- TODO design redirect status code -->
<Table.Cell {root}>
{domain?.redirectUrl || 'No redirect'}
{domain?.redirectStatusCode ? `(${domain.redirectStatusCode})` : ''}
</Table.Cell>
<Table.Cell {root}>
{domain.deploymentVcsProviderBranch || '-'}
</Table.Cell>
<Table.Cell {root}>
<Layout.Stack direction="row" justifyContent="flex-end">
<Popover let:toggle placement="bottom-start" padding="none">
<Button
text
icon
on:click={(e) => {
e.preventDefault();
toggle(e);
}}>
<Icon icon={IconDotsHorizontal} size="s" />
</Button>
<svelte:fragment slot="tooltip" let:toggle>
<ActionMenu.Root>
{#if domain.status !== 'verified'}
<ActionMenu.Item.Button
leadingIcon={IconRefresh}
on:click={(e) => {
e.preventDefault();
selectedDomain = domain;
showRetry = true;
toggle(e);
}}>
Retry
</ActionMenu.Item.Button>
{/if}
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
on:click={(e) => {
e.preventDefault();
selectedDomain = domain;
showDelete = true;
toggle(e);
trackEvent(Click.DomainDeleteClick, {
source: 'sites_domain_overview'
});
}}>
Delete
</ActionMenu.Item.Button>
</ActionMenu.Root>
</svelte:fragment>
</Popover>
</Layout.Stack>
</Table.Cell>
</Table.Row.Base>
{/each}
</Table.Root>
<Table domains={data.domains} />
<PaginationWithLimit
name="Domains"
@@ -175,15 +77,3 @@
</Card.Base>
{/if}
</Container>
{#if showDelete}
<DeleteDomainModal bind:show={showDelete} {selectedDomain} />
{/if}
{#if showRetry}
<RetryDomainModal bind:show={showRetry} {selectedDomain} />
{/if}
{#if showPreviewDomainModal}
<CreatePreviewDomainModal bind:show={showPreviewDomainModal} />
{/if}
@@ -1,7 +1,7 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Button, Form, InputSelect } from '$lib/elements/forms';
import { Button, Form, InputDomain, InputSelect } from '$lib/elements/forms';
import { Wizard } from '$lib/layout';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
@@ -19,31 +19,29 @@
import { Dependencies } from '$lib/constants';
import { sortBranches } from '$lib/stores/vcs';
import { organization } from '$lib/stores/organization';
import { consoleVariables } from '$routes/(console)/store';
import InputDomain from '$lib/elements/forms/inputDomain.svelte';
import { consoleVariables, protocol } from '$routes/(console)/store';
import { IconGlobeAlt, IconInfo } from '@appwrite.io/pink-icons-svelte';
import { LabelCard } from '$lib/components';
import { writable } from 'svelte/store';
import ConnectRepoModal from '../../../(components)/connectRepoModal.svelte';
import { isCloud } from '$lib/system';
import { onMount } from 'svelte';
import { StatusCode } from '@appwrite.io/console';
import VerificationFieldset from './verificationFieldset.svelte';
import type { Domain } from '$lib/sdk/domains';
import { statusCodeOptions } from '$lib/stores/domains';
const backPage = `${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains`;
export let data;
let formComponent: Form;
let isSubmitting = writable(false);
let showConnectRepo = false;
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = 'ACTIVE';
let step: 'add' | 'verify' = 'add';
let domain = '';
let domainName = '';
let redirect: string = null;
let statusCode: number = null;
let branch = null;
let domainData: Domain;
let selectedTab: 'cname' | 'nameserver';
const redirectOptions = data.domains.rules
.filter((d) => !d.domain.endsWith($consoleVariables._APP_DOMAIN_SITES))
.map((domain) => ({
@@ -51,113 +49,48 @@
value: domain.domain
}));
const statusCodeOptions = [
{
label: '301 Moved permanently',
value: 301
},
{
label: '302 Found',
value: 302
},
{
label: '303 See other',
value: 303
},
{
label: '307 Temporary redirect',
value: 307
},
{
label: '308 Permanent redirect',
value: 308
}
];
onMount(() => {
if (
$page.url.searchParams.has('connectRepo') &&
$page.url.searchParams.get('connectRepo') === 'true'
) {
showConnectRepo = true;
}
});
async function addDomain() {
const isPreviewDomain = domain.endsWith($consoleVariables._APP_DOMAIN_SITES);
const isNewDomain = data.domains.rules.findIndex((rule) => rule.domain === domain) === -1;
const isSubDomain = domain.split('.').length >= 2;
const isNewDomain =
data.domains.rules.findIndex((rule) => rule.domain === domainName) === -1;
try {
if (behaviour === 'CREATE') {
if (isCloud && !isPreviewDomain) {
//Redirect if subdomain so user can choose how to proceed
if (isSubDomain) {
goto(
`${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains/add-domain/verify?domain=${domain}`
);
}
//Create domain if it's a new domain
else if (isNewDomain) {
const domainData = await sdk.forConsole.domains.create(
$organization.$id,
domain
);
await sdk.forProject.proxy.createSiteRule(
domain,
$page.params.site,
branch
);
goto(
`${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains/add-domain/verify-${domainData.$id}}`
);
}
}
//if selfhosted or preview domain create site rule
else {
await sdk.forProject.proxy.createSiteRule(domain, $page.params.site, branch);
addNotification({
type: 'success',
message: 'Domain added successfully'
});
await goto(backPage);
await invalidate(Dependencies.SITES_DOMAINS);
}
} else if (behaviour === 'REDIRECT') {
if (isCloud && !isPreviewDomain) {
//Redirect if subdomain so user can choose how to proceed
if (isSubDomain) {
goto(
`${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains/add-domain/verify?domain=${domain}?redirect=${redirect}?statusCode=${statusCode}`
);
}
//Create domain if it's a new domain
else if (isNewDomain) {
const domainData = await sdk.forConsole.domains.create(
$organization.$id,
domain
);
const sc = Object.values(StatusCode).find(
(code) => parseInt(code) === statusCode
);
await sdk.forProject.proxy.createRedirectRule(domain, redirect, sc);
goto(
`${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains/add-domain/verify-${domainData.$id}}`
);
}
}
if (isNewDomain && isCloud) {
domainData = await sdk.forConsole.domains.create($organization.$id, domainName);
}
if (behaviour === 'BRANCH') {
await sdk.forProject.proxy.createSiteRule(domainName, $page.params.site, branch);
} else if (behaviour === 'REDIRECT') {
const sc = Object.values(StatusCode).find((code) => parseInt(code) === statusCode);
console.log(statusCode, sc);
await sdk.forProject.proxy.createRedirectRule(domainName, $protocol + redirect, sc);
} else if (behaviour === 'ACTIVE') {
await sdk.forProject.proxy.createSiteRule(domainName, $page.params.site);
}
addNotification({
type: 'success',
message: 'Domain added successfully'
});
await goto(backPage);
await invalidate(Dependencies.DOMAINS);
await invalidate(Dependencies.SITES_DOMAINS);
} catch (error) {
await invalidate(Dependencies.DOMAINS);
addNotification({
type: 'error',
message: error.message
});
}
}
$: isVerified = domainData?.nameservers
? domainData?.nameservers.toLocaleLowerCase() === 'appwrite'
: undefined;
</script>
<Wizard title="Add custom domain" href={backPage} column columnSize="s" hideFooter={step === 'add'}>
<Form bind:this={formComponent} onSubmit={addDomain} bind:isSubmitting>
<Form onSubmit={() => (step = 'verify')}>
{#if step === 'add'}
<Layout.Stack gap="xxl">
<Layout.Grid columns={3} columnsXS={1}>
@@ -199,7 +132,7 @@
<InputDomain
label="Domain"
id="domain"
bind:value={domain}
bind:value={domainName}
required
placeholder="appwrite.example.com" />
@@ -252,47 +185,37 @@
{/if}
<Divider />
<Layout.Stack direction="row" justifyContent="flex-end">
<Button on:click={() => (step = 'verify')}>Add</Button>
<Button submit>Add</Button>
</Layout.Stack>
</Layout.Stack>
</Fieldset>
</Layout.Stack>
{:else if step === 'verify'}
<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" />
<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">
{domain}
</Typography.Text>
<Typography.Text variation="m-500" color="--fgcolor-neutral-primary">
{domainName}
</Typography.Text>
</Layout.Stack>
<Button secondary on:click={() => (step = 'add')}>Change</Button>
</Layout.Stack>
<Button
secondary
href={`${base}/project-${$page.params.project}/sites/create-site/repositories`}>
Change
</Button>
</Layout.Stack>
</Card.Base>
</Card.Base>
<VerificationFieldset domain={domainName} verified={isVerified} bind:selectedTab />
</Layout.Stack>
{/if}
</Form>
<svelte:fragment slot="footer">
<Button secondary href={backPage}>Cancel</Button>
<Button on:click={() => formComponent.triggerSubmit()} bind:disabled={$isSubmitting}>
Verify
</Button>
<Button on:click={addDomain}>Verify</Button>
</svelte:fragment>
</Wizard>
{#if showConnectRepo}
<ConnectRepoModal
bind:show={showConnectRepo}
site={data.site}
onlyExisting
callbackState={{ connectRepo: 'true' }} />
{/if}
@@ -1,9 +1,11 @@
import { Query } from '@appwrite.io/console';
import { sdk } from '$lib/stores/sdk';
import { RuleTrigger, RuleType } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants.js';
export const load = async ({ parent }) => {
export const load = async ({ parent, depends }) => {
const { site } = await parent();
depends(Dependencies.DOMAINS);
const [domains, installations] = await Promise.all([
sdk.forProject.proxy.listRules([
@@ -0,0 +1,136 @@
<script lang="ts">
import { Link } from '$lib/elements';
import { consoleVariables } from '$routes/(console)/store';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import {
Badge,
Divider,
Fieldset,
Icon,
InteractiveText,
Layout,
Table,
Tabs,
Typography
} from '@appwrite.io/pink-svelte';
export let domain: string;
export let verified: boolean;
const nameserverList = $consoleVariables?._APP_DOMAINS_NAMESERVERS
? $consoleVariables?._APP_DOMAINS_NAMESERVERS.split(',')
: ['ns1.appwrite.io', 'ns2.appwrite.io'];
$: isSubDomain = domain?.split('.')?.length >= 3;
export let selectedTab: 'cname' | 'nameserver' = isSubDomain ? 'cname' : 'nameserver';
</script>
<Fieldset legend="Verification">
<Layout.Stack gap="xl">
<div>
<Tabs.Root variant="secondary" let:root>
{#if isSubDomain}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'cname')}
active={selectedTab === 'cname'}>
CNAME
</Tabs.Item.Button>
{/if}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'nameserver')}
active={selectedTab === 'nameserver'}>
Nameservers
</Tabs.Item.Button>
</Tabs.Root>
<Divider />
</div>
{#if selectedTab === 'cname' && isSubDomain}
<Layout.Stack gap="s">
<Layout.Stack gap="s" direction="row" alignItems="center">
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary">
{domain}
</Typography.Text>
{#if verified}
<Badge variant="secondary" type="success" content="Verified" />
{:else if verified === false}
<Badge variant="secondary" type="error" content="Verification failed" />
{: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}>{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>
{:else}
<Layout.Stack gap="s">
<Layout.Stack gap="s" direction="row" alignItems="center">
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary"
>{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 nameserverList 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>
{/if}
</Layout.Stack>
</Fieldset>
@@ -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/stores';
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>
@@ -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
};
}
};
@@ -0,0 +1,25 @@
import type { Column } from '$lib/helpers/types';
import { writable } from 'svelte/store';
export const columns = writable<Column[]>([
{
id: 'domain',
title: 'Domain',
type: 'string',
format: 'string',
width: { min: 120, max: 400 }
},
{
id: 'redirectUrl',
title: 'Redirect to',
type: 'string',
width: { min: 120, max: 200 }
},
{
id: 'deploymentVcsProviderBranch',
title: 'Production branch',
type: 'string',
width: { min: 70, max: 150 }
}
]);
@@ -0,0 +1,110 @@
<script lang="ts">
import { Click, trackEvent } from '$lib/actions/analytics';
import { Link } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { protocol } from '$routes/(console)/store';
import type { Models } from '@appwrite.io/console';
import { IconDotsHorizontal, IconRefresh, IconTrash } from '@appwrite.io/pink-icons-svelte';
import { ActionMenu, Icon, Layout, Popover, Table, Typography } from '@appwrite.io/pink-svelte';
import DeleteDomainModal from './deleteDomainModal.svelte';
import RetryDomainModal from './retryDomainModal.svelte';
import CreatePreviewDomainModal from './createPreviewDomainModal.svelte';
import { columns } from './store';
export let domains: Models.ProxyRuleList;
let showDelete = false;
let showRetry = false;
let selectedDomain: Models.ProxyRule = null;
let showPreviewDomainModal = false;
</script>
<Table.Root columns={[...$columns, { id: 'actions', width: 40 }]} let:root>
<svelte:fragment slot="header" let:root>
{#each $columns as { id, title }}
<Table.Header.Cell column={id} {root}>
{title}
</Table.Header.Cell>
{/each}
<Table.Header.Cell column="actions" {root} />
</svelte:fragment>
{#each domains.rules as domain}
<Table.Row.Base {root}>
{#each $columns as column}
<Table.Cell column={column.id} {root}>
{#if column.id === 'domain'}
<Link external href={`${$protocol}${domain.domain}`} variant="quiet" icon>
<Typography.Text truncate>
{domain.domain}
</Typography.Text>
</Link>
{:else if column.id === 'redirectUrl'}
<!-- TODO design redirect status code -->
{domain?.redirectUrl || 'No redirect'}
{domain?.redirectStatusCode ? `(${domain.redirectStatusCode})` : ''}
{:else if column.id === 'deploymentVcsProviderBranch'}
{domain.deploymentVcsProviderBranch || '-'}
{/if}
</Table.Cell>
{/each}
<Table.Cell column="actions" {root}>
<Layout.Stack direction="row" justifyContent="flex-end">
<Popover let:toggle placement="bottom-start" padding="none">
<Button
text
icon
on:click={(e) => {
e.preventDefault();
toggle(e);
}}>
<Icon icon={IconDotsHorizontal} size="s" />
</Button>
<svelte:fragment slot="tooltip" let:toggle>
<ActionMenu.Root>
{#if domain.status !== 'verified'}
<ActionMenu.Item.Button
leadingIcon={IconRefresh}
on:click={(e) => {
e.preventDefault();
selectedDomain = domain;
showRetry = true;
toggle(e);
}}>
Retry
</ActionMenu.Item.Button>
{/if}
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
on:click={(e) => {
e.preventDefault();
selectedDomain = domain;
showDelete = true;
toggle(e);
trackEvent(Click.DomainDeleteClick, {
source: 'sites_domain_overview'
});
}}>
Delete
</ActionMenu.Item.Button>
</ActionMenu.Root>
</svelte:fragment>
</Popover>
</Layout.Stack>
</Table.Cell>
</Table.Row.Base>
{/each}
</Table.Root>
{#if showDelete}
<DeleteDomainModal bind:show={showDelete} {selectedDomain} />
{/if}
{#if showRetry}
<RetryDomainModal bind:show={showRetry} {selectedDomain} />
{/if}
{#if showPreviewDomainModal}
<CreatePreviewDomainModal bind:show={showPreviewDomainModal} />
{/if}
@@ -11,13 +11,14 @@
import { Button } from '$lib/elements/forms';
import { Card, Trim } from '$lib/components';
import { Click, trackEvent } from '$lib/actions/analytics';
import { RuleTrigger } from '$lib/stores/sdk';
export let proxyRuleList: Models.ProxyRuleList;
let showDomainQR = false;
let selectedDomainURL: string;
$: rules = proxyRuleList?.rules?.filter((rule) => rule.trigger === 'manual') ?? [];
$: rules = proxyRuleList?.rules?.filter((rule) => rule.trigger === RuleTrigger.MANUAL) ?? [];
</script>
<Layout.Stack>