diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6891fef59..8fcb73389 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,6 +61,7 @@ Follow the [install instructions](https://appwrite.io/docs/advanced/self-hosting ### 4. Setup environment variables Add a `.env` file by copying the `.env.example` file as a template in the project's root directory. + > **Note** > If you are updating from Appwrite `1.5.x`, be aware that the variables for the console in the `.env` / `.env.example` file have changed in `1.6.x`. diff --git a/src/lib/components/drop.svelte b/src/lib/components/drop.svelte index 9d4e07e0d..2d4ee2b73 100644 --- a/src/lib/components/drop.svelte +++ b/src/lib/components/drop.svelte @@ -120,7 +120,7 @@ bind:this={tooltip} class:u-width-full-line={fullWidth} style:--arrow-size={`${arrowSize}px`} - style:z-index="10"> + style:z-index="21">
+ style:--drop-width-size-desktop={width ? `${width}rem` : ''} + style:position> {#if $$slots.list}
{#if isCloud} diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 28e5be689..707d0f66f 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -65,200 +65,239 @@ export const scopes: { scope: string; description: string; category: string; + icon: string; }[] = [ { scope: 'sessions.write', description: "Access to create, update and delete your project's sessions", - category: 'Auth' + category: 'Auth', + icon: 'user-group' }, { scope: 'users.read', description: "Access to read your project's users", - category: 'Auth' + category: 'Auth', + icon: 'user-group' }, { scope: 'users.write', description: "Access to create, update, and delete your project's users", - category: 'Auth' + category: 'Auth', + icon: 'user-group' }, { scope: 'teams.read', description: "Access to read your project's teams", - category: 'Auth' + category: 'Auth', + icon: 'user-group' }, { scope: 'teams.write', description: "Access to create, update, and delete your project's teams", - category: 'Auth' + category: 'Auth', + icon: 'user-group' }, { scope: 'databases.read', description: "Access to read your project's databases", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'databases.write', description: "Access to create, update, and delete your project's databases", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'collections.read', description: "Access to read your project's database collections", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'collections.write', description: "Access to create, update, and delete your project's database collections", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'attributes.read', description: "Access to read your project's database collection's attributes", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'attributes.write', description: "Access to create, update, and delete your project's database collection's attributes", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'indexes.read', description: "Access to read your project's database collection's indexes", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'indexes.write', description: "Access to create, update, and delete your project's database collection's indexes", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'documents.read', description: "Access to read your project's database documents", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'documents.write', description: "Access to create, update, and delete your project's database documents", - category: 'Database' + category: 'Database', + icon: 'database' }, { scope: 'files.read', description: "Access to read your project's storage files and preview images", - category: 'Storage' + category: 'Storage', + icon: 'folder' }, { scope: 'files.write', description: "Access to create, update, and delete your project's storage files", - category: 'Storage' + category: 'Storage', + icon: 'folder' }, { scope: 'buckets.read', description: "Access to read your project's storage buckets", - category: 'Storage' + category: 'Storage', + icon: 'folder' }, { scope: 'buckets.write', description: "Access to create, update, and delete your project's storage buckets", - category: 'Storage' + category: 'Storage', + icon: 'folder' }, { scope: 'functions.read', description: "Access to read your project's functions and code deployments", - category: 'Functions' + category: 'Functions', + icon: 'lightning-bolt' }, { scope: 'functions.write', description: "Access to create, update, and delete your project's functions and code deployments", - category: 'Functions' + category: 'Functions', + icon: 'lightning-bolt' }, { scope: 'execution.read', description: "Access to read your project's execution logs", - category: 'Functions' + category: 'Functions', + icon: 'lightning-bolt' }, { scope: 'execution.write', description: "Access to execute your project's functions", - category: 'Functions' + category: 'Functions', + icon: 'lightning-bolt' }, { scope: 'targets.read', description: "Access to read your project's messaging targets", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'targets.write', description: "Access to create, update, and delete your project's messaging targets", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'providers.read', description: "Access to read your project's messaging providers", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'providers.write', description: "Access to create, update, and delete your project's messaging providers", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'messages.read', description: "Access to read your project's messages", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'messages.write', description: "Access to create, update, and delete your project's messages", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'topics.read', description: "Access to read your project's messaging topics", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'topics.write', description: "Access to create, update, and delete your project's messaging topics", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'subscribers.read', description: "Access to read your project's messaging topic subscribers", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'subscribers.write', description: "Access to create, update, and delete your project's messaging topic subscribers", - category: 'Messaging' + category: 'Messaging', + icon: 'send' }, { scope: 'locale.read', description: "Access to access your project's Locale service", - category: 'Other' + category: 'Other', + icon: 'globe' }, { scope: 'avatars.read', description: "Access to access your project's Avatars service", - category: 'Other' + category: 'Other', + icon: 'globe' }, { scope: 'health.read', description: "Access to read your project's health status", - category: 'Other' + category: 'Other', + icon: 'globe' }, { scope: 'migrations.read', description: "Access to read your project's migration status", - category: 'Other' + category: 'Other', + icon: 'globe' }, { scope: 'migrations.write', description: 'Access to create migrations', - category: 'Other' + category: 'Other', + icon: 'globe' } ]; diff --git a/src/lib/elements/forms/inputFile.svelte b/src/lib/elements/forms/inputFile.svelte index 3ecb27959..76c3babcc 100644 --- a/src/lib/elements/forms/inputFile.svelte +++ b/src/lib/elements/forms/inputFile.svelte @@ -32,7 +32,7 @@ } function isFileExtensionAllowed(fileExtension: string) { - if (allowedFileExtensions.length && !allowedFileExtensions.includes(fileExtension)) { + if (allowedFileExtensions?.length && !allowedFileExtensions.includes(fileExtension)) { return false; } return true; @@ -42,7 +42,7 @@ hovering = false; if (!ev.dataTransfer.items) return; for (let i = 0; i < ev.dataTransfer.items.length; i++) { - const fileExtension = ev.dataTransfer.items[i].getAsFile().name.split('.')[1]; + const fileExtension = ev.dataTransfer.items[i].getAsFile().name.split('.').pop(); if (!isFileExtensionAllowed(fileExtension)) { error = 'Invalid file extension'; return; @@ -183,15 +183,16 @@ {#if files?.length}
+ +
Templates diff --git a/src/lib/wizards/functions/createManual.svelte b/src/lib/wizards/functions/createManual.svelte index f5ab83b3b..c774c3516 100644 --- a/src/lib/wizards/functions/createManual.svelte +++ b/src/lib/wizards/functions/createManual.svelte @@ -16,8 +16,8 @@ import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { base } from '$app/paths'; import { page } from '$app/stores'; - import Details from './steps/details.svelte'; - import Configuration from './steps/configuration.svelte'; + import Details from './steps/manualDetails.svelte'; + import Configuration from './steps/manualConfiguration.svelte'; import ExecuteAccess from './steps/executeAccess.svelte'; import { isValueOfStringEnum } from '$lib/helpers/types'; diff --git a/src/lib/wizards/functions/createTemplate.svelte b/src/lib/wizards/functions/createTemplate.svelte index 36d74abdd..48ceb5905 100644 --- a/src/lib/wizards/functions/createTemplate.svelte +++ b/src/lib/wizards/functions/createTemplate.svelte @@ -1,22 +1,28 @@ - + diff --git a/src/lib/wizards/functions/steps/configuration.svelte b/src/lib/wizards/functions/steps/manualConfiguration.svelte similarity index 100% rename from src/lib/wizards/functions/steps/configuration.svelte rename to src/lib/wizards/functions/steps/manualConfiguration.svelte diff --git a/src/lib/wizards/functions/steps/details.svelte b/src/lib/wizards/functions/steps/manualDetails.svelte similarity index 100% rename from src/lib/wizards/functions/steps/details.svelte rename to src/lib/wizards/functions/steps/manualDetails.svelte diff --git a/src/lib/wizards/functions/steps/repositoryBehaviour.svelte b/src/lib/wizards/functions/steps/repositoryBehaviour.svelte deleted file mode 100644 index c55fcee6b..000000000 --- a/src/lib/wizards/functions/steps/repositoryBehaviour.svelte +++ /dev/null @@ -1,41 +0,0 @@ - - - - Connect - - Connect function to a new repository or to an existing one within a selected Git - organization. - - -
    - - Create a new repository - Clone the template and create a new repository in your selected organization. - - - Add to existing repository - Clone the template to an existing repository in your selected organization. - -
-
diff --git a/src/lib/wizards/functions/steps/templateDeployment.svelte b/src/lib/wizards/functions/steps/templateDeployment.svelte new file mode 100644 index 000000000..7a830b5ff --- /dev/null +++ b/src/lib/wizards/functions/steps/templateDeployment.svelte @@ -0,0 +1,53 @@ + + + + Deployment + + Connect your function to a Git repository for automatic deployments or deploy your function + using the CLI. + + +

Automatic with Git Recommended

+ + + Create a new repository + Clone the template to a newly created repository in your organization. + + + Add to existing repository + Clone the template to an existing repository in your organization. + + + +

Manual with CLI

+
    + + Create manually + Deploy a function from a template and change the code using the CLI. + +
+
diff --git a/src/lib/wizards/functions/steps/templatePermissions.svelte b/src/lib/wizards/functions/steps/templatePermissions.svelte new file mode 100644 index 000000000..b7cf52dd9 --- /dev/null +++ b/src/lib/wizards/functions/steps/templatePermissions.svelte @@ -0,0 +1,86 @@ + + + + Permissions + + Enable recommended scopes and execute access for when your function is deployed. + +

Execute permissions

+ + + +

Function scopes

+ + {#each templateScopes as scope, i} + + {#if i < templateScopes.length - 1} +
+ {/if} + {/each} +
+
diff --git a/src/lib/wizards/functions/steps/templateVariables.svelte b/src/lib/wizards/functions/steps/templateVariables.svelte index d8e677344..0b9c9461d 100644 --- a/src/lib/wizards/functions/steps/templateVariables.svelte +++ b/src/lib/wizards/functions/steps/templateVariables.svelte @@ -12,7 +12,6 @@ InputNumber } from '$lib/elements/forms'; import { Card, Collapsible, CollapsibleItem } from '$lib/components'; - import AppwriteVariable from '../components/appwriteVariable.svelte'; import type { SvelteComponent } from 'svelte'; async function beforeSubmit() { @@ -20,10 +19,6 @@ if (!variable.required) { continue; } - if (variable.name === 'APPWRITE_API_KEY') { - if ($templateConfig.appwriteApiKey || $templateConfig.generateKey) continue; - else throw new Error(`Please set ${variable.name} variable or generate it.`); - } if (!$templateConfig.variables[variable.name]) { throw new Error(`Please set ${variable.name} variable.`); } @@ -72,25 +67,21 @@ {#each requiredVariables as variable} - {#if variable.name === 'APPWRITE_API_KEY'} - - {:else} -
- - - {@html variable.description} - -
- {/if} +
+ + + {@html variable.description} + +
{/each}
@@ -107,25 +98,21 @@ {#each optionalVariables as variable} - {#if variable.name === 'APPWRITE_API_KEY'} - - {:else} -
- +
+ - - {@html variable.description} - -
- {/if} + + {@html variable.description} + +
{/each}
diff --git a/src/lib/wizards/functions/store.ts b/src/lib/wizards/functions/store.ts index e607c113b..9600fb86e 100644 --- a/src/lib/wizards/functions/store.ts +++ b/src/lib/wizards/functions/store.ts @@ -1,7 +1,8 @@ import { page } from '$app/stores'; +import type { WizardStepsType } from '$lib/layout/wizard.svelte'; import type { MarketplaceTemplate } from '$lib/stores/marketplace'; import type { Models } from '@appwrite.io/console'; -import { derived, writable } from 'svelte/store'; +import { derived, writable, type Writable } from 'svelte/store'; export const template = writable(); export const templateConfig = writable<{ @@ -9,12 +10,12 @@ export const templateConfig = writable<{ name: string; runtime: string; variables: { [key: string]: unknown }; - repositoryBehaviour: 'new' | 'existing'; - repositoryName: string; - repositoryPrivate: boolean; + repositoryBehaviour: 'new' | 'existing' | 'manual'; + repositoryName?: string; + repositoryPrivate?: boolean; repositoryId: string; - appwriteApiKey?: string; - generateKey?: boolean; + execute?: boolean; + scopes?: string[]; }>(); export const repository = writable(); export const installation = writable(); @@ -59,3 +60,5 @@ function createFunctionStore() { export const createFunction = createFunctionStore(); export const createFunctionDeployment = writable(); + +export const templateStepsComponents: Writable = writable(new Map()); diff --git a/src/routes/(authenticated)/+layout.ts b/src/routes/(authenticated)/git/+layout.ts similarity index 100% rename from src/routes/(authenticated)/+layout.ts rename to src/routes/(authenticated)/git/+layout.ts diff --git a/src/routes/(authenticated)/mfa/+page.ts b/src/routes/(authenticated)/mfa/+page.ts index ed787b5cd..e5df4ee16 100644 --- a/src/routes/(authenticated)/mfa/+page.ts +++ b/src/routes/(authenticated)/mfa/+page.ts @@ -1,7 +1,13 @@ import type { PageLoad } from './$types'; import { sdk } from '$lib/stores/sdk'; +import { redirect } from '@sveltejs/kit'; +import { base } from '$app/paths'; -export const load: PageLoad = async () => { +export const load: PageLoad = async ({ parent }) => { + const { mfaRequired } = await parent(); + if (!mfaRequired) { + redirect(303, base); + } return { factors: await sdk.forConsole.account.listMfaFactors() }; diff --git a/src/routes/(console)/(migration-wizard)/resource-form.svelte b/src/routes/(console)/(migration-wizard)/resource-form.svelte index 66a2fadb6..1da67926c 100644 --- a/src/routes/(console)/(migration-wizard)/resource-form.svelte +++ b/src/routes/(console)/(migration-wizard)/resource-form.svelte @@ -119,8 +119,8 @@ $provider.subdomain, $provider.region, $provider.adminSecret, - $provider.database, - $provider.username, + $provider.database || $provider.subdomain, + $provider.username || 'postgres', $provider.password ); } @@ -186,7 +186,7 @@
-{#if report && !isVersionAtLeast(version, '1.4.0')} +{#if report && !isVersionAtLeast(version, '1.4.0') && $provider.provider === 'appwrite'}
import { page } from '$app/stores'; - import { InputSelect } from '$lib/elements/forms'; + import { FormList, InputSelect } from '$lib/elements/forms'; import InputText from '$lib/elements/forms/inputText.svelte'; import { WizardStep } from '$lib/layout'; import { Query, type Models, ID } from '@appwrite.io/console'; @@ -44,7 +44,7 @@ Project -
+ {#if organizations.length > 1} {/if} -
+