Merge pull request #1856 from appwrite/fix-remove-feature-flags-and-new-dns-state

Remove feature flag and add dns state for verifying
This commit is contained in:
Torsten Dittmann authored and GitHub committed 2025-05-19 03:43:06 +02:00
commit 28a2eeb485
9 files changed
+155 -167

No files matched your search

+40 -44
View File
@@ -40,7 +40,6 @@
import type { HTMLAttributes } from 'svelte/elements';
import type { NavbarProject } from '$lib/components/navbar.svelte';
import { SHOW_INIT_FEATURES } from '$lib/system';
type $$Props = HTMLAttributes<HTMLElement> & {
state?: 'closed' | 'open' | 'icons';
@@ -191,49 +190,46 @@
<span slot="tooltip">{projectOption.name}</span>
</Tooltip>
{/each}
{#if SHOW_INIT_FEATURES}
<div class="only-mobile divider">
<Divider />
</div>
<div class="products-label-container">
<span class="products-label" class:hidden={state === 'icons'}
>Deploy</span>
<span class="products-label-indicator" class:hidden={state !== 'icons'}
></span>
</div>
{@const deployProjectOptions = projectOptions.filter(
(projectOption) => projectOption.category === 'deploy'
)}
{#each deployProjectOptions as projectOption}
<Tooltip placement="right" disabled={state !== 'icons'}>
<a
href={`/console/project-${project.region}-${project.$id}/${projectOption.slug}`}
class="link"
class:active={page.url.pathname.includes(projectOption.slug)}
on:click={() => {
trackEvent(`click_menu_${projectOption.slug}`);
sideBarIsOpen = false;
}}>
<span class="link-icon">
<Icon icon={projectOption.icon} size="s" />
</span>
<span
class:no-text={state === 'icons'}
class:has-text={state === 'open'}
class="link-text">
{projectOption.name}
{#if projectOption?.badge}
<Badge
variant="secondary"
content={projectOption.badge}
size="xs" />
{/if}
</span>
</a>
<span slot="tooltip">{projectOption.name}</span>
</Tooltip>
{/each}
{/if}
<div class="only-mobile divider">
<Divider />
</div>
<div class="products-label-container">
<span class="products-label" class:hidden={state === 'icons'}>Deploy</span>
<span class="products-label-indicator" class:hidden={state !== 'icons'}
></span>
</div>
{@const deployProjectOptions = projectOptions.filter(
(projectOption) => projectOption.category === 'deploy'
)}
{#each deployProjectOptions as projectOption}
<Tooltip placement="right" disabled={state !== 'icons'}>
<a
href={`/console/project-${project.region}-${project.$id}/${projectOption.slug}`}
class="link"
class:active={page.url.pathname.includes(projectOption.slug)}
on:click={() => {
trackEvent(`click_menu_${projectOption.slug}`);
sideBarIsOpen = false;
}}>
<span class="link-icon">
<Icon icon={projectOption.icon} size="s" />
</span>
<span
class:no-text={state === 'icons'}
class:has-text={state === 'open'}
class="link-text">
{projectOption.name}
{#if projectOption?.badge}
<Badge
variant="secondary"
content={projectOption.badge}
size="xs" />
{/if}
</span>
</a>
<span slot="tooltip">{projectOption.name}</span>
</Tooltip>
{/each}
<div class="only-mobile divider">
<Divider />
</div>
+2 -3
View File
@@ -1,8 +1,8 @@
import { page } from '$app/stores';
import { derived } from 'svelte/store';
export const roles = derived(page, ($page) => $page.data?.roles ?? []);
export const scopes = derived(page, ($page) => $page.data?.scopes ?? []);
export const roles = derived(page, ($page) => ($page.data?.roles ?? []) as string[]);
export const scopes = derived(page, ($page) => ($page.data?.scopes ?? []) as string[]);
export const isDeveloper = derived(roles, ($roles) => $roles.includes('developer'));
export const isBilling = derived(roles, ($roles) => $roles.includes('billing'));
@@ -50,4 +50,3 @@ export const canSeeTeams = derived(scopes, ($scopes) => $scopes.includes('teams.
export const canSeeBuckets = derived(scopes, ($scopes) => $scopes.includes('buckets.read'));
export const canSeeMessages = derived(scopes, ($scopes) => $scopes.includes('messages.read'));
export const canSeeSites = derived(scopes, ($scopes) => $scopes.includes('sites.read'));
export const canSeeDomains = derived(scopes, ($scopes) => $scopes.includes('domains.read')); //TODO: check if correct
-1
View File
@@ -27,7 +27,6 @@ export const isDev = ENV.DEV;
export const isProd = ENV.PROD;
export const hasStripePublicKey = !!VARS.PUBLIC_STRIPE_KEY;
export const GRACE_PERIOD_OVERRIDE = false;
export const SHOW_INIT_FEATURES = true;
export function isMultiRegionSupported(url: URL): boolean {
if (env.PUBLIC_APPWRITE_MULTI_REGION === 'true') return true;
@@ -11,13 +11,13 @@
import { members, newMemberModal, organization } from '$lib/stores/organization';
import {
canSeeBilling,
canSeeDomains,
canSeeProjects,
canSeeTeams,
isBilling,
isOwner
isOwner,
scopes
} from '$lib/stores/roles';
import { GRACE_PERIOD_OVERRIDE, isCloud, SHOW_INIT_FEATURES } from '$lib/system';
import { GRACE_PERIOD_OVERRIDE, isCloud } from '$lib/system';
import { IconGithub, IconPlus } from '@appwrite.io/pink-icons-svelte';
import { Icon, Tooltip, Typography, Layout, Badge } from '@appwrite.io/pink-svelte';
@@ -33,6 +33,7 @@
$: avatars = $members.memberships?.map((m) => m.userName || m.userEmail) ?? [];
$: organizationId = page.params.organization;
$: path = `${base}/organization-${organizationId}`;
$: console.log($scopes);
$: tabs = [
{
href: path,
@@ -45,7 +46,7 @@
href: `${path}/domains`,
event: 'domains',
title: 'Domains',
disabled: !isCloud || !$canSeeDomains || !SHOW_INIT_FEATURES
disabled: !isCloud
},
{
href: `${path}/members`,
@@ -24,7 +24,6 @@
import { base } from '$app/paths';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import type { Models } from '@appwrite.io/console';
import { SHOW_INIT_FEATURES } from '$lib/system';
export let data: PageData;
@@ -100,15 +99,13 @@
analyticsSource="database_documents" />
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<ViewSelector view={data.view} {columns} hideView />
{#if SHOW_INIT_FEATURES}
<Button
secondary
event={Click.DatabaseImportCsv}
disabled={!(hasAttributes && hasValidAttributes)}
on:click={() => (showImportCSV = true)}>
Import CSV
</Button>
{/if}
<Button
secondary
event={Click.DatabaseImportCsv}
disabled={!(hasAttributes && hasValidAttributes)}
on:click={() => (showImportCSV = true)}>
Import CSV
</Button>
{#if !$isSmallViewport}
<Button
disabled={!(hasAttributes && hasValidAttributes)}
@@ -28,7 +28,6 @@
import { writable, type Writable } from 'svelte/store';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import { isSmallViewport } from '$lib/stores/viewport';
import { SHOW_INIT_FEATURES } from '$lib/system';
let period: UsagePeriods = '30d';
$: path = `${base}/project-${page.params.region}-${page.params.project}/overview`;
@@ -233,13 +232,11 @@
event="keys"
href={`${path}/keys`}
selected={isTabSelected('keys')}>API keys</Tab>
{#if SHOW_INIT_FEATURES}
<Tab
noscroll
event="keys"
href={`${path}/dev-keys`}
selected={isTabSelected('dev-keys')}>Dev keys</Tab>
{/if}
<Tab
noscroll
event="keys"
href={`${path}/dev-keys`}
selected={isTabSelected('dev-keys')}>Dev keys</Tab>
</Tabs>
{#if $action}
<svelte:component this={$action} />
@@ -41,8 +41,8 @@
});
let verified = $state(false);
let routeBase = `${base}/project-${page.params.region}-${page.params.project}/settings/domains`;
let isSubmitting = $state(writable(false));
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/settings/domains`;
const isSubmitting = writable(false);
async function verify() {
const isNewDomain =
@@ -86,7 +86,7 @@
</script>
<Wizard title="Add domain" href={routeBase} column columnSize="s">
<Form onSubmit={verify} bind:isSubmitting>
<Form onSubmit={verify} {isSubmitting}>
<Layout.Stack gap="xxl">
<Card.Base radius="s" padding="s">
<Layout.Stack
@@ -46,7 +46,13 @@
<Link external href={`${$protocol}${domain.domain}`} variant="quiet" icon>
<Typography.Text truncate>
{domain.domain}
{#if domain.status !== 'verified'}
{#if domain.status === 'verifying'}
<Badge
variant="secondary"
type="warning"
content="Verifying"
size="s" />
{:else if domain.status !== 'verified'}
<Badge
variant="secondary"
type="error"
@@ -38,7 +38,6 @@
import { type Models } from '@appwrite.io/console';
import { isSmallViewport } from '$lib/stores/viewport';
import { Menu } from '$lib/components/menu';
import { SHOW_INIT_FEATURES } from '$lib/system';
let showFileAlert = true;
@@ -231,111 +230,105 @@
</svelte:fragment>
</CardGrid>
{#if SHOW_INIT_FEATURES}
<CardGrid>
<svelte:fragment slot="title">File tokens</svelte:fragment>
Use tokens to provide public access to the file.
<svelte:fragment slot="aside">
{#if $tokens.total}
<Layout.Stack
justifyContent="flex-end"
direction={$isSmallViewport ? 'column' : 'row'}>
<Button secondary on:click={() => (showManageToken = true)}>
<Icon size="s" icon={IconPlus} />
<span class="text">Create token</span>
</Button>
</Layout.Stack>
<CardGrid>
<svelte:fragment slot="title">File tokens</svelte:fragment>
Use tokens to provide public access to the file.
<svelte:fragment slot="aside">
{#if $tokens.total}
<Layout.Stack
justifyContent="flex-end"
direction={$isSmallViewport ? 'column' : 'row'}>
<Button secondary on:click={() => (showManageToken = true)}>
<Icon size="s" icon={IconPlus} />
<span class="text">Create token</span>
</Button>
</Layout.Stack>
<Table.Root columns={$columns} let:root>
<svelte:fragment slot="header" let:root>
{#each $columns as { id, title } (id)}
<Table.Header.Cell column={id} {root}
>{title}</Table.Header.Cell>
{/each}
</svelte:fragment>
<Table.Root columns={$columns} let:root>
<svelte:fragment slot="header" let:root>
{#each $columns as { id, title } (id)}
<Table.Header.Cell column={id} {root}>{title}</Table.Header.Cell>
{/each}
</svelte:fragment>
{#each $tokens.tokens as token}
<Table.Row.Base {root}>
<Table.Cell column="created" {root}
>{toLocaleDate(token.$createdAt)}</Table.Cell>
{#each $tokens.tokens as token}
<Table.Row.Base {root}>
<Table.Cell column="created" {root}
>{toLocaleDate(token.$createdAt)}</Table.Cell>
<Table.Cell column="expire" {root}>
<Layout.Stack gap="s" direction="row">
{@const expiration = getExpiryDetails(token)}
{token.expire
? cleanFormattedDate(token.expire)
: 'Never'}
<Table.Cell column="expire" {root}>
<Layout.Stack gap="s" direction="row">
{@const expiration = getExpiryDetails(token)}
{token.expire ? cleanFormattedDate(token.expire) : 'Never'}
{#if expiration.status}
<Badge
size="s"
variant="secondary"
type={expiration.status}
content={expiration.message} />
{/if}
</Layout.Stack>
</Table.Cell>
{#if expiration.status}
<Badge
size="s"
variant="secondary"
type={expiration.status}
content={expiration.message} />
{/if}
</Layout.Stack>
</Table.Cell>
<Table.Cell column="last_accessed" {root}
>{token.accessedAt
? cleanFormattedDate(token.accessedAt, true)
: 'Never'}</Table.Cell>
<Table.Cell column="last_accessed" {root}
>{token.accessedAt
? cleanFormattedDate(token.accessedAt, true)
: 'Never'}</Table.Cell>
<Table.Cell column="actions" {root}>
<Layout.Stack alignItems="flex-end">
<Menu>
<PinkButton.Button icon variant="ghost">
<Icon size="s" icon={IconDotsHorizontal} />
</PinkButton.Button>
<Table.Cell column="actions" {root}>
<Layout.Stack alignItems="flex-end">
<Menu>
<PinkButton.Button icon variant="ghost">
<Icon size="s" icon={IconDotsHorizontal} />
</PinkButton.Button>
<svelte:fragment slot="menu" let:toggle>
<ActionMenu.Root>
<ActionMenu.Root noPadding>
<ActionMenu.Item.Button
on:click={() => {
toggle();
showCopyUrlModal = true;
selectedFileToken = token;
}}
leadingIcon={IconDuplicate}>
Copy URL
</ActionMenu.Item.Button>
</ActionMenu.Root>
<svelte:fragment slot="menu" let:toggle>
<ActionMenu.Root>
<ActionMenu.Root noPadding>
<ActionMenu.Item.Button
leadingIcon={IconPencil}
on:click={() => {
toggle();
showManageToken = true;
showCopyUrlModal = true;
selectedFileToken = token;
}}>
Edit expiry
</ActionMenu.Item.Button>
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
on:click={() => {
toggle();
tokenDeleteMode = true;
showManageToken = true;
selectedFileToken = token;
}}>
Delete
}}
leadingIcon={IconDuplicate}>
Copy URL
</ActionMenu.Item.Button>
</ActionMenu.Root>
</svelte:fragment>
</Menu>
</Layout.Stack>
</Table.Cell>
</Table.Row.Base>
{/each}
</Table.Root>
{:else}
<Empty on:click={() => (showManageToken = true)}
>Create new file token</Empty>
{/if}
</svelte:fragment>
</CardGrid>
{/if}
<ActionMenu.Item.Button
leadingIcon={IconPencil}
on:click={() => {
toggle();
showManageToken = true;
selectedFileToken = token;
}}>
Edit expiry
</ActionMenu.Item.Button>
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
on:click={() => {
toggle();
tokenDeleteMode = true;
showManageToken = true;
selectedFileToken = token;
}}>
Delete
</ActionMenu.Item.Button>
</ActionMenu.Root>
</svelte:fragment>
</Menu>
</Layout.Stack>
</Table.Cell>
</Table.Row.Base>
{/each}
</Table.Root>
{:else}
<Empty on:click={() => (showManageToken = true)}>Create new file token</Empty>
{/if}
</svelte:fragment>
</CardGrid>
<CardGrid>
<svelte:fragment slot="title">Permissions</svelte:fragment>
Assign read or write permissions at the bucket level or file level. If bucket level permissions