diff --git a/package-lock.json b/package-lock.json index 3cb51c8c5..875763d65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "@appwrite/console", "dependencies": { - "@appwrite.io/console": "^0.6.0-rc.13", + "@appwrite.io/console": "^0.6.0-rc.14", "@appwrite.io/pink": "0.4.0", "@appwrite.io/pink-icons": "0.4.0", "@popperjs/core": "^2.11.8", @@ -158,9 +158,9 @@ "integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==" }, "node_modules/@appwrite.io/console": { - "version": "0.6.0-rc.13", - "resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.0-rc.13.tgz", - "integrity": "sha512-/c+HGkqdqWjjlzVgOmC6vb4t2jsHgbmX/aaDLoQHXFmaakEDWzK1cgVYRHoU3o14xIEpBupteh3KzOoqdLvvsQ==", + "version": "0.6.0-rc.14", + "resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.0-rc.14.tgz", + "integrity": "sha512-7Od0RuGRF01YUCWGTAvlTvgUG7sUCVHG9ig11OKz9jjBxE91BVcWsmqGWiXw+xb4HhF2jiyHd9ZU3sKAo0IC3w==", "dependencies": { "cross-fetch": "3.1.5", "isomorphic-form-data": "2.0.0" @@ -2336,9 +2336,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.0.tgz", - "integrity": "sha512-1uyXvzC2Lu1FZa30T4y5jUAC21R309ZMRG0TPt+PPPbNUoDpy8zSmSNVWYaBWxYDqLGQ5oPNWvjvvF2IjJ1jmA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.1.tgz", + "integrity": "sha512-TKj08o3mJCoQNLTdRdGkHPePTCPUGTgkew65RDqjVU3MtPVxljsofXQYfXndHfq0P7KoPRO/0/reF6HesU0Djw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3256,9 +3256,9 @@ } }, "node_modules/ai": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/ai/-/ai-2.2.35.tgz", - "integrity": "sha512-YzR56VAMjqvGIVzMUFwH7jjo7K+Z3Old4nXcigiWsuqXnWQeQi3iPR8p2/xOZzmuZyMTOC+6jjbIJ8hoEOhfcQ==", + "version": "2.2.36", + "resolved": "https://registry.npmjs.org/ai/-/ai-2.2.36.tgz", + "integrity": "sha512-QX3ZXgHjn4cQ233PHne1m7ZP+nfP93CkDEgNCIxuiDp+mhLEIEV10F1Qk3NozJ8mmSoyIJR82ea16kMZKOi8hw==", "dependencies": { "eventsource-parser": "1.0.0", "nanoid": "3.3.6", @@ -9514,9 +9514,9 @@ } }, "node_modules/vitest/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" diff --git a/package.json b/package.json index 07f589ab2..c608c667c 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,13 @@ "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check . && eslint .", "format": "prettier --write .", - "test": "vitest run", - "test:ui": "vitest --ui", - "test:watch": "vitest watch", + "test": "TZ=EST vitest run", + "test:ui": "TZ=EST vitest --ui", + "test:watch": "TZ=EST vitest watch", "e2e": "playwright test tests/e2e" }, "dependencies": { - "@appwrite.io/console": "^0.6.0-rc.13", + "@appwrite.io/console": "^0.6.0-rc.14", "@appwrite.io/pink": "0.4.0", "@appwrite.io/pink-icons": "0.4.0", "@popperjs/core": "^2.11.8", diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index e967ec3d2..4a5b473e9 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -245,6 +245,7 @@ export enum Submit { WebhookUpdateUrl = 'submit_webhook_update_url', WebhookUpdateEvents = 'submit_webhook_update_events', WebhookUpdateName = 'submit_webhook_update_name', + WebhookUpdateEnabled = 'submit_webhook_update_enabled', WebhookUpdateSecurity = 'submit_webhook_update_security', BucketCreate = 'submit_bucket_create', BucketDelete = 'submit_bucket_delete', @@ -301,7 +302,7 @@ export enum Submit { MessagingTopicCreate = 'submit_messaging_topic_create', MessagingTopicDelete = 'submit_messaging_topic_delete', MessagingTopicUpdateName = 'submit_messaging_topic_update_name', - MessagingTopicUpdateDescription = 'submit_messaging_topic_update_description', + MessagingTopicUpdatePermissions = 'submit_messaging_topic_update_permissions', MessagingTopicSubscriberAdd = 'submit_messaging_topic_subscriber_add', MessagingTopicSubscriberDelete = 'submit_messaging_topic_subscriber_delete' } diff --git a/src/lib/components/collapsibleItem.svelte b/src/lib/components/collapsibleItem.svelte index 736f2fe21..3420b555c 100644 --- a/src/lib/components/collapsibleItem.svelte +++ b/src/lib/components/collapsibleItem.svelte @@ -3,10 +3,11 @@ export let withIndentation = false; export let open = false; + export let disabled = false;
  • -
    +
    - + {#if $$slots.subtitle} - + {/if}
    -
  • + + diff --git a/src/lib/components/drop.svelte b/src/lib/components/drop.svelte index f61ff6a24..a1c222e08 100644 --- a/src/lib/components/drop.svelte +++ b/src/lib/components/drop.svelte @@ -12,6 +12,7 @@ export let childStart = false; export let noStyle = false; export let fullWidth = false; + export let wrapperFullWidth = false; export let fixed = false; export let display = 'block'; @@ -104,6 +105,7 @@
    diff --git a/src/lib/components/dropList.svelte b/src/lib/components/dropList.svelte index dd8271f1d..c6ad97dd1 100644 --- a/src/lib/components/dropList.svelte +++ b/src/lib/components/dropList.svelte @@ -11,10 +11,20 @@ export let noStyle = false; export let width: string = null; export let fullWidth = false; + export let wrapperFullWidth = false; export let position: 'relative' | 'static' = 'relative'; - +
    ; + export let fullWidthMobile = false; const parsedQueries = queryParamToMap(query); queries.set(parsedQueries); @@ -55,7 +56,7 @@
    - + +
    + +
    +
    + {#key copyParent} + + + {/key} +
    +
    +
    +
    + {/await} +
    diff --git a/src/routes/console/organization-[organization]/billing/wizard/addCredit.svelte b/src/routes/console/organization-[organization]/billing/wizard/addCredit.svelte index ddc5292c2..d62ffc7ab 100644 --- a/src/routes/console/organization-[organization]/billing/wizard/addCredit.svelte +++ b/src/routes/console/organization-[organization]/billing/wizard/addCredit.svelte @@ -38,7 +38,7 @@ - Add credits + Credits Add Appwrite credits to your organization. A payment method is required before credits can be applied. diff --git a/src/routes/console/organization-[organization]/billing/wizard/paymentDetails.svelte b/src/routes/console/organization-[organization]/billing/wizard/paymentDetails.svelte index b4f54264d..72dfd81c2 100644 --- a/src/routes/console/organization-[organization]/billing/wizard/paymentDetails.svelte +++ b/src/routes/console/organization-[organization]/billing/wizard/paymentDetails.svelte @@ -41,7 +41,7 @@ - Payment details + Details Add a payment method to your organization. You will not be charged until you upgrade to a Pro or Scale plan. diff --git a/src/routes/console/organization-[organization]/excesLimitModal.svelte b/src/routes/console/organization-[organization]/excesLimitModal.svelte index bead52e17..848f1b51e 100644 --- a/src/routes/console/organization-[organization]/excesLimitModal.svelte +++ b/src/routes/console/organization-[organization]/excesLimitModal.svelte @@ -13,7 +13,6 @@ import ChangeOrganizationTierCloud from '../changeOrganizationTierCloud.svelte'; import { goto } from '$app/navigation'; import { last } from '$lib/helpers/array'; - import { BillingPlan } from '$lib/constants'; import { trackEvent } from '$lib/actions/analytics'; export let show = false; @@ -58,25 +57,14 @@ - - Your usage exceeds the {tierToPlan($organization.billingPlan).name} plan limits - - - {#if $organization.billingPlan === BillingPlan.STARTER} -

    - Usage for {$organization.name} organization has reached the limits of the {tierToPlan( - $organization.billingPlan - ).name} plan. Consider upgrading to increase your resource usage. -

    - {:else} -

    - Usage for {$organization.name} organization has reached the limits of the {tierToPlan( - $organization.billingPlan - ).name} plan. Excess usage fees will apply. -

    - {/if} +

    + Usage for {$organization.name} organization has reached the limits of the {tierToPlan( + $organization.billingPlan + ).name} plan. Excess usage fees will apply. +

    +
    diff --git a/src/routes/console/organization-[organization]/wizard/step1.svelte b/src/routes/console/organization-[organization]/wizard/step1.svelte index 70bbc0050..612fd11fc 100644 --- a/src/routes/console/organization-[organization]/wizard/step1.svelte +++ b/src/routes/console/organization-[organization]/wizard/step1.svelte @@ -9,7 +9,7 @@ - Project Details + Details Send an invitation email to become a member of your project.

    + { + e.preventDefault(); + openEmail('mfaChallenge'); + }}> + 2FA verification +

    Send a two-factor authentication email to a user.

    + +
    diff --git a/src/routes/console/project-[project]/auth/templates/email2FATemplate.svelte b/src/routes/console/project-[project]/auth/templates/email2FATemplate.svelte new file mode 100644 index 000000000..094de917a --- /dev/null +++ b/src/routes/console/project-[project]/auth/templates/email2FATemplate.svelte @@ -0,0 +1,44 @@ + + +
    + + + {'{{user}}'} + {'{{project}}'} + {'{{otp}}'} + +
    diff --git a/src/routes/console/project-[project]/auth/templates/emailMagicUrlTemplate.svelte b/src/routes/console/project-[project]/auth/templates/emailMagicUrlTemplate.svelte index 9d5041acf..0941013bf 100644 --- a/src/routes/console/project-[project]/auth/templates/emailMagicUrlTemplate.svelte +++ b/src/routes/console/project-[project]/auth/templates/emailMagicUrlTemplate.svelte @@ -39,7 +39,6 @@
    - {'{{team}}'} {'{{user}}'} {'{{project}}'} {'{{redirect}}'} diff --git a/src/routes/console/project-[project]/auth/templates/emailRecoveryTemplate.svelte b/src/routes/console/project-[project]/auth/templates/emailRecoveryTemplate.svelte index 674ff61e5..bba93231c 100644 --- a/src/routes/console/project-[project]/auth/templates/emailRecoveryTemplate.svelte +++ b/src/routes/console/project-[project]/auth/templates/emailRecoveryTemplate.svelte @@ -38,7 +38,6 @@
    - {'{{team}}'} {'{{user}}'} {'{{project}}'} {'{{redirect}}'} diff --git a/src/routes/console/project-[project]/auth/templates/emailVerificationTemplate.svelte b/src/routes/console/project-[project]/auth/templates/emailVerificationTemplate.svelte index 55f8c5f98..6ac693b0a 100644 --- a/src/routes/console/project-[project]/auth/templates/emailVerificationTemplate.svelte +++ b/src/routes/console/project-[project]/auth/templates/emailVerificationTemplate.svelte @@ -39,7 +39,6 @@ - {'{{team}}'} {'{{user}}'} {'{{project}}'} {'{{redirect}}'} diff --git a/src/routes/console/project-[project]/auth/user-[user]/deleteMfa.svelte b/src/routes/console/project-[project]/auth/user-[user]/deleteMfa.svelte index 06322677f..3727ffcba 100644 --- a/src/routes/console/project-[project]/auth/user-[user]/deleteMfa.svelte +++ b/src/routes/console/project-[project]/auth/user-[user]/deleteMfa.svelte @@ -15,7 +15,7 @@ async function deleteProvider() { try { - await sdk.forConsole.users.deleteAuthenticator($user.$id, AuthenticatorType.Totp, ''); + await sdk.forConsole.users.deleteAuthenticator($user.$id, AuthenticatorType.Totp); await invalidate(Dependencies.ACCOUNT); await invalidate(Dependencies.FACTORS); showDelete = false; @@ -43,12 +43,8 @@ state="warning" bind:error headerDivider={false}> -

    - Deleting the authentication method will disable multi-factor authentication for this - account. To re-enable it, user will need to add a new authentication method. -

    -

    Are you sure you want to delete this authentication method from your account?

    - +

    Are you sure you want to delete this authentication?

    +

    This action is irreversible.

    diff --git a/src/routes/console/project-[project]/auth/user-[user]/updateMfa.svelte b/src/routes/console/project-[project]/auth/user-[user]/updateMfa.svelte index 96d5cce40..3a99efa4a 100644 --- a/src/routes/console/project-[project]/auth/user-[user]/updateMfa.svelte +++ b/src/routes/console/project-[project]/auth/user-[user]/updateMfa.svelte @@ -1,7 +1,7 @@ - - Multi-factor authentication -

    MFA allow users to enhance the security of their account in you app.

    - - {#if $userFactors.totp} - - - Authenticator - - - - - TOTP (One-time code) - - - - - -
    - - {:else} - -

    - No authenticators have been enabled. Once the user adds an authenticator, you’ll - see it here. -

    -
    - {/if} -
    -
    +
    + + Multi-factor authentication +

    MFA allow users to enhance the security of their account in you app.

    + + + + + {#if $userFactors.totp} + + + Authenticator + + + + + TOTP (One-time code) + + + + + +
    + + {:else} + +

    + No authenticators have been enabled. Once the user adds an authenticator, + you’ll see it here. +

    +
    + {/if} +
    + + + + +
    +
    + + diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step1.svelte b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step1.svelte index fc7bb5c78..b14c3a728 100644 --- a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step1.svelte +++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/wizard/step1.svelte @@ -5,7 +5,7 @@ - Create data + Data Provide document data based on attributes you created earlier. diff --git a/src/routes/console/project-[project]/functions/function-[function]/execute.svelte b/src/routes/console/project-[project]/functions/function-[function]/execute.svelte index a8460d6db..57d52063d 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/execute.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/execute.svelte @@ -121,11 +121,7 @@
    - + {:else} @@ -214,7 +210,7 @@ diff --git a/src/routes/console/project-[project]/functions/wizard/step1.svelte b/src/routes/console/project-[project]/functions/wizard/step1.svelte index 17408aacb..8700c7bbe 100644 --- a/src/routes/console/project-[project]/functions/wizard/step1.svelte +++ b/src/routes/console/project-[project]/functions/wizard/step1.svelte @@ -20,7 +20,7 @@ - Configuration function + Configuration Create your new Appwrite Function. ([ + { id: '$id', title: 'Message ID', type: 'string', show: true, width: 140 }, + { id: 'message', title: 'Message', type: 'string', show: false, filter: false, width: 140 }, + { id: 'providerType', title: 'Type', type: 'string', show: true, width: 100 }, + { id: 'status', title: 'Status', type: 'string', show: true, width: 120 }, + { id: 'scheduledAt', title: 'Scheduled at', type: 'datetime', show: true, width: 120 }, + { id: 'deliveredAt', title: 'Delivered at', type: 'datetime', show: false, width: 120 } + ]); const project = $page.params.project; @@ -82,46 +91,42 @@ -
    -
    - Messages -
    - -
    -
    - + + + +
    -
    - - - - +
    +
    + + + +
    -
    +
    - + showColsTextMobile + fullWidthMobile />
    - - +
    - {#if data.messages.total} @@ -141,7 +146,7 @@ + disabled={message.status === 'processing'} /> {#each $columns as column (column.id)} {#if column.show} diff --git a/src/routes/console/project-[project]/messaging/create.svelte b/src/routes/console/project-[project]/messaging/create.svelte new file mode 100644 index 000000000..e1f5d15bf --- /dev/null +++ b/src/routes/console/project-[project]/messaging/create.svelte @@ -0,0 +1,151 @@ + + + diff --git a/src/routes/console/project-[project]/messaging/createMessageDropdown.svelte b/src/routes/console/project-[project]/messaging/createMessageDropdown.svelte index f35e08683..4e23952a0 100644 --- a/src/routes/console/project-[project]/messaging/createMessageDropdown.svelte +++ b/src/routes/console/project-[project]/messaging/createMessageDropdown.svelte @@ -3,8 +3,8 @@ import { Button } from '$lib/elements/forms'; import { wizard } from '$lib/stores/wizard'; import { providers } from './providers/store'; - import Wizard from './wizard.svelte'; - import { messageParams, operation, providerType, targetsById } from './wizard/store'; + import Create from './create.svelte'; + import { messageParams, providerType, targetsById } from './wizard/store'; import { topicsById } from './store'; import { MessagingProviderType } from '@appwrite.io/console'; @@ -30,7 +30,6 @@ ) return; $providerType = type; - $operation = 'create'; $topicsById = {}; $targetsById = {}; const common = { @@ -62,7 +61,7 @@ break; } showCreateDropdown = false; - wizard.start(Wizard); + wizard.start(Create); }}> {option.name} diff --git a/src/routes/console/project-[project]/messaging/message-[message]/+page.svelte b/src/routes/console/project-[project]/messaging/message-[message]/+page.svelte index 8bcefdc55..878c47ffd 100644 --- a/src/routes/console/project-[project]/messaging/message-[message]/+page.svelte +++ b/src/routes/console/project-[project]/messaging/message-[message]/+page.svelte @@ -1,118 +1,40 @@ - + {#if $message.providerType === MessagingProviderType.Email} - + {:else if $message.providerType === MessagingProviderType.Sms} - + {:else if $message.providerType === MessagingProviderType.Push} - + {/if} - - - {#if $message.status !== MessageStatus.Processing} + + + {#if $message.status !== 'processing'} {/if} diff --git a/src/routes/console/project-[project]/messaging/message-[message]/cancelModal.svelte b/src/routes/console/project-[project]/messaging/message-[message]/cancelModal.svelte new file mode 100644 index 000000000..39802b18d --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/cancelModal.svelte @@ -0,0 +1,95 @@ + + + +
    +

    + Are you sure you want to cancel the scheduling of {message.data.title ?? + message.data.subject ?? + message.data.content ?? + 'Message'}? +

    +
    + + + +
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/emailMessage.svelte b/src/routes/console/project-[project]/messaging/message-[message]/emailMessage.svelte new file mode 100644 index 000000000..6fcaad6d4 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/emailMessage.svelte @@ -0,0 +1,93 @@ + + +
    + +
    + Message +
    + + + + + + + Enable the HTML mode if your message contains HTML tags. + + + + + + + +
    +
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/emailPreview.svelte b/src/routes/console/project-[project]/messaging/message-[message]/emailPreview.svelte deleted file mode 100644 index c6d5e051d..000000000 --- a/src/routes/console/project-[project]/messaging/message-[message]/emailPreview.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - -
    - Preview -
    - - - - - - -
    - -
    -
    -
    -
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/overview.svelte b/src/routes/console/project-[project]/messaging/message-[message]/overview.svelte index b9c95e2d8..c9bbe244f 100644 --- a/src/routes/console/project-[project]/messaging/message-[message]/overview.svelte +++ b/src/routes/console/project-[project]/messaging/message-[message]/overview.svelte @@ -1,64 +1,77 @@ - +
    - - {providerType} + + + +
    -

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

    -

    Scheduled at: {toLocaleDateTime(scheduledAt)}

    +

    Created: {toLocaleDateTime(message.$createdAt)}

    + {#if message.scheduledAt} +

    Scheduled at: {toLocaleDateTime(message.scheduledAt)}

    + {/if} + {#if message.deliveredAt} +

    Sent at: {toLocaleDateTime(message.deliveredAt)}

    + {/if}
    - +
    - + {#if message.status === 'draft'} +
    + + +
    + {:else if message.status === 'scheduled'} +
    + + +
    + {:else if message.status === 'failed'} + + {/if}
    + + + + + + diff --git a/src/routes/console/project-[project]/messaging/message-[message]/pushMessage.svelte b/src/routes/console/project-[project]/messaging/message-[message]/pushMessage.svelte new file mode 100644 index 000000000..d35aa1131 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/pushMessage.svelte @@ -0,0 +1,180 @@ + + +
    + +
    + Message +
    + +
    +
    + + + + + + + + +
    +
      + {#each customData || [] as _, rowIndex} + + + + + + + + + {/each} +
    + {#if dataError} + {dataError} + {/if} + +
    + +
    +
    + + + +
    + diff --git a/src/routes/console/project-[project]/messaging/message-[message]/pushPreview.svelte b/src/routes/console/project-[project]/messaging/message-[message]/pushPreview.svelte deleted file mode 100644 index eefb59c0a..000000000 --- a/src/routes/console/project-[project]/messaging/message-[message]/pushPreview.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - -
    - Preview -
    - -
    -
    - - - - - - -
    - -
    -
    -
    -
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/scheduleModal.svelte b/src/routes/console/project-[project]/messaging/message-[message]/scheduleModal.svelte new file mode 100644 index 000000000..a8d749d2c --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/scheduleModal.svelte @@ -0,0 +1,138 @@ + + + +
    + +
    + + +
    +
    + + {#if !dateTime || isNaN(dateTime.getTime())} + The message will be sent later + {:else} + The message will be sent at {dateTime.toLocaleString('en', formatOptions)} + {/if} + +
    + + + + +
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/sendModal.svelte b/src/routes/console/project-[project]/messaging/message-[message]/sendModal.svelte new file mode 100644 index 000000000..fdfaa1d5c --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/sendModal.svelte @@ -0,0 +1,100 @@ + + + +
    +

    + You are about to send a message to an estimated {totalTargets} targets. Would you like to proceed? +

    + +

    This action is irreversible.

    +
    + + + + +
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/smsMessage.svelte b/src/routes/console/project-[project]/messaging/message-[message]/smsMessage.svelte new file mode 100644 index 000000000..d71353c40 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/smsMessage.svelte @@ -0,0 +1,68 @@ + + +
    + +
    + Message + +
    + + + + + + + + +
    +
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/smsPreview.svelte b/src/routes/console/project-[project]/messaging/message-[message]/smsPreview.svelte deleted file mode 100644 index 8e6e772bb..000000000 --- a/src/routes/console/project-[project]/messaging/message-[message]/smsPreview.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - -
    - Preview - -
    - - - - -
    - -
    -
    -
    -
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/targets.svelte b/src/routes/console/project-[project]/messaging/message-[message]/targets.svelte deleted file mode 100644 index ca3e6ae03..000000000 --- a/src/routes/console/project-[project]/messaging/message-[message]/targets.svelte +++ /dev/null @@ -1,62 +0,0 @@ - - - - Targets - - {@const sum = targets.length} - {#if sum} -
    - - - ID - Name - Identifier - - - {#each targets.slice(offset, offset + limit) as target (target.$id)} - - - {target.$id} - - - - {usersById[target.userId]?.name || 'Unknown'} - - - - {target.providerType === MessagingProviderType.Push - ? target.name - : target.identifier} - - - {/each} - -
    -
    -

    Total targets: {sum}

    - -
    -
    - {:else} - Edit the message to add a Target - {/if} -
    -
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/topics.svelte b/src/routes/console/project-[project]/messaging/message-[message]/topics.svelte deleted file mode 100644 index 1df5200aa..000000000 --- a/src/routes/console/project-[project]/messaging/message-[message]/topics.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - - - Topics - - {@const sum = topics.length} - {#if sum} -
    - - - ID - Name - Subscribers - - - {#each topics.slice(offset, offset + limit) as topic (topic.$id)} - - - {topic.$id} - - - - {topic.name} - - - - {topic.smsTotal + topic.emailTotal + topic.pushTotal} - - - {/each} - -
    -
    -

    Total topics: {sum}

    - -
    -
    - {:else} - Edit the message to add a Topic - {/if} -
    -
    diff --git a/src/routes/console/project-[project]/messaging/message-[message]/updateTargets.svelte b/src/routes/console/project-[project]/messaging/message-[message]/updateTargets.svelte new file mode 100644 index 000000000..8c112fba9 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/updateTargets.svelte @@ -0,0 +1,208 @@ + + +
    + + Targets + + {@const sum = targetIds.length} + {#if sum} +
    +
    + Target +
    + {#if message.status == 'draft'} + + {/if} +
    +
    + + + + + + + + {#each targets.slice(offset, offset + limit) as target (target.$id)} + + +
    + + + + {#if target.providerType === MessagingProviderType.Push} + {target.name} + {:else} + {target.identifier} + {/if} + + +
    +
    + + {#if message.status === 'draft'} +
    + +
    + {/if} +
    +
    + {/each} +
    +
    +
    +

    Total targets: {sum}

    + +
    +
    + {:else if message.status == 'draft'} + (showTargets = true)}>Add a target + {:else} + +
    + No targets have been selected. +

    + Need a hand? Check out our . +

    +
    +
    + {/if} +
    + + + +
    +
    + + { + showTargets = false; + targetsById = e.detail; + }}> + Select existing targets to which you want to send this message. + diff --git a/src/routes/console/project-[project]/messaging/message-[message]/updateTopics.svelte b/src/routes/console/project-[project]/messaging/message-[message]/updateTopics.svelte new file mode 100644 index 000000000..be240b2d1 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/message-[message]/updateTopics.svelte @@ -0,0 +1,189 @@ + + +
    + + Topics + + {@const sum = topicIds.length} + {#if sum} +
    +
    + Topic +
    + {#if message.status == 'draft'} + + {/if} +
    +
    + + + + + + + {#each topics.slice(offset, offset + limit) as topic (topic.$id)} + + +
    + + + + {topic.name} + + + ({getTotal(topic)} targets) + + + +
    +
    + + {#if message.status === 'draft'} +
    + +
    + {/if} +
    +
    + {/each} +
    +
    +
    +

    Total topics: {sum}

    + +
    +
    + {:else if message.status == 'draft'} + (showTopics = true)}>Add a topic + {:else} + +
    + No topics have been selected. +

    + Need a hand? Check out our . +

    +
    +
    + {/if} +
    + + + +
    +
    + + { + showTopics = false; + topicsById = e.detail; + }} /> diff --git a/src/routes/console/project-[project]/messaging/providers/create.svelte b/src/routes/console/project-[project]/messaging/providers/create.svelte index 53cdf91a4..60da9ed89 100644 --- a/src/routes/console/project-[project]/messaging/providers/create.svelte +++ b/src/routes/console/project-[project]/messaging/providers/create.svelte @@ -44,8 +44,8 @@ providerId, $providerParams[$provider].name, $providerParams[$provider].from, - $providerParams[$provider].username, - $providerParams[$provider].password, + $providerParams[$provider].customerId, + $providerParams[$provider].apiKey, $providerParams[$provider].enabled ); break; @@ -156,7 +156,7 @@ const stepsComponents: WizardStepsType = new Map(); stepsComponents.set(1, { - label: 'Proivder', + label: 'Provider', component: Provider }); stepsComponents.set(2, { 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 139723fc4..e54e44eba 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 @@ -48,8 +48,8 @@ providerId: $providerData.$id, name: $providerData.name, enabled: $providerData.enabled, - username: $providerData.credentials['username'], - password: $providerData.credentials['password'], + customerId: $providerData.credentials['customerId'], + apiKey: $providerData.credentials['apiKey'], from: $providerData.options['from'] }; break; @@ -78,7 +78,7 @@ providerId: $providerData.$id, name: $providerData.name, enabled: $providerData.enabled, - isEuRegion: false, + isEuRegion: $providerData.credentials['isEuRegion'], fromEmail: $providerData.options['fromEmail'], fromName: $providerData.options['fromName'], replyToEmail: $providerData.options['replyToEmail'], 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 index fb806d134..e1fe4b242 100644 --- a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateSettings.svelte +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateSettings.svelte @@ -13,12 +13,13 @@ import { onMount } from 'svelte'; import CreateMember from '$routes/console/organization-[organization]/createMember.svelte'; - export let inputs: ProviderInput[]; + export let inputs: (ProviderInput | ProviderInput[])[]; export let providerType: MessagingProviderType; export let provider: Providers; export let providerId: string; export let params: object; + let flattened: ProviderInput[] = []; let formValues: object = {}; let originalfiles: Record = {}; let files: Record = {}; @@ -41,7 +42,15 @@ } onMount(() => { - for (const input of inputs) { + flattened = []; + for (const i of inputs) { + if (Array.isArray(i)) { + flattened.push(...i); + } else { + flattened.push(i); + } + } + for (const input of flattened) { const value = params[input.name]; formValues[input.name] = value; if (input.type === 'file' && typeof value == 'string' && value.length > 0) { @@ -91,8 +100,8 @@ providerId, undefined, undefined, - formValues['username'], - formValues['password'], + formValues['customerId'], + formValues['apiKey'], formValues['from'] ); break; @@ -198,7 +207,7 @@ } $: updated = - inputs + flattened .filter((input) => input.type !== 'file') .some((input) => formValues[input.name] !== params[input.name]) || Object.keys(files).some((key) => files[key] !== originalfiles[key]); 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 6e62a27fc..adb34d307 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 @@ -134,16 +134,20 @@
    -
    +
    -

    Provider:

    -

    Channel:

    -

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

    +
    +

    + Provider: +

    +

    Type:

    +

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

    +
    diff --git a/src/routes/console/project-[project]/messaging/providers/settingsFormInput.svelte b/src/routes/console/project-[project]/messaging/providers/settingsFormInput.svelte new file mode 100644 index 000000000..6bec64045 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/providers/settingsFormInput.svelte @@ -0,0 +1,147 @@ + + +{#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'} + + {fullWidth} + + + + +{:else if input.type === 'switch'} + + +

    {@html input.description}

    +
    +
    +{:else if input.type === 'checkbox'} + + + {input.description} + + +{:else if input.type === 'select'} + +{/if} diff --git a/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte b/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte index 582ce00c0..356ea4759 100644 --- a/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte +++ b/src/routes/console/project-[project]/messaging/providers/settingsFormList.svelte @@ -1,17 +1,6 @@ -
    - - +
    +
    + Subscribers +
    + +
    +
    + + +
    + + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + {#if data.subscribers.total} + + + + {:else if $hasPageQueries} + + {:else if data.search} + +
    + Sorry, we couldn't find '{data.search}' +

    There are no subscribers that match your search.

    +
    + +
    + {:else} + (showAdd = true)} + href="https://appwrite.io/docs/products/messaging/topics#subscribe-targets-to-topics" + target="subscriber" /> + {/if} + + + +

    + Add subscribers to this topic by selecting the targets for directing messages. Learn more about subscribers. +

    +
    +
    diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/+page.ts b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/+page.ts similarity index 100% rename from src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/+page.ts rename to src/routes/console/project-[project]/messaging/topics/topic-[topic]/+page.ts diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/header.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/header.svelte index 0848e48db..680a967e5 100644 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/header.svelte +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/header.svelte @@ -11,11 +11,6 @@ const tabs = [ { href: path, - title: 'Overview', - event: 'overview' - }, - { - href: `${path}/subscribers`, title: 'Subscribers', event: 'subscribers' }, @@ -23,6 +18,11 @@ href: `${path}/activity`, title: 'Activity', event: 'activity' + }, + { + href: `${path}/settings`, + title: 'Settings', + event: 'settings' } ]; diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/+page.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/+page.svelte new file mode 100644 index 000000000..8c5837596 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/+page.svelte @@ -0,0 +1,14 @@ + + + +
    + + + + diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/dangerZone.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/dangerZone.svelte similarity index 54% rename from src/routes/console/project-[project]/messaging/topics/topic-[topic]/dangerZone.svelte rename to src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/dangerZone.svelte index b9a2801bd..4758bcd6f 100644 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/dangerZone.svelte +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/dangerZone.svelte @@ -1,20 +1,10 @@ - - @@ -37,9 +27,9 @@ - - + diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/details.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/details.svelte similarity index 92% rename from src/routes/console/project-[project]/messaging/topics/topic-[topic]/details.svelte rename to src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/details.svelte index 09e919152..be120ba35 100644 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/details.svelte +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/details.svelte @@ -1,7 +1,7 @@ diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/updateName.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updateName.svelte similarity index 97% rename from src/routes/console/project-[project]/messaging/topics/topic-[topic]/updateName.svelte rename to src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updateName.svelte index 4b9305911..ad1e1998b 100644 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/updateName.svelte +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updateName.svelte @@ -2,7 +2,7 @@ import { CardGrid, Heading } from '$lib/components'; import { Button, Form, InputText } from '$lib/elements/forms'; import { onMount } from 'svelte'; - import { topic } from './store'; + import { topic } from '../store'; import { invalidate } from '$app/navigation'; import { trackEvent, Submit, trackError } from '$lib/actions/analytics'; import { Dependencies } from '$lib/constants'; diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updatePermissions.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updatePermissions.svelte new file mode 100644 index 000000000..7fff86143 --- /dev/null +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/settings/updatePermissions.svelte @@ -0,0 +1,65 @@ + + +
    + + Subscription access +

    + Choose who can subscribe to this topic using the client API. Learn more about + Permissions. +

    + + + + + + + +
    + diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/+page.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/+page.svelte deleted file mode 100644 index c5c308a5e..000000000 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/+page.svelte +++ /dev/null @@ -1,168 +0,0 @@ - - - -
    -
    - Subscribers -
    - -
    -
    - - -
    - - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    - {#if data.subscribers.total} -
    - - - {:else if $hasPageQueries} - - {:else if data.search} - -
    - Sorry, we couldn't find '{data.search}' -

    There are no subscribers that match your search.

    -
    - -
    - {:else} - (showAdd = true)} - href="https://appwrite.io/docs/products/messaging/topics/#subscribe-targets-to-topics" - target="subscriber" /> - {/if} - - - - -

    - Add subscribers to this topic by selecting the targets for directing messages. Learn more about subscribers. -

    -
    -
    diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/store.ts b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/store.ts deleted file mode 100644 index f5186a589..000000000 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/store.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Column } from '$lib/helpers/types'; -import { writable } from 'svelte/store'; - -export const columns = writable([ - { id: '$id', title: 'Subscriber ID', type: 'string', show: true, width: 140 }, - { id: 'userName', title: 'Name', type: 'string', show: true, filter: false, width: 100 }, - { id: 'targetId', title: 'Target ID', type: 'string', show: true, width: 140 }, - { id: 'target', title: 'Target', type: 'string', show: true, filter: false, width: 140 }, - { id: 'type', title: 'Type', type: 'string', show: true, width: 80 }, - { id: '$createdAt', title: 'Created', type: 'datetime', show: true, width: 100 } -]); diff --git a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/table.svelte b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/table.svelte similarity index 95% rename from src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/table.svelte rename to src/routes/console/project-[project]/messaging/topics/topic-[topic]/table.svelte index 8fce7c8c3..e469b7991 100644 --- a/src/routes/console/project-[project]/messaging/topics/topic-[topic]/subscribers/table.svelte +++ b/src/routes/console/project-[project]/messaging/topics/topic-[topic]/table.svelte @@ -18,15 +18,16 @@ } from '$lib/elements/table'; import { addNotification } from '$lib/stores/notifications'; import type { PageData } from './$types'; - import { columns } from './store'; - import ProviderType from '../../../providerType.svelte'; + import ProviderType from '../../providerType.svelte'; import { toLocaleDateTime } from '$lib/helpers/date'; import { project } from '$routes/console/project-[project]/store'; import { sdk } from '$lib/stores/sdk'; import { page } from '$app/stores'; - import { targetsById } from '../../../store'; + import { targetsById } from '../../store'; import { MessagingProviderType, type Models } from '@appwrite.io/console'; + import type { Column } from '$lib/helpers/types'; + export let columns: Column[]; export let data: PageData; let subscribers: Record = {}; @@ -84,7 +85,7 @@ d.$id)} /> - {#each $columns as column} + {#each columns as column} {#if column.show} {column.title} {/if} @@ -97,10 +98,10 @@ href={`${base}/console/project-${$project.$id}/auth/user-${subscriber.target.userId}`}> - {#each $columns as column} + {#each columns as column} {#if column.show} {#if column.id === '$id'} - {#key $columns} + {#key column.id} {subscriber.$id} diff --git a/src/routes/console/project-[project]/messaging/topicsModal.svelte b/src/routes/console/project-[project]/messaging/topicsModal.svelte index 377b5d1bd..a2aad2b57 100644 --- a/src/routes/console/project-[project]/messaging/topicsModal.svelte +++ b/src/routes/console/project-[project]/messaging/topicsModal.svelte @@ -91,86 +91,105 @@ -

    - Select existing topics you want to send this message to its targets. The message will be - sent only to targets. -

    - - {#if Object.keys(topicResultsById).length > 0} - -
    - - {#each Object.entries(topicResultsById) as [topicId, topic]} - - - onTopicSelection(event, topic)}> - - - - - {topic.name} - - - ({getTotal(topic)} targets) - - - - - - - {/each} - -
    - -
    -

    Total results: {totalResults}

    - +
    +

    + Select existing topics you want to send this message to its targets. The message will be + sent only to targets. +

    +
    + +
    + {#if Object.keys(topicResultsById).length > 0} +
    + + + + {#each Object.entries(topicResultsById) as [topicId, topic]} + + + + onTopicSelection(event, topic)}> + + + + + {topic.name} + + + ({getTotal(topic)} targets) + + + + + + + {/each} + +
    +
    +
    +

    Total results: {totalResults}

    + +
    +
    + {:else if search} + +
    +
    + Sorry we couldn't find "{search}" +

    There are no topics that match your search.

    +
    +
    + + +
    +
    +
    + {:else} + +
    +
    +

    + You have no topics. Create a topic to see them here. +

    +

    + Need a hand? Learn more in our . +

    +
    +
    +
    + {/if} +
    - {:else if search} - -
    -
    - Sorry we couldn't find "{search}" -

    There are no topics that match your search.

    -
    -
    - - -
    -
    -
    - {:else} - -
    -
    -

    - You have no topics. Create a topic to see them here. -

    -

    - Need a hand? Learn more in our - documentation. -

    -
    -
    -
    - {/if} - +
    - +
    +
    + {selectedSize} + Topics selected +
    + +
    diff --git a/src/routes/console/project-[project]/messaging/userTargetsModal.svelte b/src/routes/console/project-[project]/messaging/userTargetsModal.svelte index 7552144aa..7c7ca0266 100644 --- a/src/routes/console/project-[project]/messaging/userTargetsModal.svelte +++ b/src/routes/console/project-[project]/messaging/userTargetsModal.svelte @@ -24,6 +24,8 @@ let totalResults = 0; let userResultsById: Record>> = {}; // use a hash map so we can quickly look up a user by id let selected: Record = {}; + let selectedSize = 0; + let selectedUsers = 0; let hasSelection = false; function reset() { @@ -108,7 +110,16 @@ request(); } - $: selectedSize = Object.keys(selected).length; + $: { + selectedSize = 0; + const users = new Set(); + for (const s in selected) { + const target = selected[s]; + users.add(target.userId); + selectedSize++; + } + selectedUsers = users.size; + } $: hasSelection = selectedSize > 0; @@ -118,120 +129,160 @@ - +
    + - - {#if Object.keys(userResultsById).length > 0} -
    - - {#each Object.entries(userResultsById) as [userId, user] (userId)} - {@const selectedCount = user.targets.filter( - (target) => selected[target.$id] - ).length} - - - 0 && - user.targets.every((target) => targetsById[target.$id])} - checked={selectedCount > 0 && selectedCount === user.targets.length} - on:change={(event) => onUserSelection(event, userId)} /> - - - - - {#if user.name} - {user.name} - {:else if user.email} - {user.email} - {:else if user.phone} - {user.phone} - {:else} - {userId} - {/if} - - - - - ({selectedCount}/{user.targets.length} targets) - - - {#each user.targets as target} -
    - onTargetSelection(event, target)}> - -
    - - {#if target.providerType !== MessagingProviderType.Push} - {target.identifier} - {:else} - {target.name} - {/if} -
    +
    + +
    + {#if Object.keys(userResultsById).length > 0} +
    +
    + + {#each Object.entries(userResultsById) as [userId, user] (userId)} + {@const selectedCount = user.targets.filter( + (target) => selected[target.$id] + ).length} + + + 0 && + user.targets.every( + (target) => targetsById[target.$id] + ))} + checked={selectedCount > 0 && + selectedCount === user.targets.length} + on:change={(event) => + onUserSelection(event, userId)} /> - -
    - {/each} - - - {/each} - -
    -
    -

    Total results: {totalResults}

    - -
    - {:else if search} - -
    -
    - Sorry we couldn't find "{search}" -

    There are no Users that match your search.

    -
    -
    - - -
    + + + + {#if user.name} + {user.name} + {:else if user.email} + {user.email} + {:else if user.phone} + {user.phone} + {:else} + {userId} + {/if} + + + + + {#if user.targets.length === 0} + (0 targets) + {:else} + ({selectedCount}/{user.targets.length} targets) + {/if} + + + {#each user.targets as target} +
    + + onTargetSelection(event, target)}> + +
    + + {#if target.providerType !== MessagingProviderType.Push} + {target.identifier} + {:else} + {target.name} + {/if} +
    +
    +
    +
    + {/each} +
    + + {/each} + +
    +
    +

    Total results: {totalResults}

    + +
    +
    + {:else if search} + +
    +
    + Sorry we couldn't find "{search}" +

    There are no Users that match your search.

    +
    +
    + + +
    +
    +
    + {:else} + +
    +
    +

    + You have no users. Create a user to see them here. +

    +

    + Need a hand? Learn more in our . +

    +
    +
    +
    + {/if}
    - - {:else} - -
    -
    -

    - You have no users. Create a user to see them here. -

    -

    - Need a hand? Learn more in our - documentation. -

    -
    -
    -
    - {/if} - +
    +
    - +
    +
    + {selectedUsers} + Users selected +
    + +
    + + diff --git a/src/routes/console/project-[project]/messaging/wizard.svelte b/src/routes/console/project-[project]/messaging/wizard.svelte deleted file mode 100644 index 4fbc93c55..000000000 --- a/src/routes/console/project-[project]/messaging/wizard.svelte +++ /dev/null @@ -1,263 +0,0 @@ - - - diff --git a/src/routes/console/project-[project]/messaging/wizard/emailFormList.svelte b/src/routes/console/project-[project]/messaging/wizard/emailFormList.svelte index bcc6be1d6..693d209fb 100644 --- a/src/routes/console/project-[project]/messaging/wizard/emailFormList.svelte +++ b/src/routes/console/project-[project]/messaging/wizard/emailFormList.svelte @@ -1,5 +1,5 @@ - + Targets Select targets to whom this message should be directed. @@ -89,7 +95,7 @@ {topic.name} - ({getTotal(topic)} subscribers) + ({getTotal(topic)} targets)
    diff --git a/src/routes/console/project-[project]/messaging/wizard/step3.svelte b/src/routes/console/project-[project]/messaging/wizard/step3.svelte index ba2e7be3b..47b9c2b2e 100644 --- a/src/routes/console/project-[project]/messaging/wizard/step3.svelte +++ b/src/routes/console/project-[project]/messaging/wizard/step3.svelte @@ -2,12 +2,12 @@ import { Button, FormList, InputDate, InputSelect, InputTime } from '$lib/elements/forms'; import Helper from '$lib/elements/forms/helper.svelte'; import { WizardStep } from '$lib/layout'; - import { MessageStatus, MessagingProviderType } from '@appwrite.io/console'; + import { MessagingProviderType } from '@appwrite.io/console'; import { messageParams, providerType } from './store'; + import { isSameDay, toLocaleDateISO, toLocaleTimeISO } from '$lib/helpers/date'; let when: 'now' | 'later' = 'now'; let now = new Date(); - let timeZoneOffset: number; let minDate: string; let date: string; let time: string; @@ -40,30 +40,23 @@ timeZoneName: 'longGeneric' }; - async function beforeSubmit() { - $messageParams[$providerType].status = MessageStatus.Processing; - if (when === 'later') { - $messageParams[$providerType].status = 'scheduled' as MessageStatus; - $messageParams[$providerType].scheduledAt = dateTime.toISOString(); - } - } - $: if (when === 'now') { date = time = ''; } $: if (when === 'later') { now = new Date(); } - $: timeZoneOffset = now ? now.getTimezoneOffset() * 60 * 1000 : 0; - $: minDate = new Date(now.getTime() - timeZoneOffset).toISOString().split('T')[0]; - $: minTime = - date === minDate - ? new Date(now.getTime() - timeZoneOffset).toISOString().split('T')[1].substring(0, 5) - : '00:00'; + $: minDate = toLocaleDateISO(now.getTime()); + $: minTime = isSameDay(new Date(date), new Date(minDate)) + ? toLocaleTimeISO(now.getTime()) + : '00:00'; $: dateTime = new Date(`${date}T${time}`); + $: if (!isNaN(dateTime.getTime())) { + $messageParams[$providerType].scheduledAt = dateTime.toISOString(); + } - + Schedule Schedule the time you want to deliver this message. Learn more in our + {#if data.webhooks.total} - Name - POST URL - Events + {#each $columns as column} + {#if column.show} + {column.title} + {/if} + {/each} {#each data.webhooks.webhooks as webhook} - -
    - {webhook.name} - {#if webhook.security === false} - SLL/TLS disabled + {#each $columns as column (column.id)} + {#if column.show} + {#if column.id === '$id'} + {#key $columns} + + {webhook.$id} + + {/key} + {:else if column.id === 'events'} + + {webhook.events.length} + + {:else if column.type === 'datetime'} + + {#if !webhook[column.id]} + - + {:else} + {toLocaleDateTime(webhook[column.id])} + {/if} + + {:else if column.id === 'enabled'} + + + +   + + {#if webhook.enabled === false} + + {/if} + + {:else} + + {webhook[column.id]} + {/if} -
    -
    - {webhook.url} - {webhook.events.length} events + {/if} + {/each}
    {/each}
    @@ -80,3 +123,5 @@ on:click={openWizard} /> {/if} + + diff --git a/src/routes/console/project-[project]/settings/webhooks/+page.ts b/src/routes/console/project-[project]/settings/webhooks/+page.ts index 10c30754e..10e665b00 100644 --- a/src/routes/console/project-[project]/settings/webhooks/+page.ts +++ b/src/routes/console/project-[project]/settings/webhooks/+page.ts @@ -1,11 +1,17 @@ import { Dependencies } from '$lib/constants'; +import { View, getPage, getView } from '$lib/helpers/load'; import { sdk } from '$lib/stores/sdk'; import type { PageLoad } from './$types'; -export const load: PageLoad = async ({ params, depends }) => { +export const load: PageLoad = async ({ params, url, route, depends }) => { depends(Dependencies.WEBHOOKS); + const page = getPage(url); + const view = getView(url, route, View.Grid); + return { + page, + view, webhooks: await sdk.forConsole.projects.listWebhooks(params.project) }; }; 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 ab3bd3c63..bbb9863ad 100644 --- a/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/+page.svelte @@ -6,9 +6,11 @@ import UpdateSecurity from './updateSecurity.svelte'; import UpdateSignature from './updateSignature.svelte'; import UpdateUrl from './updateURL.svelte'; + import Details from './details.svelte'; +
    diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/details.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/details.svelte new file mode 100644 index 000000000..37424e263 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/details.svelte @@ -0,0 +1,89 @@ + + + + {$webhook.url} + + +
    +
      + + + + +
    • Created: {toLocaleDateTime($webhook.$createdAt)}
    • +
    • Last updated: {toLocaleDateTime($webhook.$updatedAt)}
    • +
    + +
    +
    + + +
    + {#if $webhook.logs.length > 0} + + {/if} + + +
    +
    +
    + + diff --git a/src/routes/console/project-[project]/settings/webhooks/[webhook]/header.svelte b/src/routes/console/project-[project]/settings/webhooks/[webhook]/header.svelte index 9a09cbb01..8debdc385 100644 --- a/src/routes/console/project-[project]/settings/webhooks/[webhook]/header.svelte +++ b/src/routes/console/project-[project]/settings/webhooks/[webhook]/header.svelte @@ -12,6 +12,6 @@ {$webhook?.name} - Webhook ID + {$webhook?.$id} diff --git a/src/routes/console/project-[project]/settings/webhooks/failedModal.svelte b/src/routes/console/project-[project]/settings/webhooks/failedModal.svelte new file mode 100644 index 000000000..67437a82b --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/failedModal.svelte @@ -0,0 +1,52 @@ + + + +
    +
    +

    +

    + + {#if showUpdateButton} + + {/if} +
    + +

    + The connection to {webhook.url} stopped after {webhook.attempts} consecutive failures. Please + refer to the logs below for more information or try to update the webhook to resolve this + issue. +

    +
    + +
    +
    + + + + +
    diff --git a/src/routes/console/project-[project]/settings/webhooks/messageStatusPill.svelte b/src/routes/console/project-[project]/settings/webhooks/messageStatusPill.svelte new file mode 100644 index 000000000..2c12a4ee0 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/messageStatusPill.svelte @@ -0,0 +1,16 @@ + + + + + + diff --git a/src/routes/console/project-[project]/settings/webhooks/store.ts b/src/routes/console/project-[project]/settings/webhooks/store.ts new file mode 100644 index 000000000..4d7bfd323 --- /dev/null +++ b/src/routes/console/project-[project]/settings/webhooks/store.ts @@ -0,0 +1,17 @@ +// import { page } from '$app/stores'; +import type { Column } from '$lib/helpers/types'; +// import type { Models } from '@appwrite.io/console'; +import { writable } from 'svelte/store'; + +// export const database = derived(page, ($page) => $page.data.database as Models.Database); +// export const showCreate = writable(false); + +export const columns = writable([ + { id: '$id', title: 'Webhook ID', type: 'string', show: true, width: 150 }, + { id: 'name', title: 'Name', type: 'string', show: true, width: 120 }, + { id: 'url', title: 'Post URL', type: 'string', show: true, width: 120 }, + { id: 'events', title: 'Events', type: 'string', show: true, width: 60 }, + { id: 'enabled', title: 'Status', type: 'string', show: true, width: 150 }, + { id: '$createdAt', title: 'Created', type: 'datetime', show: true, width: 120 }, + { id: '$updatedAt', title: 'Updated', type: 'datetime', show: true, width: 120 } +]); diff --git a/src/routes/console/project-[project]/settings/webhooks/wizard/step1.svelte b/src/routes/console/project-[project]/settings/webhooks/wizard/step1.svelte index 4045874d7..c48e6b0ab 100644 --- a/src/routes/console/project-[project]/settings/webhooks/wizard/step1.svelte +++ b/src/routes/console/project-[project]/settings/webhooks/wizard/step1.svelte @@ -6,7 +6,7 @@ - Add your webhook + Configuration Use webhooks to build integrations that subscribe to specific events on Appwrite. Appwrite will send an HTTP POST payload to the webhook's configured URL when one of the specified diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step1.svelte b/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step1.svelte index 8453a8ee0..77a953bc6 100644 --- a/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step1.svelte +++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step1.svelte @@ -18,7 +18,7 @@ - Create file + File Upload a file to add it to your bucket. {#if isCloud} diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step2.svelte b/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step2.svelte index 6a98039ef..58363e57d 100644 --- a/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step2.svelte +++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/create-file/step2.svelte @@ -7,7 +7,7 @@ - Update Permissions + Permissions Choose who can access your buckets and files. For more information, check out the
    - Confirm your details + Details Confirm the details of your new organization and start your free trial. diff --git a/src/routes/console/wizard/cloudOrganization/inviteMembers.svelte b/src/routes/console/wizard/cloudOrganization/inviteMembers.svelte index e1359f39b..1bfe98fc6 100644 --- a/src/routes/console/wizard/cloudOrganization/inviteMembers.svelte +++ b/src/routes/console/wizard/cloudOrganization/inviteMembers.svelte @@ -36,7 +36,7 @@ - Invite organization members + Invites Invite team members to collaborate with you in the Appwrite console. Members will have access to all services and payment data within your organization. diff --git a/src/routes/console/wizard/cloudOrganizationChangeTier/choosePlan.svelte b/src/routes/console/wizard/cloudOrganizationChangeTier/choosePlan.svelte index 5a94e9ec8..2327bd948 100644 --- a/src/routes/console/wizard/cloudOrganizationChangeTier/choosePlan.svelte +++ b/src/routes/console/wizard/cloudOrganizationChangeTier/choosePlan.svelte @@ -103,7 +103,7 @@ - Choose a plan + Plan selection

    Plan

    diff --git a/src/routes/console/wizard/cloudOrganizationChangeTier/confirmDetails.svelte b/src/routes/console/wizard/cloudOrganizationChangeTier/confirmDetails.svelte index e62c6af3f..aa1c4bf8b 100644 --- a/src/routes/console/wizard/cloudOrganizationChangeTier/confirmDetails.svelte +++ b/src/routes/console/wizard/cloudOrganizationChangeTier/confirmDetails.svelte @@ -49,7 +49,7 @@ {#if downgradeToStarter} - Confirm plan change + Change confirmation Your feedback is important to us and helps us improve the services Appwrite offer. If there is a specific reason you chose to change your plan at this time, please let us @@ -65,7 +65,7 @@ {:else} - Confirm your details + Details Confirm the details of your new organization and start your free trial. diff --git a/src/routes/console/wizard/cloudOrganizationChangeTier/inviteMembers.svelte b/src/routes/console/wizard/cloudOrganizationChangeTier/inviteMembers.svelte index 94d86e267..0695e7e0f 100644 --- a/src/routes/console/wizard/cloudOrganizationChangeTier/inviteMembers.svelte +++ b/src/routes/console/wizard/cloudOrganizationChangeTier/inviteMembers.svelte @@ -52,7 +52,7 @@ - Invite organization members + Invites Invite team members to collaborate with you in the Appwrite console. Members will have access to all services and payment data within your organization. diff --git a/src/routes/console/wizard/cloudOrganizationChangeTier/usageExcess.svelte b/src/routes/console/wizard/cloudOrganizationChangeTier/usageExcess.svelte index f3b1a6baa..e5bd500fb 100644 --- a/src/routes/console/wizard/cloudOrganizationChangeTier/usageExcess.svelte +++ b/src/routes/console/wizard/cloudOrganizationChangeTier/usageExcess.svelte @@ -7,8 +7,8 @@ - Your usage exceeds the limits of the {tierToPlan($organization.billingPlan).name} plan + + Your usage exceeds the limits of the {tierToPlan($organization.billingPlan).name} plan View the current usage for {$organization.name} and where you will exceed the limits of your new plan. diff --git a/src/routes/console/wizard/feedback/step2.svelte b/src/routes/console/wizard/feedback/step2.svelte index 1e91272cf..6a79839c5 100644 --- a/src/routes/console/wizard/feedback/step2.svelte +++ b/src/routes/console/wizard/feedback/step2.svelte @@ -6,7 +6,7 @@ - Thanks for the feedback! + Thank you

    {#if $app.themeInUse === 'dark'} diff --git a/tests/unit/helpers/date.test.ts b/tests/unit/helpers/date.test.ts index fab13619a..d28106973 100644 --- a/tests/unit/helpers/date.test.ts +++ b/tests/unit/helpers/date.test.ts @@ -4,13 +4,16 @@ import { toLocaleDateTime, isSameDay, isValidDate, - diffDays + diffDays, + toLocaleDateISO, + toLocaleTimeISO } from '$lib/helpers/date'; describe('local date', () => { [ ['2022-11-15 08:26:28', 'Nov 15, 2022'], - ['2022-11-15 00:26:28', 'Nov 15, 2022'] + ['2022-11-15 00:26:28', 'Nov 15, 2022'], + ['2022-11-15 00:26:28Z', 'Nov 14, 2022'] ].forEach(([value, expected]) => { it(value, () => { expect(toLocaleDate(value)).toBe(expected); @@ -25,7 +28,8 @@ describe('local date', () => { describe('local date time', () => { [ ['2022-11-15 08:26:28', 'Nov 15, 2022, 08:26'], - ['2022-11-15 00:26:28', 'Nov 15, 2022, 00:26'] + ['2022-11-15 00:26:28', 'Nov 15, 2022, 00:26'], + ['2022-11-15 00:26:28Z', 'Nov 14, 2022, 19:26'] ].forEach(([value, expected]) => { it(value, () => { expect(toLocaleDateTime(value)).toBe(expected); @@ -37,6 +41,38 @@ describe('local date time', () => { }); }); +describe('local date ISO', () => { + [ + ['2022-11-15 20:26:28Z', '2022-11-15'], + ['2022-11-15 08:26:28Z', '2022-11-15'], + ['2022-11-16 00:26:28Z', '2022-11-15'] + ].forEach(([value, expected]) => { + it(value, () => { + expect(toLocaleDateISO(value)).toBe(expected); + }); + }); + + it('invalid date', () => { + expect(toLocaleDateISO('')).toBe('n/a'); + }); +}); + +describe('local time ISO', () => { + [ + ['2022-11-15 20:26:28Z', '15:26:28'], + ['2022-11-15 08:26:28Z', '03:26:28'], + ['2022-11-16 00:26:28Z', '19:26:28'] + ].forEach(([value, expected]) => { + it(value, () => { + expect(toLocaleTimeISO(value)).toBe(expected); + }); + }); + + it('invalid date', () => { + expect(toLocaleTimeISO('')).toBe('n/a'); + }); +}); + describe('is same day', () => { const entries: Array<[string, string, boolean]> = [ ['2022-11-15 08:26:28', '2022-11-15 08:26:28', true],