diff --git a/.env.example b/.env.example index 06149b167..e9457b89f 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ VITE_APPWRITE_ENDPOINT= +VITE_APPWRITE_GROWTH_ENDPOINT= VITE_GA_PROJECT= VITE_SENTRY_DSN= VITE_CONSOLE_MODE=self-hosted \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 785ae480a..13f5a7f44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@analytics/google-analytics": "^1.0.5", - "@aw-labs/appwrite-console": "^13.0.0", + "@aw-labs/appwrite-console": "^13.1.0", "@aw-labs/icons": "0.0.0-77", "@aw-labs/ui": "0.0.0-77", "@popperjs/core": "^2.11.6", @@ -145,9 +145,9 @@ "integrity": "sha512-1Yw7u/COtxx06BfwlI+kVhsa/upKYzmCNrT4c8QDeCY2KMYlnijkUjtHiPU08HxyTIVB5j6d75O0YWVIHwQS8g==" }, "node_modules/@aw-labs/appwrite-console": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.0.0.tgz", - "integrity": "sha512-a5illDoFZAhgLP8Ae+KHPzBIUozKXzjyHUw6jTwNPZaL+b2RnTe3oRLZU8l8Kt5pB5m7NZx6kAcZm+NMf8NeCw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.1.0.tgz", + "integrity": "sha512-1FyKke5b3vx+D3VfNYd3YnFhzUOlsj9bD+KTRLWA4WRItb55thFVZJMWQQ4XnZtDiLPuJAn2XjbMSfMr+9XYwg==", "dependencies": { "cross-fetch": "3.1.5", "isomorphic-form-data": "2.0.0" @@ -7740,9 +7740,9 @@ "integrity": "sha512-1Yw7u/COtxx06BfwlI+kVhsa/upKYzmCNrT4c8QDeCY2KMYlnijkUjtHiPU08HxyTIVB5j6d75O0YWVIHwQS8g==" }, "@aw-labs/appwrite-console": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.0.0.tgz", - "integrity": "sha512-a5illDoFZAhgLP8Ae+KHPzBIUozKXzjyHUw6jTwNPZaL+b2RnTe3oRLZU8l8Kt5pB5m7NZx6kAcZm+NMf8NeCw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.1.0.tgz", + "integrity": "sha512-1FyKke5b3vx+D3VfNYd3YnFhzUOlsj9bD+KTRLWA4WRItb55thFVZJMWQQ4XnZtDiLPuJAn2XjbMSfMr+9XYwg==", "requires": { "cross-fetch": "3.1.5", "isomorphic-form-data": "2.0.0" diff --git a/package.json b/package.json index cbd2c487c..266a4d365 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "dependencies": { "@analytics/google-analytics": "^1.0.5", "analytics": "^0.8.1", - "@aw-labs/appwrite-console": "^13.0.0", + "@aw-labs/appwrite-console": "^13.1.0", "@aw-labs/icons": "0.0.0-77", "@aw-labs/ui": "0.0.0-77", "@popperjs/core": "^2.11.6", diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index d169790ac..a57000024 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -3,7 +3,7 @@ import googleAnalytics from '@analytics/google-analytics'; import { get } from 'svelte/store'; import { page } from '$app/stores'; import { user } from '$lib/stores/user'; -import { Mode } from '$lib/constants'; +import { growthEndpoint, Mode } from '$lib/constants'; const analytics = Analytics({ app: 'appwrite', @@ -40,7 +40,7 @@ function sendEventToGrowth(event: string, path: string, data: object = null): vo email = userStore.email; name = userStore.name; } - fetch('https://growth.appwrite.io/v1/analytics', { + fetch(`${growthEndpoint}/analytics`, { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/src/lib/components/copy.svelte b/src/lib/components/copy.svelte index 1f0e5dfd8..0e859e79c 100644 --- a/src/lib/components/copy.svelte +++ b/src/lib/components/copy.svelte @@ -2,6 +2,7 @@ import { trackEvent } from '$lib/actions/analytics'; import { tooltip } from '$lib/actions/tooltip'; import { clickOnEnter } from '$lib/helpers/a11y'; + import { copy } from '$lib/helpers/copy'; import { addNotification } from '$lib/stores/notifications'; export let value: string; @@ -9,27 +10,28 @@ let content = 'Click to copy'; - const copy = async () => { - try { - await navigator.clipboard.writeText(value); + async function handleClick() { + const success = await copy(value); + + if (success) { content = 'Copied'; - } catch (error) { + } else { addNotification({ - message: error.message, + message: 'Unable to copy to clipboard', type: 'error' }); - } finally { - if (event) { - trackEvent('click_id_tag', { - name: event - }); - } } - }; + + if (event) { + trackEvent('click_id_tag', { + name: event + }); + } + } setTimeout(() => (content = 'Click to copy'))} use:tooltip={{ diff --git a/src/lib/components/copyInput.svelte b/src/lib/components/copyInput.svelte index 65bd6bb81..b06f1ae36 100644 --- a/src/lib/components/copyInput.svelte +++ b/src/lib/components/copyInput.svelte @@ -1,5 +1,6 @@ +
@@ -98,8 +106,7 @@ bind:value bind:this={element} on:keydown={handleInput} - on:blur={addValue} - on:invalid={handleInvalid} /> + on:blur={addValue} />
{#if error} diff --git a/src/lib/helpers/copy.ts b/src/lib/helpers/copy.ts new file mode 100644 index 000000000..6399995ea --- /dev/null +++ b/src/lib/helpers/copy.ts @@ -0,0 +1,36 @@ +async function securedCopy(value: string) { + try { + await navigator.clipboard.writeText(value); + } catch { + return false; + } + + return true; +} + +function unsecuredCopy(value: string) { + const textArea = document.createElement('textarea'); + textArea.value = value; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + let success = true; + try { + document.execCommand('copy'); + } catch { + success = false; + } finally { + document.body.removeChild(textArea); + } + + return success; +} + +export async function copy(value: string) { + // securedCopy works only in HTTPS environment. + // unsecuredCopy works in HTTP and only runs if securedCopy fails. + const success = (await securedCopy(value)) || unsecuredCopy(value); + + return success; +} diff --git a/src/lib/layout/unauthenticated.svelte b/src/lib/layout/unauthenticated.svelte index 62d9e923b..1028e4f0a 100644 --- a/src/lib/layout/unauthenticated.svelte +++ b/src/lib/layout/unauthenticated.svelte @@ -4,6 +4,7 @@ import LoginDark from '$lib/images/login/login-dark-mode.svg'; import { app } from '$lib/stores/app'; import { base } from '$app/paths'; + import { user } from '$lib/stores/user'; const technologies = [ 'js', @@ -25,7 +26,7 @@ diff --git a/src/lib/stores/app.ts b/src/lib/stores/app.ts index 555d36415..f3b03e36b 100644 --- a/src/lib/stores/app.ts +++ b/src/lib/stores/app.ts @@ -1,4 +1,5 @@ import { browser } from '$app/environment'; +import { growthEndpoint } from '$lib/constants'; import { writable } from 'svelte/store'; export type AppStore = { @@ -59,7 +60,7 @@ function createFeedbackStore() { email?: string, value?: number ) => { - const response = await fetch('https://growth.appwrite.io/v1/feedback', { + const response = await fetch(`${growthEndpoint}/feedback`, { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/src/lib/stores/project-services.ts b/src/lib/stores/project-services.ts index 6f4a8cb0d..ef8a1c444 100644 --- a/src/lib/stores/project-services.ts +++ b/src/lib/stores/project-services.ts @@ -54,6 +54,11 @@ function createServices() { label: 'Users', method: 'users', value: null + }, + { + label: 'GraphQL', + method: 'graphql', + value: null } ] }); @@ -107,6 +112,11 @@ function createServices() { label: 'Users', method: 'users', value: project.serviceStatusForUsers + }, + { + label: 'GraphQL', + method: 'graphql', + value: project.serviceStatusForGraphql } ]; set({ list }); diff --git a/src/lib/stores/uploader.ts b/src/lib/stores/uploader.ts index 6ca846214..9538d0b79 100644 --- a/src/lib/stores/uploader.ts +++ b/src/lib/stores/uploader.ts @@ -1,5 +1,6 @@ import type { Models } from '@aw-labs/appwrite-console'; import { writable } from 'svelte/store'; +import { sdkForProject } from './sdk'; type UploaderFile = { $id: string; @@ -8,7 +9,6 @@ type UploaderFile = { progress: number; completed: boolean; failed: boolean; - cancelled: boolean; error?: string; }; export type Uploader = { @@ -42,7 +42,6 @@ const createUploader = () => { close: () => update((n) => { n.isOpen = !n.isOpen; - return n; }), toggle: () => @@ -57,22 +56,43 @@ const createUploader = () => { isCollapsed: false, files: [] }), - addFile: async (file: Models.File, isOpen = true, isCollapsed = false) => { + uploadFile: async (bucketId: string, id: string, file: File, permissions: string[]) => { const newFile: UploaderFile = { - $id: file.$id, - bucketId: file.bucketId, + $id: id, + bucketId: bucketId, name: file.name, - progress: calculateProgress(file), - completed: calculateProgress(file) === 100 ? true : false, - failed: false, - cancelled: false + progress: 0, + completed: false, + failed: false }; - return update((n) => { - n.isOpen = isOpen; - n.isCollapsed = isCollapsed; + update((n) => { + n.isOpen = true; + n.isCollapsed = false; n.files.unshift(newFile); return n; }); + const uploadedFile = await sdkForProject.storage.createFile( + bucketId, + id ?? 'unique()', + file, + permissions, + (p) => { + newFile.$id = p.$id; + newFile.progress = p.progress; + newFile.completed = p.progress === 100 ? true : false; + updateFile(p.$id, newFile); + } + ); + newFile.$id = uploadedFile.$id; + newFile.progress = 100; + newFile.completed = true; + updateFile(newFile.$id, newFile); + }, + removeFromQueue: (id: string) => { + update((n) => { + n.files = n.files.filter((f) => f.$id !== id); + return n; + }); }, removeFile: async (file: Models.File) => { if (file.chunksTotal === file.chunksUploaded) { @@ -81,18 +101,9 @@ const createUploader = () => { return n; }); - } else { - if (confirm('Are you sure you want to cancel the upload?')) { - updateFile(file.$id, { cancelled: true }); - } } } }; }; export const uploader = createUploader(); - -function calculateProgress(file: Models.File) { - const progress = file.chunksUploaded / file.chunksTotal; - return Math.round(progress * 100); -} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 43965143d..bdaa9a1ad 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -49,11 +49,16 @@ if (!$page.url.pathname.startsWith('/auth')) { const acceptedRoutes = ['/login', '/register', '/recover', '/invite']; if ($user) { - if (!$page.url.pathname.startsWith('/console')) { + if ( + !$page.url.pathname.startsWith('/console') && + !$page.url.pathname.startsWith('/invite') + ) { + console.log('test'); await goto(`${base}/console`, { replaceState: true }); } + loading.set(false); } else { if (acceptedRoutes.includes($page.url.pathname)) { await goto(`${base}${$page.url.pathname}${$page.url.search}`); diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 4544b5beb..84e164569 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -8,9 +8,6 @@ import type { LayoutLoad } from './$types'; export const ssr = false; export const load: LayoutLoad = async ({ depends, url }) => { - if (url.pathname.startsWith('/auth')) { - return; - } depends(Dependencies.ACCOUNT); try { const account = await sdkForConsole.account.get(); @@ -20,7 +17,15 @@ export const load: LayoutLoad = async ({ depends, url }) => { organizations: sdkForConsole.teams.list() }; } catch (error) { - const acceptedRoutes = ['/login', '/register', '/recover', '/invite']; + const acceptedRoutes = [ + '/login', + '/register', + '/recover', + '/invite', + '/auth/magic-url', + '/auth/oauth2/success', + '/auth/oauth2/failure' + ]; if (!acceptedRoutes.includes(url.pathname)) { throw redirect(303, '/login'); diff --git a/src/routes/console/account/delete.svelte b/src/routes/console/account/delete.svelte index a64b1321f..bf1a7d2a3 100644 --- a/src/routes/console/account/delete.svelte +++ b/src/routes/console/account/delete.svelte @@ -1,17 +1,19 @@ {#if $collection} - - {$collection.name} - - -
    - -
-
-

Created: {toLocaleDateTime($collection.$createdAt)}

-

Last Updated: {toLocaleDateTime($collection.$updatedAt)}

-
-
- - - - -
- - - Update Name - - -
    - - {#if showError === 'name'} - {errorMessage} - {/if} -
-
- - - - -
- - - Update Permissions -

- Choose who can access your collection and documents. For more information, check out - the Permissions Guide in our documentation. -

- - {#if collectionPermissions} - - {/if} - - - - -
- - - Update Document Security - - - - -

- When document security is enabled, users will be able to access documents for - which they have been granted either Document or Collection permissions. -

-

- If document security is disabled, users can access documents only if they have Collection permissions. Document permissions will be ignored. -

-
- - - -
- - - Delete Collection -

- The collection will be permanently deleted, including all the documents within it. - This action is irreversible. -

- - - -
{$collection.name}
-
-

Last Updated: {toLocaleDateTime($collection.$updatedAt)}

-
-
- - - - -
+ + + + + {/if}
- - diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/dangerZone.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/dangerZone.svelte new file mode 100644 index 000000000..53653a2d4 --- /dev/null +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/dangerZone.svelte @@ -0,0 +1,31 @@ + + + + Delete Collection +

+ The collection will be permanently deleted, including all the documents within it. This + action is irreversible. +

+ + + +
{$collection.name}
+
+

Last Updated: {toLocaleDateTime($collection.$updatedAt)}

+
+
+ + + + +
+ + diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateName.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateName.svelte new file mode 100644 index 000000000..e98422453 --- /dev/null +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateName.svelte @@ -0,0 +1,66 @@ + + +
+ + Update Name + + +
    + +
+
+ + + + +
+
diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updatePermissions.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updatePermissions.svelte new file mode 100644 index 000000000..6589c22c0 --- /dev/null +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updatePermissions.svelte @@ -0,0 +1,75 @@ + + + + Update Permissions +

+ Choose who can access your collection and documents. For more information, check out the Permissions Guide in our documentation. +

+ + {#if collectionPermissions} + + {/if} + + + + +
diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateSecurity.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateSecurity.svelte new file mode 100644 index 000000000..87d601be6 --- /dev/null +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateSecurity.svelte @@ -0,0 +1,70 @@ + + + + Update Document Security + + + + +

+ When document security is enabled, users will be able to access documents for which they + have been granted either Document or Collection permissions. +

+

+ If document security is disabled, users can access documents only if they have Collection permissions. Document permissions will be ignored. +

+
+ + + +
diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateStatus.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateStatus.svelte new file mode 100644 index 000000000..6c1353320 --- /dev/null +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/settings/updateStatus.svelte @@ -0,0 +1,68 @@ + + + + {$collection.name} + + +
    + +
+
+

Created: {toLocaleDateTime($collection.$createdAt)}

+

Last Updated: {toLocaleDateTime($collection.$updatedAt)}

+
+
+ + + + +
diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step2.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step2.svelte index 0768461c1..1024dcba2 100644 --- a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step2.svelte +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step2.svelte @@ -12,7 +12,8 @@ Choose who can access your collection and documents. For more information, check out the Permissions Guide in our documentation. + rel="noopener noreferrer" + class="link">Permissions Guide in our documentation. {#if $collection.documentSecurity}
diff --git a/src/routes/console/project-[project]/functions/function-[function]/create.svelte b/src/routes/console/project-[project]/functions/function-[function]/create.svelte index 14373c646..c8e2f9e08 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/create.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/create.svelte @@ -97,7 +97,7 @@ files = entrypoint = active = null; showCreate = false; dispatch('created'); - trackEvent('submit_function_create'); + trackEvent('submit_deployment_create'); } catch (error) { addNotification({ type: 'error', diff --git a/src/routes/console/project-[project]/overview/platforms/[platform]/android.svelte b/src/routes/console/project-[project]/overview/platforms/[platform]/android.svelte index ebcd4ce21..fa23169a1 100644 --- a/src/routes/console/project-[project]/overview/platforms/[platform]/android.svelte +++ b/src/routes/console/project-[project]/overview/platforms/[platform]/android.svelte @@ -10,10 +10,10 @@ import { project } from '../../../store'; import { platform } from './store'; - let hostname: string = null; + let key: string = null; onMount(() => { - hostname ??= $platform.hostname; + key ??= $platform.key; }); const updateHostname = async () => { @@ -22,9 +22,9 @@ $project.$id, $platform.$id, $platform.name, - $platform.key, + key, $platform.store, - hostname + $platform.hostname ); invalidate(Dependencies.PLATFORM); trackEvent('submit_platform_update', { @@ -52,16 +52,16 @@ - + diff --git a/src/routes/console/project-[project]/overview/platforms/wizard/android/step1.svelte b/src/routes/console/project-[project]/overview/platforms/wizard/android/step1.svelte index 2ff8ac01c..7971b24e6 100644 --- a/src/routes/console/project-[project]/overview/platforms/wizard/android/step1.svelte +++ b/src/routes/console/project-[project]/overview/platforms/wizard/android/step1.svelte @@ -31,9 +31,9 @@ projectId, 'android', $createPlatform.name, + $createPlatform.key, undefined, - undefined, - $createPlatform.hostname + undefined ); $createPlatform.$id = platform.$id; @@ -50,11 +50,11 @@ required bind:value={$createPlatform.name} /> + bind:value={$createPlatform.key} /> diff --git a/src/routes/console/project-[project]/overview/platforms/wizard/apple/step1.svelte b/src/routes/console/project-[project]/overview/platforms/wizard/apple/step1.svelte index 08052981f..49cdcd687 100644 --- a/src/routes/console/project-[project]/overview/platforms/wizard/apple/step1.svelte +++ b/src/routes/console/project-[project]/overview/platforms/wizard/apple/step1.svelte @@ -41,9 +41,9 @@ projectId, platform, $createPlatform.name, + $createPlatform.key, undefined, - undefined, - $createPlatform.hostname + undefined ); $createPlatform.$id = response.$id; @@ -95,6 +95,6 @@ placeholder="com.company.appname" tooltip="You can find your Bundle Identifier in the General tab for your app's primary target in Xcode." required - bind:value={$createPlatform.hostname} /> + bind:value={$createPlatform.key} /> diff --git a/src/routes/console/project-[project]/overview/platforms/wizard/flutter/step1.svelte b/src/routes/console/project-[project]/overview/platforms/wizard/flutter/step1.svelte index df6f60ad0..82a356e4c 100644 --- a/src/routes/console/project-[project]/overview/platforms/wizard/flutter/step1.svelte +++ b/src/routes/console/project-[project]/overview/platforms/wizard/flutter/step1.svelte @@ -25,7 +25,7 @@ let platform: Platform = Platform.Android; const projectId = $page.params.project; - const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.app']; + const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.io']; const placeholder: Record< Platform, { @@ -97,9 +97,9 @@ projectId, platform, $createPlatform.name, + platform !== Platform.Web ? $createPlatform.key : undefined, undefined, - undefined, - $createPlatform.hostname + platform === Platform.Web ? $createPlatform.hostname : undefined ); $createPlatform.$id = response.$id; @@ -160,15 +160,16 @@ placeholder={placeholder[platform].name} required bind:value={$createPlatform.name} /> -
- - {#if platform === Platform.Web} + {#if platform === Platform.Web} +
+ +
{#each suggestions as suggestion} {/each}
- {/if} -
+
+ {:else} + + {/if} diff --git a/src/routes/console/project-[project]/overview/platforms/wizard/web/step1.svelte b/src/routes/console/project-[project]/overview/platforms/wizard/web/step1.svelte index aa1ff28ea..5a3e555da 100644 --- a/src/routes/console/project-[project]/overview/platforms/wizard/web/step1.svelte +++ b/src/routes/console/project-[project]/overview/platforms/wizard/web/step1.svelte @@ -12,7 +12,7 @@ import Dark from './dark.svg'; const projectId = $page.params.project; - const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.app']; + const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.io']; $wizard.media = $app.themeInUse === 'dark' ? Dark : Light; async function beforeSubmit() { diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte index 9b7195420..ab3bd3c63 100644 --- a/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte @@ -1,353 +1,18 @@ - - Signature Key -

- Add the Signature Key to the X-Appwrite-Webhook-Signature header to validate your - webhooks. Learn more about webhook validation. -

- -
-

Key

- -
-
- - - -
-
- - Update Name -

Choose any name that will help you distinguish between Webhooks.

- - - - - - - - - -
-
- -
- - Update Url - - - - - - - - - - - -
- -
- - Update Events -

- Set the events that will trigger your webhook. Maximum 100 events allowed. -

- - {#if $eventSet.size} - - {#each Array.from($eventSet) as event} -
  • - - {event} - - - - -
  • - {/each} -
    -
    - -
    - {:else} - (showCreateEvent = true)}> - Add an event to get started - - {/if} -
    - - - - -
    -
    - -
    - - Security -

    - Set an optional basic HTTP authentication username and password to protect your - endpoint from unauthorized access. -

    - - -
    - HTTP Authentication -

    Use to secure your endpoint from untrusted sources.

    -
    - - - - - Warning: Untrusted or self-signed certificates - may not be secure. - - Learn more - -
    -
    - - - - -
    -
    - - -
    - Delete Webhook -
    -

    The webhook will be permanently deleted. This action is irreversible.

    - - - -
    {$webhook.name}
    -
    -

    Last updated: {toLocaleDateTime($webhook.$updatedAt)}

    -
    -
    - - - - -
    + + + + + +
    - - - - - diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/dangerZone.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/dangerZone.svelte new file mode 100644 index 000000000..c531b91a4 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/dangerZone.svelte @@ -0,0 +1,30 @@ + + + +
    + Delete Webhook +
    +

    The webhook will be permanently deleted. This action is irreversible.

    + + + +
    {$webhook.name}
    +
    +

    Last updated: {toLocaleDateTime($webhook.$updatedAt)}

    +
    +
    + + + + +
    + + diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateEvents.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateEvents.svelte new file mode 100644 index 000000000..919d21402 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateEvents.svelte @@ -0,0 +1,109 @@ + + +
    + + Update Events +

    + Set the events that will trigger your webhook. Maximum 100 events allowed. +

    + + {#if $eventSet.size} + + {#each Array.from($eventSet) as event} +
  • + + {event} + + + + +
  • + {/each} +
    +
    + +
    + {:else} + (showCreateEvent = true)}>Add an event to get started + {/if} +
    + + + + +
    +
    + + diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateName.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateName.svelte new file mode 100644 index 000000000..1d4fcd0cf --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateName.svelte @@ -0,0 +1,66 @@ + + +
    + + Update Name +

    Choose any name that will help you distinguish between Webhooks.

    + + + + + + + + + +
    +
    diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSecurity.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSecurity.svelte new file mode 100644 index 000000000..dc1d1d8ce --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSecurity.svelte @@ -0,0 +1,110 @@ + + +
    + + Security +

    + Set an optional basic HTTP authentication username and password to protect your endpoint + from unauthorized access. +

    + + +
    + HTTP Authentication +

    Use to secure your endpoint from untrusted sources.

    +
    + + + + + Warning: Untrusted or self-signed certificates may + not be secure. + + Learn more + +
    +
    + + + + +
    +
    diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSignature.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSignature.svelte new file mode 100644 index 000000000..7f65c7677 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateSignature.svelte @@ -0,0 +1,30 @@ + + + + Signature Key +

    + Add the Signature Key to the X-Appwrite-Webhook-Signature header to validate your webhooks. Learn more about webhook validation. +

    + +
    +

    Key

    + +
    +
    + + + +
    + + diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateURL.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateURL.svelte new file mode 100644 index 000000000..ff775045d --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/updateURL.svelte @@ -0,0 +1,66 @@ + + +
    + + Update Url + + + + + + + + + + + +
    diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.svelte b/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.svelte index 95727668a..3e0dfb37f 100644 --- a/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.svelte +++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.svelte @@ -162,11 +162,15 @@ { + showDropdown[index] = false; + }} href={`${base}/console/project-${projectId}/storage/bucket-${bucketId}/file-${file.$id}`} icon="pencil">Update { + showDropdown[index] = false; selectedFile = file; showDelete = true; }}>Delete diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/create.svelte b/src/routes/console/project-[project]/storage/bucket-[bucket]/create.svelte index 5570b62f1..da6046ee3 100644 --- a/src/routes/console/project-[project]/storage/bucket-[bucket]/create.svelte +++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/create.svelte @@ -2,7 +2,6 @@ import { Button, FormList, InputFile } from '$lib/elements/forms'; import { Pill } from '$lib/elements'; import { Modal, CustomId, Heading, Alert } from '$lib/components'; - import { sdkForProject } from '$lib/stores/sdk'; import { createEventDispatcher } from 'svelte'; import { page } from '$app/stores'; import { uploader } from '$lib/stores/uploader'; @@ -25,20 +24,15 @@ async function create() { try { - const file = await sdkForProject.storage.createFile( - bucketId, - id ?? 'unique()', - files[0], - permissions - ); - files = null; showCreate = false; + await uploader.uploadFile(bucketId, id, files[0], permissions); + files = null; showCustomId = false; - uploader.addFile(file); + // uploader.addFile(file); dispatch('created'); addNotification({ type: 'success', - message: `${file.name} has been created` + message: `File has been uploaded` }); trackEvent('submit_file_create'); } catch ({ message }) { @@ -74,8 +68,11 @@ Update Permissions

    Choose who can access your buckets and files. For more information, check out the - Permissions Guide in our documentation. + Permissions Guide in our documentation.

    {#if $bucket.fileSecurity}
    diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/settings/+page.svelte b/src/routes/console/project-[project]/storage/bucket-[bucket]/settings/+page.svelte index 393eac3e9..5d1aa0c48 100644 --- a/src/routes/console/project-[project]/storage/bucket-[bucket]/settings/+page.svelte +++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/settings/+page.svelte @@ -36,8 +36,9 @@ arePermsDisabled = true, encryption: boolean = null, antivirus: boolean = null, - maxSize: number; - let byteUnit = writable('KB'); + maxSize: number, + compression: string = null; + let byteUnit = writable('MB'); let sizeInBytes: number = null; const options = [ { label: 'Bytes', value: 'Bytes' }, @@ -45,6 +46,11 @@ { label: 'Megabytes', value: 'MB' }, { label: 'Gigabytes', value: 'GB' } ]; + const compressionOptions = [ + { label: 'None', value: 'none' }, + { label: 'Gzip', value: 'gzip' }, + { label: 'Zstd', value: 'zstd' } + ]; let suggestedExtensions = ['jpg', 'png', 'svg', 'gif', 'html', 'pdf', 'mp4']; let extensions = $bucket.allowedFileExtensions; let isExtensionsDisabled = true; @@ -57,8 +63,10 @@ bucketPermissions ??= $bucket.$permissions; encryption ??= $bucket.encryption; antivirus ??= $bucket.antivirus; - maxSize = $bucket.maximumFileSize / 1024; + maxSize = $bucket.maximumFileSize / 1024 / 1024; + compression ??= $bucket.compression; }); + $: if (bucketPermissions) { if (symmetricDifference(bucketPermissions, $bucket.$permissions).length) { arePermsDisabled = false; @@ -192,6 +200,17 @@ ); } + function updateCompression() { + updateBucket( + { + compression + }, + { + trackEventName: 'submit_bucket_update_size' + } + ); + } + function updateAllowedExtensions() { updateBucket( { @@ -234,8 +253,8 @@ id="toggle" bind:value={enabled} /> -

    Created: {toLocaleDateTime($bucket.$createdAt)}

    -

    Last Updated: {toLocaleDateTime($bucket.$updatedAt)}

    +

    Created: {toLocaleDateTime($bucket.$createdAt)}

    +

    Last Updated: {toLocaleDateTime($bucket.$updatedAt)}

    @@ -275,7 +294,8 @@ the Permissions Guide in our documentation. + rel="noopener noreferrer" + class="link">Permissions Guide in our documentation.

    {#if bucketPermissions} @@ -319,7 +339,7 @@
    Update Security Settings -

    +

    Enable or disable security services for the bucket including Ecryption and Antivirus scanning.

    @@ -380,17 +400,40 @@
    +
    + + Update Compression Algorithm +

    + Choose an algorithm for compression. For files larger than 20MB, compression + will be skipped even if it's enabled. +

    + + + + + + + + + +
    +
    +
    Update Maximum File Size -

    Set the maximum file size allowed in the bucket.

    +

    Set the maximum file size allowed in the bucket.

      Update Allowed File Extensions -

      +

      A maximum of 100 file extensions can be added. Leave blank to allow all file types.

      @@ -452,7 +495,7 @@ Delete Bucket -

      +

      The bucket will be permanently deleted, including all the files within it. This action is irreversible.

      @@ -461,7 +504,7 @@
      {$bucket.name}
      -

      Last Updated: {toLocaleDateTime($bucket.$updatedAt)}

      +

      Last Updated: {toLocaleDateTime($bucket.$updatedAt)}