Skip to content

Commit da91098

Browse files
Merge pull request #203 from appwrite/chore-unbundle-webhooks
feat: unbundle webhooks page
2 parents 4e7e861 + 3c0ff70 commit da91098

File tree

7 files changed

+423
-347
lines changed

7 files changed

+423
-347
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,353 +1,18 @@
11
<script lang="ts">
2-
import { onMount } from 'svelte';
3-
import { CardGrid, Box, Secret, Empty, EventModal, Heading } from '$lib/components';
4-
import {
5-
Button,
6-
Form,
7-
FormList,
8-
InputText,
9-
InputChoice,
10-
InputPassword
11-
} from '$lib/elements/forms';
12-
import { TableList, TableCellText, TableCell } from '$lib/elements/table';
132
import { Container } from '$lib/layout';
14-
import { addNotification } from '$lib/stores/notifications';
15-
import { sdkForConsole } from '$lib/stores/sdk';
16-
import { webhook } from './store';
17-
import { page } from '$app/stores';
18-
import { toLocaleDateTime } from '$lib/helpers/date';
19-
import Delete from './delete.svelte';
20-
import Regenerate from './regenerate.svelte';
21-
import { symmetricDifference } from '$lib/helpers/array';
22-
import { invalidate } from '$app/navigation';
23-
import { Dependencies } from '$lib/constants';
24-
import { writable, type Writable } from 'svelte/store';
25-
import { trackEvent } from '$lib/actions/analytics';
26-
27-
const projectId = $page.params.project;
28-
let name: string = null;
29-
let url: string = null;
30-
31-
const eventSet: Writable<Set<string>> = writable(new Set());
32-
33-
let httpUser: string = null;
34-
let httpPass: string = null;
35-
let security = false;
36-
let showDelete = false;
37-
let showCreateEvent = false;
38-
let areEventsDisabled = true;
39-
let showRegenerate = false;
40-
41-
onMount(async () => {
42-
name ??= $webhook.name;
43-
url ??= $webhook.url;
44-
$eventSet = new Set($webhook.events);
45-
httpUser ??= $webhook.httpUser;
46-
httpPass ??= $webhook.httpPass;
47-
security = $webhook.security;
48-
});
49-
50-
async function updateName() {
51-
try {
52-
await sdkForConsole.projects.updateWebhook(
53-
projectId,
54-
$webhook.$id,
55-
name,
56-
$webhook.events,
57-
$webhook.url,
58-
$webhook.security,
59-
$webhook.httpUser,
60-
$webhook.httpPass
61-
);
62-
invalidate(Dependencies.WEBHOOK);
63-
addNotification({
64-
type: 'success',
65-
message: 'Webhook name has been updated'
66-
});
67-
trackEvent('submit_webhook_update_name');
68-
} catch (error) {
69-
addNotification({
70-
type: 'error',
71-
message: error.message
72-
});
73-
}
74-
}
75-
async function updateUrl() {
76-
try {
77-
await sdkForConsole.projects.updateWebhook(
78-
projectId,
79-
$webhook.$id,
80-
$webhook.name,
81-
$webhook.events,
82-
url,
83-
$webhook.security,
84-
$webhook.httpUser,
85-
$webhook.httpPass
86-
);
87-
invalidate(Dependencies.WEBHOOK);
88-
addNotification({
89-
type: 'success',
90-
message: 'Webhook url has been updated'
91-
});
92-
trackEvent('submit_webhook_update_url');
93-
} catch (error) {
94-
addNotification({
95-
type: 'error',
96-
message: error.message
97-
});
98-
}
99-
}
100-
async function updateEvents() {
101-
try {
102-
await sdkForConsole.projects.updateWebhook(
103-
projectId,
104-
$webhook.$id,
105-
$webhook.name,
106-
Array.from($eventSet),
107-
$webhook.url,
108-
$webhook.security,
109-
$webhook.httpUser,
110-
$webhook.httpPass
111-
);
112-
invalidate(Dependencies.WEBHOOK);
113-
areEventsDisabled = true;
114-
addNotification({
115-
type: 'success',
116-
message: 'Webhook events have been updated'
117-
});
118-
trackEvent('submit_webhook_update_events');
119-
} catch (error) {
120-
addNotification({
121-
type: 'error',
122-
message: error.message
123-
});
124-
}
125-
}
126-
127-
async function updateSecurity() {
128-
try {
129-
await sdkForConsole.projects.updateWebhook(
130-
projectId,
131-
$webhook.$id,
132-
$webhook.name,
133-
$webhook.events,
134-
$webhook.url,
135-
security,
136-
httpUser,
137-
httpPass
138-
);
139-
invalidate(Dependencies.WEBHOOK);
140-
addNotification({
141-
type: 'success',
142-
message: 'Webhook security has been updated'
143-
});
144-
trackEvent('submit_webhook_update_security');
145-
} catch (error) {
146-
addNotification({
147-
type: 'error',
148-
message: error.message
149-
});
150-
}
151-
}
152-
153-
function handleEvent(event: CustomEvent) {
154-
eventSet.set($eventSet.add(event.detail));
155-
}
156-
157-
$: if ($eventSet) {
158-
if (symmetricDifference(Array.from($eventSet), $webhook.events).length) {
159-
areEventsDisabled = false;
160-
} else areEventsDisabled = true;
161-
}
3+
import DangerZone from './dangerZone.svelte';
4+
import UpdateEvents from './updateEvents.svelte';
5+
import UpdateName from './updateName.svelte';
6+
import UpdateSecurity from './updateSecurity.svelte';
7+
import UpdateSignature from './updateSignature.svelte';
8+
import UpdateUrl from './updateURL.svelte';
1629
</script>
16310

16411
<Container>
165-
<CardGrid>
166-
<Heading tag="h2" size="7">Signature Key</Heading>
167-
<p>
168-
Add the Signature Key to the X-Appwrite-Webhook-Signature header to validate your
169-
webhooks. <a
170-
href="https://appwrite.io/docs/webhooks#verification"
171-
target="_blank"
172-
rel="noopener noreferrer"
173-
class="link">Learn more about webhook validation.</a>
174-
</p>
175-
<svelte:fragment slot="aside">
176-
<div>
177-
<p>Key</p>
178-
<Secret bind:value={$webhook.signatureKey} />
179-
</div>
180-
</svelte:fragment>
181-
<svelte:fragment slot="actions">
182-
<Button on:click={() => (showRegenerate = true)} secondary submit>
183-
Regenerate Key
184-
</Button>
185-
</svelte:fragment>
186-
</CardGrid>
187-
<Form on:submit={updateName}>
188-
<CardGrid>
189-
<Heading tag="h2" size="7">Update Name</Heading>
190-
<p>Choose any name that will help you distinguish between Webhooks.</p>
191-
<svelte:fragment slot="aside">
192-
<FormList>
193-
<InputText
194-
id="name"
195-
label="Name"
196-
bind:value={name}
197-
required
198-
placeholder="Enter name" />
199-
</FormList>
200-
</svelte:fragment>
201-
202-
<svelte:fragment slot="actions">
203-
<Button disabled={name === $webhook.name || !name} submit>Update</Button>
204-
</svelte:fragment>
205-
</CardGrid>
206-
</Form>
207-
208-
<Form on:submit={updateUrl}>
209-
<CardGrid>
210-
<Heading tag="h2" size="7">Update Url</Heading>
211-
212-
<svelte:fragment slot="aside">
213-
<FormList>
214-
<InputText
215-
id="url"
216-
label="POST URL"
217-
bind:value={url}
218-
required
219-
placeholder="https://example.com/callback" />
220-
</FormList>
221-
</svelte:fragment>
222-
223-
<svelte:fragment slot="actions">
224-
<Button disabled={url === $webhook.url || !url} submit>Update</Button>
225-
</svelte:fragment>
226-
</CardGrid>
227-
</Form>
228-
229-
<Form on:submit={updateEvents}>
230-
<CardGrid>
231-
<Heading tag="h6" size="7">Update Events</Heading>
232-
<p class="text">
233-
Set the events that will trigger your webhook. Maximum 100 events allowed.
234-
</p>
235-
<svelte:fragment slot="aside">
236-
{#if $eventSet.size}
237-
<TableList>
238-
{#each Array.from($eventSet) as event}
239-
<li class="table-row">
240-
<TableCellText title="id">
241-
{event}
242-
</TableCellText>
243-
<TableCell showOverflow title="options" width={40}>
244-
<button
245-
class="button is-text is-only-icon"
246-
aria-label="delete id"
247-
on:click|preventDefault={() => {
248-
$eventSet.delete(event);
249-
eventSet.set($eventSet);
250-
}}>
251-
<span class="icon-x" aria-hidden="true" />
252-
</button>
253-
</TableCell>
254-
</li>
255-
{/each}
256-
</TableList>
257-
<div class="u-flex u-margin-block-start-16">
258-
<Button text noMargin on:click={() => (showCreateEvent = true)}>
259-
<span class="icon-plus" aria-hidden="true" />
260-
<span class="u-text">Add event</span>
261-
</Button>
262-
</div>
263-
{:else}
264-
<Empty on:click={() => (showCreateEvent = true)}>
265-
Add an event to get started
266-
</Empty>
267-
{/if}
268-
</svelte:fragment>
269-
270-
<svelte:fragment slot="actions">
271-
<Button disabled={areEventsDisabled} submit>Update</Button>
272-
</svelte:fragment>
273-
</CardGrid>
274-
</Form>
275-
276-
<Form on:submit={updateSecurity}>
277-
<CardGrid>
278-
<Heading tag="h2" size="7">Security</Heading>
279-
<p class="text">
280-
Set an optional basic HTTP authentication username and password to protect your
281-
endpoint from unauthorized access.
282-
</p>
283-
<svelte:fragment slot="aside">
284-
<FormList>
285-
<div>
286-
<Heading tag="h3" size="7">HTTP Authentication</Heading>
287-
<p class="text">Use to secure your endpoint from untrusted sources.</p>
288-
</div>
289-
<InputText
290-
label="User"
291-
id="user"
292-
placeholder="Enter username"
293-
bind:value={httpUser} />
294-
<InputPassword
295-
label="Password"
296-
id="password"
297-
minlength={0}
298-
showPasswordButton
299-
placeholder="Enter password"
300-
bind:value={httpPass} />
301-
302-
<InputChoice
303-
id="Security"
304-
label="Certificate verification (SSL/TLS)"
305-
bind:value={security}>
306-
<span class="u-error">Warning:</span> Untrusted or self-signed certificates
307-
may not be secure.
308-
<a
309-
href="https://appwrite.io/docs/custom-domains#enjoySSLCert"
310-
target="_blank"
311-
rel="noopener noreferrer"
312-
class="link">
313-
Learn more</a>
314-
</InputChoice>
315-
</FormList>
316-
</svelte:fragment>
317-
318-
<svelte:fragment slot="actions">
319-
<Button
320-
disabled={httpUser === $webhook.httpUser &&
321-
httpPass === $webhook.httpPass &&
322-
security === $webhook.security}
323-
submit>
324-
Update
325-
</Button>
326-
</svelte:fragment>
327-
</CardGrid>
328-
</Form>
329-
330-
<CardGrid danger>
331-
<div>
332-
<Heading tag="h2" size="7">Delete Webhook</Heading>
333-
</div>
334-
<p>The webhook will be permanently deleted. This action is irreversible.</p>
335-
<svelte:fragment slot="aside">
336-
<Box>
337-
<svelte:fragment slot="title">
338-
<h6 class="u-bold u-trim-1">{$webhook.name}</h6>
339-
</svelte:fragment>
340-
<p>Last updated: {toLocaleDateTime($webhook.$updatedAt)}</p>
341-
</Box>
342-
</svelte:fragment>
343-
344-
<svelte:fragment slot="actions">
345-
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
346-
</svelte:fragment>
347-
</CardGrid>
12+
<UpdateSignature />
13+
<UpdateName />
14+
<UpdateUrl />
15+
<UpdateEvents />
16+
<UpdateSecurity />
17+
<DangerZone />
34818
</Container>
349-
350-
<Delete bind:showDelete />
351-
<Regenerate bind:show={showRegenerate} />
352-
353-
<EventModal bind:show={showCreateEvent} on:created={handleEvent} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script lang="ts">
2+
import { Box, CardGrid, Heading } from '$lib/components';
3+
import { Button } from '$lib/elements/forms';
4+
import { webhook } from './store';
5+
import Delete from './delete.svelte';
6+
import { toLocaleDateTime } from '$lib/helpers/date';
7+
8+
let showDelete = false;
9+
</script>
10+
11+
<CardGrid danger>
12+
<div>
13+
<Heading tag="h2" size="7">Delete Webhook</Heading>
14+
</div>
15+
<p>The webhook will be permanently deleted. This action is irreversible.</p>
16+
<svelte:fragment slot="aside">
17+
<Box>
18+
<svelte:fragment slot="title">
19+
<h6 class="u-bold u-trim-1">{$webhook.name}</h6>
20+
</svelte:fragment>
21+
<p>Last updated: {toLocaleDateTime($webhook.$updatedAt)}</p>
22+
</Box>
23+
</svelte:fragment>
24+
25+
<svelte:fragment slot="actions">
26+
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
27+
</svelte:fragment>
28+
</CardGrid>
29+
30+
<Delete bind:showDelete />

0 commit comments

Comments
 (0)