From 4e2290009b7ae13d174878950fcb386872a8e000 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Tue, 21 Apr 2026 18:41:28 +0530 Subject: [PATCH 1/3] feat: add deployment retention settings --- src/lib/actions/analytics.ts | 2 + .../function-[function]/settings/+page.svelte | 2 + .../settings/updateDeploymentRetention.svelte | 101 ++++++++++++++++++ .../sites/site-[site]/settings/+page.svelte | 2 + .../settings/updateDeploymentRetention.svelte | 96 +++++++++++++++++ 5 files changed, 203 insertions(+) create mode 100644 src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte create mode 100644 src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index 0ca802658..e8502b5e7 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -321,6 +321,7 @@ export enum Submit { FunctionUpdateScopes = 'submit_function_key_update_scopes', FunctionUpdateRuntime = 'submit_function_update_runtime', FunctionUpdateBuildCommand = 'submit_function_update_build_command', + FunctionUpdateDeploymentRetention = 'submit_function_update_deployment_retention', FunctionConnectRepo = 'submit_function_connect_repo', FunctionDisconnectRepo = 'submit_function_disconnect_repo', FunctionRedeploy = 'submit_function_redeploy', @@ -443,6 +444,7 @@ export enum Submit { SiteUpdateScopes = 'submit_site_key_update_scopes', SiteUpdateBuildSettings = 'submit_site_update_build_settings', SiteUpdateResourceLimits = 'submit_site_update_resource_limits', + SiteUpdateDeploymentRetention = 'submit_site_update_deployment_retention', SiteUpdateSinglePageApplication = 'submit_site_update_single_page_application', SiteConnectRepo = 'submit_site_connect_repo', SiteRedeploy = 'submit_site_redeploy', diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/+page.svelte index 3c69a5099..cdfb04752 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/+page.svelte @@ -19,6 +19,7 @@ import UpdateRepository from './updateRepository.svelte'; import UpdateBuildCommand from './updateBuildCommand.svelte'; import UpdateResourceLimits from './updateResourceLimits.svelte'; + import UpdateDeploymentRetention from './updateDeploymentRetention.svelte'; import { isCloud } from '$lib/system'; import UpdateVariables from '$routes/(console)/project-[region]-[project]/updateVariables.svelte'; import { page } from '$app/state'; @@ -108,6 +109,7 @@ project={data.project} analyticsSource="function_settings" /> + {#if isCloud} diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte new file mode 100644 index 000000000..26193759c --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte @@ -0,0 +1,101 @@ + + +
+ + Deployment retention + Automatically delete inactive deployments after a set number of days. Active deployments are never + deleted. + + + + + + + + + +
diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.svelte index fc9763be7..e91e06eeb 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.svelte @@ -16,6 +16,7 @@ import UpdateResourceLimits from './updateResourceLimits.svelte'; import UpdateVariables from '$routes/(console)/project-[region]-[project]/updateVariables.svelte'; import UpdateLogging from './updateLogging.svelte'; + import UpdateDeploymentRetention from './updateDeploymentRetention.svelte'; export let data; @@ -81,6 +82,7 @@ {#if isCloud} {/if} + diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte new file mode 100644 index 000000000..45a1184fc --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte @@ -0,0 +1,96 @@ + + +
+ + Deployment retention + Automatically delete inactive deployments after a set number of days. Active deployments are never + deleted. + + + + + + + + + +
From 75d2f0df2ddd20017f4cff0f170257bab99eb01e Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Tue, 21 Apr 2026 18:41:28 +0530 Subject: [PATCH 2/3] feat: add deployment retention settings --- .../settings/updateDeploymentRetention.svelte | 34 +++++++++++++++---- .../settings/updateDeploymentRetention.svelte | 34 +++++++++++++++---- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte index 26193759c..a5943d385 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte @@ -4,7 +4,7 @@ import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { CardGrid } from '$lib/components'; import { Dependencies } from '$lib/constants'; - import { Button, Form, InputNumber, InputSwitch } from '$lib/elements/forms'; + import { Button, Form, InputSelect, InputSwitch } from '$lib/elements/forms'; import { isValueOfStringEnum } from '$lib/helpers/types'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; @@ -13,12 +13,35 @@ let { func }: { func: Models.Function } = $props(); const MAX_DEPLOYMENT_RETENTION = 36500; + const DEPLOYMENT_RETENTION_OPTIONS = [ + { value: 7, label: '1 week' }, + { value: 30, label: '1 month' }, + { value: 90, label: '3 months' }, + { value: 180, label: '6 months' }, + { value: 365, label: '1 year' }, + { value: 730, label: '2 years' }, + { value: 1825, label: '5 years' }, + { value: 3650, label: '10 years' }, + { value: MAX_DEPLOYMENT_RETENTION, label: '100 years' } + ]; const getInitialDeploymentRetention = () => func.deploymentRetention; + const getRetentionOptions = (retention: number) => { + const hasCurrentOption = DEPLOYMENT_RETENTION_OPTIONS.some( + (option) => option.value === retention + ); + + if (retention < 1 || retention > MAX_DEPLOYMENT_RETENTION || hasCurrentOption) { + return DEPLOYMENT_RETENTION_OPTIONS; + } + + return [{ value: retention, label: `${retention} days` }, ...DEPLOYMENT_RETENTION_OPTIONS]; + }; let retentionEnabled = $state(getInitialDeploymentRetention() > 0); let retentionDays = $state( getInitialDeploymentRetention() > 0 ? getInitialDeploymentRetention() : 30 ); + const retentionOptions = $derived(getRetentionOptions(retentionDays)); const deploymentRetention = $derived(retentionEnabled ? retentionDays : 0); let isUnchanged = $derived(func.deploymentRetention === deploymentRetention); let isInvalid = $derived( @@ -83,12 +106,11 @@ id="deployment-retention-enabled" label="Delete inactive deployments" bind:value={retentionEnabled} /> - diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte index 45a1184fc..2a0a183d5 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte @@ -4,7 +4,7 @@ import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { CardGrid } from '$lib/components'; import { Dependencies } from '$lib/constants'; - import { Button, Form, InputNumber, InputSwitch } from '$lib/elements/forms'; + import { Button, Form, InputSelect, InputSwitch } from '$lib/elements/forms'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; import { Adapter, BuildRuntime, Framework, type Models } from '@appwrite.io/console'; @@ -12,12 +12,35 @@ let { site }: { site: Models.Site } = $props(); const MAX_DEPLOYMENT_RETENTION = 36500; + const DEPLOYMENT_RETENTION_OPTIONS = [ + { value: 7, label: '1 week' }, + { value: 30, label: '1 month' }, + { value: 90, label: '3 months' }, + { value: 180, label: '6 months' }, + { value: 365, label: '1 year' }, + { value: 730, label: '2 years' }, + { value: 1825, label: '5 years' }, + { value: 3650, label: '10 years' }, + { value: MAX_DEPLOYMENT_RETENTION, label: '100 years' } + ]; const getInitialDeploymentRetention = () => site.deploymentRetention; + const getRetentionOptions = (retention: number) => { + const hasCurrentOption = DEPLOYMENT_RETENTION_OPTIONS.some( + (option) => option.value === retention + ); + + if (retention < 1 || retention > MAX_DEPLOYMENT_RETENTION || hasCurrentOption) { + return DEPLOYMENT_RETENTION_OPTIONS; + } + + return [{ value: retention, label: `${retention} days` }, ...DEPLOYMENT_RETENTION_OPTIONS]; + }; let retentionEnabled = $state(getInitialDeploymentRetention() > 0); let retentionDays = $state( getInitialDeploymentRetention() > 0 ? getInitialDeploymentRetention() : 30 ); + const retentionOptions = $derived(getRetentionOptions(retentionDays)); const deploymentRetention = $derived(retentionEnabled ? retentionDays : 0); let isUnchanged = $derived(site.deploymentRetention === deploymentRetention); let isInvalid = $derived( @@ -78,12 +101,11 @@ id="deployment-retention-enabled" label="Delete inactive deployments" bind:value={retentionEnabled} /> - From abfb038acb9600b74ed3abb51dda3a5de7ab6ff1 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 22 Apr 2026 19:43:00 +0530 Subject: [PATCH 3/3] changed design --- .../settings/updateDeploymentRetention.svelte | 50 +++++++++---------- .../settings/updateDeploymentRetention.svelte | 50 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte index a5943d385..f88ad9aa4 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateDeploymentRetention.svelte @@ -14,15 +14,14 @@ const MAX_DEPLOYMENT_RETENTION = 36500; const DEPLOYMENT_RETENTION_OPTIONS = [ - { value: 7, label: '1 week' }, - { value: 30, label: '1 month' }, - { value: 90, label: '3 months' }, - { value: 180, label: '6 months' }, - { value: 365, label: '1 year' }, - { value: 730, label: '2 years' }, - { value: 1825, label: '5 years' }, - { value: 3650, label: '10 years' }, - { value: MAX_DEPLOYMENT_RETENTION, label: '100 years' } + { value: 7, label: '1 Week' }, + { value: 30, label: '1 Month' }, + { value: 90, label: '3 Months' }, + { value: 180, label: '6 Months' }, + { value: 365, label: '1 Year' }, + { value: 730, label: '2 Years' }, + { value: 1825, label: '5 Years' }, + { value: 3650, label: '10 Years' } ]; const getInitialDeploymentRetention = () => func.deploymentRetention; const getRetentionOptions = (retention: number) => { @@ -37,15 +36,15 @@ return [{ value: retention, label: `${retention} days` }, ...DEPLOYMENT_RETENTION_OPTIONS]; }; - let retentionEnabled = $state(getInitialDeploymentRetention() > 0); + let unlimitedRetention = $state(getInitialDeploymentRetention() === 0); let retentionDays = $state( getInitialDeploymentRetention() > 0 ? getInitialDeploymentRetention() : 30 ); const retentionOptions = $derived(getRetentionOptions(retentionDays)); - const deploymentRetention = $derived(retentionEnabled ? retentionDays : 0); + const deploymentRetention = $derived(unlimitedRetention ? 0 : retentionDays); let isUnchanged = $derived(func.deploymentRetention === deploymentRetention); let isInvalid = $derived( - retentionEnabled && + !unlimitedRetention && (retentionDays === null || retentionDays < 1 || retentionDays > MAX_DEPLOYMENT_RETENTION) @@ -99,21 +98,22 @@
Deployment retention - Automatically delete inactive deployments after a set number of days. Active deployments are never - deleted. + Keep active deployments and choose when inactive deployments are deleted. - + id="deployment-retention-unlimited" + label="Keep deployments forever" + bind:value={unlimitedRetention} /> + + {#if !unlimitedRetention} + + {/if} diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte index 2a0a183d5..9b2a64849 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateDeploymentRetention.svelte @@ -13,15 +13,14 @@ const MAX_DEPLOYMENT_RETENTION = 36500; const DEPLOYMENT_RETENTION_OPTIONS = [ - { value: 7, label: '1 week' }, - { value: 30, label: '1 month' }, - { value: 90, label: '3 months' }, - { value: 180, label: '6 months' }, - { value: 365, label: '1 year' }, - { value: 730, label: '2 years' }, - { value: 1825, label: '5 years' }, - { value: 3650, label: '10 years' }, - { value: MAX_DEPLOYMENT_RETENTION, label: '100 years' } + { value: 7, label: '1 Week' }, + { value: 30, label: '1 Month' }, + { value: 90, label: '3 Months' }, + { value: 180, label: '6 Months' }, + { value: 365, label: '1 Year' }, + { value: 730, label: '2 Years' }, + { value: 1825, label: '5 Years' }, + { value: 3650, label: '10 Years' } ]; const getInitialDeploymentRetention = () => site.deploymentRetention; const getRetentionOptions = (retention: number) => { @@ -36,15 +35,15 @@ return [{ value: retention, label: `${retention} days` }, ...DEPLOYMENT_RETENTION_OPTIONS]; }; - let retentionEnabled = $state(getInitialDeploymentRetention() > 0); + let unlimitedRetention = $state(getInitialDeploymentRetention() === 0); let retentionDays = $state( getInitialDeploymentRetention() > 0 ? getInitialDeploymentRetention() : 30 ); const retentionOptions = $derived(getRetentionOptions(retentionDays)); - const deploymentRetention = $derived(retentionEnabled ? retentionDays : 0); + const deploymentRetention = $derived(unlimitedRetention ? 0 : retentionDays); let isUnchanged = $derived(site.deploymentRetention === deploymentRetention); let isInvalid = $derived( - retentionEnabled && + !unlimitedRetention && (retentionDays === null || retentionDays < 1 || retentionDays > MAX_DEPLOYMENT_RETENTION) @@ -94,21 +93,22 @@ Deployment retention - Automatically delete inactive deployments after a set number of days. Active deployments are never - deleted. + Keep active deployments and choose when inactive deployments are deleted. - + id="deployment-retention-unlimited" + label="Keep deployments forever" + bind:value={unlimitedRetention} /> + + {#if !unlimitedRetention} + + {/if}