From 8a78c414c331cc6fc4284f8dd53cb4bf355bbccd Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 16 Aug 2024 19:18:29 +0900 Subject: [PATCH 01/14] 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/14] 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/14] 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/14] 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 bfa142dc55b4e6983fc1a3b222f64d42c13d9e84 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 18 Dec 2024 09:30:37 +0900 Subject: [PATCH 05/14] 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 06/14] 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 07/14] 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 08/14] 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 cedc1af747e9c1dfb3a2d4190f4a10e6e6ff99f1 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 30 Dec 2024 15:17:05 +0000 Subject: [PATCH 09/14] Update specification label --- .../functions/function-[function]/settings/updateRuntime.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a151d3e7a..1f06dbe9c 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 @@ -103,7 +103,7 @@ required hideRequired /> Date: Mon, 6 Jan 2025 14:24:24 +0100 Subject: [PATCH 10/14] 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 11/14] 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 12/14] 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 13/14] 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 14/14] 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)); } };