diff --git a/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte b/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte index 9c6c84d39..8492bb66c 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte @@ -8,16 +8,36 @@ import { protocols, type Protocol } from '$lib/stores/project-protocols'; import { sdk } from '$lib/stores/sdk'; import { project } from '../store'; - import { Divider, Layout, Spinner } from '@appwrite.io/pink-svelte'; + import Button from '$lib/elements/forms/button.svelte'; + import { Dialog, Divider, Layout, Spinner } from '@appwrite.io/pink-svelte'; import { SvelteSet } from 'svelte/reactivity'; import { ProtocolId } from '@appwrite.io/console'; + import { get } from 'svelte/store'; + let isUpdatingAllProtocols = $state(false); + let showUpdateProtocolDialog = $state(false); + let updateProtocolsEnabledMode = $state(null); let apiProtocolUpdates = new SvelteSet(); const protocolDescriptions: Record = { [ProtocolId.Rest]: 'Standard HTTP API requests from client SDKs.', [ProtocolId.Graphql]: 'GraphQL API access for queries and mutations.', [ProtocolId.Websocket]: 'Realtime subscriptions over WebSocket connections.' }; + const isAnyProtocolUpdating = $derived(apiProtocolUpdates.size > 0); + const isAnyUpdateInProgress = $derived(isUpdatingAllProtocols || isAnyProtocolUpdating); + + const allProtocolsEnabled = $derived.by(() => { + if (isAnyUpdateInProgress) return false; + return $protocols.list.every((protocol) => protocol.value); + }); + + const allProtocolsDisabled = $derived.by(() => { + if (isAnyUpdateInProgress) return false; + return $protocols.list.every((protocol) => !protocol.value); + }); + + const shouldDisableEnableAllButton = $derived(isAnyUpdateInProgress || allProtocolsEnabled); + const shouldDisableDisableAllButton = $derived(isAnyUpdateInProgress || allProtocolsDisabled); async function protocolUpdate(protocol: Protocol) { apiProtocolUpdates.add(protocol.method); @@ -51,6 +71,60 @@ } } + async function toggleAllProtocols(status: boolean) { + isUpdatingAllProtocols = true; + + try { + const projectSdk = sdk.forProject($project.region, $project.$id); + for (const protocol of get(protocols).list) { + if (protocol.value === status) continue; + await projectSdk.project.updateProtocolStatus({ + protocolId: protocol.method, + enabled: status + }); + } + + await invalidate(Dependencies.PROJECT); + + addNotification({ + type: 'success', + message: + 'All protocols for ' + + $project.name + + ' have been ' + + (status ? 'enabled.' : 'disabled.') + }); + trackEvent(Submit.ProjectService); + } catch (error) { + addNotification({ + type: 'error', + message: error.message + }); + trackError(error, Submit.ProjectService); + } finally { + isUpdatingAllProtocols = false; + showUpdateProtocolDialog = false; + updateProtocolsEnabledMode = null; + } + } + + const dialogDetails = $derived.by(() => { + if (updateProtocolsEnabledMode) { + return { + title: 'Enable all protocols', + message: 'All project protocols will be enabled.', + actionButton: 'Enable all' + }; + } else { + return { + title: 'Disable all protocols', + message: + 'Are you sure you want to disable all protocols? This will disable client access over those protocols until they are re-enabled.', + actionButton: 'Disable all' + }; + } + }); + $effect(() => protocols.load($project)); @@ -60,44 +134,96 @@ until re-enabled.
- - {#each $protocols.list as protocol, index} -
-
- protocolUpdate(protocol)} - disabled={apiProtocolUpdates.has(protocol.method)} /> +
+ + + + + + + +
+ +
+ + {#each $protocols.list as protocol, index} +
+
+ protocolUpdate(protocol)} + disabled={apiProtocolUpdates.has(protocol.method)} /> - {#if apiProtocolUpdates.has(protocol.method)} - - - - {/if} + {#if apiProtocolUpdates.has(protocol.method)} + + + + {/if} +
-
- {#if index < $protocols.list.length - 1} - - {/if} - {/each} - + {#if index < $protocols.list.length - 1} + + {/if} + {/each} + +
+ +

{dialogDetails.message}

+ + + + + + + +
+