diff --git a/src/routes/console/project-[project]/messaging/provider.svelte b/src/routes/console/project-[project]/messaging/provider.svelte index e130ea23ff..a78eb75c0c 100644 --- a/src/routes/console/project-[project]/messaging/provider.svelte +++ b/src/routes/console/project-[project]/messaging/provider.svelte @@ -11,6 +11,50 @@ FCM = 'fcm', APNS = 'apns' } + + export function getProviderDisplayNameAndIcon(provider: Providers | string) { + let icon = ''; + let displayName = provider.charAt(0).toUpperCase() + provider.slice(1); + + switch (provider) { + case Providers.FCM: + icon = 'firebase'; + displayName = 'FCM'; + break; + case Providers.APNS: + icon = 'apple'; + displayName = 'APNS'; + break; + case Providers.Sendgrid: + icon = 'sendgrid'; + break; + case Providers.Mailgun: + icon = 'mailgun'; + break; + case Providers.SMTP: + icon = 'smtp'; + displayName = 'SMTP'; + break; + case Providers.Twilio: + icon = 'twilio'; + break; + case Providers.Telesign: + icon = 'telesign'; + break; + case Providers.Msg91: + icon = 'msg91'; + displayName = 'MSG91'; + break; + case Providers.Textmagic: + icon = 'textmagic'; + displayName = 'Textmagic'; + break; + case Providers.Vonage: + icon = 'vonage'; + break; + } + return { icon, displayName }; + } {#if icon === ''} @@ -89,12 +94,12 @@ {displayName} + alt={name || displayName} /> {/if} {/if} - {displayName} + {name || displayName} {/if} diff --git a/src/routes/console/project-[project]/messaging/providers/create.svelte b/src/routes/console/project-[project]/messaging/providers/create.svelte index 9b814ffb00..53cdf91a4a 100644 --- a/src/routes/console/project-[project]/messaging/providers/create.svelte +++ b/src/routes/console/project-[project]/messaging/providers/create.svelte @@ -1,9 +1,8 @@ diff --git a/src/routes/console/project-[project]/messaging/providers/popoverContent.svelte b/src/routes/console/project-[project]/messaging/providers/popoverContent.svelte new file mode 100644 index 0000000000..f76d7baf6b --- /dev/null +++ b/src/routes/console/project-[project]/messaging/providers/popoverContent.svelte @@ -0,0 +1,37 @@ + + +
+ {#each lines as line} +

{@html line}

+ {/each} + + {#if popoverImage} + + {/if} +
+ + diff --git a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/+page.svelte b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/+page.svelte index 2262f62ac1..e6e4f4a559 100644 --- a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/+page.svelte +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/+page.svelte @@ -2,11 +2,158 @@ import { Container } from '$lib/layout'; import DangerZone from './dangerZone.svelte'; import UpdateName from './updateName.svelte'; + import UpdateSettings from './updateSettings.svelte'; import UpdateStatus from './updateStatus.svelte'; + import { isValueOfStringEnum } from '$lib/helpers/types'; + import { MessagingProviderType } from '@appwrite.io/console'; + import { Providers } from '../../provider.svelte'; + import { providers } from '../store'; + import { provider as providerData } from './store'; + + let providerType: MessagingProviderType; + if (isValueOfStringEnum(MessagingProviderType, $providerData.type)) { + providerType = $providerData.type; + } + + let provider: Providers; + if (isValueOfStringEnum(Providers, $providerData.provider)) { + provider = $providerData.provider; + } + + let params: object = {}; + + $: switch (provider) { + case Providers.Twilio: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + accountSid: $providerData.credentials['accountSid'], + authToken: $providerData.credentials['authToken'], + from: $providerData.options['from'] + }; + break; + case Providers.Msg91: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + from: $providerData.options['from'], + senderId: $providerData.credentials['senderId'], + authKey: $providerData.credentials['authKey'] + }; + break; + case Providers.Telesign: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + username: $providerData.credentials['username'], + password: $providerData.credentials['password'], + from: $providerData.options['from'] + }; + break; + case Providers.Textmagic: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + username: $providerData.credentials['username'], + apiKey: $providerData.credentials['apiKey'], + from: $providerData.options['from'] + }; + break; + case Providers.Vonage: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + apiKey: $providerData.credentials['apiKey'], + apiSecret: $providerData.credentials['apiSecret'], + from: $providerData.options['from'] + }; + break; + case Providers.Mailgun: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + isEuRegion: false, + fromEmail: $providerData.options['fromEmail'], + fromName: $providerData.options['fromName'], + replyToEmail: $providerData.options['replyToEmail'], + replyToName: $providerData.options['replyToName'], + apiKey: $providerData.credentials['apiKey'], + domain: $providerData.credentials['domain'] + }; + break; + case Providers.Sendgrid: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + apiKey: $providerData.credentials['apiKey'], + fromEmail: $providerData.options['fromEmail'], + fromName: $providerData.options['fromName'], + replyToEmail: $providerData.options['replyToEmail'], + replyToName: $providerData.options['replyToName'] + }; + break; + case Providers.SMTP: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + host: $providerData.credentials['host'], + port: $providerData.credentials['port'], + username: $providerData.credentials['username'], + password: $providerData.credentials['password'], + fromName: $providerData.options['fromName'], + fromEmail: $providerData.options['fromEmail'], + replyToName: $providerData.options['replyToName'], + replyToEmail: $providerData.options['replyToEmail'], + encryption: $providerData.options['encryption'], + autoTLS: $providerData.options['autoTLS'], + mailer: $providerData.options['mailer'] + }; + break; + case Providers.FCM: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled + }; + if ('serviceAccountJSON' in $providerData.credentials) { + const serviceAccountJSON = $providerData.credentials['serviceAccountJSON']; + if (typeof serviceAccountJSON === 'string') { + params['serviceAccountJSON'] = serviceAccountJSON; + } else if (serviceAccountJSON instanceof Object) { + params['serviceAccountJSON'] = JSON.stringify(serviceAccountJSON); + } + } + break; + case Providers.APNS: + params = { + providerId: $providerData.$id, + name: $providerData.name, + enabled: $providerData.enabled, + authKey: $providerData.credentials['authKey'], + authKeyId: $providerData.credentials['authKeyId'], + teamId: $providerData.credentials['teamId'], + bundleId: $providerData.credentials['bundleId'] + }; + break; + } + diff --git a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/store.ts b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/store.ts index 441524d170..d4211320e9 100644 --- a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/store.ts @@ -2,8 +2,4 @@ import { derived } from 'svelte/store'; import { page } from '$app/stores'; import type { Models } from '@appwrite.io/console'; -export const provider = derived( - page, - // TODO: Set actual type - ($page) => $page.data.provider as Models.Provider -); +export const provider = derived(page, ($page) => $page.data.provider as Models.Provider); diff --git a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateSettings.svelte b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateSettings.svelte new file mode 100644 index 0000000000..0b186d168a --- /dev/null +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateSettings.svelte @@ -0,0 +1,233 @@ + + +
+ +
+ Settings +
+

+ Configure the settings to to send {message}, or to complete the + provider settings. +

+ + + + + +
+ +
+
+
+
+ + diff --git a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte index 03f9d6cc11..6e62a27fce 100644 --- a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte @@ -5,168 +5,24 @@ import { Dependencies } from '$lib/constants'; import { Button, InputSwitch } from '$lib/elements/forms'; import { toLocaleDateTime } from '$lib/helpers/date'; - import { isValueOfStringEnum } from '$lib/helpers/types'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; - import { wizard } from '$lib/stores/wizard'; import { onMount } from 'svelte'; - import { MessagingProviderType } from '@appwrite.io/console'; import Provider, { Providers } from '../../provider.svelte'; import ProviderType from '../../providerType.svelte'; - import Update from '../update.svelte'; - import { providerParams, providerType, provider as wizardProvider } from '../wizard/store'; - import { provider } from './store'; + import { provider as providerData } from './store'; let enabled: boolean = null; onMount(() => { - enabled ??= $provider.enabled; + enabled ??= $providerData.enabled; }); - function configure() { - if (!isValueOfStringEnum(MessagingProviderType, $provider.type)) { - throw new Error(`Invalid provider type: ${$provider.type}`); - } - - if (!isValueOfStringEnum(Providers, $provider.provider)) { - throw new Error(`Invalid provider: ${$provider.provider}`); - } - $providerType = $provider.type; - $wizardProvider = $provider.provider; - - switch ($wizardProvider) { - case Providers.Twilio: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - accountSid: $provider.credentials['accountSid'], - authToken: $provider.credentials['authToken'], - from: $provider.options['from'] - }; - break; - case Providers.Msg91: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - from: $provider.options['from'], - senderId: $provider.credentials['senderId'], - authKey: $provider.credentials['authKey'] - }; - break; - case Providers.Telesign: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - username: $provider.credentials['username'], - password: $provider.credentials['password'], - from: $provider.options['from'] - }; - break; - case Providers.Textmagic: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - username: $provider.credentials['username'], - apiKey: $provider.credentials['apiKey'], - from: $provider.options['from'] - }; - break; - case Providers.Vonage: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - apiKey: $provider.credentials['apiKey'], - apiSecret: $provider.credentials['apiSecret'], - from: $provider.options['from'] - }; - break; - case Providers.Mailgun: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - isEuRegion: false, - fromEmail: $provider.options['fromEmail'], - fromName: $provider.options['fromName'], - replyToEmail: $provider.options['replyToEmail'], - replyToName: $provider.options['replyToName'], - apiKey: $provider.credentials['apiKey'], - domain: $provider.credentials['domain'] - }; - break; - case Providers.Sendgrid: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - apiKey: $provider.credentials['apiKey'], - fromEmail: $provider.options['fromEmail'], - fromName: $provider.options['fromName'], - replyToEmail: $provider.options['replyToEmail'], - replyToName: $provider.options['replyToName'] - }; - break; - case Providers.SMTP: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - host: $provider.credentials['host'], - port: $provider.credentials['port'], - username: $provider.credentials['username'], - password: $provider.credentials['password'], - fromName: $provider.options['fromName'], - fromEmail: $provider.options['fromEmail'], - replyToName: $provider.options['replyToName'], - replyToEmail: $provider.options['replyToEmail'], - encryption: $provider.options['encryption'], - autoTLS: $provider.options['autoTLS'], - mailer: $provider.options['mailer'] - }; - break; - case Providers.FCM: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled - }; - if ('serviceAccountJSON' in $provider.credentials) { - const serviceAccountJSON = $provider.credentials['serviceAccountJSON']; - if (typeof serviceAccountJSON === 'string') { - $providerParams[$wizardProvider].serviceAccountJSON = serviceAccountJSON; - } else if (serviceAccountJSON instanceof Object) { - $providerParams[$wizardProvider].serviceAccountJSON = - JSON.stringify(serviceAccountJSON); - } - } - break; - case Providers.APNS: - $providerParams[$wizardProvider] = { - providerId: $provider.$id, - name: $provider.name, - enabled: $provider.enabled, - authKey: $provider.credentials['authKey'], - authKeyId: $provider.credentials['authKeyId'], - teamId: $provider.credentials['teamId'], - bundleId: $provider.credentials['bundleId'], - sandbox: $provider.options['sandbox'] - }; - break; - } - - wizard.start(Update); - } - async function updateStatus() { try { let response = { $id: '', name: '' }; - const providerId = $provider.$id; - switch ($provider.provider) { + const providerId = $providerData.$id; + switch ($providerData.provider) { case Providers.Twilio: response = await sdk.forProject.messaging.updateTwilioProvider( providerId, @@ -258,7 +114,7 @@ message: `${response.name} has been ${enabled ? 'enabled' : 'disabled'}` }); trackEvent(Submit.MessagingProviderUpdate, { - provider: $provider + provider: $providerData }); } catch (error) { addNotification({ @@ -272,8 +128,8 @@
- - {$provider.name} + + {$providerData.name}
@@ -285,17 +141,16 @@ label={enabled ? 'Enabled' : 'Disabled'} bind:value={enabled} /> -

Provider:

-

Channel:

-

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

+

Provider:

+

Channel:

+

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

- -
diff --git a/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte b/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte new file mode 100644 index 0000000000..470a3beb1a --- /dev/null +++ b/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte @@ -0,0 +1,134 @@ + + + + {#each inputs as input} + {@const popoverImage = input.popoverImage} + {#if input.type === 'text'} + + + + + + {:else if input.type === 'password'} + + + + + + {:else if input.type === 'email'} + + + + + + {:else if input.type === 'domain'} + + + + + + {:else if input.type === 'phone'} + + + + + + {:else if input.type === 'file'} + + + + + + {:else if input.type === 'switch'} + + + {input.description} + + + {:else if input.type === 'select'} + + {/if} + {/each} + diff --git a/src/routes/console/project-[project]/messaging/providers/store.ts b/src/routes/console/project-[project]/messaging/providers/store.ts index f828e6f857..9d5a46c7d6 100644 --- a/src/routes/console/project-[project]/messaging/providers/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/store.ts @@ -11,6 +11,19 @@ export const columns = writable([ { id: 'enabled', title: 'Status', type: 'boolean', show: true } ]); +export type ProviderInput = { + label: string; + name: string; + type: 'text' | 'password' | 'phone' | 'email' | 'domain' | 'file' | 'switch' | 'select'; + placeholder?: string; + description?: string; + popover?: string[]; + popoverImage?: { src: { light: string; dark: string }; alt: string }; + allowedFileExtensions?: string[]; + optional?: boolean; + options?: { label: string; value: string | number | boolean }[]; +}; + type ProvidersMap = { [key in MessagingProviderType]: { name: string; @@ -23,26 +36,7 @@ type ProvidersMap = { title: string; description: string; needAHand?: string[]; - configure: { - label: string; - name: string; - type: - | 'text' - | 'password' - | 'phone' - | 'email' - | 'domain' - | 'file' - | 'switch' - | 'select'; - placeholder?: string; - description?: string; - popover?: string[]; - popoverImage?: { src: { light: string; dark: string }; alt: string }; - allowedFileExtensions?: string[]; - optional?: boolean; - options?: { label: string; value: string | number | boolean }[]; - }[]; + configure: ProviderInput[]; }; }; }; @@ -548,3 +542,96 @@ export const providers: ProvidersMap = { } } }; + +type ProviderParams = { + providerId: string; + name: string; + enabled: boolean; +}; + +/** + * SMS providers + */ +export type TwilioProviderParams = ProviderParams & { + accountSid: string; + authToken: string; + from: string; +}; + +export type Msg91ProviderParams = ProviderParams & { + from: string; + senderId: string; + authKey: string; +}; + +export type TelesignProviderParams = ProviderParams & { + from: string; + username: string; + password: string; +}; + +export type TextmagicProviderParams = ProviderParams & { + from: string; + username: string; + apiKey: string; +}; + +export type VonageProviderParams = ProviderParams & { + from: string; + apiKey: string; + apiSecret: string; +}; + +/** + * Email providers + */ +export type MailgunProviderParams = ProviderParams & { + fromEmail: string; + fromName: string; + replyToEmail: string; + replyToName: string; + isEuRegion: boolean; + apiKey: string; + domain: string; +}; + +export type SendgridProviderParams = ProviderParams & { + fromEmail: string; + fromName: string; + replyToEmail: string; + replyToName: string; + apiKey: string; +}; + +export type SMTPProviderParams = ProviderParams & { + fromEmail: string; + fromName: string; + replyToEmail: string; + replyToName: string; + host: string; + port: number; + username: string; + password: string; + encryption: SmtpEncryption; + autoTLS: boolean; + mailer: string; +}; + +/** + * Push providers + */ +export type FCMProviderParams = ProviderParams & { + serviceAccountJSON: string; +}; + +export type APNSProviderParams = ProviderParams & { + authKey: string; + authKeyId: string; + teamId: string; + bundleId: string; + sandbox: boolean; +}; + +export type MQTTProviderParams = ProviderParams & { + serverKey: string; +}; diff --git a/src/routes/console/project-[project]/messaging/providers/update.svelte b/src/routes/console/project-[project]/messaging/providers/update.svelte deleted file mode 100644 index 4ec2896b4a..0000000000 --- a/src/routes/console/project-[project]/messaging/providers/update.svelte +++ /dev/null @@ -1,165 +0,0 @@ - - - diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte b/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte index d5e4949912..ec43fac469 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte +++ b/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte @@ -13,8 +13,6 @@ let id: string = null; async function beforeSubmit() { - console.log($provider); - switch ($provider) { case Providers.Twilio: $providerParams[$provider] = { diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte b/src/routes/console/project-[project]/messaging/providers/wizard/settings.svelte similarity index 54% rename from src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte rename to src/routes/console/project-[project]/messaging/providers/wizard/settings.svelte index ec119c419a..57908ad4b1 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte +++ b/src/routes/console/project-[project]/messaging/providers/wizard/settings.svelte @@ -1,20 +1,9 @@ - Configure + Settings Set up the credentials below to enable {providers[$providerType].providers[$provider].title} for sending {providers[$providerType].text}. - - {#each inputs as input} - {@const popoverImage = input.popoverImage} - {#if input.type === 'text'} - - - {@html input.popover?.join('

')} - {#if popoverImage} -
-
- - {/if} -
-
- {:else if input.type === 'password'} - - - {@html input.popover?.join('

')} -
-
- {:else if input.type === 'email'} - - -

- {@html input.popover?.join('

')} -

-
-
- {:else if input.type === 'domain'} - - -

- {@html input.popover?.join('

')} -

-
-
- {:else if input.type === 'phone'} - - -

- {@html input.popover?.join('

')} -

-
-
- {:else if input.type === 'file'} - - -

- {@html input.popover?.join('

')} - {#if popoverImage} -
-
- - {/if} -

-
-
- {:else if input.type === 'switch'} - - - {input.description} - - - {:else if input.type === 'select'} - - {/if} - {/each} -
+ +

Need a hand?

diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/store.ts b/src/routes/console/project-[project]/messaging/providers/wizard/store.ts index 4ea4d8c4d2..41741b3ceb 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/wizard/store.ts @@ -1,102 +1,18 @@ +import type { MessagingProviderType } from '@appwrite.io/console'; import { writable } from 'svelte/store'; import type { Providers } from '../../provider.svelte'; -import type { MessagingProviderType, SmtpEncryption } from '@appwrite.io/console'; - -type ProviderParams = { - providerId: string; - name: string; - enabled: boolean; -}; - -/** - * SMS providers - */ - -export type TwilioProviderParams = ProviderParams & { - accountSid: string; - authToken: string; - from: string; -}; - -export type Msg91ProviderParams = ProviderParams & { - from: string; - senderId: string; - authKey: string; -}; - -export type TelesignProviderParams = ProviderParams & { - from: string; - username: string; - password: string; -}; - -export type TextmagicProviderParams = ProviderParams & { - from: string; - username: string; - apiKey: string; -}; - -export type VonageProviderParams = ProviderParams & { - from: string; - apiKey: string; - apiSecret: string; -}; - -/** - * Email providers - */ - -export type MailgunProviderParams = ProviderParams & { - fromEmail: string; - fromName: string; - replyToEmail: string; - replyToName: string; - isEuRegion: boolean; - apiKey: string; - domain: string; -}; - -export type SendgridProviderParams = ProviderParams & { - fromEmail: string; - fromName: string; - replyToEmail: string; - replyToName: string; - apiKey: string; -}; - -export type SMTPProviderParams = ProviderParams & { - fromEmail: string; - fromName: string; - replyToEmail: string; - replyToName: string; - host: string; - port: number; - username: string; - password: string; - encryption: SmtpEncryption; - autoTLS: boolean; - mailer: string; -}; - -/** - * Push providers - */ - -export type FCMProviderParams = ProviderParams & { - serviceAccountJSON: string; -}; - -export type APNSProviderParams = ProviderParams & { - authKey: string; - authKeyId: string; - teamId: string; - bundleId: string; - sandbox: boolean; -}; - -export type MQTTProviderParams = ProviderParams & { - serverKey: string; -}; +import type { + APNSProviderParams, + FCMProviderParams, + MailgunProviderParams, + Msg91ProviderParams, + SMTPProviderParams, + SendgridProviderParams, + TelesignProviderParams, + TextmagicProviderParams, + TwilioProviderParams, + VonageProviderParams +} from '../store'; export const providerType = writable(null); export const provider = writable(null);