From 8a78c414c331cc6fc4284f8dd53cb4bf355bbccd Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 16 Aug 2024 19:18:29 +0900 Subject: [PATCH 01/73] Cherrypick Runtime Controls Feat implement runtime controls --- package-lock.json | 9 +++--- package.json | 2 +- src/lib/elements/forms/inputSelect.svelte | 6 +++- .../project-[project]/functions/+layout.ts | 8 +++-- .../settings/updateRuntime.svelte | 31 ++++++++++++++++--- .../usage/[[period]]/+page.svelte | 22 +++++++++++++ .../project-[project]/functions/store.ts | 5 +++ 7 files changed, 70 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 650428e1e..f8b587631 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "@appwrite/console", "dependencies": { - "@appwrite.io/console": "^0.6.2", + "@appwrite.io/console": "^0.6.4", "@appwrite.io/pink": "0.25.0", "@appwrite.io/pink-icons": "0.25.0", "@popperjs/core": "^2.11.8", @@ -149,9 +149,10 @@ "integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==" }, "node_modules/@appwrite.io/console": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.2.tgz", - "integrity": "sha512-3qYknuFwhvTN2GnPB8G1w5DgxfVorGtfj4uuEaXbTmMUmjA8fHaW5VkJriuUxCi6/TpxDxqV/hhEkdoXL+5H4w==" + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.4.tgz", + "integrity": "sha512-0LPeeHR3fLQpTiX/AjguXqHYRgjMLf2lxie5TevBPxMssi1tcipctTGmj0YMyjWxQKD05NBmgvkJwAXEsm9rRA==", + "license": "BSD-3-Clause" }, "node_modules/@appwrite.io/pink": { "version": "0.25.0", diff --git a/package.json b/package.json index e566dcf14..6be5e3013 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "e2e:ui": "playwright test tests/e2e --ui" }, "dependencies": { - "@appwrite.io/console": "^0.6.2", + "@appwrite.io/console": "^0.6.4", "@appwrite.io/pink": "0.25.0", "@appwrite.io/pink-icons": "0.25.0", "@popperjs/core": "^2.11.8", diff --git a/src/lib/elements/forms/inputSelect.svelte b/src/lib/elements/forms/inputSelect.svelte index 9de5dd726..b6901ee31 100644 --- a/src/lib/elements/forms/inputSelect.svelte +++ b/src/lib/elements/forms/inputSelect.svelte @@ -15,6 +15,7 @@ export let options: { value: string | boolean | number | null; label: string; + disabled?: boolean; }[]; export let isMultiple = false; export let fullWidth = false; @@ -70,7 +71,10 @@ {/if} {#each options as option} - {/each} diff --git a/src/routes/console/project-[project]/functions/+layout.ts b/src/routes/console/project-[project]/functions/+layout.ts index 68ecb719d..f30945205 100644 --- a/src/routes/console/project-[project]/functions/+layout.ts +++ b/src/routes/console/project-[project]/functions/+layout.ts @@ -8,15 +8,17 @@ import type { LayoutLoad } from './$types'; export const load: LayoutLoad = async ({ depends }) => { depends(Dependencies.FUNCTION_INSTALLATIONS); - const [runtimesList, installations] = await Promise.all([ + const [runtimesList, installations, specifications] = await Promise.all([ sdk.forProject.functions.listRuntimes(), - sdk.forProject.vcs.listInstallations([Query.limit(100)]) + sdk.forProject.vcs.listInstallations([Query.limit(100)]), + sdk.forProject.functions.getSpecifications() ]); return { header: Header, breadcrumbs: Breadcrumbs, runtimesList, - installations + installations, + specifications }; }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte index a4a2f806c..21b6ded4f 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte @@ -10,23 +10,35 @@ import { onMount } from 'svelte'; import { func } from '../store'; import InputSelect from '$lib/elements/forms/inputSelect.svelte'; - import { runtimesList } from '../../store'; + import { runtimesList, specifications } from '../../store'; import { isValueOfStringEnum } from '$lib/helpers/types'; import { Runtime } from '@appwrite.io/console'; const functionId = $page.params.function; let runtime: string = null; + let specification: string = null; let options = []; + let specificationOptions = []; onMount(async () => { runtime ??= $func.runtime; + specification ??= $func.specification; let runtimes = await $runtimesList; + let allowedSpecifications = await $specifications; options = runtimes.runtimes.map((runtime) => ({ label: `${runtime.name} - ${runtime.version}`, value: runtime.$id })); + + specificationOptions = allowedSpecifications.map((size) => ({ + label: + `${size.cpus} CPU, ${size.memory} MB RAM` + + (!size.enabled ? ` (Upgrade to use this)` : ''), + value: size.slug, + disabled: !size.enabled + })); }); async function updateRuntime() { @@ -50,11 +62,12 @@ $func.providerRepositoryId || undefined, $func.providerBranch || undefined, $func.providerSilentMode || undefined, - $func.providerRootDirectory || undefined + $func.providerRootDirectory || undefined, + specification ); await invalidate(Dependencies.FUNCTION); addNotification({ - message: 'Runtime has been updated', + message: 'Runtime settings have been updated', type: 'success' }); trackEvent(Submit.FunctionUpdateName); @@ -66,6 +79,8 @@ trackError(error, Submit.FunctionUpdateName); } } + + $: isUpdateButtonEnabled = runtime !== $func?.runtime || specification !== $func?.specification;
@@ -82,11 +97,19 @@ {options} required hideRequired /> + - + diff --git a/src/routes/console/project-[project]/functions/function-[function]/usage/[[period]]/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/usage/[[period]]/+page.svelte index c486d2ba5..3513b90a3 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/usage/[[period]]/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/usage/[[period]]/+page.svelte @@ -9,6 +9,8 @@ export let data: PageData; $: total = data.executionsTotal; $: count = data.executions; + $: gbHoursTotal = data.executionsMbSecondsTotal / 1000 / 3600; + $: mbSecondsCount = data.executionsMbSeconds; @@ -46,4 +48,24 @@ ]} /> {/if} + + {#if mbSecondsCount} + + {formatNumberWithCommas(gbHoursTotal)} +

GB Hours

+
+ [ + e.date, + Math.ceil((e.value / 1000 / 3600) * 1000) / 1000 + ]) + ] + } + ]} /> + + {/if} diff --git a/src/routes/console/project-[project]/functions/store.ts b/src/routes/console/project-[project]/functions/store.ts index 3acf62136..e56f264ea 100644 --- a/src/routes/console/project-[project]/functions/store.ts +++ b/src/routes/console/project-[project]/functions/store.ts @@ -7,6 +7,11 @@ export const runtimesList = derived( async ($page) => (await $page.data.runtimesList) as Models.RuntimeList ); +export const specifications = derived( + page, + async ($page) => (await $page.data.specifications.specifications) as Models.Specification[] +); + export const baseRuntimesList = derived(runtimesList, async ($runtimesList) => { const baseRuntimes = new Map(); for (const runtime of (await $runtimesList).runtimes) { From 10b48f97a2f0a9d8f0470fdae87b6be599e76618 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 19 Aug 2024 13:23:14 +0900 Subject: [PATCH 02/73] Update pnpm lockfile --- pnpm-lock.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d89979a2d..6541888cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@appwrite.io/console': - specifier: npm:matej-appwrite-console@0.6.13 - version: matej-appwrite-console@0.6.13 + specifier: npm:bradley-console@0.6.5 + version: bradley-console@0.6.5 '@appwrite.io/pink': specifier: 0.25.0 version: 0.25.0 @@ -1147,6 +1147,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + bradley-console@0.6.5: + resolution: {integrity: sha512-IzXpW9MW3Ofx8+cKsEdQQU1TztA/LyzOEF4A6EgvdM2z3dx5S7FV99jWk9U1G9ugV2BGv49Pwp+yjqe8vRnzVA==} + browserslist@4.23.3: resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -2164,9 +2167,6 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - matej-appwrite-console@0.6.13: - resolution: {integrity: sha512-F15YP98n9Um809SN3wbyZun8ZFY/m5MEU2uWUUU+4ej+PI0af3YGhwnkYC1nmciKpDbILf8O4hQ1+ORXKho8hg==} - mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} @@ -4346,6 +4346,8 @@ snapshots: dependencies: fill-range: 7.1.1 + bradley-console@0.6.5: {} + browserslist@4.23.3: dependencies: caniuse-lite: 1.0.30001651 @@ -5602,8 +5604,6 @@ snapshots: dependencies: tmpl: 1.0.5 - matej-appwrite-console@0.6.13: {} - mdn-data@2.0.30: {} merge-stream@2.0.0: {} From 84bb17b72c4c01f75ee3bf2c55c4e5237ef803a3 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 19 Aug 2024 18:40:08 +0900 Subject: [PATCH 03/73] Run Linter --- src/lib/stores/specifications.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/stores/specifications.ts b/src/lib/stores/specifications.ts index ad7f14589..30bc5eabb 100644 --- a/src/lib/stores/specifications.ts +++ b/src/lib/stores/specifications.ts @@ -5,4 +5,4 @@ import { derived } from 'svelte/store'; export const specificationsList = derived( page, async ($page) => (await $page.data.specificationsList) as Models.SpecificationList -); \ No newline at end of file +); From 7984f3894af399cc9e9270647b103de4707cad02 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 23 Aug 2024 12:37:39 +0900 Subject: [PATCH 04/73] Remove console and change getSpec... to listSpec... --- package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- .../project-[project]/functions/+layout.ts | 2 +- .../settings/updateRuntime.svelte | 2 -- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 46a01ef3e..07b50665a 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "e2e:ui": "playwright test tests/e2e --ui" }, "dependencies": { - "@appwrite.io/console": "npm:bradley-console@0.6.5", + "@appwrite.io/console": "npm:matej-appwrite-console@0.6.18", "@appwrite.io/pink": "0.25.0", "@appwrite.io/pink-icons": "0.25.0", "@popperjs/core": "^2.11.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6541888cf..51026dac0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@appwrite.io/console': - specifier: npm:bradley-console@0.6.5 - version: bradley-console@0.6.5 + specifier: npm:matej-appwrite-console@0.6.18 + version: matej-appwrite-console@0.6.18 '@appwrite.io/pink': specifier: 0.25.0 version: 0.25.0 @@ -1147,9 +1147,6 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - bradley-console@0.6.5: - resolution: {integrity: sha512-IzXpW9MW3Ofx8+cKsEdQQU1TztA/LyzOEF4A6EgvdM2z3dx5S7FV99jWk9U1G9ugV2BGv49Pwp+yjqe8vRnzVA==} - browserslist@4.23.3: resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -2167,6 +2164,9 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + matej-appwrite-console@0.6.18: + resolution: {integrity: sha512-n1WmZBKjmJEJ3Fc3w/qAKwfLJSPoDQDR+B4loWpa2NLkKRICxZScIvUsegxaBx9uGPOE8Q+A8sw3iCQBVihLuQ==} + mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} @@ -4346,8 +4346,6 @@ snapshots: dependencies: fill-range: 7.1.1 - bradley-console@0.6.5: {} - browserslist@4.23.3: dependencies: caniuse-lite: 1.0.30001651 @@ -5604,6 +5602,8 @@ snapshots: dependencies: tmpl: 1.0.5 + matej-appwrite-console@0.6.18: {} + mdn-data@2.0.30: {} merge-stream@2.0.0: {} diff --git a/src/routes/(console)/project-[project]/functions/+layout.ts b/src/routes/(console)/project-[project]/functions/+layout.ts index 0f9f72535..8d7b68a16 100644 --- a/src/routes/(console)/project-[project]/functions/+layout.ts +++ b/src/routes/(console)/project-[project]/functions/+layout.ts @@ -12,7 +12,7 @@ export const load: LayoutLoad = async ({ depends }) => { sdk.forProject.functions.listRuntimes(), sdk.forProject.vcs.listInstallations([Query.limit(100)]), sdk.forProject.functions.listTemplates(undefined, undefined, 100), - sdk.forProject.functions.getSpecifications() + sdk.forProject.functions.listSpecifications() ]); return { diff --git a/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte b/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte index ac1254d13..c447e6e36 100644 --- a/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte +++ b/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte @@ -33,8 +33,6 @@ value: runtime.$id })); - console.log(allowedSpecifications); - specificationOptions = allowedSpecifications.map((size) => ({ label: `${size.cpus} CPU, ${size.memory} MB RAM` + From 869813ed3ebd256b2ecfeb6e27fd935246f70905 Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 2 Dec 2024 14:56:43 +0530 Subject: [PATCH 05/73] remove: `icon-x` button in a read-only view. --- src/lib/components/collapsibleItem.svelte | 7 +- .../billing/+page.svelte | 4 +- .../billing/availableCredit.svelte | 4 +- .../billing/budgetAlert.svelte | 126 ++++--- .../billing/budgetCap.svelte | 12 +- .../billing/paymentHistory.svelte | 246 +++++++------- .../billing/paymentMethods.svelte | 198 +++++------ .../billing/planSummary.svelte | 316 ++++++++++-------- 8 files changed, 497 insertions(+), 416 deletions(-) diff --git a/src/lib/components/collapsibleItem.svelte b/src/lib/components/collapsibleItem.svelte index a16b63460..f98c8845e 100644 --- a/src/lib/components/collapsibleItem.svelte +++ b/src/lib/components/collapsibleItem.svelte @@ -7,12 +7,15 @@ export let noContent = false; export let isInfo = false; export let gap = 16; + + export let style = null; + export let wrapperStyle = null;
  • {#if noContent} -
    -
    +
    +
    diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index d3d6b7fd1..23802e081 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -130,9 +130,7 @@ - {#if $organization?.billingPlan !== BillingPlan.FREE && !!$organization?.billingBudget} - - {/if} + diff --git a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte index b0a1efd7f..6efbb5434 100644 --- a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte +++ b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte @@ -90,7 +90,9 @@ - Available credit + + {$organization?.billingPlan === BillingPlan.FREE ? 'Credit' : 'Available credit'} +

    Appwrite credit will automatically be applied to your next invoice.

    diff --git a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte index a75439aac..9c391398b 100644 --- a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte +++ b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte @@ -1,8 +1,9 @@ - - Payment history +{#if $organization?.billingPlan === BillingPlan.FREE && invoiceList.total > 0} + + Payment history -

    - Transaction history for this organization. Download invoices for more details about your - payments. -

    - - {#if invoiceList.total > 0} - - - Due Date - Status - Amount Due - - - - {#each invoiceList?.invoices as invoice, i} - {@const status = invoice.status} - - - {toLocaleDate(invoice.dueAt)} - - - {#if invoice?.lastError} - +

    + Transaction history for this organization. Download invoices for more details about your + payments. +

    + + {#if invoiceList.total > 0} + + + Due Date + Status + Amount Due + + + + {#each invoiceList?.invoices as invoice, i} + {@const status = invoice.status} + + + {toLocaleDate(invoice.dueAt)} + + + {#if invoice?.lastError} + + (showFailedError = true)} + button> + {status === 'requires_authentication' + ? 'failed' + : status} + + +
  • + The scheduled payment has failed. + + . +
  • + + + {:else} (showFailedError = true)} - button> + warning={status === 'pending'}> {status === 'requires_authentication' ? 'failed' : status} - -
  • - The scheduled payment has failed. . -
  • -
    - - {:else} - - {status === 'requires_authentication' ? 'failed' : status} - - {/if} - - - {formatCurrency(invoice.grossAmount)} - - - - - - (showDropdown[i] = !showDropdown[i])} - event="view_invoice"> - View invoice - - + + {formatCurrency(invoice.grossAmount)} + + + + + + + (showDropdown[i] = !showDropdown[i])} + event="view_invoice"> + View invoice + + { - retryPayment(invoice); showDropdown[i] = !showDropdown[i]; - trackEvent(`click_retry_payment`, { - from: 'button', - source: 'billing_invoice_menu' - }); - }}> - Retry payment - - {/if} - - - - - {/each} - - -
    -

    Total results: {invoiceList?.total ?? 0}

    - -
    - {:else} - -

    - You have no payment history. After you receive your first invoice, you'll see it - here. -

    -
    - {/if} -
    - + }} + event="download_invoice"> + Download PDF + + {#if status === 'overdue' || status === 'failed'} + { + retryPayment(invoice); + showDropdown[i] = !showDropdown[i]; + trackEvent(`click_retry_payment`, { + from: 'button', + source: 'billing_invoice_menu' + }); + }}> + Retry payment + + {/if} + +
    +
    + + {/each} + + +
    +

    Total results: {invoiceList?.total ?? 0}

    + +
    + {:else} + +

    + You have no payment history. After you receive your first invoice, you'll + see it here. +

    +
    + {/if} + + +{/if} diff --git a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte index 4e7bdbcdc..1a7938d24 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte @@ -99,7 +99,6 @@

    View or update your organization payment methods here.

    -

    Default

    {#if $organization?.paymentMethodId} @@ -196,112 +195,115 @@ {/if}
    -
    -

    Backup

    - {#if $organization?.backupPaymentMethodId} - - - - - {#if backupPaymentMethod.userId === $user.$id} + {#if $organization?.billingPlan !== BillingPlan.FREE} + +
    +

    Backup

    + {#if $organization?.backupPaymentMethodId} + + + + + {#if backupPaymentMethod.userId === $user.$id} + { + showEdit = true; + isSelectedBackup = true; + showDropdownBackup = false; + }}> + Edit + + {/if} { - showEdit = true; + showReplace = true; isSelectedBackup = true; showDropdownBackup = false; }}> - Edit + Replace - {/if} - { - showReplace = true; - isSelectedBackup = true; - showDropdownBackup = false; - }}> - Replace - - { - showDelete = true; - isSelectedBackup = true; - showDropdownBackup = false; - }}> - Delete - - - - - {:else} - {@const filteredPaymentMethods = $paymentMethods.paymentMethods.filter( - (o) => !!o.last4 && o.$id !== $organization?.paymentMethodId - )} -
    -
    -
    - - - - {#if $paymentMethods.total} - {#each filteredPaymentMethods as paymentMethod} - { - showDropdownBackup = true; - addBackupPaymentMethod(paymentMethod?.$id); - }}> - -

    - Card ending in {paymentMethod.last4} -

    - -
    -
    - {/each} - {/if} - (showPayment = true)}> - Add new payment method - -
    -
    + Delete + + + + + {:else} + {@const filteredPaymentMethods = $paymentMethods.paymentMethods.filter( + (o) => !!o.last4 && o.$id !== $organization?.paymentMethodId + )} +
    +
    +
    + + + + {#if $paymentMethods.total} + {#each filteredPaymentMethods as paymentMethod} + { + showDropdownBackup = true; + addBackupPaymentMethod(paymentMethod?.$id); + }}> + +

    + Card ending in {paymentMethod.last4} +

    + +
    +
    + {/each} + {/if} + (showPayment = true)}> + Add new payment method + +
    +
    +
    +
    + Add a backup payment method + +
    -
    - Add a backup payment method - -
    -
    -
    - {/if} -
    + + {/if} +
    + {/if}
    diff --git a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte index c84356b75..f356741ad 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte @@ -1,6 +1,6 @@ -{#if isCloud} -
    -
    -

    Premium support

    - {#if isPaid} +
    +

    Support

    + + {#each supportOptions as option} + +
    +

    {option.label}

    +

    - Get personalized support from the Appwrite team from {supportTimings} + {option.description}

    +
    + + {#if option.showSupport} +
    + {#if !isPaid} + + {:else} + + {/if} + +
    + {#if isSupportOnline()} +
    +
    + {:else} + {/if} -
    - {#if $organization?.billingPlan === BillingPlan.FREE} - - {:else} - - {/if} -
    -{/if} -
    -
    -

    Troubleshooting

    + + {/each} -
    - {#key $app.themeInUse} - - {/key} -
    -
    - -
    - - - - +
    + {#key $app.themeInUse} + + {/key}
    -
    -
    -

    Community support

    -

    Get help from our community

    -
    -
      -
    • - -
    • -
    • - -
    • -
    -
    + + diff --git a/src/lib/helpers/date.ts b/src/lib/helpers/date.ts index f8275753b..87bc7dc5f 100644 --- a/src/lib/helpers/date.ts +++ b/src/lib/helpers/date.ts @@ -128,6 +128,11 @@ export const localeTimezoneName = () => { return dateWithTimezone.split(', ')[1]; }; +export const localeShortTimezoneName = () => { + const timezone = localeTimezoneName(); + return timezone.match(/[A-Z]/g)?.join('') || timezone; +}; + export const isSameDay = (date1: Date, date2: Date) => { return ( date1.getFullYear() === date2.getFullYear() && diff --git a/src/lib/layout/header.svelte b/src/lib/layout/header.svelte index 390cad41b..124cbba96 100644 --- a/src/lib/layout/header.svelte +++ b/src/lib/layout/header.svelte @@ -127,7 +127,7 @@ {#if isCloud} - + From e1fa344d3972a7d681ac9dde2548013d849f028d Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 17 Dec 2024 11:09:18 +0530 Subject: [PATCH 12/73] address comments, fix colors. --- src/lib/components/support.svelte | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/lib/components/support.svelte b/src/lib/components/support.svelte index 8ed77f6ec..08e96dbbb 100644 --- a/src/lib/components/support.svelte +++ b/src/lib/components/support.svelte @@ -61,7 +61,7 @@ {#each supportOptions as option}

    {option.label}

    @@ -142,18 +142,21 @@
    - From 25f5bd036ac13bd9d2a16d6cde710b6660c4d08f Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 17 Dec 2024 14:08:03 +0530 Subject: [PATCH 13/73] ci: empty commit From bfa142dc55b4e6983fc1a3b222f64d42c13d9e84 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 18 Dec 2024 09:30:37 +0900 Subject: [PATCH 14/73] Add specification selector into wizard --- src/lib/wizards/functions/cover.svelte | 3 +- .../wizards/functions/createTemplate.svelte | 6 ++- .../steps/templateConfiguration.svelte | 40 +++++++++++++++++++ src/lib/wizards/functions/store.ts | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/lib/wizards/functions/cover.svelte b/src/lib/wizards/functions/cover.svelte index 84f47a74c..28452bf7b 100644 --- a/src/lib/wizards/functions/cover.svelte +++ b/src/lib/wizards/functions/cover.svelte @@ -19,7 +19,8 @@ repositoryBehaviour: 'new', repositoryName: template.id, repositoryPrivate: true, - repositoryId: null + repositoryId: null, + specification: null }); wizard.start(CreateTemplate); } diff --git a/src/lib/wizards/functions/createTemplate.svelte b/src/lib/wizards/functions/createTemplate.svelte index 355a62e47..6017fc46d 100644 --- a/src/lib/wizards/functions/createTemplate.svelte +++ b/src/lib/wizards/functions/createTemplate.svelte @@ -58,7 +58,8 @@ $template.providerRepositoryId || undefined, $template.providerOwner || undefined, runtimeDetail.providerRootDirectory || undefined, - $template.providerVersion || undefined + $template.providerVersion || undefined, + $templateConfig.specification || undefined ); if ($templateConfig.variables) { @@ -78,7 +79,8 @@ customId: !!response.$id, runtime: response.runtime, deployment_type: $templateConfig.repositoryBehaviour, - scopes: $templateConfig.scopes + scopes: $templateConfig.scopes, + specification: $templateConfig.specification }); resetState(); } catch (error) { diff --git a/src/lib/wizards/functions/steps/templateConfiguration.svelte b/src/lib/wizards/functions/steps/templateConfiguration.svelte index 481cd5026..07c35cd91 100644 --- a/src/lib/wizards/functions/steps/templateConfiguration.svelte +++ b/src/lib/wizards/functions/steps/templateConfiguration.svelte @@ -4,6 +4,7 @@ import { FormList, InputSelect, InputText } from '$lib/elements/forms'; import { WizardStep } from '$lib/layout'; import { runtimesList } from '$lib/stores/runtimes'; + import { specificationsList } from '$lib/stores/specifications'; import { template, templateConfig } from '../store'; let showCustomId = false; @@ -12,6 +13,10 @@ if (!$templateConfig.runtime) { throw new Error('Please select a runtime.'); } + + if (!$templateConfig.specification) { + throw new Error('Please select a specification.'); + } } async function loadRuntimes() { @@ -27,6 +32,22 @@ return options; } + + async function loadSpecifications() { + const specificationOptions = (await $specificationsList).specifications.map((size) => ({ + label: + `${size.cpus} CPU, ${size.memory} MB RAM` + + (!size.enabled ? ` (Upgrade to use this)` : ''), + value: size.slug, + disabled: !size.enabled + })); + + if (!$templateConfig.specification && specificationOptions.length > 0) { + $templateConfig.specification = specificationOptions[0].value; + } + + return specificationOptions; + } @@ -61,6 +82,25 @@ {options} bind:value={$templateConfig.runtime} /> {/await} + {#await loadSpecifications()} + + {:then specificationOptions} + + {/await} diff --git a/src/lib/wizards/functions/store.ts b/src/lib/wizards/functions/store.ts index 205c2847e..6ae23d609 100644 --- a/src/lib/wizards/functions/store.ts +++ b/src/lib/wizards/functions/store.ts @@ -15,6 +15,7 @@ export const templateConfig = writable<{ repositoryId: string; execute?: boolean; scopes?: string[]; + specification?: string; }>(); export const repository = writable(); export const installation = writable(); From 21f3d9453774f9565d2ec7816af6a40230ba4a6e Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 18 Dec 2024 12:36:51 +0900 Subject: [PATCH 15/73] Add create manual --- src/lib/wizards/functions/createManual.svelte | 13 ++++++++++++- .../functions/steps/manualDetails.svelte | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/lib/wizards/functions/createManual.svelte b/src/lib/wizards/functions/createManual.svelte index c774c3516..6bcfeba33 100644 --- a/src/lib/wizards/functions/createManual.svelte +++ b/src/lib/wizards/functions/createManual.svelte @@ -37,7 +37,18 @@ undefined, undefined, $createFunction.entrypoint, - $createFunction.commands || undefined + $createFunction.commands || undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + $createFunction.specification ); await sdk.forProject.functions.createDeployment( response.$id, diff --git a/src/lib/wizards/functions/steps/manualDetails.svelte b/src/lib/wizards/functions/steps/manualDetails.svelte index 55fe5655c..b361dfdd1 100644 --- a/src/lib/wizards/functions/steps/manualDetails.svelte +++ b/src/lib/wizards/functions/steps/manualDetails.svelte @@ -6,16 +6,26 @@ import { onMount } from 'svelte'; import { createFunction } from '../store'; import { runtimesList } from '$lib/stores/runtimes'; + import { specificationsList } from '$lib/stores/specifications'; let showCustomId = false; let options = []; + let specificationOptions = []; onMount(async () => { options = (await $runtimesList).runtimes.map((runtime) => ({ label: `${runtime.name} - ${runtime.version}`, value: runtime.$id })); + + specificationOptions = (await $specificationsList).specifications.map((size) => ({ + label: + `${size.cpus} CPU, ${size.memory} MB RAM` + + (!size.enabled ? ` (Upgrade to use this)` : ''), + value: size.slug, + disabled: !size.enabled + })); }); @@ -39,6 +49,15 @@ {options} required /> + + {#if !showCustomId}
    (showCustomId = !showCustomId)}> From c95befed8615eda0e2a2cc2c284349372e8b84f1 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 18 Dec 2024 16:38:28 +0900 Subject: [PATCH 16/73] Add tooltip to specifications --- .../components/specificationsTooltip.svelte | 30 +++++++++++++++++++ .../steps/templateConfiguration.svelte | 7 +++++ 2 files changed, 37 insertions(+) create mode 100644 src/lib/wizards/functions/components/specificationsTooltip.svelte diff --git a/src/lib/wizards/functions/components/specificationsTooltip.svelte b/src/lib/wizards/functions/components/specificationsTooltip.svelte new file mode 100644 index 000000000..701989a4e --- /dev/null +++ b/src/lib/wizards/functions/components/specificationsTooltip.svelte @@ -0,0 +1,30 @@ +
    +
    +

    Additional CPU and RAM are available for Pro and Scale teams.

    +

    + Learn more +

    +
    +
    + + diff --git a/src/lib/wizards/functions/steps/templateConfiguration.svelte b/src/lib/wizards/functions/steps/templateConfiguration.svelte index 07c35cd91..fbce477fb 100644 --- a/src/lib/wizards/functions/steps/templateConfiguration.svelte +++ b/src/lib/wizards/functions/steps/templateConfiguration.svelte @@ -5,7 +5,11 @@ import { WizardStep } from '$lib/layout'; import { runtimesList } from '$lib/stores/runtimes'; import { specificationsList } from '$lib/stores/specifications'; + import { BillingPlan } from '$lib/constants'; + import SpecificationsTooltip from '../components/specificationsTooltip.svelte'; import { template, templateConfig } from '../store'; + import { organization } from '$lib/stores/organization'; + import { isCloud } from '$lib/system'; let showCustomId = false; @@ -99,6 +103,9 @@ required disabled={specificationOptions.length < 1} options={specificationOptions} + popover={isCloud && $organization?.billingPlan === BillingPlan.FREE + ? SpecificationsTooltip + : null} bind:value={$templateConfig.specification} /> {/await} From 557dbba25d986b955d309c9812646486c4d11b75 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 20 Dec 2024 10:56:07 +0900 Subject: [PATCH 17/73] Add tooltips for free users --- .../components/specificationsTooltip.svelte | 40 ++++++++----------- .../functions/steps/manualDetails.svelte | 7 ++++ .../settings/updateRuntime.svelte | 8 +++- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/lib/wizards/functions/components/specificationsTooltip.svelte b/src/lib/wizards/functions/components/specificationsTooltip.svelte index 701989a4e..7b870f376 100644 --- a/src/lib/wizards/functions/components/specificationsTooltip.svelte +++ b/src/lib/wizards/functions/components/specificationsTooltip.svelte @@ -1,30 +1,24 @@ + +
    -
    -

    Additional CPU and RAM are available for Pro and Scale teams.

    -

    - Learn more -

    +

    Additional CPU and RAM are available for Pro and Scale teams.

    +
    + Learn more +
    diff --git a/src/lib/wizards/functions/steps/manualDetails.svelte b/src/lib/wizards/functions/steps/manualDetails.svelte index b361dfdd1..9167474d0 100644 --- a/src/lib/wizards/functions/steps/manualDetails.svelte +++ b/src/lib/wizards/functions/steps/manualDetails.svelte @@ -7,6 +7,10 @@ import { createFunction } from '../store'; import { runtimesList } from '$lib/stores/runtimes'; import { specificationsList } from '$lib/stores/specifications'; + import { isCloud } from '$lib/system'; + import { organization } from '$lib/stores/organization'; + import { BillingPlan } from '$lib/constants'; + import SpecificationsTooltip from '../components/specificationsTooltip.svelte'; let showCustomId = false; @@ -56,6 +60,9 @@ required disabled={specificationOptions.length < 1} options={specificationOptions} + popover={isCloud && $organization?.billingPlan === BillingPlan.FREE + ? SpecificationsTooltip + : null} bind:value={$createFunction.specification} /> {#if !showCustomId} diff --git a/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte b/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte index c447e6e36..a151d3e7a 100644 --- a/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte +++ b/src/routes/(console)/project-[project]/functions/function-[function]/settings/updateRuntime.svelte @@ -3,7 +3,7 @@ import { page } from '$app/stores'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { CardGrid, Heading } from '$lib/components'; - import { Dependencies } from '$lib/constants'; + import { BillingPlan, Dependencies } from '$lib/constants'; import { Button, Form, FormList } from '$lib/elements/forms'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; @@ -14,6 +14,9 @@ import { runtimesList } from '$lib/stores/runtimes'; import { isValueOfStringEnum } from '$lib/helpers/types'; import { Runtime } from '@appwrite.io/console'; + import { isCloud } from '$lib/system'; + import { organization } from '$lib/stores/organization'; + import SpecificationsTooltip from '$lib/wizards/functions/components/specificationsTooltip.svelte'; const functionId = $page.params.function; let runtime: string = null; @@ -105,6 +108,9 @@ placeholder="Select runtime specification" bind:value={specification} options={specificationOptions} + popover={isCloud && $organization?.billingPlan === BillingPlan.FREE + ? SpecificationsTooltip + : null} required hideRequired /> From 89b4496313a3211f6c2b84264157d5f23e1b83df Mon Sep 17 00:00:00 2001 From: ernstmul Date: Fri, 20 Dec 2024 11:02:02 +0100 Subject: [PATCH 18/73] Add check to which plan the org is changing when applying the credits --- src/routes/(console)/apply-credit/+page.svelte | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index 884fd1763..d39827c03 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -189,6 +189,18 @@ $: selectedOrg = $organizationList?.teams?.find( (team) => team.$id === selectedOrgId ) as Organization; + + function getNewBillingPlan(organization: Organization): BillingPlan { + if (organization?.billingPlan === BillingPlan.SCALE) { + return BillingPlan.SCALE; + } else if (campaign?.plan) { + return campaign.plan; + } else { + return BillingPlan.PRO; + } + } + + $: billingPlan = getNewBillingPlan(selectedOrg); From 94576911f51a5f21f01f583a35dfd9b9d420c8e0 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Fri, 20 Dec 2024 11:22:15 +0100 Subject: [PATCH 19/73] Fix typo --- src/lib/components/billing/estimatedTotalBox.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/billing/estimatedTotalBox.svelte b/src/lib/components/billing/estimatedTotalBox.svelte index b7ab73af7..a6c8db6a7 100644 --- a/src/lib/components/billing/estimatedTotalBox.svelte +++ b/src/lib/components/billing/estimatedTotalBox.svelte @@ -64,7 +64,7 @@

    - You'll pay {formatCurrency(estimatedTotal)} now, with our first + You'll pay {formatCurrency(estimatedTotal)} now, with your first billing cycle starting on {!currentPlan.trialDays From 8c36c6202aab9f2d0b52e474ce390667eac35cfd Mon Sep 17 00:00:00 2001 From: ernstmul Date: Fri, 20 Dec 2024 11:24:04 +0100 Subject: [PATCH 20/73] Fix education plan not showing change to pro plan when applying credits --- src/routes/(console)/apply-credit/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index d39827c03..9bc53d5cb 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -280,7 +280,7 @@

    {/if} - {#if selectedOrg?.$id && selectedOrg?.billingPlan !== BillingPlan.FREE} + {#if selectedOrg?.$id && selectedOrg?.billingPlan !== BillingPlan.FREE && selectedOrg?.billingPlan !== BillingPlan.GITHUB_EDUCATION}
    Date: Fri, 20 Dec 2024 13:40:50 +0100 Subject: [PATCH 21/73] Filter the new users count to not include future days --- .../usage/[[invoice]]/+page.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 82c211c19..287d24e61 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -143,9 +143,11 @@ Users

    The total number of users across all projects in your organization.

    - {#if data.organizationUsage.users} + {@const users = data.organizationUsage.users.filter( + (user) => new Date(user.date) < new Date() + )} {@const current = data.organizationUsage.usersTotal} {@const max = getServiceLimit('users', tier, plan)} Date: Fri, 20 Dec 2024 14:00:09 +0100 Subject: [PATCH 22/73] Move users usage data tot .ts --- .../usage/[[invoice]]/+page.svelte | 5 +---- .../organization-[organization]/usage/[[invoice]]/+page.ts | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 287d24e61..636f88fdd 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -145,9 +145,6 @@

    The total number of users across all projects in your organization.

    {#if data.organizationUsage.users} - {@const users = data.organizationUsage.users.filter( - (user) => new Date(user.date) < new Date() - )} {@const current = data.organizationUsage.usersTotal} {@const max = getServiceLimit('users', tier, plan)} { } } + const usersUsageToDate = usage.users.filter((user) => new Date(user.date) < new Date()); + return { organizationUsage: usage, projectNames, invoices, currentInvoice, organizationMembers, - plan + plan, + usersUsageToDate }; }; From 01b4dd1d94cece7c048bf9db5cb6272ddc34ca9f Mon Sep 17 00:00:00 2001 From: ernstmul Date: Mon, 23 Dec 2024 14:09:37 +0100 Subject: [PATCH 23/73] Switch to if statement setup --- src/routes/(console)/apply-credit/+page.svelte | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index 9bc53d5cb..df8a16bf9 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -190,17 +190,11 @@ (team) => team.$id === selectedOrgId ) as Organization; - function getNewBillingPlan(organization: Organization): BillingPlan { - if (organization?.billingPlan === BillingPlan.SCALE) { - return BillingPlan.SCALE; - } else if (campaign?.plan) { - return campaign.plan; - } else { - return BillingPlan.PRO; - } + $: if (selectedOrg?.billingPlan === BillingPlan.SCALE) { + billingPlan = BillingPlan.SCALE; + } else if (campaign?.plan) { + billingPlan = campaign.plan; } - - $: billingPlan = getNewBillingPlan(selectedOrg); From ef116a39d0b8ab45b6dbe2761deaa65518769fca Mon Sep 17 00:00:00 2001 From: ernstmul Date: Mon, 23 Dec 2024 14:27:39 +0100 Subject: [PATCH 24/73] Change to ternary --- src/routes/(console)/+layout.ts | 1 + src/routes/(console)/apply-credit/+page.svelte | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 1f5bbfc3e..0521240c1 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -25,6 +25,7 @@ export const load: LayoutLoad = async ({ fetch, depends, parent }) => { let plansInfo = new Map(); if (isCloud) { const plansArray = await sdk.forConsole.billing.getPlansInfo(); + console.log('plansArray', plansArray); plansInfo = plansArray.plans.reduce((map, plan) => { map.set(plan.$id as Tier, plan); return map; diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index df8a16bf9..95af6175f 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -190,11 +190,10 @@ (team) => team.$id === selectedOrgId ) as Organization; - $: if (selectedOrg?.billingPlan === BillingPlan.SCALE) { - billingPlan = BillingPlan.SCALE; - } else if (campaign?.plan) { - billingPlan = campaign.plan; - } + $: billingPlan = + selectedOrg?.billingPlan === BillingPlan.SCALE + ? BillingPlan.SCALE + : (campaign?.plan ?? BillingPlan.PRO); From b3af21dcfd52c01efccf68a20dfa1bfcb9c63817 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Mon, 23 Dec 2024 15:40:32 +0100 Subject: [PATCH 25/73] Remove console.log --- src/routes/(console)/+layout.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 0521240c1..1f5bbfc3e 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -25,7 +25,6 @@ export const load: LayoutLoad = async ({ fetch, depends, parent }) => { let plansInfo = new Map(); if (isCloud) { const plansArray = await sdk.forConsole.billing.getPlansInfo(); - console.log('plansArray', plansArray); plansInfo = plansArray.plans.reduce((map, plan) => { map.set(plan.$id as Tier, plan); return map; From 38fa2cf5fe22af9032d107a510341fa068c91c88 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 24 Dec 2024 14:23:25 +0100 Subject: [PATCH 26/73] Add new appwrite logo to git authorize page --- .../git/authorize-contributor/+page.svelte | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/routes/(authenticated)/git/authorize-contributor/+page.svelte b/src/routes/(authenticated)/git/authorize-contributor/+page.svelte index 1f6a9f1b9..9e2c270ee 100644 --- a/src/routes/(authenticated)/git/authorize-contributor/+page.svelte +++ b/src/routes/(authenticated)/git/authorize-contributor/+page.svelte @@ -1,5 +1,8 @@ - {#if isCloud} - {#if $organization?.billingPlan === BillingPlan.PRO} - - - New roles are free until 1st January 2025. Learn more. - - {/if} - {/if} Date: Wed, 1 Jan 2025 13:05:40 +0530 Subject: [PATCH 30/73] fix: tests. --- .../(console)/organization-[organization]/createMember.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/createMember.svelte b/src/routes/(console)/organization-[organization]/createMember.svelte index ec06b001c..683501c13 100644 --- a/src/routes/(console)/organization-[organization]/createMember.svelte +++ b/src/routes/(console)/organization-[organization]/createMember.svelte @@ -1,14 +1,14 @@ From eb44a215a33ea68c9b483938f41d0642d60dec97 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Mon, 6 Jan 2025 14:24:24 +0100 Subject: [PATCH 36/73] disable replays --- src/hooks.client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks.client.ts b/src/hooks.client.ts index c6404ee81..bbb414b88 100644 --- a/src/hooks.client.ts +++ b/src/hooks.client.ts @@ -8,7 +8,7 @@ Sentry.init({ dsn: 'https://c7ce178bdedd486480317b72f282fd39@o1063647.ingest.us.sentry.io/4504158071422976', tracesSampleRate: 1, replaysSessionSampleRate: 0, - replaysOnErrorSampleRate: 1, + replaysOnErrorSampleRate: 0, integrations: [Sentry.replayIntegration()] }); From b90ce4218844d5ad3cff8a74ceaf6f635605492c Mon Sep 17 00:00:00 2001 From: ernstmul Date: Mon, 6 Jan 2025 14:26:10 +0100 Subject: [PATCH 37/73] disable replays --- src/hooks.client.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hooks.client.ts b/src/hooks.client.ts index bbb414b88..9c8679912 100644 --- a/src/hooks.client.ts +++ b/src/hooks.client.ts @@ -8,8 +8,7 @@ Sentry.init({ dsn: 'https://c7ce178bdedd486480317b72f282fd39@o1063647.ingest.us.sentry.io/4504158071422976', tracesSampleRate: 1, replaysSessionSampleRate: 0, - replaysOnErrorSampleRate: 0, - integrations: [Sentry.replayIntegration()] + replaysOnErrorSampleRate: 0 }); export const handleError: HandleClientError = Sentry.handleErrorWithSentry( From 15b30c70ea491d0f0954c2a68e0bd0f02533ca11 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Tue, 7 Jan 2025 20:47:22 +0900 Subject: [PATCH 38/73] Update console docs URL --- .../wizards/functions/components/specificationsTooltip.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/wizards/functions/components/specificationsTooltip.svelte b/src/lib/wizards/functions/components/specificationsTooltip.svelte index 7b870f376..5ef18e313 100644 --- a/src/lib/wizards/functions/components/specificationsTooltip.svelte +++ b/src/lib/wizards/functions/components/specificationsTooltip.svelte @@ -10,7 +10,7 @@ class="u-bold u-block" target="_blank" rel="noopener noreferrer" - href="https://appwrite.io/docs/products/functions/specifications">Learn more + href="https://appwrite.io/docs/advanced/platform/specifications">Learn more From a5749c700621afffd16d131472bc1178806b7442 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Tue, 7 Jan 2025 21:55:05 +0900 Subject: [PATCH 39/73] Update docs URL --- .../wizards/functions/components/specificationsTooltip.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/wizards/functions/components/specificationsTooltip.svelte b/src/lib/wizards/functions/components/specificationsTooltip.svelte index 5ef18e313..279f5a0f1 100644 --- a/src/lib/wizards/functions/components/specificationsTooltip.svelte +++ b/src/lib/wizards/functions/components/specificationsTooltip.svelte @@ -10,7 +10,7 @@ class="u-bold u-block" target="_blank" rel="noopener noreferrer" - href="https://appwrite.io/docs/advanced/platform/specifications">Learn more + href="https://appwrite.io/docs/advanced/platform/gb-hours">Learn more From b65eaaa78bd2cb395f85a7e668f3fdda66050c45 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Wed, 8 Jan 2025 10:08:02 +0100 Subject: [PATCH 40/73] Check and handle if the console is visited from the start building pro button on the site --- src/lib/helpers/pricingRedirect.ts | 13 +++++++++++++ .../(console)/create-organization/+page.svelte | 6 +++++- src/routes/(console)/onboarding/+page.svelte | 8 ++------ .../organization-[organization]/+page.svelte | 8 ++------ src/routes/(public)/(guest)/register/+page.svelte | 3 +++ src/routes/+layout.ts | 6 ++++++ 6 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 src/lib/helpers/pricingRedirect.ts diff --git a/src/lib/helpers/pricingRedirect.ts b/src/lib/helpers/pricingRedirect.ts new file mode 100644 index 000000000..5de04212f --- /dev/null +++ b/src/lib/helpers/pricingRedirect.ts @@ -0,0 +1,13 @@ +import { goto } from '$app/navigation'; +import { base } from '$app/paths'; + +export function checkPricingRefAndRedirect(searchParams: URLSearchParams, shouldRegister = false) { + if (searchParams.has('type')) { + const paramType = searchParams.get('type'); + if (paramType === 'createPro') { + shouldRegister + ? goto(`${base}/register?type=createPro`) + : goto(`${base}/create-organization?type=createPro`); + } + } +} diff --git a/src/routes/(console)/create-organization/+page.svelte b/src/routes/(console)/create-organization/+page.svelte index c463a5d4a..63cc1f210 100644 --- a/src/routes/(console)/create-organization/+page.svelte +++ b/src/routes/(console)/create-organization/+page.svelte @@ -79,7 +79,11 @@ billingPlan = plan as BillingPlan; } } - if (anyOrgFree) { + if ( + anyOrgFree || + ($page.url.searchParams.has('type') && + $page.url.searchParams.get('type') === 'createPro') + ) { billingPlan = BillingPlan.PRO; } }); diff --git a/src/routes/(console)/onboarding/+page.svelte b/src/routes/(console)/onboarding/+page.svelte index 3f112011c..b4a9b4aba 100644 --- a/src/routes/(console)/onboarding/+page.svelte +++ b/src/routes/(console)/onboarding/+page.svelte @@ -17,6 +17,7 @@ import { tierToPlan, type Tier, plansInfo } from '$lib/stores/billing'; import { formatCurrency } from '$lib/helpers/numbers'; import { base } from '$app/paths'; + import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect'; let name: string; let id: string; @@ -42,12 +43,7 @@ onMount(() => { if (isCloud) { - if ($page.url.searchParams.has('type')) { - const paramType = $page.url.searchParams.get('type'); - if (paramType === 'createPro') { - goto(`${base}/create-organization`); - } - } + checkPricingRefAndRedirect($page.url.searchParams); } }); diff --git a/src/routes/(console)/organization-[organization]/+page.svelte b/src/routes/(console)/organization-[organization]/+page.svelte index d16339072..76607b429 100644 --- a/src/routes/(console)/organization-[organization]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/+page.svelte @@ -32,6 +32,7 @@ import { onMount } from 'svelte'; import { organization } from '$lib/stores/organization'; import { canWriteProjects } from '$lib/stores/roles'; + import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect'; export let data; @@ -123,12 +124,7 @@ onMount(async () => { if (isCloud) { regions = await sdk.forConsole.billing.listRegions(); - if ($page.url.searchParams.has('type')) { - const paramType = $page.url.searchParams.get('type'); - if (paramType === 'createPro') { - goto(`${base}/create-organization`); - } - } + checkPricingRefAndRedirect($page.url.searchParams); } }); diff --git a/src/routes/(public)/(guest)/register/+page.svelte b/src/routes/(public)/(guest)/register/+page.svelte index f8fab2e6f..96fe43ae0 100644 --- a/src/routes/(public)/(guest)/register/+page.svelte +++ b/src/routes/(public)/(guest)/register/+page.svelte @@ -20,6 +20,7 @@ import { isCloud } from '$lib/system'; import { page } from '$app/stores'; import { redirectTo } from '$routes/store'; + import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect'; export let data; @@ -52,6 +53,8 @@ $page.url.searchParams.delete('redirect'); if (redirect) { await goto(`${redirect}${$page.url.search}`); + } else if (isCloud) { + checkPricingRefAndRedirect($page.url.searchParams); } else { await goto(`${base}/${$page.url.search ?? ''}`); } diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 77fd3e8b1..134ef1e22 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -9,6 +9,8 @@ import { redirectTo } from './store'; import { base } from '$app/paths'; import type { Account } from '$lib/stores/user'; import type { AppwriteException } from '@appwrite.io/console'; +import { isCloud } from '$lib/system'; +import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect'; export const ssr = false; @@ -46,6 +48,10 @@ export const load: LayoutLoad = async ({ depends, url, route }) => { } if (!isPublicRoute) { + if (isCloud) { + checkPricingRefAndRedirect(url.searchParams, true); + } + redirect(303, withParams(`${base}/login`, url.searchParams)); } }; From 62fb063e63428b8186f93da8377e77cd87d5e65e Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 8 Jan 2025 19:05:17 +0530 Subject: [PATCH 41/73] change: upgrade button style. --- .../organization-[organization]/billing/planSummary.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte index d3afdbd58..260338e86 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte @@ -218,7 +218,6 @@ View estimated usage
    diff --git a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte index 06420a1a1..152f7211b 100644 --- a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte +++ b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte @@ -72,7 +72,7 @@ {selectedOption}
    - Beta + Experimental
    {:else} From 3ae83a3b6ef2b86612f924b978ce6c83cd0e176d Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 26 Jun 2024 21:09:09 +0000 Subject: [PATCH 44/73] fix: hide attribute type icon for relationships on mobile The experimental tag is too big for the modal pushing the close button off screen, requiring horizontal scroll. To prevent that, we'll just hide the attribute type icon on the left so there's enough room for the experimental tag and the close button. --- src/lib/components/modal.svelte | 2 ++ .../collection-[collection]/attributes/edit.svelte | 8 +++++++- .../collection-[collection]/createAttribute.svelte | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib/components/modal.svelte b/src/lib/components/modal.svelte index c043fc1dc..cf70c44a6 100644 --- a/src/lib/components/modal.svelte +++ b/src/lib/components/modal.svelte @@ -8,6 +8,7 @@ export let show = false; export let size: 'small' | 'big' | 'huge' = null; export let icon: string = null; + export let iconNotMobile: boolean = false; export let state: 'success' | 'warning' | 'error' | 'info' = null; export let error: string = null; export let closable = true; @@ -39,6 +40,7 @@ {#if icon}
    - +
    {option?.name} diff --git a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte index 152f7211b..f873a94fd 100644 --- a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte +++ b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/createAttribute.svelte @@ -66,7 +66,13 @@ } - + {#if selectedOption === 'Relationship'} From 2b78dc51be4c73407b737bb39af1c5cbeeef876e Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 9 Jan 2025 09:19:47 +0530 Subject: [PATCH 45/73] remove: todo. --- .../organization-[organization]/billing/budgetAlert.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte index cd3e6a4cb..67f0846d4 100644 --- a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte +++ b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte @@ -100,7 +100,6 @@ {:else} - You can set a maximum of 4 billing alerts per organization. From c51bf9cddcf22bcda483447864a321205ed24d1c Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 9 Jan 2025 09:23:44 +0530 Subject: [PATCH 46/73] ci: empty commit From 92c45a5621eeea2489ab7e9f19dcb13baba2c2f9 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:21:53 +0000 Subject: [PATCH 47/73] feat: add sms to usage --- src/lib/sdk/billing.ts | 5 ++ src/lib/stores/billing.ts | 9 +++- .../usage/[[invoice]]/+page.svelte | 53 +++++++++++++++++++ .../usage/[[invoice]]/+page.ts | 4 +- .../usage/[[invoice]]/ProjectBreakdown.svelte | 34 +++++++++--- 5 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 8cb3b58a9..95c9f5c77 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -195,7 +195,11 @@ export type OrganizationUsage = { executions: number; bandwidth: number; users: number; + authPhoneTotal: number; + authPhoneEstimate: number; }>; + authPhoneTotal: number; + authPhoneEstimate: number; }; export type AggregationList = { @@ -270,6 +274,7 @@ export type Plan = { executions: number; realtime: number; logs: number; + authPhone: number; addons: { bandwidth: AdditionalResource; executions: AdditionalResource; diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index c14b4b949..734445daa 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -128,15 +128,20 @@ export type PlanServices = | 'teams' | 'users' | 'usersAddon' - | 'webhooks'; + | 'webhooks' + | 'authPhone'; export function getServiceLimit(serviceId: PlanServices, tier: Tier = null, plan?: Plan): number { + + if (serviceId === 'authPhone') { + return 10; + } if (!isCloud) return 0; if (!serviceId) return 0; const info = get(plansInfo); if (!info) return 0; plan ??= info.get(tier ?? get(organization)?.billingPlan); - return plan?.[serviceId]; + return plan?.[serviceId] ?? 0; } export const failedInvoice = cachedStore< diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 636f88fdd..089bcaa56 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -18,6 +18,8 @@ import { BillingPlan } from '$lib/constants'; import { trackEvent } from '$lib/actions/analytics'; import TotalMembers from './totalMembers.svelte'; + import { tooltip } from '$lib/actions/tooltip'; + import { formatCurrency } from '$lib/helpers/numbers'; export let data; @@ -376,6 +378,57 @@ {/if} + + SMS OTP +

    + OTPs are billed per SMS message, with rates varying by recipient country. For a detailed + cost breakdown, see the pricing page. +

    + + {#if data.organizationUsage.authPhoneTotal} +
    +

    + {formatNum(data.organizationUsage.authPhoneTotal)} + SMS OTPs +

    +

    + Estimated cost + + {formatCurrency(data.organizationUsage.authPhoneEstimate)} + + +

    +
    + + {#if project?.length > 0} + + {/if} + {:else} + +
    +
    +
    + {/if} +
    +

    diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts index 74dffcda2..65bc7ca86 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts @@ -27,7 +27,9 @@ export const load: PageLoad = async ({ params, parent }) => { executionsTotal: null, projects: null, executionsMBSecondsTotal: null, - buildsMBSecondsTotal: null + buildsMBSecondsTotal: null, + authPhoneTotal: null, + authPhoneEstimate: null, } }; } diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index 5516b61b7..aaba05954 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -10,41 +10,52 @@ TableRowLink, TableScroll } from '$lib/elements/table'; - import { abbreviateNumber } from '$lib/helpers/numbers'; + import { abbreviateNumber, formatCurrency } from '$lib/helpers/numbers'; import { humanFileSize } from '$lib/helpers/sizeConvertion'; import type { OrganizationUsage } from '$lib/sdk/billing'; import { base } from '$app/paths'; import { canSeeProjects } from '$lib/stores/roles'; - type Metric = 'users' | 'storage' | 'bandwidth' | 'executions'; + type Metric = 'users' | 'storage' | 'bandwidth' | 'executions' | 'authPhoneTotal'; + type Estimate = 'authPhoneEstimate'; + export let data: PageData; export let projects: OrganizationUsage['projects']; export let metric: Metric; + export let estimate: Estimate | undefined = undefined; function getProjectUsageLink(projectId: string): string { return `${base}/project-${projectId}/settings/usage`; } - function groupByProject(metric: Metric): Array<{ projectId: string; usage: number }> { + function groupByProject( + metric: Metric, + estimate?: Estimate + ): Array<{ projectId: string; usage: number; estimate?: number }> { const data = []; for (const project of projects) { const usage = project[metric]; + if (!usage) { + continue; + } data.push({ projectId: project.projectId, - usage: usage ?? 0 + usage: usage ?? 0, + estimate: estimate ? project[estimate] : undefined }); } return data; } function format(value: number): string { - const humanized = humanFileSize(value); switch (metric) { + case 'authPhoneTotal': case 'executions': case 'users': return abbreviateNumber(value); case 'storage': case 'bandwidth': + const humanized = humanFileSize(value); return humanized.value + humanized.unit; } } @@ -57,18 +68,25 @@ Project Usage + {#if estimate} + Estimated Cost + {/if} {#if $canSeeProjects} {/if} - {#each groupByProject(metric).sort((a, b) => b.usage - a.usage) as project} + {#each groupByProject(metric, estimate).sort((a, b) => b.usage - a.usage) as project} {#if !$canSeeProjects} {data.projectNames[project.projectId]?.name ?? 'Unknown'} {format(project.usage)} + {#if project.estimate} + {formatCurrency(project.estimate)} + {/if} {:else} @@ -76,6 +94,10 @@ {data.projectNames[project.projectId]?.name ?? 'Unknown'} {format(project.usage)} + {#if project.estimate} + {formatCurrency(project.estimate)} + {/if} From d496093bb4223786819921888592d73eb8aa3d2f Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:25:03 +0000 Subject: [PATCH 48/73] chore: fmt --- src/lib/stores/billing.ts | 1 - .../organization-[organization]/usage/[[invoice]]/+page.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 734445daa..5c4b4bee9 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -132,7 +132,6 @@ export type PlanServices = | 'authPhone'; export function getServiceLimit(serviceId: PlanServices, tier: Tier = null, plan?: Plan): number { - if (serviceId === 'authPhone') { return 10; } diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts index 65bc7ca86..4138acfa1 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts @@ -29,7 +29,7 @@ export const load: PageLoad = async ({ params, parent }) => { executionsMBSecondsTotal: null, buildsMBSecondsTotal: null, authPhoneTotal: null, - authPhoneEstimate: null, + authPhoneEstimate: null } }; } From 9f68ee7e0f70d5f2ef4046f0d35bf8c6f98252df Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:33:33 +0000 Subject: [PATCH 49/73] fix: eslint --- .../usage/[[invoice]]/ProjectBreakdown.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index aaba05954..8b6306293 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -55,8 +55,7 @@ return abbreviateNumber(value); case 'storage': case 'bandwidth': - const humanized = humanFileSize(value); - return humanized.value + humanized.unit; + return humanFileSize(value).value + humanFileSize(value).unit; } } From 3b9c702c76d7215de0ef411465fcb3a0f7840b0b Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:01:36 +0000 Subject: [PATCH 50/73] fix: copy --- .../organization-[organization]/usage/[[invoice]]/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 089bcaa56..a68b0452e 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -403,7 +403,7 @@ class="icon-info u-color-text-offline" use:tooltip={{ content: - 'The first 10 SMS OTP messages are provided at no cost. Pricing may vary as it depends on telecom rates and vendor agreements.' + 'The first 10 SMS OTP messages each month are provided at no cost. Pricing may vary as it depends on telecom rates and vendor agreements.' }} />

    From d8ae8f6ec1c4c263b2807acde6f0acc797fa2486 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:13:10 +0000 Subject: [PATCH 51/73] chore: design review --- src/lib/components/collapsibleItem.svelte | 2 +- .../usage/[[invoice]]/ProjectBreakdown.svelte | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/components/collapsibleItem.svelte b/src/lib/components/collapsibleItem.svelte index 92dd4e13d..075b4431f 100644 --- a/src/lib/components/collapsibleItem.svelte +++ b/src/lib/components/collapsibleItem.svelte @@ -58,7 +58,7 @@ // TODO: remove once pink is updated .collapsible-item:not(.is-info) { .collapsible-wrapper { - padding-left: 0.5rem; + padding-left: 0rem; } .collapsible-wrapper.is-disabled { cursor: not-allowed; diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index 8b6306293..b0d979b5c 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -61,9 +61,9 @@ - + Project breakdown - + Project Usage From aee8bbd183e4dfe64ef2d7fe24a965161b42cae6 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:29:11 +0000 Subject: [PATCH 52/73] fix: right padding --- src/lib/components/collapsibleItem.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/collapsibleItem.svelte b/src/lib/components/collapsibleItem.svelte index 075b4431f..7cc30bca0 100644 --- a/src/lib/components/collapsibleItem.svelte +++ b/src/lib/components/collapsibleItem.svelte @@ -58,7 +58,7 @@ // TODO: remove once pink is updated .collapsible-item:not(.is-info) { .collapsible-wrapper { - padding-left: 0rem; + padding: 0; } .collapsible-wrapper.is-disabled { cursor: not-allowed; From 5c1240e8b19d613208dab86ad99b984111cee66e Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 16:00:20 +0000 Subject: [PATCH 53/73] ui: deadline warning --- .../organization-[organization]/usage/[[invoice]]/+page.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index a68b0452e..00cff028b 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -387,6 +387,7 @@ class="link">pricing page.

    +

    You will not be charged for SMS OTP for messages before February 10th

    {#if data.organizationUsage.authPhoneTotal}
    From 90036b32ab0b4016d221880978fb36b82b7d5ab3 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 16:00:55 +0000 Subject: [PATCH 54/73] ui: breakdown title --- .../usage/[[invoice]]/ProjectBreakdown.svelte | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index b0d979b5c..e591da973 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -24,6 +24,15 @@ export let metric: Metric; export let estimate: Estimate | undefined = undefined; + function getMetricTitle(metric: Metric): string { + switch (metric) { + case 'authPhoneTotal': + return 'Amount'; + default: + return 'Usage'; + } + } + function getProjectUsageLink(projectId: string): string { return `${base}/project-${projectId}/settings/usage`; } @@ -50,6 +59,7 @@ function format(value: number): string { switch (metric) { case 'authPhoneTotal': + return value.toString(); case 'executions': case 'users': return abbreviateNumber(value); @@ -61,14 +71,14 @@ - + Project breakdown Project - Usage + {getMetricTitle(metric)} {#if estimate} - Estimated Cost + Estimated cost {/if} {#if $canSeeProjects} @@ -81,9 +91,10 @@ {data.projectNames[project.projectId]?.name ?? 'Unknown'} - {format(project.usage)} + {format(project.usage)} {#if project.estimate} - {formatCurrency(project.estimate)} {/if} @@ -92,9 +103,10 @@ {data.projectNames[project.projectId]?.name ?? 'Unknown'} - {format(project.usage)} + {format(project.usage)} {#if project.estimate} - {formatCurrency(project.estimate)} {/if} From 760122d4e4d43e1dde72b9826a5591379e8f2015 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:19:14 +0000 Subject: [PATCH 55/73] feat: project level --- src/lib/helpers/diallingCodes.ts | 191 ++++++++++++++++++ src/lib/sdk/usage.ts | 15 ++ .../usage/[[invoice]]/+page.svelte | 4 +- .../usage/[[invoice]]/ProjectBreakdown.svelte | 4 +- .../settings/usage/[[invoice]]/+page.svelte | 69 +++++++ 5 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 src/lib/helpers/diallingCodes.ts diff --git a/src/lib/helpers/diallingCodes.ts b/src/lib/helpers/diallingCodes.ts new file mode 100644 index 000000000..dab27f26f --- /dev/null +++ b/src/lib/helpers/diallingCodes.ts @@ -0,0 +1,191 @@ +const dialingCodes = { + '213': 'Algeria', + '376': 'Andorra', + '244': 'Angola', + '54': 'Argentina', + '374': 'Armenia', + '297': 'Aruba', + '61': 'Australia', + '43': 'Austria', + '994': 'Azerbaijan', + '973': 'Bahrain', + '880': 'Bangladesh', + '375': 'Belarus', + '32': 'Belgium', + '501': 'Belize', + '229': 'Benin', + '975': 'Bhutan', + '591': 'Bolivia', + '387': 'Bosnia and Herzegovina', + '267': 'Botswana', + '55': 'Brazil', + '673': 'Brunei', + '359': 'Bulgaria', + '226': 'Burkina Faso', + '257': 'Burundi', + '855': 'Cambodia', + '237': 'Cameroon', + '1': 'North America', + '238': 'Cape Verde Islands', + '56': 'Chile', + '86': 'China', + '57': 'Colombia', + '269': 'Comoros and Mayotte', + '242': 'Congo', + '682': 'Cook Islands', + '506': 'Costa Rica', + '385': 'Croatia', + '53': 'Cuba', + '357': 'Cyprus', + '420': 'Czech Republic', + '45': 'Denmark', + '253': 'Djibouti', + '593': 'Ecuador', + '20': 'Egypt', + '503': 'El Salvador', + '240': 'Equatorial Guinea', + '291': 'Eritrea', + '372': 'Estonia', + '251': 'Ethiopia', + '500': 'Falkland Islands', + '298': 'Faroe Islands', + '679': 'Fiji', + '358': 'Finland', + '33': 'France', + '594': 'French Guiana', + '689': 'French Polynesia', + '241': 'Gabon', + '220': 'Gambia', + '995': 'Georgia', + '49': 'Germany', + '233': 'Ghana', + '350': 'Gibraltar', + '30': 'Greece', + '299': 'Greenland', + '590': 'Guadeloupe', + '1671': 'Guam', + '502': 'Guatemala', + '224': 'Guinea', + '245': 'Guinea-Bissau', + '592': 'Guyana', + '509': 'Haiti', + '504': 'Honduras', + '852': 'Hong Kong', + '36': 'Hungary', + '354': 'Iceland', + '91': 'India', + '62': 'Indonesia', + '98': 'Iran', + '964': 'Iraq', + '353': 'Ireland', + '972': 'Israel', + '39': 'Italy', + '81': 'Japan', + '962': 'Jordan', + '254': 'Kenya', + '686': 'Kiribati', + '850': 'North Korea', + '82': 'South Korea', + '965': 'Kuwait', + '996': 'Kyrgyzstan', + '856': 'Laos', + '371': 'Latvia', + '961': 'Lebanon', + '266': 'Lesotho', + '231': 'Liberia', + '218': 'Libya', + '423': 'Liechtenstein', + '370': 'Lithuania', + '352': 'Luxembourg', + '853': 'Macao', + '389': 'Macedonia', + '261': 'Madagascar', + '265': 'Malawi', + '60': 'Malaysia', + '960': 'Maldives', + '223': 'Mali', + '356': 'Malta', + '692': 'Marshall Islands', + '596': 'Martinique', + '222': 'Mauritania', + '52': 'Mexico', + '691': 'Micronesia', + '373': 'Moldova', + '377': 'Monaco', + '976': 'Mongolia', + '212': 'Morocco', + '258': 'Mozambique', + '95': 'Myanmar', + '264': 'Namibia', + '674': 'Nauru', + '977': 'Nepal', + '31': 'Netherlands', + '687': 'New Caledonia', + '64': 'New Zealand', + '505': 'Nicaragua', + '227': 'Niger', + '234': 'Nigeria', + '683': 'Niue', + '672': 'Norfolk Islands', + '1670': 'Northern Mariana Islands', + '47': 'Norway', + '968': 'Oman', + '680': 'Palau', + '507': 'Panama', + '675': 'Papua New Guinea', + '595': 'Paraguay', + '51': 'Peru', + '63': 'Philippines', + '48': 'Poland', + '351': 'Portugal', + '974': 'Qatar', + '262': 'Reunion', + '40': 'Romania', + '7': 'Russia, Kazakhstan, Uzbekistan, Turkmenistan, and Tajikistan', + '250': 'Rwanda', + '378': 'San Marino', + '239': 'Sao Tome and Principe', + '966': 'Saudi Arabia', + '221': 'Senegal', + '381': 'Serbia', + '248': 'Seychelles', + '232': 'Sierra Leone', + '65': 'Singapore', + '421': 'Slovak Republic', + '386': 'Slovenia', + '677': 'Solomon Islands', + '252': 'Somalia', + '27': 'South Africa', + '34': 'Spain', + '94': 'Sri Lanka', + '290': 'St. Helena', + '249': 'Sudan', + '597': 'Suriname', + '268': 'Swaziland', + '46': 'Sweden', + '41': 'Switzerland', + '963': 'Syria', + '886': 'Taiwan', + '66': 'Thailand', + '228': 'Togo', + '676': 'Tonga', + '216': 'Tunisia', + '90': 'Turkey', + '688': 'Tuvalu', + '256': 'Uganda', + '380': 'Ukraine', + '971': 'United Arab Emirates', + '44': 'United Kingdom', + '598': 'Uruguay', + '678': 'Vanuatu', + '58': 'Venezuela', + '84': 'Vietnam', + '967': 'Yemen', + '260': 'Zambia', + '255': 'Zanzibar', + '263': 'Zimbabwe' +}; + +export function getCountryName(diallingCode: string): string { + return dialingCodes[diallingCode] ?? 'Unknown'; +} diff --git a/src/lib/sdk/usage.ts b/src/lib/sdk/usage.ts index f47e14341..304bad1f6 100644 --- a/src/lib/sdk/usage.ts +++ b/src/lib/sdk/usage.ts @@ -299,4 +299,19 @@ export type UsageProject = { * Aggregated statistics of total number of buckets. */ bucketsTotal: number; + + /** + * Aggregated statistics of total number of SMS sent. + */ + authPhoneTotal: number; + + /** + * Aggregated statistics of estimated SMS cost. + */ + authPhoneEstimate: number; + + /** + * Aggregated statistics of total number SMS by country + */ + authPhoneCountriesBreakdown: Models.MetricBreakdown[]; }; diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 00cff028b..697c0dcf5 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -19,7 +19,7 @@ import { trackEvent } from '$lib/actions/analytics'; import TotalMembers from './totalMembers.svelte'; import { tooltip } from '$lib/actions/tooltip'; - import { formatCurrency } from '$lib/helpers/numbers'; + import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers'; export let data; @@ -393,7 +393,7 @@

    {formatNum(data.organizationUsage.authPhoneTotal)} + >{formatNumberWithCommas(data.organizationUsage.authPhoneTotal)} SMS OTPs

    diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index e591da973..8542fe75c 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -10,7 +10,7 @@ TableRowLink, TableScroll } from '$lib/elements/table'; - import { abbreviateNumber, formatCurrency } from '$lib/helpers/numbers'; + import { abbreviateNumber, formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers'; import { humanFileSize } from '$lib/helpers/sizeConvertion'; import type { OrganizationUsage } from '$lib/sdk/billing'; import { base } from '$app/paths'; @@ -59,7 +59,7 @@ function format(value: number): string { switch (metric) { case 'authPhoneTotal': - return value.toString(); + return formatNumberWithCommas(value); case 'executions': case 'users': return abbreviateNumber(value); diff --git a/src/routes/(console)/project-[project]/settings/usage/[[invoice]]/+page.svelte b/src/routes/(console)/project-[project]/settings/usage/[[invoice]]/+page.svelte index d7666f5bc..c24e99a60 100644 --- a/src/routes/(console)/project-[project]/settings/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/project-[project]/settings/usage/[[invoice]]/+page.svelte @@ -2,6 +2,7 @@ import { Container } from '$lib/layout'; import { CardGrid, Heading, Card, ProgressBarBig } from '$lib/components'; import { + TableRow, TableBody, TableCell, TableCellHead, @@ -18,6 +19,10 @@ import { total } from '$lib/layout/usage.svelte'; import { BillingPlan } from '$lib/constants.js'; import { base } from '$app/paths'; + import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers'; + import Collapsible from '$lib/components/collapsible.svelte'; + import CollapsibleItem from '$lib/components/collapsibleItem.svelte'; + import { getCountryName } from '$lib/helpers/diallingCodes.js'; export let data; @@ -380,6 +385,70 @@ {/if} + + SMS OTP + +

    + Calculated for all SMS OTP sent across your project. Resets at the start of each billing + cycle. +

    + + {#if data.usage.authPhoneTotal} +
    +

    + {formatNumberWithCommas(data.usage.authPhoneTotal)} + SMS OTPs +

    +

    + Estimated cost + + {formatCurrency(data.usage.authPhoneEstimate)} + +

    +
    + {#if data.usage.authPhoneCountryBreakdown.length > 0} + + + Region breakdown + + + Region + Amount + Estimated cost + + + {#each data.usage.authPhoneCountryBreakdown as phone} + + + {getCountryName(phone.name)} + + + {formatNumberWithCommas(phone.value)} + + + {formatCurrency(phone.estimate)} + + + {/each} + +
    +
    +
    + {/if} + {:else} + +
    +
    +
    + {/if} +
    +

    Metrics are estimates updated every 24 hours and may not accurately reflect your invoice.

    From af828c92f56a327e948ff948b31a0505c7217542 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:27:15 +0000 Subject: [PATCH 56/73] chore: remove service limit --- src/lib/stores/billing.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 5c4b4bee9..9b42358d1 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -132,9 +132,6 @@ export type PlanServices = | 'authPhone'; export function getServiceLimit(serviceId: PlanServices, tier: Tier = null, plan?: Plan): number { - if (serviceId === 'authPhone') { - return 10; - } if (!isCloud) return 0; if (!serviceId) return 0; const info = get(plansInfo); From f8712c3ea4904de8465f45620da788b8efe9adcc Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Thu, 9 Jan 2025 12:50:56 -0800 Subject: [PATCH 57/73] fix(avatars): fall back to email if name is empty The fetch avatar API won't render properly if an empty string is provided for the name so we should fall back to the email if the name is empty. --- src/lib/layout/header.svelte | 4 ++-- src/routes/(console)/account/header.svelte | 2 +- src/routes/(console)/account/organizations/+page.svelte | 2 +- .../(console)/organization-[organization]/header.svelte | 2 +- .../organization-[organization]/settings/+page.svelte | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/layout/header.svelte b/src/lib/layout/header.svelte index 390cad41b..5158456e7 100644 --- a/src/lib/layout/header.svelte +++ b/src/lib/layout/header.svelte @@ -156,9 +156,9 @@ {#if $user}
    diff --git a/src/routes/(console)/account/organizations/+page.svelte b/src/routes/(console)/account/organizations/+page.svelte index 04404d65c..37aafa8cb 100644 --- a/src/routes/(console)/account/organizations/+page.svelte +++ b/src/routes/(console)/account/organizations/+page.svelte @@ -28,7 +28,7 @@ const getMemberships = async (teamId: string) => { const memberships = await sdk.forConsole.teams.listMemberships(teamId); - return memberships.memberships.map((team) => team.userName); + return memberships.memberships.map((team) => team.userName || team.userEmail); }; function isCloudOrg( diff --git a/src/routes/(console)/organization-[organization]/header.svelte b/src/routes/(console)/organization-[organization]/header.svelte index 090c9b82a..c2438d1f3 100644 --- a/src/routes/(console)/organization-[organization]/header.svelte +++ b/src/routes/(console)/organization-[organization]/header.svelte @@ -58,7 +58,7 @@ } else newOrgModal.set(true); } - $: avatars = $members.memberships?.map((m) => m.userName) ?? []; + $: avatars = $members.memberships?.map((m) => m.userName || m.userEmail) ?? []; $: organizationId = $page.params.organization; $: path = `${base}/organization-${organizationId}`; $: tabs = [ diff --git a/src/routes/(console)/organization-[organization]/settings/+page.svelte b/src/routes/(console)/organization-[organization]/settings/+page.svelte index c70eb1a8e..98b236e6d 100644 --- a/src/routes/(console)/organization-[organization]/settings/+page.svelte +++ b/src/routes/(console)/organization-[organization]/settings/+page.svelte @@ -42,7 +42,7 @@ } } - $: avatars = $members.memberships.map((team) => team.userName); + $: avatars = $members.memberships.map((m) => m.userName || m.userEmail); $: orgProjects = `${$projects.total} ${$projects.total === 1 ? 'project' : 'projects'}`; $: orgMembers = `${$organization.total} ${$organization.total === 1 ? 'member' : 'members'}`; From dff6ecd6ef924247b7634b05b7f036f1dbc81696 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 10 Jan 2025 14:52:59 +0530 Subject: [PATCH 58/73] address comments. --- .../billing/budgetAlert.svelte | 11 ++++++----- .../billing/paymentMethods.svelte | 3 +-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte index 67f0846d4..f2881c78b 100644 --- a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte +++ b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte @@ -3,7 +3,7 @@ import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Alert, CardGrid, Heading } from '$lib/components'; import { BillingPlan, Dependencies } from '$lib/constants'; - import { upgradeURL } from '$lib/stores/billing'; + import { tierToPlan, upgradeURL } from '$lib/stores/billing'; import { Button, Form, FormList, InputSelectSearch } from '$lib/elements/forms'; import { Table, @@ -82,16 +82,17 @@ Billing alerts

    - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE || $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION} Get notified by email when your organization meets a percentage of your budget cap. Free organizations will receive one notification at 75% resource usage. + >{tierToPlan($organization.billingPlan).name} organizations will receive one notification + at 75% resource usage. {:else} Get notified by email when your organization meets or exceeds a percentage of your specified billing alert(s). {/if}

    - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE || $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION} Billing alerts are a Pro plan feature @@ -156,7 +157,7 @@ - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE || $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION}
    - {#if $organization?.billingPlan !== BillingPlan.FREE} - + {#if $organization?.billingPlan !== BillingPlan.FREE && $organization?.billingPlan !== BillingPlan.GITHUB_EDUCATION}
    {#if $organization?.backupPaymentMethodId}

    Backup

    From be917bd88dedaf6a5e4da149d3ea2f7deada3a83 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 10 Jan 2025 15:02:47 +0530 Subject: [PATCH 59/73] add: tooltip. --- .../billing/paymentMethods.svelte | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte index 892c7c017..ebffd5426 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte @@ -20,6 +20,7 @@ import DeleteOrgPayment from './deleteOrgPayment.svelte'; import ReplaceCard from './replaceCard.svelte'; import EditPaymentModal from '$routes/(console)/account/payments/editPaymentModal.svelte'; + import { tooltip } from '$lib/actions/tooltip'; import PaymentModal from '$lib/components/billing/paymentModal.svelte'; import { user } from '$lib/stores/user'; @@ -249,20 +250,29 @@
    - +
    + + +
    {#if $paymentMethods.total} {#each filteredPaymentMethods as paymentMethod} From 8811fa12d86d2e1e26a22f5302d7cee3ddd3ebdc Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 10 Jan 2025 12:54:29 +0000 Subject: [PATCH 60/73] chore: bump console sdk --- package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index f189113b9..6386a59f2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "e2e:ui": "playwright test tests/e2e --ui" }, "dependencies": { - "@appwrite.io/console": "1.4.4", + "@appwrite.io/console": "^1.4.6", "@appwrite.io/pink": "0.25.0", "@appwrite.io/pink-icons": "0.25.0", "@popperjs/core": "^2.11.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 627a97cc9..c7575548e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@appwrite.io/console': - specifier: 1.4.4 - version: 1.4.4 + specifier: ^1.4.6 + version: 1.4.6 '@appwrite.io/pink': specifier: 0.25.0 version: 0.25.0 @@ -95,7 +95,7 @@ importers: version: 6.6.3 '@testing-library/svelte': specifier: ^5.2.4 - version: 5.2.4(svelte@4.2.19)(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0))(vitest@1.6.0(@types/node@22.9.0)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.81.0)) + version: 5.2.4(svelte@4.2.19)(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0))(vitest@1.6.0) '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) @@ -199,8 +199,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@1.4.4': - resolution: {integrity: sha512-0B7PEHJIi0eS8+WQOs7RNwY+j3gffMTz6DKyvZAEJbe4550UnmTn4i8pxmyaiEVbhlqIVZ+QD8jVrjXqtkPK6Q==} + '@appwrite.io/console@1.4.6': + resolution: {integrity: sha512-oGA5gkecpy9E/fKJkaGn26JP9mgknc2Vn8hS6xhRBhmUPg8Vqlz0vgPpx1EQbPB2C5HWIf4yToSicOH31XGx6Q==} '@appwrite.io/pink-icons@0.25.0': resolution: {integrity: sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q==} @@ -3834,7 +3834,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@1.4.4': {} + '@appwrite.io/console@1.4.6': {} '@appwrite.io/pink-icons@0.25.0': {} @@ -5075,7 +5075,7 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/svelte@5.2.4(svelte@4.2.19)(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0))(vitest@1.6.0(@types/node@22.9.0)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.81.0))': + '@testing-library/svelte@5.2.4(svelte@4.2.19)(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0))(vitest@1.6.0)': dependencies: '@testing-library/dom': 10.4.0 svelte: 4.2.19 From 5294517128201b4a7c59ce06a0b2c81547466e3a Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 10 Jan 2025 18:30:53 +0530 Subject: [PATCH 61/73] address comments, fix styles. --- src/lib/components/support.svelte | 184 ++++++++++-------- src/lib/layout/header.svelte | 19 +- .../wizard/support/mobileSupportModal.svelte | 24 ++- 3 files changed, 136 insertions(+), 91 deletions(-) diff --git a/src/lib/components/support.svelte b/src/lib/components/support.svelte index d1b48681e..6514b1765 100644 --- a/src/lib/components/support.svelte +++ b/src/lib/components/support.svelte @@ -9,9 +9,12 @@ import { Card } from '$lib/components/index'; import { app } from '$lib/stores/app'; import { currentPlan } from '$lib/stores/organization'; + import { isCloud } from '$lib/system'; export let show = false; + export let showHeader = true; + $: hasPremiumSupport = $currentPlan?.premiumSupport ?? false; $: supportTimings = `${utcHourToLocaleHour('16:00')} - ${utcHourToLocaleHour('00:00')} ${localeShortTimezoneName()}`; @@ -46,97 +49,108 @@ cta: 'Open issue', showSupport: false, label: 'Open GitHub issue', - link: 'https://github.com/appwrite', + link: 'https://github.com/appwrite/appwrite/issues/new/choose', description: 'Report a bug or pitch a new feature' } ]; + + const showCloudSupport = (index) => { + return (index === 0 && isCloud) || index > 0; + };
    -

    Support

    + {#if showHeader} +

    Support

    + {/if} - {#each supportOptions as option} - -
    -

    {option.label}

    + {#each supportOptions as option, index} + {#if showCloudSupport(index)} + +
    +

    {option.label}

    -

    - {option.description} -

    -
    +

    + {option.description} +

    +
    - {#if option.showSupport} -
    - {#if !hasPremiumSupport} - - {:else} - - {/if} - -
    - {#if isSupportOnline()} -
    - {:else} - - {/if} - + {:else} + + {/if} + + {/if} {/each} -
    - {#key $app.themeInUse} - - {/key} -
    + {#if isCloud} +
    + {#key $app.themeInUse} + + {/key} +
    + {/if}
    diff --git a/src/lib/layout/header.svelte b/src/lib/layout/header.svelte index 124cbba96..4818efd2e 100644 --- a/src/lib/layout/header.svelte +++ b/src/lib/layout/header.svelte @@ -125,17 +125,14 @@
    - - {#if isCloud} - - - - - - - {/if} + + + + + +