Skip to content

Commit f98b287

Browse files
committed
feat new protocols ui card
1 parent 56a5901 commit f98b287

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { writable } from 'svelte/store';
2+
import { ProtocolId, type Models } from '@appwrite.io/console';
3+
4+
export type Protocol = {
5+
label: string;
6+
method: ProtocolId;
7+
value: boolean | null;
8+
};
9+
10+
function projectProtocolRows(project: Models.Project | null): Protocol[] {
11+
return [
12+
{
13+
label: 'REST',
14+
method: ProtocolId.Rest,
15+
value: project?.protocolStatusForRest ?? null
16+
},
17+
{
18+
label: 'GraphQL',
19+
method: ProtocolId.Graphql,
20+
value: project?.protocolStatusForGraphql ?? null
21+
},
22+
{
23+
label: 'WebSocket',
24+
method: ProtocolId.Websocket,
25+
value: project?.protocolStatusForWebsocket ?? null
26+
}
27+
];
28+
}
29+
30+
function createProtocols() {
31+
const { subscribe, set } = writable({
32+
list: projectProtocolRows(null)
33+
});
34+
35+
return {
36+
subscribe,
37+
set,
38+
load: (project: Models.Project) => {
39+
set({ list: projectProtocolRows(project) });
40+
}
41+
};
42+
}
43+
44+
export const protocols = createProtocols();

src/routes/(console)/project-[region]-[project]/settings/+page.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { invalidate } from '$app/navigation';
88
import { Dependencies } from '$lib/constants';
99
import UpdateName from './updateName.svelte';
10+
import UpdateProtocols from './updateProtocols.svelte';
1011
import UpdateServices from './updateServices.svelte';
1112
import UpdateInstallations from './updateInstallations.svelte';
1213
import DeleteProject from './deleteProject.svelte';
@@ -89,6 +90,7 @@
8990
{#if $canWriteProjects}
9091
<UpdateName />
9192
<UpdateLabels />
93+
<UpdateProtocols />
9294
<UpdateServices />
9395
<UpdateInstallations {...data.installations} limit={data.limit} offset={data.offset} />
9496
<UpdateVariables
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<script lang="ts">
2+
import { invalidate } from '$app/navigation';
3+
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
4+
import { CardGrid } from '$lib/components';
5+
import { Dependencies } from '$lib/constants';
6+
import { InputSwitch } from '$lib/elements/forms';
7+
import { addNotification } from '$lib/stores/notifications';
8+
import { protocols, type Protocol } from '$lib/stores/project-protocols';
9+
import { sdk } from '$lib/stores/sdk';
10+
import { project } from '../store';
11+
import { Divider, Layout, Spinner } from '@appwrite.io/pink-svelte';
12+
import { SvelteSet } from 'svelte/reactivity';
13+
import { ProtocolId } from '@appwrite.io/console';
14+
15+
let apiProtocolUpdates = new SvelteSet<ProtocolId>();
16+
const protocolDescriptions: Record<ProtocolId, string> = {
17+
[ProtocolId.Rest]: 'Standard HTTP API requests from client SDKs.',
18+
[ProtocolId.Graphql]: 'GraphQL API access for queries and mutations.',
19+
[ProtocolId.Websocket]: 'Realtime subscriptions over WebSocket connections.'
20+
};
21+
22+
async function protocolUpdate(protocol: Protocol) {
23+
apiProtocolUpdates.add(protocol.method);
24+
25+
try {
26+
await sdk.forProject($project.region, $project.$id).project.updateProtocolStatus({
27+
protocolId: protocol.method,
28+
enabled: protocol.value
29+
});
30+
31+
await invalidate(Dependencies.PROJECT);
32+
33+
addNotification({
34+
type: 'success',
35+
message: `${protocol.label} protocol has been ${
36+
protocol.value ? 'enabled' : 'disabled'
37+
}`
38+
});
39+
trackEvent(Submit.ProjectService, {
40+
method: protocol.method,
41+
value: protocol.value
42+
});
43+
} catch (error) {
44+
addNotification({
45+
type: 'error',
46+
message: error.message
47+
});
48+
trackError(error, Submit.ProjectService);
49+
} finally {
50+
apiProtocolUpdates.delete(protocol.method);
51+
}
52+
}
53+
54+
$effect(() => protocols.load($project));
55+
</script>
56+
57+
<CardGrid>
58+
<svelte:fragment slot="title">Protocols</svelte:fragment>
59+
Choose which protocols clients can use to access your project. Disabled protocols remain unavailable
60+
until re-enabled.
61+
<svelte:fragment slot="aside">
62+
<div class="protocols-list">
63+
<Layout.Stack gap="xs">
64+
{#each $protocols.list as protocol, index}
65+
<div class="protocol-row">
66+
<div class="protocol-control">
67+
<InputSwitch
68+
id={protocol.method}
69+
label={protocol.label}
70+
description={protocolDescriptions[protocol.method]}
71+
bind:value={protocol.value}
72+
on:change={() => protocolUpdate(protocol)}
73+
disabled={apiProtocolUpdates.has(protocol.method)} />
74+
75+
{#if apiProtocolUpdates.has(protocol.method)}
76+
<span class="protocol-spinner">
77+
<Spinner size="s" />
78+
</span>
79+
{/if}
80+
</div>
81+
</div>
82+
83+
{#if index < $protocols.list.length - 1}
84+
<Divider />
85+
{/if}
86+
{/each}
87+
</Layout.Stack>
88+
</div>
89+
</svelte:fragment>
90+
</CardGrid>
91+
92+
<style>
93+
.protocols-list {
94+
max-width: 36rem;
95+
}
96+
97+
.protocol-row {
98+
width: 100%;
99+
}
100+
101+
.protocol-control {
102+
display: flex;
103+
align-items: center;
104+
gap: var(--space-4);
105+
width: 100%;
106+
}
107+
108+
.protocol-control :global(label) {
109+
flex: 1;
110+
}
111+
112+
.protocol-spinner {
113+
opacity: 0.75;
114+
flex-shrink: 0;
115+
}
116+
</style>

0 commit comments

Comments
 (0)