mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge remote-tracking branch 'origin/feat-pink-v2' into feat-pink-v2
This commit is contained in:
+2
-2
@@ -21,7 +21,8 @@
|
||||
"e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e",
|
||||
"@ai-sdk/svelte": "^1.1.22",
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1",
|
||||
"@appwrite.io/pink": "0.25.0",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f",
|
||||
@@ -32,7 +33,6 @@
|
||||
"@stripe/stripe-js": "^3.5.0",
|
||||
"ai": "^2.2.37",
|
||||
"analytics": "^0.8.16",
|
||||
"@ai-sdk/svelte": "^1.1.22",
|
||||
"cron-parser": "^4.9.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"deep-equal": "^2.2.3",
|
||||
|
||||
Generated
+5
-5
@@ -12,8 +12,8 @@ importers:
|
||||
specifier: ^1.1.22
|
||||
version: 1.1.22(svelte@5.25.3)(zod@3.24.3)
|
||||
'@appwrite.io/console':
|
||||
specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e
|
||||
version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e
|
||||
specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1
|
||||
version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1
|
||||
'@appwrite.io/pink':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
@@ -254,8 +254,8 @@ packages:
|
||||
'@analytics/type-utils@0.6.2':
|
||||
resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1}
|
||||
version: 1.2.1
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f':
|
||||
@@ -3625,7 +3625,7 @@ snapshots:
|
||||
|
||||
'@analytics/type-utils@0.6.2': {}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e': {}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1': {}
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f(svelte@5.25.3)':
|
||||
dependencies:
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
|
||||
let responseTab: 'logs' | 'errors' | 'headers' | 'body' = $state('logs');
|
||||
|
||||
let href = $derived(
|
||||
product === 'site'
|
||||
? 'https://appwrite.io/docs/products/sites/logs#log-details'
|
||||
: 'https://appwrite.io/docs/products/functions/develop#logging'
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
if (selectedLog?.errors) {
|
||||
responseTab = 'errors';
|
||||
@@ -128,8 +134,8 @@
|
||||
|
||||
<Input.Helper state="default">
|
||||
<span>
|
||||
Missing headers? Check the <Link variant="muted" href="#" external>docs</Link> to
|
||||
see the supported data and how to log it.
|
||||
Missing headers? Check the <Link variant="muted" {href} external>docs</Link> to see
|
||||
the supported data and how to log it.
|
||||
</span>
|
||||
</Input.Helper>
|
||||
{:else}
|
||||
@@ -146,12 +152,7 @@
|
||||
Body data is not captured by Appwrite for your user's security and privacy. To
|
||||
display body data in the Logs tab, use <InlineCode
|
||||
code="context.log()"
|
||||
size="s" />. <Link
|
||||
external
|
||||
href="https://appwrite.io/docs/products/functions/develop#logging"
|
||||
variant="muted">
|
||||
Learn more</Link
|
||||
>.
|
||||
size="s" />. <Link external {href} variant="muted">Learn more</Link>.
|
||||
</Typography.Text>
|
||||
</Card>
|
||||
{/if}
|
||||
|
||||
@@ -101,6 +101,12 @@ export function secsToUnit(time: number, unit: Unit) {
|
||||
* @returns Formatted string like "3d 4h 30m 23s"
|
||||
*/
|
||||
export function formatTimeDetailed(time: number): string {
|
||||
if (typeof time !== 'number' || time === undefined || time === null) {
|
||||
return '-';
|
||||
}
|
||||
if (time <= 0) {
|
||||
return '0s';
|
||||
}
|
||||
const seconds = Math.floor(time % 60);
|
||||
const minutes = Math.floor((time / 60) % 60);
|
||||
const hours = Math.floor((time / (60 * 60)) % 24);
|
||||
|
||||
+3
-1
@@ -122,7 +122,9 @@
|
||||
|
||||
<Modal title="Create Git deployment" bind:show onSubmit={createDeployment} bind:error>
|
||||
<span slot="description">
|
||||
Enter a valid commit reference to create a new deployment. <Link href="#">Learn more</Link>
|
||||
Enter a valid commit reference to create a new deployment. <Link
|
||||
href="https://appwrite.io/docs/products/functions/deployments#create-deployment"
|
||||
external>Learn more</Link>
|
||||
</span>
|
||||
{#if hasRepository}
|
||||
{#await load()}
|
||||
|
||||
@@ -5,18 +5,21 @@
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import Container from '$lib/layout/container.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 { Card, Empty, Icon } from '@appwrite.io/pink-svelte';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import Table from './table.svelte';
|
||||
import { ResponsiveContainerHeader } from '$lib/layout';
|
||||
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
<SearchQuery placeholder="Search domain" />
|
||||
<ResponsiveContainerHeader
|
||||
hasSearch
|
||||
hideView
|
||||
searchPlaceholder="Search by domain"
|
||||
analyticsSource="settings_domain_overview">
|
||||
<Button
|
||||
href={`${base}/project-${page.params.project}/settings/domains/add-domain`}
|
||||
on:click={() => {
|
||||
@@ -27,8 +30,7 @@
|
||||
<Icon icon={IconPlus} size="s" />
|
||||
Add domain
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
|
||||
</ResponsiveContainerHeader>
|
||||
{#if data.rules.total}
|
||||
<Table domains={data.rules} />
|
||||
|
||||
|
||||
@@ -5,21 +5,27 @@
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Fieldset, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { Fieldset } from '@appwrite.io/pink-svelte';
|
||||
import { goto, invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { writable } from 'svelte/store';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const routeBase = `${base}/project-${page.params.project}/settings/domains`;
|
||||
|
||||
//TODO: enable once combo box is fixed
|
||||
// let { data } = $props();
|
||||
|
||||
let formComponent: Form;
|
||||
let isSubmitting = $state(writable(false));
|
||||
|
||||
let showConnectRepo = $state(false);
|
||||
let domainName = $state('');
|
||||
|
||||
onMount(() => {
|
||||
if (page.url.searchParams.has('domain')) {
|
||||
domainName = page.url.searchParams.get('domain');
|
||||
}
|
||||
});
|
||||
|
||||
async function addDomain() {
|
||||
try {
|
||||
const rule = await sdk.forProject.proxy.createAPIRule(domainName);
|
||||
@@ -41,27 +47,12 @@
|
||||
|
||||
<Wizard title="Add domain" href={routeBase} column columnSize="s" confirmExit>
|
||||
<Form bind:this={formComponent} onSubmit={addDomain} bind:isSubmitting>
|
||||
<Layout.Stack gap="xxl">
|
||||
<Fieldset legend="Domain">
|
||||
<!-- <Input.ComboBox
|
||||
label="Domain"
|
||||
id="domain"
|
||||
name="domain"
|
||||
bind:value={domain}
|
||||
options={data.domains.rules.map((domain) => ({
|
||||
label: domain.domain,
|
||||
value: domain.domain
|
||||
}))}
|
||||
required
|
||||
placeholder="appwrite.example.com" /> -->
|
||||
<InputDomain
|
||||
label="Domain"
|
||||
id="domain"
|
||||
bind:value={domainName}
|
||||
required
|
||||
placeholder="appwrite.example.com" />
|
||||
</Fieldset>
|
||||
</Layout.Stack>
|
||||
<InputDomain
|
||||
label="Domain"
|
||||
id="domain"
|
||||
bind:value={domainName}
|
||||
required
|
||||
placeholder="appwrite.example.com" />
|
||||
</Form>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
|
||||
+75
-11
@@ -1,7 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { IconGlobeAlt } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card, Divider, Icon, Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
import VerificationFieldset from './verificationFieldset.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';
|
||||
@@ -13,21 +20,34 @@
|
||||
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');
|
||||
const routeBase = `${base}/project-${page.params.project}/settings/domains`;
|
||||
let selectedTab: 'cname' | 'nameserver' = $state();
|
||||
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}/settings/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 === 'cname') {
|
||||
if (selectedTab !== 'nameserver') {
|
||||
const ruleData = await sdk.forProject.proxy.updateRuleVerification(ruleId);
|
||||
verified = ruleData.status === 'verified';
|
||||
} else if (isNewDomain && isCloud) {
|
||||
@@ -44,9 +64,9 @@
|
||||
});
|
||||
await goto(routeBase);
|
||||
await invalidate(Dependencies.DOMAINS);
|
||||
await invalidate(Dependencies.SITES_DOMAINS);
|
||||
} catch (error) {
|
||||
verified = false;
|
||||
isSubmitting.set(false);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
@@ -82,14 +102,58 @@
|
||||
</Layout.Stack>
|
||||
</Card.Base>
|
||||
|
||||
<VerificationFieldset domain={page.params.domain} {verified} bind:selectedTab>
|
||||
<Divider />
|
||||
<Layout.Stack direction="row" justifyContent="flex-end">
|
||||
<Fieldset legend="Verification">
|
||||
<Layout.Stack gap="xl">
|
||||
<div>
|
||||
<Button submit disabled={$isSubmitting}>Verify</Button>
|
||||
<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>
|
||||
</VerificationFieldset>
|
||||
</Fieldset>
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
</Wizard>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ 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 }) => {
|
||||
export const load = async ({ depends, params }) => {
|
||||
depends(Dependencies.DOMAINS);
|
||||
|
||||
let domain: Domain;
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
<script lang="ts">
|
||||
import CnameTable from '$lib/components/domains/cnameTable.svelte';
|
||||
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
|
||||
import { isCloud, isSelfHosted } from '$lib/system';
|
||||
import { Divider, Fieldset, Layout, Tabs } from '@appwrite.io/pink-svelte';
|
||||
|
||||
export let domain: string;
|
||||
export let verified: boolean;
|
||||
|
||||
$: isSubDomain = domain?.split('.')?.length >= 3;
|
||||
export let selectedTab: 'cname' | 'nameserver' =
|
||||
isSubDomain || isSelfHosted ? '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}
|
||||
{#if isCloud}
|
||||
<Tabs.Item.Button
|
||||
{root}
|
||||
on:click={() => (selectedTab = 'nameserver')}
|
||||
active={selectedTab === 'nameserver'}>
|
||||
Nameservers
|
||||
</Tabs.Item.Button>
|
||||
{/if}
|
||||
</Tabs.Root>
|
||||
<Divider />
|
||||
</div>
|
||||
{#if selectedTab === 'cname' && isSubDomain}
|
||||
<CnameTable {domain} {verified} />
|
||||
{:else if isCloud}
|
||||
<NameserverTable {domain} {verified} />
|
||||
{/if}
|
||||
<slot />
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
@@ -21,7 +21,7 @@
|
||||
async function deleteDomain() {
|
||||
try {
|
||||
await sdk.forProject.proxy.deleteRule(selectedDomain.$id);
|
||||
await invalidate(Dependencies.SITES_DOMAINS);
|
||||
await invalidate(Dependencies.DOMAINS);
|
||||
show = false;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
@@ -38,11 +38,7 @@
|
||||
<Confirm title="Delete domain" bind:open={show} onSubmit={deleteDomain} bind:error confirmDeletion>
|
||||
{#if selectedDomain}
|
||||
<Typography.Text variant="m-400">
|
||||
Are you sure you want to delete this domain? You will no longer be able to view your
|
||||
site by visiting:
|
||||
</Typography.Text>
|
||||
<Typography.Text variant="m-500">
|
||||
{selectedDomain.domain}
|
||||
Are you sure you want to delete this domain?
|
||||
</Typography.Text>
|
||||
{/if}
|
||||
</Confirm>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
async function retryDomain() {
|
||||
try {
|
||||
await sdk.forProject.proxy.updateRuleVerification(selectedDomain.$id);
|
||||
await invalidate(Dependencies.SITES_DOMAINS);
|
||||
await invalidate(Dependencies.DOMAINS);
|
||||
show = false;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
|
||||
@@ -5,7 +5,15 @@
|
||||
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 {
|
||||
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';
|
||||
@@ -19,7 +27,6 @@
|
||||
let showDelete = $state(false);
|
||||
let showRetry = $state(false);
|
||||
let selectedDomain: Models.ProxyRule = $state(null);
|
||||
let showPreviewDomainModal = $state(false);
|
||||
</script>
|
||||
|
||||
<Table.Root columns={[...$columns, { id: 'actions', width: 40 }]} let:root>
|
||||
@@ -39,14 +46,15 @@
|
||||
<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 === '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}
|
||||
@@ -69,7 +77,6 @@
|
||||
<ActionMenu.Item.Button
|
||||
leadingIcon={IconRefresh}
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
selectedDomain = domain;
|
||||
showRetry = true;
|
||||
toggle(e);
|
||||
@@ -81,12 +88,11 @@
|
||||
status="danger"
|
||||
leadingIcon={IconTrash}
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
selectedDomain = domain;
|
||||
showDelete = true;
|
||||
toggle(e);
|
||||
trackEvent(Click.DomainDeleteClick, {
|
||||
source: 'sites_domain_overview'
|
||||
source: 'settings_domain_overview'
|
||||
});
|
||||
}}>
|
||||
Delete
|
||||
|
||||
@@ -122,7 +122,11 @@
|
||||
{#if secretVariables?.length > 0}
|
||||
<Alert.Inline status="info">
|
||||
{secretVariables.length} secret variables are hidden from the editor. Their values will
|
||||
remain unchanged. <Link href="#" variant="muted">Learn more</Link>.
|
||||
remain unchanged. <Link
|
||||
href="https://appwrite.io/docs/products/sites/develop#accessing-environment-variables"
|
||||
external
|
||||
variant="muted">Learn more</Link
|
||||
>.
|
||||
</Alert.Inline>
|
||||
{/if}
|
||||
<Layout.Stack gap="s">
|
||||
|
||||
+3
-1
@@ -127,7 +127,9 @@
|
||||
|
||||
<Modal title="Create Git deployment" bind:show onSubmit={createDeployment} bind:error>
|
||||
<span slot="description">
|
||||
Enter a valid commit reference to create a new deployment. <Link href="#">Learn more</Link>
|
||||
Enter a valid commit reference to create a new deployment. <Link
|
||||
href="https://appwrite.io/docs/products/sites/deployments#create-deployment"
|
||||
external>Learn more</Link>
|
||||
</span>
|
||||
{#if hasRepository}
|
||||
{#await load()}
|
||||
|
||||
+20
-4
@@ -7,6 +7,8 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/state';
|
||||
import { UsageCard } from '$lib/components';
|
||||
import { humanFileSize } from '$lib/helpers/sizeConvertion';
|
||||
import { formatTimeDetailed } from '$lib/helpers/timeConversion';
|
||||
|
||||
const now = new Date();
|
||||
const rangeOptions = [
|
||||
@@ -33,17 +35,17 @@
|
||||
description: 'Total builds time'
|
||||
},
|
||||
{
|
||||
id: 'avgTime',
|
||||
id: 'buildsTimeAverage',
|
||||
value: null,
|
||||
description: 'Avg. builds time'
|
||||
},
|
||||
{
|
||||
id: 'success',
|
||||
id: 'buildsSuccessTotal',
|
||||
value: null,
|
||||
description: 'Successful'
|
||||
},
|
||||
{
|
||||
id: 'failed',
|
||||
id: 'buildsFailedTotal',
|
||||
value: null,
|
||||
description: 'Failed '
|
||||
}
|
||||
@@ -63,7 +65,21 @@
|
||||
try {
|
||||
const usage = await sdk.forProject.sites.getUsage(page.params.site, range);
|
||||
metrics = metrics.map((metric) => {
|
||||
metric.value = usage[metric.id] ?? '-';
|
||||
if (metric.id === 'buildsStorageTotal') {
|
||||
const size = humanFileSize(usage[metric.id]);
|
||||
|
||||
metric.value = parseInt(size?.value) > 0 ? size.value + size.unit : '-';
|
||||
} else if (
|
||||
metric.id === 'buildsTimeTotal' ||
|
||||
metric.id === 'buildsTimeAverage'
|
||||
) {
|
||||
const seconds = usage[metric.id] > 0 ? usage[metric.id] / 1000 : 0;
|
||||
const time = formatTimeDetailed(seconds);
|
||||
|
||||
metric.value = time !== '0s' ? time : '-';
|
||||
} else {
|
||||
metric.value = usage[metric.id] ?? '-';
|
||||
}
|
||||
return metric;
|
||||
});
|
||||
metrics = metrics;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
external
|
||||
href="#/"
|
||||
href="https://appwrite.io/docs/products/sites/domains#add-a-custom-domain"
|
||||
text
|
||||
event="empty_documentation"
|
||||
size="s"
|
||||
|
||||
+2
-1
@@ -54,7 +54,8 @@
|
||||
<Modal title="Instant rollback" bind:show onSubmit={handleSubmit}>
|
||||
<svelte:fragment slot="description">
|
||||
Rollback is only available for deployments that are <b>ready and previously active</b>. <Link
|
||||
href="#/">Learn more</Link
|
||||
href="https://appwrite.io/docs/products/sites/deployments#instant-rollback"
|
||||
external>Learn more</Link
|
||||
>.
|
||||
</svelte:fragment>
|
||||
<Layout.Stack gap="xl">
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
external
|
||||
href="#"
|
||||
href="https://appwrite.io/docs/products/sites/logs"
|
||||
secondary
|
||||
event="empty_documentation"
|
||||
size="s"
|
||||
|
||||
@@ -121,14 +121,15 @@
|
||||
</svelte:head>
|
||||
|
||||
<Modal
|
||||
title={state === 'authenticated' ? 'Request access' : 'Sign up or log in to view this preview'}
|
||||
title={state === 'authenticated' ? 'Access required' : 'Sign up or log in to view this preview'}
|
||||
dismissible={false}
|
||||
show
|
||||
hideFooter={state !== 'authenticated'}
|
||||
hideFooter
|
||||
{error}>
|
||||
<span slot="description">
|
||||
{#if state === 'authenticated'}
|
||||
Request access to view this preview. You'll gain access once your request is approved.
|
||||
Access is required to view this preview. You'll be able to see it once an admin invites
|
||||
you to the organization.
|
||||
{/if}
|
||||
</span>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
@@ -225,21 +226,23 @@
|
||||
{data.account.email}
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
<Link
|
||||
variant="muted"
|
||||
on:click={() => {
|
||||
logout(false);
|
||||
state = 'login';
|
||||
}}>Switch account</Link>
|
||||
<div>
|
||||
<Link
|
||||
variant="muted"
|
||||
on:click={() => {
|
||||
logout(false);
|
||||
state = 'login';
|
||||
}}>Switch account</Link>
|
||||
</div>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<!-- <svelte:fragment slot="footer">
|
||||
<Button on:click={requestAccess}>Request access</Button>
|
||||
</svelte:fragment>
|
||||
</svelte:fragment> -->
|
||||
</Modal>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user