mirror of
https://github.com/appwrite/console.git
synced 2026-04-07 19:17:46 +00:00
feat: centralize connect repo logic, functions domains
This commit is contained in:
+28
-43
@@ -4,32 +4,38 @@
|
||||
import { Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { installation, repository } from '$lib/stores/vcs';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { IconArrowSmRight } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Link } from '$lib/elements';
|
||||
import { NewRepository, Repositories } from '$lib/components/git';
|
||||
import ConnectGit from '$lib/components/git/connectGit.svelte';
|
||||
import { Adapter, BuildRuntime, Framework, type Models } from '@appwrite.io/console';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import RepositoryBehaviour from '$lib/components/git/repositoryBehaviour.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let {
|
||||
show = $bindable(false),
|
||||
product,
|
||||
callbackState = null,
|
||||
onlyExisting = false,
|
||||
connect = async () => {}
|
||||
}: {
|
||||
show?: boolean;
|
||||
product: 'functions' | 'sites';
|
||||
callbackState?: Record<string, string>;
|
||||
onlyExisting?: boolean;
|
||||
connect?: (installationId: string, repositoryId: string) => Promise<void>;
|
||||
} = $props();
|
||||
|
||||
export let show = false;
|
||||
export let site: Models.Site;
|
||||
export let callbackState: Record<string, string> = null;
|
||||
export let onlyExisting = false;
|
||||
|
||||
let repositoryBehaviour: 'new' | 'existing' | undefined = onlyExisting ? 'existing' : undefined;
|
||||
let repositoryName = '';
|
||||
let repositoryPrivate = true;
|
||||
let selectedInstallationId = '';
|
||||
let selectedRepository = '';
|
||||
let installations = { installations: [], total: 0 };
|
||||
let error = '';
|
||||
let repositoryBehaviour: 'new' | 'existing' | undefined = $state(
|
||||
onlyExisting ? 'existing' : undefined
|
||||
);
|
||||
let repositoryName = $state('');
|
||||
let repositoryPrivate = $state(true);
|
||||
let selectedInstallationId = $state('');
|
||||
let selectedRepository = $state('');
|
||||
let installations = $state({ installations: [], total: 0 });
|
||||
let error = $state('');
|
||||
|
||||
onMount(async () => {
|
||||
installations = await sdk.forProject.vcs.listInstallations();
|
||||
@@ -40,7 +46,6 @@
|
||||
if (!!installations?.total) {
|
||||
repositoryBehaviour = 'existing';
|
||||
}
|
||||
console.log(selectedInstallationId);
|
||||
});
|
||||
|
||||
async function connectRepo() {
|
||||
@@ -55,29 +60,8 @@
|
||||
selectedRepository = repo.id;
|
||||
}
|
||||
|
||||
const s = await sdk.forProject.sites.update(
|
||||
site.$id,
|
||||
site.name,
|
||||
site.framework as Framework,
|
||||
site.enabled,
|
||||
site.logging || undefined,
|
||||
site.timeout,
|
||||
site.installCommand,
|
||||
site.buildCommand,
|
||||
site.outputDirectory,
|
||||
site.buildRuntime as BuildRuntime,
|
||||
site.adapter as Adapter,
|
||||
site.fallbackFile,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
invalidate(Dependencies.SITE);
|
||||
await connect(selectedInstallationId, selectedRepository);
|
||||
show = false;
|
||||
dispatch('connect', s);
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Repository connected successfully'
|
||||
@@ -95,7 +79,8 @@
|
||||
onSubmit={connectRepo}
|
||||
bind:error>
|
||||
<span slot="description">
|
||||
Connect your site to an existing repository or create a new one.
|
||||
Connect your {product === 'functions' ? 'function' : 'site'} to an existing repository or create
|
||||
a new one.
|
||||
</span>
|
||||
{#if !!installations?.total}
|
||||
<Layout.Stack gap="xl">
|
||||
@@ -111,12 +96,12 @@
|
||||
{:else}
|
||||
<Repositories
|
||||
bind:selectedRepository
|
||||
product="sites"
|
||||
{product}
|
||||
action="button"
|
||||
{callbackState}
|
||||
connect={(e) => {
|
||||
trackEvent(Click.ConnectRepositoryClick, {
|
||||
from: 'sites'
|
||||
from: product
|
||||
});
|
||||
repository.set(e);
|
||||
repositoryName = e.name;
|
||||
@@ -8,3 +8,4 @@ export { default as DeploymentDomains } from './deploymentDomains.svelte';
|
||||
export { default as ConnectBehaviour } from './connectBehaviour.svelte';
|
||||
export { default as ProductionBranchFieldset } from './productionBranchFieldset.svelte';
|
||||
export { default as RepositoryCard } from './repositoryCard.svelte';
|
||||
export { default as ConnectRepoModal } from './connectRepoModal.svelte';
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
import { VCSDetectionType, type Models } from '@appwrite.io/console';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
import { connectGitHub } from '$lib/stores/git';
|
||||
import { debounce } from '$lib/helpers/debounce';
|
||||
|
||||
let {
|
||||
action = $bindable('select'),
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Modal } from '$lib/components';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { installation, repository } from '$lib/stores/vcs';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { onMount } from 'svelte';
|
||||
import { IconArrowSmRight } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Link } from '$lib/elements';
|
||||
import { NewRepository, Repositories } from '$lib/components/git';
|
||||
import ConnectGit from '$lib/components/git/connectGit.svelte';
|
||||
import { Runtime, type Models } from '@appwrite.io/console';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import RepositoryBehaviour from '$lib/components/git/repositoryBehaviour.svelte';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types';
|
||||
|
||||
export let show = false;
|
||||
export let func: Models.Function;
|
||||
export let callbackState: Record<string, string> = null;
|
||||
|
||||
let repositoryBehaviour: 'new' | 'existing' | undefined = undefined;
|
||||
let repositoryName = '';
|
||||
let repositoryPrivate = true;
|
||||
let selectedInstallationId = '';
|
||||
let selectedRepository = '';
|
||||
let installations = { installations: [], total: 0 };
|
||||
let error = '';
|
||||
|
||||
onMount(async () => {
|
||||
installations = await sdk.forProject.vcs.listInstallations();
|
||||
if (!$installation?.$id && installations?.total) {
|
||||
$installation = installations.installations[0];
|
||||
}
|
||||
selectedInstallationId = installations.total ? installations.installations[0]?.$id : '';
|
||||
if (!!installations?.total) {
|
||||
repositoryBehaviour = 'existing';
|
||||
}
|
||||
console.log(selectedInstallationId);
|
||||
});
|
||||
|
||||
async function connectRepo() {
|
||||
try {
|
||||
if (repositoryBehaviour === 'new') {
|
||||
const repo = await sdk.forProject.vcs.createRepository(
|
||||
$installation.$id,
|
||||
repositoryName,
|
||||
repositoryPrivate
|
||||
);
|
||||
repository.set(repo);
|
||||
selectedRepository = repo.id;
|
||||
}
|
||||
|
||||
if (!isValueOfStringEnum(Runtime, func.runtime)) {
|
||||
throw new Error(`Invalid runtime: ${func.runtime}`);
|
||||
}
|
||||
await sdk.forProject.functions.update(
|
||||
func.$id,
|
||||
func.name,
|
||||
func.runtime,
|
||||
func.execute || undefined,
|
||||
func.events || undefined,
|
||||
func.schedule || undefined,
|
||||
func.timeout || undefined,
|
||||
func.enabled || undefined,
|
||||
func.logging || undefined,
|
||||
func.entrypoint,
|
||||
func.commands || undefined,
|
||||
func.scopes || undefined,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
await invalidate(Dependencies.FUNCTION);
|
||||
show = false;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Repository connected successfully'
|
||||
});
|
||||
} catch (e) {
|
||||
error = e.message;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
title="Connect repository"
|
||||
bind:show
|
||||
hideFooter={!repositoryBehaviour}
|
||||
onSubmit={connectRepo}
|
||||
bind:error>
|
||||
<span slot="description">
|
||||
Connect your function to an existing repository or create a new one.
|
||||
</span>
|
||||
{#if !!installations?.total}
|
||||
<Layout.Stack gap="xl">
|
||||
<RepositoryBehaviour bind:repositoryBehaviour />
|
||||
{#if repositoryBehaviour === 'new'}
|
||||
<NewRepository
|
||||
bind:repositoryName
|
||||
bind:repositoryPrivate
|
||||
bind:selectedInstallationId
|
||||
{installations} />
|
||||
{:else}
|
||||
<Repositories
|
||||
bind:selectedRepository
|
||||
action="button"
|
||||
{callbackState}
|
||||
connect={(e) => {
|
||||
trackEvent(Click.ConnectRepositoryClick, {
|
||||
from: 'functions'
|
||||
});
|
||||
repository.set(e);
|
||||
repositoryName = e.name;
|
||||
selectedRepository = e.id;
|
||||
connectRepo();
|
||||
}} />
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
{:else}
|
||||
<ConnectGit {callbackState} />
|
||||
{/if}
|
||||
<svelte:fragment slot="footer">
|
||||
{#if repositoryBehaviour === 'existing'}
|
||||
<Layout.Stack>
|
||||
<Link variant="quiet" href="#/">
|
||||
<Layout.Stack direction="row" gap="xs">
|
||||
Missing a repository? check your permissions <Icon
|
||||
icon={IconArrowSmRight} />
|
||||
</Layout.Stack>
|
||||
</Link>
|
||||
</Layout.Stack>
|
||||
{:else if repositoryBehaviour === 'new'}
|
||||
<Button text size="s" on:click={() => (show = false)}>Cancel</Button>
|
||||
<Button size="s" submit disabled={!repositoryName || !$installation?.$id}>
|
||||
Create
|
||||
</Button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
+18
-130
@@ -3,148 +3,40 @@
|
||||
import { page } from '$app/state';
|
||||
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 { IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card, Empty, Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import DeleteDomainModal from './deleteDomainModal.svelte';
|
||||
import RetryDomainModal from './retryDomainModal.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 Table from './table.svelte';
|
||||
|
||||
export let data;
|
||||
let { data } = $props();
|
||||
|
||||
let showDelete = false;
|
||||
let showRetry = false;
|
||||
let showDelete = $state(false);
|
||||
let showRetry = $state(false);
|
||||
let selectedDomain: Models.ProxyRule = null;
|
||||
let showPreviewDomainModal = false;
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
<SearchQuery search={data.search} placeholder="Search domain" />
|
||||
<Popover padding="none" let:toggle placement="bottom-end">
|
||||
<Button
|
||||
on:click={(event) => {
|
||||
toggle(event);
|
||||
trackEvent(Click.DomainCreateClick, {
|
||||
source: 'functions_domain_overview'
|
||||
});
|
||||
}}>
|
||||
<Icon icon={IconPlus} size="s" />
|
||||
Add domain
|
||||
</Button>
|
||||
<svelte:fragment slot="tooltip">
|
||||
<ActionMenu.Root>
|
||||
<ActionMenu.Item.Anchor
|
||||
href={`${base}/project-${page.params.project}/functions/function-${page.params.function}/domains/add-domain`}>
|
||||
Custom domain
|
||||
</ActionMenu.Item.Anchor>
|
||||
<ActionMenu.Item.Button on:click={() => (showPreviewDomainModal = true)}>
|
||||
Preview domain
|
||||
</ActionMenu.Item.Button>
|
||||
</ActionMenu.Root>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
<SearchQuery placeholder="Search domain" />
|
||||
<Button
|
||||
href={`${base}/project-${page.params.project}/functions/function-${page.params.function}/domains/add-domain`}
|
||||
on:click={() => {
|
||||
trackEvent(Click.DomainCreateClick, {
|
||||
source: 'functions_domain_overview'
|
||||
});
|
||||
}}>
|
||||
<Icon icon={IconPlus} size="s" />
|
||||
Add domain
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
|
||||
{#if data.domains.total}
|
||||
<Table.Root
|
||||
let:root
|
||||
columns={[
|
||||
{ id: 'domain', width: { min: 200 } },
|
||||
{ id: 'redirect' },
|
||||
{ id: 'branch' },
|
||||
{ id: 'actions', width: 40 }
|
||||
]}>
|
||||
<svelte:fragment slot="header" let:root>
|
||||
<Table.Header.Cell column="domain" {root}>Domain</Table.Header.Cell>
|
||||
<Table.Header.Cell column="redirect" {root}>Redirect to</Table.Header.Cell>
|
||||
<Table.Header.Cell column="branch" {root}>Production branch</Table.Header.Cell>
|
||||
<Table.Header.Cell column="actions" {root} />
|
||||
</svelte:fragment>
|
||||
{#each data.domains.rules as domain}
|
||||
<Table.Row.Base {root}>
|
||||
<Table.Cell column="domain" {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>
|
||||
<Table.Cell column="redirect" {root}>
|
||||
{domain?.redirectUrl || 'No redirect'}
|
||||
{domain?.redirectStatusCode ? `(${domain.redirectStatusCode})` : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell column="branch" {root}>
|
||||
{domain.deploymentVcsProviderBranch || '-'}
|
||||
</Table.Cell>
|
||||
<Table.Cell column="actions" {root}>
|
||||
<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: 'functions_domain_overview'
|
||||
});
|
||||
}}>
|
||||
Delete
|
||||
</ActionMenu.Item.Button>
|
||||
</ActionMenu.Root>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
</Table.Cell>
|
||||
</Table.Row.Base>
|
||||
{/each}
|
||||
</Table.Root>
|
||||
<Table domains={data.domains} />
|
||||
|
||||
<PaginationWithLimit
|
||||
name="Domains"
|
||||
@@ -197,7 +89,3 @@
|
||||
{#if showRetry}
|
||||
<RetryDomainModal bind:show={showRetry} {selectedDomain} />
|
||||
{/if}
|
||||
|
||||
{#if showPreviewDomainModal}
|
||||
<CreatePreviewDomainModal bind:show={showPreviewDomainModal} />
|
||||
{/if}
|
||||
|
||||
+110
-161
@@ -1,26 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { Button, Form, InputSelect } from '$lib/elements/forms';
|
||||
import { Button, Form, InputDomain, InputSelect, InputURL } from '$lib/elements/forms';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Fieldset, Layout, Tooltip, Icon, Alert } from '@appwrite.io/pink-svelte';
|
||||
import { Fieldset, Layout, Tooltip, Icon, Input, Alert } from '@appwrite.io/pink-svelte';
|
||||
import { goto, invalidate } from '$app/navigation';
|
||||
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 { protocol } from '$routes/(console)/store';
|
||||
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
|
||||
import { LabelCard } from '$lib/components';
|
||||
import { Runtime, StatusCode, type Models } from '@appwrite.io/console';
|
||||
import { statusCodeOptions } from '$lib/stores/domains';
|
||||
import { writable } from 'svelte/store';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { onMount } from 'svelte';
|
||||
import { StatusCode } from '@appwrite.io/console';
|
||||
import ConnectRepoModal from '../../(modals)/connectRepoModal.svelte';
|
||||
import { ConnectRepoModal } from '$lib/components/git/index.js';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types.js';
|
||||
|
||||
const backPage = `${base}/project-${page.params.project}/functions/function-${page.params.function}/domains`;
|
||||
const routeBase = `${base}/project-${page.params.project}/functions/function-${page.params.function}/domains`;
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -28,42 +27,13 @@
|
||||
let isSubmitting = writable(false);
|
||||
|
||||
let showConnectRepo = false;
|
||||
let behaviour: 'REDIRECT' | 'CREATE' = 'CREATE';
|
||||
let domain = '';
|
||||
|
||||
let behaviour: 'REDIRECT' | 'BRANCH' | 'ACTIVE' = 'ACTIVE';
|
||||
let domainName = '';
|
||||
let redirect: string = null;
|
||||
let statusCode: number = null;
|
||||
let statusCode = 307;
|
||||
let branch = null;
|
||||
|
||||
const redirectOptions = data.domains.rules
|
||||
.filter((d) => !d.domain.endsWith($consoleVariables._APP_DOMAIN_FUNCTIONS))
|
||||
.map((domain) => ({
|
||||
label: domain.domain,
|
||||
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') &&
|
||||
@@ -71,75 +41,39 @@
|
||||
) {
|
||||
showConnectRepo = true;
|
||||
}
|
||||
if (page.url.searchParams.has('domain')) {
|
||||
domainName = page.url.searchParams.get('domain');
|
||||
}
|
||||
});
|
||||
|
||||
async function addDomain() {
|
||||
const isPreviewDomain = domain.endsWith($consoleVariables._APP_DOMAIN_FUNCTIONS);
|
||||
const isNewDomain = data.domains.rules.findIndex((rule) => rule.domain === domain) === -1;
|
||||
const isSubDomain = domain.split('.').length >= 2;
|
||||
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}/functions/function-${page.params.function}/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.createFunctionRule(
|
||||
domain,
|
||||
page.params.function,
|
||||
branch
|
||||
);
|
||||
goto(
|
||||
`${base}/project-${page.params.project}/functions/function-${page.params.function}/domains/add-domain/verify-${domainData.$id}}`
|
||||
);
|
||||
}
|
||||
}
|
||||
//if selfhosted or preview domain create function rule
|
||||
else {
|
||||
await sdk.forProject.proxy.createFunctionRule(
|
||||
domain,
|
||||
page.params.function,
|
||||
branch
|
||||
);
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Domain added successfully'
|
||||
});
|
||||
await goto(backPage);
|
||||
await invalidate(Dependencies.FUNCTION_DOMAINS);
|
||||
}
|
||||
let rule: Models.ProxyRule;
|
||||
if (behaviour === 'BRANCH') {
|
||||
rule = await sdk.forProject.proxy.createFunctionRule(
|
||||
domainName,
|
||||
page.params.function,
|
||||
branch
|
||||
);
|
||||
} 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}/functions/function-${page.params.function}/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}/functions/function-${page.params.function}/domains/add-domain/verify-${domainData.$id}}`
|
||||
);
|
||||
}
|
||||
}
|
||||
const sc = Object.values(StatusCode).find((code) => parseInt(code) === statusCode);
|
||||
rule = await sdk.forProject.proxy.createRedirectRule(
|
||||
domainName,
|
||||
$protocol + redirect,
|
||||
sc
|
||||
);
|
||||
} else if (behaviour === 'ACTIVE') {
|
||||
rule = await sdk.forProject.proxy.createFunctionRule(
|
||||
domainName,
|
||||
page.params.function
|
||||
);
|
||||
}
|
||||
if (rule?.status === 'verified') {
|
||||
await goto(routeBase);
|
||||
await invalidate(Dependencies.FUNCTION_DOMAINS);
|
||||
} else {
|
||||
await goto(`${routeBase}/add-domain/verify-${domainName}?rule=${rule.$id}`);
|
||||
await invalidate(Dependencies.FUNCTION_DOMAINS);
|
||||
}
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
@@ -148,12 +82,43 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
if (!isValueOfStringEnum(Runtime, data.func.runtime)) {
|
||||
throw new Error(`Invalid runtime: ${data.func.runtime}`);
|
||||
}
|
||||
await sdk.forProject.functions.update(
|
||||
data.func.$id,
|
||||
data.func.name,
|
||||
data.func.runtime as Runtime,
|
||||
data.func.execute || undefined,
|
||||
data.func.events || undefined,
|
||||
data.func.schedule || undefined,
|
||||
data.func.timeout || undefined,
|
||||
data.func.enabled || undefined,
|
||||
data.func.logging || undefined,
|
||||
data.func.entrypoint,
|
||||
data.func.commands || undefined,
|
||||
data.func.scopes || undefined,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
await invalidate(Dependencies.FUNCTION);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Wizard title="Add custom domain" href={backPage} column columnSize="s">
|
||||
<Wizard title="Add domain" href={routeBase} column columnSize="s" confirmExit>
|
||||
<Form bind:this={formComponent} onSubmit={addDomain} bind:isSubmitting>
|
||||
<Layout.Stack gap="xxl">
|
||||
<Fieldset legend="Details">
|
||||
<Fieldset legend="Domain">
|
||||
<!-- <Input.ComboBox
|
||||
label="Domain"
|
||||
id="domain"
|
||||
@@ -168,43 +133,47 @@
|
||||
<InputDomain
|
||||
label="Domain"
|
||||
id="domain"
|
||||
bind:value={domain}
|
||||
bind:value={domainName}
|
||||
required
|
||||
placeholder="appwrite.example.com" />
|
||||
</Fieldset>
|
||||
|
||||
<Layout.Grid columns={2} columnsXS={1}>
|
||||
<LabelCard
|
||||
value="CREATE"
|
||||
bind:group={behaviour}
|
||||
title="Connect to active deployment">
|
||||
Connect this domain to your active deployment and configure the linked Git
|
||||
branch as needed.
|
||||
<Layout.Grid columns={3} columnsXS={1}>
|
||||
<LabelCard value="ACTIVE" bind:group={behaviour} title="Active deployment">
|
||||
Point this domain to the latest deployed version.
|
||||
</LabelCard>
|
||||
<LabelCard
|
||||
value="REDIRECT"
|
||||
bind:group={behaviour}
|
||||
title="Redirect to another domain">
|
||||
Automatically forward traffic from this domain to another URL of your choice.
|
||||
<LabelCard value="BRANCH" bind:group={behaviour} title="Git branch">
|
||||
Point this domain to a specific branch in your repository.
|
||||
</LabelCard>
|
||||
<LabelCard value="REDIRECT" bind:group={behaviour} title="Redirect">
|
||||
Forward all traffic from this domain to another URL.
|
||||
</LabelCard>
|
||||
</Layout.Grid>
|
||||
|
||||
{#if behaviour === 'CREATE'}
|
||||
<Fieldset legend="Configuration">
|
||||
{#if behaviour === 'BRANCH'}
|
||||
<Fieldset legend="Settings">
|
||||
<Layout.Stack gap="xl">
|
||||
{#if data.branches?.total}
|
||||
{#if data.function?.providerRepositoryId}
|
||||
{@const sortedBranches = sortBranches(data.branches.branches)}
|
||||
{@const options = sortedBranches.map((branch) => ({
|
||||
label: branch.name,
|
||||
value: branch.name
|
||||
}))}
|
||||
<InputSelect
|
||||
{options}
|
||||
label="Production branch"
|
||||
id="branch"
|
||||
required
|
||||
bind:value={branch}
|
||||
placeholder="Select branch" />
|
||||
<Layout.Stack gap="s">
|
||||
<InputSelect
|
||||
{options}
|
||||
label="Production branch"
|
||||
id="branch"
|
||||
required
|
||||
bind:value={branch}
|
||||
placeholder="Select branch" />
|
||||
{#if !data.branches?.total}
|
||||
<Input.Helper state="default">
|
||||
No branches found in the selected repository. Create a
|
||||
branch to see it here.
|
||||
</Input.Helper>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
{:else}
|
||||
<InputSelect
|
||||
disabled
|
||||
@@ -214,7 +183,6 @@
|
||||
required
|
||||
value="main"
|
||||
placeholder="Select branch" />
|
||||
|
||||
<Alert.Inline
|
||||
title=" There is no repository connected to your function">
|
||||
<Layout.Stack>
|
||||
@@ -232,42 +200,20 @@
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
|
||||
<!-- {:else if data.function.installationId || data.installations?.total}
|
||||
<PinkCard.Base padding="none" border="dashed">
|
||||
<Empty
|
||||
type="secondary"
|
||||
title="Connect Git repository"
|
||||
description="Link a repository to associate your domain with an active deployment.">
|
||||
<svelte:fragment slot="actions">
|
||||
<Button secondary on:click={() => (showConnectRepo = true)}>
|
||||
<Icon icon={IconGithub} size="s" slot="start" />
|
||||
Connect Git repository
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</Empty>
|
||||
</PinkCard.Base>
|
||||
{:else}
|
||||
<ConnectGit callbackState={{ newInstallation: 'true' }} />
|
||||
{/if} -->
|
||||
{:else if behaviour === 'REDIRECT'}
|
||||
<Fieldset legend="Configuration">
|
||||
<Fieldset legend="Settings">
|
||||
<Layout.Stack gap="xl">
|
||||
<InputSelect
|
||||
<InputURL
|
||||
label="Redirect to"
|
||||
id="redirect"
|
||||
placeholder="Select domain"
|
||||
options={redirectOptions}
|
||||
placeholder="https://appwrite.io/docs"
|
||||
bind:value={redirect}
|
||||
required>
|
||||
<Tooltip slot="info">
|
||||
<Icon icon={IconInfo} size="s" />
|
||||
<span slot="tooltip">
|
||||
Redirect this domain. Domains added to your project will be
|
||||
listed here.
|
||||
</span>
|
||||
<span slot="tooltip"> Redirect your domain to this URL.</span>
|
||||
</Tooltip>
|
||||
</InputSelect>
|
||||
</InputURL>
|
||||
<InputSelect
|
||||
options={statusCodeOptions}
|
||||
label="Status code"
|
||||
@@ -280,8 +226,9 @@
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button secondary href={backPage}>Cancel</Button>
|
||||
<Button secondary href={routeBase}>Cancel</Button>
|
||||
<Button on:click={() => formComponent.triggerSubmit()} bind:disabled={$isSubmitting}>
|
||||
Add
|
||||
</Button>
|
||||
@@ -291,6 +238,8 @@
|
||||
{#if showConnectRepo}
|
||||
<ConnectRepoModal
|
||||
bind:show={showConnectRepo}
|
||||
func={data.function}
|
||||
{connect}
|
||||
product="functions"
|
||||
onlyExisting
|
||||
callbackState={{ connectRepo: 'true' }} />
|
||||
{/if}
|
||||
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Modal } from '$lib/components';
|
||||
import { Button, InputText } from '$lib/elements/forms';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
import { page } from '$app/state';
|
||||
import { Layout, Status, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { ConsoleResourceType, ID } from '@appwrite.io/console';
|
||||
import { debounce } from '$lib/helpers/debounce';
|
||||
|
||||
export let show = false;
|
||||
|
||||
let baseDomain = ID.unique();
|
||||
let domain = baseDomain;
|
||||
let domainStatus: 'complete' | 'failed' | 'pending' = 'complete';
|
||||
|
||||
let error = null;
|
||||
async function onSubmit() {
|
||||
try {
|
||||
await sdk.forProject.proxy.createFunctionRule(
|
||||
`${domain}.${$consoleVariables._APP_DOMAIN_FUNCTIONS}`,
|
||||
page.params.function
|
||||
);
|
||||
|
||||
await invalidate(Dependencies.FUNCTION_DOMAINS);
|
||||
show = false;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Preview domain has been added'
|
||||
});
|
||||
trackEvent(Submit.DomainCreate);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
trackError(e, Submit.DomainCreate);
|
||||
}
|
||||
}
|
||||
|
||||
function setDomainLabel(status: typeof domainStatus) {
|
||||
switch (status) {
|
||||
case 'complete':
|
||||
return 'Domain is available';
|
||||
case 'failed':
|
||||
return 'Domain is not available';
|
||||
case 'pending':
|
||||
return 'Checking domain availability';
|
||||
}
|
||||
}
|
||||
|
||||
const checkDomain = debounce(async (value: string) => {
|
||||
if (!value) {
|
||||
domainStatus = 'failed';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await sdk.forConsole.console.getResource(
|
||||
`${value}.${$consoleVariables._APP_DOMAIN_FUNCTIONS}`,
|
||||
ConsoleResourceType.Rules
|
||||
);
|
||||
domainStatus = 'complete';
|
||||
baseDomain = domain;
|
||||
} catch {
|
||||
domainStatus = 'failed';
|
||||
} finally {
|
||||
baseDomain = domain;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
$: if (domain !== baseDomain) {
|
||||
domainStatus = 'pending';
|
||||
checkDomain(domain);
|
||||
}
|
||||
|
||||
$: if (!show) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal title="Add preview domain" bind:show {onSubmit} bind:error>
|
||||
<span slot="description">
|
||||
Get an auto-generated domain to quickly access your project. You can customize its prefix.
|
||||
</span>
|
||||
|
||||
<Layout.Stack>
|
||||
<Layout.Stack gap="s">
|
||||
<InputText id="domain" placeholder="my-domain" bind:value={domain}>
|
||||
<svelte:fragment slot="end">
|
||||
<Typography.Text variant="m-400" color="--fgcolor-neutral-tertiary">
|
||||
.{$consoleVariables._APP_DOMAIN_FUNCTIONS}
|
||||
</Typography.Text>
|
||||
</svelte:fragment>
|
||||
</InputText>
|
||||
<Status status={domainStatus} label={setDomainLabel(domainStatus)}></Status>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button text on:click={() => (show = false)}>Cancel</Button>
|
||||
<Button submit>Add</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
@@ -0,0 +1,19 @@
|
||||
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: 200 }
|
||||
},
|
||||
|
||||
{
|
||||
id: 'target',
|
||||
title: 'Target',
|
||||
type: 'string',
|
||||
width: { min: 120, max: 400 }
|
||||
}
|
||||
]);
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
<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,
|
||||
Badge,
|
||||
Icon,
|
||||
Layout,
|
||||
Popover,
|
||||
Table,
|
||||
Typography
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import DeleteDomainModal from './deleteDomainModal.svelte';
|
||||
import RetryDomainModal from './retryDomainModal.svelte';
|
||||
import { columns } from './store';
|
||||
|
||||
let {
|
||||
domains
|
||||
}: {
|
||||
domains: Models.ProxyRuleList;
|
||||
} = $props();
|
||||
|
||||
let showDelete = $state(false);
|
||||
let showRetry = $state(false);
|
||||
let selectedDomain: Models.ProxyRule = $state(null);
|
||||
</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}
|
||||
{#if domain.status !== 'verified'}
|
||||
<Badge
|
||||
variant="secondary"
|
||||
type="error"
|
||||
content="Verification failed"
|
||||
size="s" />
|
||||
{/if}
|
||||
</Typography.Text>
|
||||
</Link>
|
||||
{:else if column.id === 'target'}
|
||||
{domain?.redirectUrl
|
||||
? 'Redirect to ' + domain.redirectUrl
|
||||
: domain?.deploymentVcsProviderBranch
|
||||
? 'Deployed from' + 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) => {
|
||||
selectedDomain = domain;
|
||||
showRetry = true;
|
||||
toggle(e);
|
||||
}}>
|
||||
Retry
|
||||
</ActionMenu.Item.Button>
|
||||
{/if}
|
||||
<ActionMenu.Item.Button
|
||||
status="danger"
|
||||
leadingIcon={IconTrash}
|
||||
on:click={(e) => {
|
||||
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}
|
||||
+33
-3
@@ -22,9 +22,8 @@
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import Card from '$lib/components/card.svelte';
|
||||
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
|
||||
import { ConnectGit, RepositoryCard } from '$lib/components/git';
|
||||
import { ConnectGit, ConnectRepoModal, RepositoryCard } from '$lib/components/git';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types';
|
||||
import ConnectRepoModal from '../(modals)/connectRepoModal.svelte';
|
||||
|
||||
export let func: Models.Function;
|
||||
export let installations: Models.InstallationList;
|
||||
@@ -114,6 +113,37 @@
|
||||
selectedBranch !== func?.providerBranch ||
|
||||
silentMode !== func?.providerSilentMode ||
|
||||
selectedDir !== func?.providerRootDirectory;
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
if (!isValueOfStringEnum(Runtime, func.runtime)) {
|
||||
throw new Error(`Invalid runtime: ${func.runtime}`);
|
||||
}
|
||||
await sdk.forProject.functions.update(
|
||||
func.$id,
|
||||
func.name,
|
||||
func.runtime as Runtime,
|
||||
func.execute || undefined,
|
||||
func.events || undefined,
|
||||
func.schedule || undefined,
|
||||
func.timeout || undefined,
|
||||
func.enabled || undefined,
|
||||
func.logging || undefined,
|
||||
func.entrypoint,
|
||||
func.commands || undefined,
|
||||
func.scopes || undefined,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
await invalidate(Dependencies.FUNCTION);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Form onSubmit={updateConfiguration}>
|
||||
@@ -224,7 +254,7 @@
|
||||
</Form>
|
||||
|
||||
{#if showConnectRepo}
|
||||
<ConnectRepoModal bind:show={showConnectRepo} {func} />
|
||||
<ConnectRepoModal bind:show={showConnectRepo} {connect} product="functions" />
|
||||
{/if}
|
||||
|
||||
{#if showDisconnect}
|
||||
|
||||
@@ -8,11 +8,15 @@
|
||||
import Button from '$lib/elements/forms/button.svelte';
|
||||
import OpenOnMobileModal from '../../(components)/openOnMobileModal.svelte';
|
||||
import SiteCard from '../../(components)/siteCard.svelte';
|
||||
import ConnectRepoModal from '../../(components)/connectRepoModal.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import AddCollaboratorModal from '../../(components)/addCollaboratorModal.svelte';
|
||||
import { protocol } from '$routes/(console)/store';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { Adapter, BuildRuntime, Framework } from '@appwrite.io/console';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { ConnectRepoModal } from '$lib/components/git';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -30,6 +34,34 @@
|
||||
showConnectRepositry = true;
|
||||
}
|
||||
});
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
await sdk.forProject.sites.update(
|
||||
data.site.$id,
|
||||
data.site.name,
|
||||
data.site.framework as Framework,
|
||||
data.site.enabled,
|
||||
data.site.logging || undefined,
|
||||
data.site.timeout,
|
||||
data.site.installCommand,
|
||||
data.site.buildCommand,
|
||||
data.site.outputDirectory,
|
||||
data.site.buildRuntime as BuildRuntime,
|
||||
data.site.adapter as Adapter,
|
||||
data.site.fallbackFile,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
invalidate(Dependencies.SITE);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Wizard column href={`${base}/project-${page.params.project}/sites/site-${data.site.$id}`}>
|
||||
@@ -173,9 +205,11 @@
|
||||
{#if showConnectRepositry}
|
||||
<ConnectRepoModal
|
||||
bind:show={showConnectRepositry}
|
||||
site={data.site}
|
||||
{connect}
|
||||
product="sites"
|
||||
callbackState={{ connectRepo: 'true' }} />
|
||||
{/if}
|
||||
|
||||
{#if showOpenOnMobile}
|
||||
<OpenOnMobileModal bind:show={showOpenOnMobile} proxyRuleList={data.proxyRuleList} />
|
||||
{/if}
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
import { PaginationWithLimit, ViewSelector, EmptyFilter, Empty } from '$lib/components';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { Container } from '$lib/layout';
|
||||
import { type Models } from '@appwrite.io/console';
|
||||
import { Adapter, BuildRuntime, Framework, type Models } from '@appwrite.io/console';
|
||||
import { View } from '$lib/helpers/load';
|
||||
import { ActionMenu, Icon, Layout, Popover } from '@appwrite.io/pink-svelte';
|
||||
import Table from './table.svelte';
|
||||
import RedeployModal from '../../redeployModal.svelte';
|
||||
import CreateGitDeploymentModal from './createGitDeploymentModal.svelte';
|
||||
import ConnectRepoModal from '../../(components)/connectRepoModal.svelte';
|
||||
import { columns } from './store';
|
||||
import CreateManualDeploymentModal from './createManualDeploymentModal.svelte';
|
||||
// import DeploymentMetrics from './deploymentMetrics.svelte';
|
||||
@@ -20,6 +19,7 @@
|
||||
import CreateCliModal from './createCliModal.svelte';
|
||||
import { ParsedTagList, QuickFilters } from '$lib/components/filters';
|
||||
import { page } from '$app/state';
|
||||
import { ConnectRepoModal } from '$lib/components/git';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -42,6 +42,34 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
await sdk.forProject.sites.update(
|
||||
data.site.$id,
|
||||
data.site.name,
|
||||
data.site.framework as Framework,
|
||||
data.site.enabled,
|
||||
data.site.logging || undefined,
|
||||
data.site.timeout,
|
||||
data.site.installCommand,
|
||||
data.site.buildCommand,
|
||||
data.site.outputDirectory,
|
||||
data.site.buildRuntime as BuildRuntime,
|
||||
data.site.adapter as Adapter,
|
||||
data.site.fallbackFile,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
invalidate(Dependencies.SITE);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
@@ -137,7 +165,8 @@
|
||||
{#if showConnectRepo}
|
||||
<ConnectRepoModal
|
||||
bind:show={showConnectRepo}
|
||||
site={data.site}
|
||||
{connect}
|
||||
product="sites"
|
||||
callbackState={{ connectRepo: 'true' }} />
|
||||
{/if}
|
||||
|
||||
|
||||
+38
-3
@@ -12,11 +12,17 @@
|
||||
import { protocol } from '$routes/(console)/store';
|
||||
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
|
||||
import { LabelCard } from '$lib/components';
|
||||
import { StatusCode, type Models } from '@appwrite.io/console';
|
||||
import {
|
||||
Adapter,
|
||||
BuildRuntime,
|
||||
Framework,
|
||||
StatusCode,
|
||||
type Models
|
||||
} from '@appwrite.io/console';
|
||||
import { statusCodeOptions } from '$lib/stores/domains';
|
||||
import ConnectRepoModal from '../../../(components)/connectRepoModal.svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import { onMount } from 'svelte';
|
||||
import { ConnectRepoModal } from '$lib/components/git/index.js';
|
||||
|
||||
const routeBase = `${base}/project-${page.params.project}/sites/site-${page.params.site}/domains`;
|
||||
|
||||
@@ -78,6 +84,34 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
await sdk.forProject.sites.update(
|
||||
data.site.$id,
|
||||
data.site.name,
|
||||
data.site.framework as Framework,
|
||||
data.site.enabled,
|
||||
data.site.logging || undefined,
|
||||
data.site.timeout,
|
||||
data.site.installCommand,
|
||||
data.site.buildCommand,
|
||||
data.site.outputDirectory,
|
||||
data.site.buildRuntime as BuildRuntime,
|
||||
data.site.adapter as Adapter,
|
||||
data.site.fallbackFile,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
invalidate(Dependencies.SITE);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Wizard title="Add domain" href={routeBase} column columnSize="s" confirmExit>
|
||||
@@ -202,7 +236,8 @@
|
||||
{#if showConnectRepo}
|
||||
<ConnectRepoModal
|
||||
bind:show={showConnectRepo}
|
||||
site={data.site}
|
||||
{connect}
|
||||
product="sites"
|
||||
onlyExisting
|
||||
callbackState={{ connectRepo: 'true' }} />
|
||||
{/if}
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
import RetryDomainModal from './retryDomainModal.svelte';
|
||||
import { columns } from './store';
|
||||
|
||||
export let domains: Models.ProxyRuleList;
|
||||
let {
|
||||
domains
|
||||
}: {
|
||||
domains: Models.ProxyRuleList;
|
||||
} = $props();
|
||||
|
||||
let showDelete = false;
|
||||
let showRetry = false;
|
||||
let selectedDomain: Models.ProxyRule = null;
|
||||
let showDelete = $state(false);
|
||||
let showRetry = $state(false);
|
||||
let selectedDomain: Models.ProxyRule = $state(null);
|
||||
</script>
|
||||
|
||||
<Table.Root columns={[...$columns, { id: 'actions', width: 40 }]} let:root>
|
||||
|
||||
+30
-3
@@ -22,8 +22,7 @@
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import Card from '$lib/components/card.svelte';
|
||||
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
|
||||
import { ConnectGit, RepositoryCard } from '$lib/components/git';
|
||||
import ConnectRepoModal from '../../(components)/connectRepoModal.svelte';
|
||||
import { ConnectGit, ConnectRepoModal, RepositoryCard } from '$lib/components/git';
|
||||
import { showConnectRepo } from './store';
|
||||
|
||||
export let site: Models.Site;
|
||||
@@ -104,6 +103,34 @@
|
||||
selectedBranch = site?.providerBranch ?? branchesList.branches[0].name;
|
||||
}
|
||||
|
||||
async function connect(selectedInstallationId: string, selectedRepository: string) {
|
||||
try {
|
||||
await sdk.forProject.sites.update(
|
||||
site.$id,
|
||||
site.name,
|
||||
site.framework as Framework,
|
||||
site.enabled,
|
||||
site.logging || undefined,
|
||||
site.timeout,
|
||||
site.installCommand,
|
||||
site.buildCommand,
|
||||
site.outputDirectory,
|
||||
site.buildRuntime as BuildRuntime,
|
||||
site.adapter as Adapter,
|
||||
site.fallbackFile,
|
||||
selectedInstallationId,
|
||||
selectedRepository,
|
||||
'main',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
invalidate(Dependencies.SITE);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
$: if (site?.installationId && site?.providerRepositoryId) {
|
||||
getBranches(site.installationId, site.providerRepositoryId);
|
||||
}
|
||||
@@ -223,7 +250,7 @@
|
||||
</Form>
|
||||
|
||||
{#if $showConnectRepo}
|
||||
<ConnectRepoModal bind:show={$showConnectRepo} {site} />
|
||||
<ConnectRepoModal bind:show={$showConnectRepo} {connect} product="sites" />
|
||||
{/if}
|
||||
|
||||
{#if showDisconnect}
|
||||
|
||||
Reference in New Issue
Block a user