{#if $page.data?.header}
diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index d3a77a8c4..109bdabb3 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -334,7 +334,6 @@ Date: Thu, 11 Dec 2025 18:03:42 +0530 Subject: [PATCH 459/599] add: nice looking thing :D --- package.json | 4 + pnpm-lock.yaml | 232 ++++++++++++++++++ src/lib/components/bottomModalAlert.svelte | 46 +++- src/lib/components/promos/imagine.svelte | 39 +++ src/lib/components/promos/imagine.svg | 61 +++++ src/lib/components/promos/shader.svelte | 109 ++++++++ .../promos/threlte/shaders/noise.glsl | 166 +++++++++++++ src/lib/stores/bottom-alerts.ts | 13 +- src/routes/(console)/bottomAlerts.ts | 38 +-- 9 files changed, 684 insertions(+), 24 deletions(-) create mode 100644 src/lib/components/promos/imagine.svelte create mode 100644 src/lib/components/promos/imagine.svg create mode 100644 src/lib/components/promos/shader.svelte create mode 100644 src/lib/components/promos/threlte/shaders/noise.glsl diff --git a/package.json b/package.json index 5579ef272..59dc1e885 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,8 @@ "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.38.0", "@stripe/stripe-js": "^3.5.0", + "@threlte/core": "^8.3.1", + "@threlte/extras": "^9.7.1", "ai": "^2.2.37", "analytics": "^0.8.16", "cron-parser": "^4.9.0", @@ -45,6 +47,7 @@ "prismjs": "^1.30.0", "remarkable": "^2.0.1", "svelte-confetti": "^1.4.0", + "three": "^0.181.2", "tippy.js": "^6.3.7" }, "devDependencies": { @@ -63,6 +66,7 @@ "@types/deep-equal": "^1.0.4", "@types/prismjs": "^1.26.5", "@types/remarkable": "^2.0.8", + "@types/three": "^0.182.0", "@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/parser": "^8.28.0", "@vitest/ui": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 479be4ae9..f7492f49f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,12 @@ importers: '@stripe/stripe-js': specifier: ^3.5.0 version: 3.5.0 + '@threlte/core': + specifier: ^8.3.1 + version: 8.3.1(svelte@5.25.3)(three@0.181.2) + '@threlte/extras': + specifier: ^9.7.1 + version: 9.7.1(@types/three@0.182.0)(svelte@5.25.3)(three@0.181.2) ai: specifier: ^2.2.37 version: 2.2.37(react@18.3.1)(solid-js@1.9.5)(svelte@5.25.3)(vue@3.5.13(typescript@5.8.2)) @@ -80,6 +86,9 @@ importers: svelte-confetti: specifier: ^1.4.0 version: 1.4.0(svelte@5.25.3) + three: + specifier: ^0.181.2 + version: 0.181.2 tippy.js: specifier: ^6.3.7 version: 6.3.7 @@ -129,6 +138,9 @@ importers: '@types/remarkable': specifier: ^2.0.8 version: 2.0.8 + '@types/three': + specifier: ^0.182.0 + version: 0.182.0 '@typescript-eslint/eslint-plugin': specifier: ^8.28.0 version: 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.31.0)(typescript@5.8.2))(eslint@9.31.0)(typescript@5.8.2) @@ -405,6 +417,9 @@ packages: resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} engines: {node: '>=18'} + '@dimforge/rapier3d-compat@0.12.0': + resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} + '@esbuild/aix-ppc64@0.25.1': resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} engines: {node: '>=18'} @@ -1330,6 +1345,26 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@threejs-kit/instanced-sprite-mesh@2.5.1': + resolution: {integrity: sha512-pmt1ALRhbHhCJQTj2FuthH6PeLIeaM4hOuS2JO3kWSwlnvx/9xuUkjFR3JOi/myMqsH7pSsLIROSaBxDfttjeA==} + peerDependencies: + three: '>=0.170.0' + + '@threlte/core@8.3.1': + resolution: {integrity: sha512-qKjjNCQ+40hyeBcfOMh/8ef5x/j5PG5Wmo/L9Ye0aDCcdD6fCewWxfp7tV/J3CxPzX1dEp1JGK7sjyc7ntZSrg==} + peerDependencies: + svelte: '>=5' + three: '>=0.160' + + '@threlte/extras@9.7.1': + resolution: {integrity: sha512-SGm59HDCdHxADFHuweHfFDknwubkCPodyK0pbfsVtOWWOX26gE2xfK7aKolh6YFDiPAjWjGxN0jIgkNbbr1ohg==} + peerDependencies: + svelte: '>=5' + three: '>=0.160' + + '@tweenjs/tween.js@23.1.3': + resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1393,12 +1428,21 @@ packages: '@types/shimmer@1.2.0': resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + '@types/tedious@4.0.14': resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} + '@types/three@0.182.0': + resolution: {integrity: sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/webxr@0.5.24': + resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + '@typescript-eslint/eslint-plugin@8.28.0': resolution: {integrity: sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1559,6 +1603,9 @@ packages: '@vue/shared@3.5.13': resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@webgpu/types@0.1.67': + resolution: {integrity: sha512-uk53+2ECGUkWoDFez/hymwpRfdgdIn6y1ref70fEecGMe5607f4sozNFgBk0oxlr7j2CRGWBEc3IBYMmFdGGTQ==} + acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -1674,6 +1721,9 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1713,6 +1763,12 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camera-controls@3.1.2: + resolution: {integrity: sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==} + engines: {node: '>=22.0.0', npm: '>=10.5.1'} + peerDependencies: + three: '>=0.126.1' + caniuse-lite@1.0.30001707: resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==} @@ -2022,6 +2078,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diet-sprite@0.0.1: + resolution: {integrity: sha512-zSHI2WDAn1wJqJYxcmjWfJv3Iw8oL9reQIbEyx2x2/EZ4/qmUTIo8/5qOCurnAcq61EwtJJaZ0XTy2NRYqpB5A==} + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -2039,6 +2098,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + echarts@5.6.0: resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} @@ -2601,6 +2663,12 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + maath@0.10.8: + resolution: {integrity: sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==} + peerDependencies: + '@types/three': '>=0.134.0' + three: '>=0.134.0' + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -2635,6 +2703,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meshoptimizer@0.22.0: + resolution: {integrity: sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==} + micromark-util-character@2.1.1: resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} @@ -2680,6 +2751,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + module-details-from-path@1.0.3: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} @@ -2987,6 +3061,10 @@ packages: engines: {node: '>= 6.0.0'} hasBin: true + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + require-in-the-middle@7.5.2: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} @@ -3286,6 +3364,29 @@ packages: the-new-css-reset@1.11.3: resolution: {integrity: sha512-61SB81vu9foUyEIqoU1CeqxrdlsVjJojj/CBXoG8BdvlKFsllB0Rza63DblnRqH+3uttPj3FGWo7+c9nu7MT+A==} + three-instanced-uniforms-mesh@0.52.4: + resolution: {integrity: sha512-YwDBy05hfKZQtU+Rp0KyDf9yH4GxfhxMbVt9OYruxdgLfPwmDG5oAbGoW0DrKtKZSM3BfFcCiejiOHCjFBTeng==} + peerDependencies: + three: '>=0.125.0' + + three-mesh-bvh@0.9.3: + resolution: {integrity: sha512-LaxfvQpF+At96fS90GnQxHpff9bu78UL5eooJNxYyBbyiWrOBpjRx+5yn/+Dj2lQVhz5A/jHqwpVchYYnz/hWQ==} + peerDependencies: + three: '>= 0.159.0' + + three-perf@1.0.11: + resolution: {integrity: sha512-OgBpZjwL+csQKGKZjpkH/QHdbGFMxqngMbSEJeSnVNfXDYd6On7WHNv/GhUZH4YxIpNMwMahBWrNnsJvnbSJHQ==} + peerDependencies: + three: '>=0.170' + + three-viewport-gizmo@2.2.0: + resolution: {integrity: sha512-Jo9Liur1rUmdKk75FZumLU/+hbF+RtJHi1qsKZpntjKlCYScK6tjbYoqvJ9M+IJphrlQJF5oReFW7Sambh0N4Q==} + peerDependencies: + three: '>=0.162.0 <1.0.0' + + three@0.181.2: + resolution: {integrity: sha512-k/CjiZ80bYss6Qs7/ex1TBlPD11whT9oKfT8oTGiHa34W4JRd1NiH/Tr1DbHWQ2/vMUypxksLnF2CfmlmM5XFQ==} + tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} @@ -3353,6 +3454,19 @@ packages: trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + troika-three-text@0.52.4: + resolution: {integrity: sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==} + peerDependencies: + three: '>=0.125.0' + + troika-three-utils@0.52.4: + resolution: {integrity: sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==} + peerDependencies: + three: '>=0.125.0' + + troika-worker-utils@0.52.0: + resolution: {integrity: sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -3371,6 +3485,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tweakpane@3.1.10: + resolution: {integrity: sha512-rqwnl/pUa7+inhI2E9ayGTqqP0EPOOn/wVvSWjZsRbZUItzNShny7pzwL3hVlaN4m9t/aZhsP0aFQ9U5VVR2VQ==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3524,6 +3641,9 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} + webgl-sdf-generator@1.1.1: + resolution: {integrity: sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -3881,6 +4001,8 @@ snapshots: '@csstools/css-tokenizer@3.0.3': {} + '@dimforge/rapier3d-compat@0.12.0': {} + '@esbuild/aix-ppc64@0.25.1': optional: true @@ -4844,6 +4966,38 @@ snapshots: dependencies: '@testing-library/dom': 10.4.0 + '@threejs-kit/instanced-sprite-mesh@2.5.1(@types/three@0.182.0)(three@0.181.2)': + dependencies: + diet-sprite: 0.0.1 + earcut: 2.2.4 + maath: 0.10.8(@types/three@0.182.0)(three@0.181.2) + three: 0.181.2 + three-instanced-uniforms-mesh: 0.52.4(three@0.181.2) + troika-three-utils: 0.52.4(three@0.181.2) + transitivePeerDependencies: + - '@types/three' + + '@threlte/core@8.3.1(svelte@5.25.3)(three@0.181.2)': + dependencies: + mitt: 3.0.1 + svelte: 5.25.3 + three: 0.181.2 + + '@threlte/extras@9.7.1(@types/three@0.182.0)(svelte@5.25.3)(three@0.181.2)': + dependencies: + '@threejs-kit/instanced-sprite-mesh': 2.5.1(@types/three@0.182.0)(three@0.181.2) + camera-controls: 3.1.2(three@0.181.2) + svelte: 5.25.3 + three: 0.181.2 + three-mesh-bvh: 0.9.3(three@0.181.2) + three-perf: 1.0.11(three@0.181.2) + three-viewport-gizmo: 2.2.0(three@0.181.2) + troika-three-text: 0.52.4(three@0.181.2) + transitivePeerDependencies: + - '@types/three' + + '@tweenjs/tween.js@23.1.3': {} + '@types/aria-query@5.0.4': {} '@types/chai@5.2.2': @@ -4907,12 +5061,26 @@ snapshots: '@types/shimmer@1.2.0': {} + '@types/stats.js@0.17.4': {} + '@types/tedious@4.0.14': dependencies: '@types/node': 22.13.14 + '@types/three@0.182.0': + dependencies: + '@dimforge/rapier3d-compat': 0.12.0 + '@tweenjs/tween.js': 23.1.3 + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.24 + '@webgpu/types': 0.1.67 + fflate: 0.8.2 + meshoptimizer: 0.22.0 + '@types/unist@3.0.3': {} + '@types/webxr@0.5.24': {} + '@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.31.0)(typescript@5.8.2))(eslint@9.31.0)(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -5176,6 +5344,8 @@ snapshots: '@vue/shared@3.5.13': {} + '@webgpu/types@0.1.67': {} + acorn-import-attributes@1.9.5(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -5285,6 +5455,10 @@ snapshots: balanced-match@1.0.2: {} + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + binary-extensions@2.3.0: {} brace-expansion@1.1.11: @@ -5328,6 +5502,10 @@ snapshots: callsites@3.1.0: {} + camera-controls@3.1.2(three@0.181.2): + dependencies: + three: 0.181.2 + caniuse-lite@1.0.30001707: {} ccount@2.0.1: {} @@ -5664,6 +5842,8 @@ snapshots: dependencies: dequal: 2.0.3 + diet-sprite@0.0.1: {} + dlv@1.1.3: {} dom-accessibility-api@0.5.16: {} @@ -5678,6 +5858,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + earcut@2.2.4: {} + echarts@5.6.0: dependencies: tslib: 2.3.0 @@ -6277,6 +6459,11 @@ snapshots: lz-string@1.5.0: {} + maath@0.10.8(@types/three@0.182.0)(three@0.181.2): + dependencies: + '@types/three': 0.182.0 + three: 0.181.2 + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -6321,6 +6508,8 @@ snapshots: merge2@1.4.1: {} + meshoptimizer@0.22.0: {} + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 @@ -6363,6 +6552,8 @@ snapshots: minipass@7.1.2: {} + mitt@3.0.1: {} + module-details-from-path@1.0.3: {} mri@1.2.0: {} @@ -6626,6 +6817,8 @@ snapshots: argparse: 1.0.10 autolinker: 3.16.2 + require-from-string@2.0.2: {} + require-in-the-middle@7.5.2: dependencies: debug: 4.4.0 @@ -6964,6 +7157,27 @@ snapshots: the-new-css-reset@1.11.3: {} + three-instanced-uniforms-mesh@0.52.4(three@0.181.2): + dependencies: + three: 0.181.2 + troika-three-utils: 0.52.4(three@0.181.2) + + three-mesh-bvh@0.9.3(three@0.181.2): + dependencies: + three: 0.181.2 + + three-perf@1.0.11(three@0.181.2): + dependencies: + three: 0.181.2 + troika-three-text: 0.52.4(three@0.181.2) + tweakpane: 3.1.10 + + three-viewport-gizmo@2.2.0(three@0.181.2): + dependencies: + three: 0.181.2 + + three@0.181.2: {} + tiny-glob@0.2.9: dependencies: globalyzer: 0.1.0 @@ -7020,6 +7234,20 @@ snapshots: trim-lines@3.0.1: {} + troika-three-text@0.52.4(three@0.181.2): + dependencies: + bidi-js: 1.0.3 + three: 0.181.2 + troika-three-utils: 0.52.4(three@0.181.2) + troika-worker-utils: 0.52.0 + webgl-sdf-generator: 1.1.1 + + troika-three-utils@0.52.4(three@0.181.2): + dependencies: + three: 0.181.2 + + troika-worker-utils@0.52.0: {} + ts-api-utils@2.1.0(typescript@5.8.2): dependencies: typescript: 5.8.2 @@ -7032,6 +7260,8 @@ snapshots: tslib@2.8.1: {} + tweakpane@3.1.10: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -7201,6 +7431,8 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + webgl-sdf-generator@1.1.1: {} + webidl-conversions@3.0.1: {} webidl-conversions@7.0.0: {} diff --git a/src/lib/components/bottomModalAlert.svelte b/src/lib/components/bottomModalAlert.svelte index 1c0f24a9f..c8ce42282 100644 --- a/src/lib/components/bottomModalAlert.svelte +++ b/src/lib/components/bottomModalAlert.svelte @@ -19,6 +19,14 @@ import { goto } from '$app/navigation'; import { Typography } from '@appwrite.io/pink-svelte'; + function resolveThemeColor( + color: Record<'light' | 'dark', string> | string | undefined + ): string | undefined { + if (!color) return undefined; + if (typeof color === 'string') return color; + return color[$app.themeInUse]; + } + let currentIndex = $state(0); let openModalOnMobile = $state(false); @@ -199,7 +207,10 @@
- {#if $app.themeInUse === 'dark'} + {#if currentModalAlert.backgroundComponent} + {@const BackgroundComponent = currentModalAlert.backgroundComponent} + + {:else if $app.themeInUse === 'dark'} {currentModalAlert.title} triggerWindowLink(currentModalAlert)}> - {currentModalAlert.cta.text} + + {currentModalAlert.cta.text} + {#if currentModalAlert.learnMore} @@ -310,7 +329,10 @@
- {#if $app.themeInUse === 'dark'} + {#if currentModalAlert.backgroundComponent} + {@const BackgroundComponent = currentModalAlert.backgroundComponent} + + {:else if $app.themeInUse === 'dark'} {currentModalAlert.title} { openModalOnMobile = false; triggerWindowLink(currentModalAlert); }}> - {shouldShowUpgrade - ? 'Upgrade plan' - : currentModalAlert.cta.text} + + {shouldShowUpgrade + ? 'Upgrade plan' + : currentModalAlert.cta.text} + {#if currentModalAlert.learnMore} @@ -466,6 +499,7 @@ .icon-inline-tag { top: 1rem; + z-index: 1; right: 1rem; cursor: pointer; diff --git a/src/lib/components/promos/imagine.svelte b/src/lib/components/promos/imagine.svelte new file mode 100644 index 000000000..0f275b3da --- /dev/null +++ b/src/lib/components/promos/imagine.svelte @@ -0,0 +1,39 @@ + + +
+
+ + + +
+ + +
+ + diff --git a/src/lib/components/promos/imagine.svg b/src/lib/components/promos/imagine.svg new file mode 100644 index 000000000..58e33f62c --- /dev/null +++ b/src/lib/components/promos/imagine.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/components/promos/shader.svelte b/src/lib/components/promos/shader.svelte new file mode 100644 index 000000000..15ce23040 --- /dev/null +++ b/src/lib/components/promos/shader.svelte @@ -0,0 +1,109 @@ + + + + + + diff --git a/src/lib/components/promos/threlte/shaders/noise.glsl b/src/lib/components/promos/threlte/shaders/noise.glsl new file mode 100644 index 000000000..dea577c65 --- /dev/null +++ b/src/lib/components/promos/threlte/shaders/noise.glsl @@ -0,0 +1,166 @@ +// +// psrddnoise3.glsl +// +// Authors: Stefan Gustavson (stefan.gustavson@gmail.com) +// and Ian McEwan (ijm567@gmail.com) +// Version 2021-12-02, published under the MIT license (see below) +// +// Copyright (c) 2021 Stefan Gustavson and Ian McEwan. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +vec4 permute(vec4 i) { + vec4 im = mod(i, 289.0); + return mod(((im*34.0)+10.0)*im, 289.0); +} + +float psrddnoise(vec3 x, vec3 period, float alpha, out vec3 gradient, + out vec3 dg, out vec3 dg2) +{ + const mat3 M = mat3(0.0, 1.0, 1.0, + 1.0, 0.0, 1.0, + 1.0, 1.0, 0.0); + + const mat3 Mi = mat3(-0.5, 0.5, 0.5, + 0.5,-0.5, 0.5, + 0.5, 0.5,-0.5); + + vec3 uvw; + uvw = M * x; + + vec3 i0 = floor(uvw); + vec3 f0 = fract(uvw); + + vec3 g_ = step(f0.xyx, f0.yzz); + vec3 l_ = 1.0 - g_; + vec3 g = vec3(l_.z, g_.xy); + vec3 l = vec3(l_.xy, g_.z); + vec3 o1 = min( g, l ); + vec3 o2 = max( g, l ); + + vec3 i1 = i0 + o1; + vec3 i2 = i0 + o2; + vec3 i3 = i0 + vec3(1.0); + + vec3 v0, v1, v2, v3; + + v0 = Mi * i0; + v1 = Mi * i1; + v2 = Mi * i2; + v3 = Mi * i3; + + vec3 x0 = x - v0; + vec3 x1 = x - v1; + vec3 x2 = x - v2; + vec3 x3 = x - v3; + + if(any(greaterThan(period, vec3(0.0)))) { + vec4 vx = vec4(v0.x, v1.x, v2.x, v3.x); + vec4 vy = vec4(v0.y, v1.y, v2.y, v3.y); + vec4 vz = vec4(v0.z, v1.z, v2.z, v3.z); + if(period.x > 0.0) vx = mod(vx, period.x); + if(period.y > 0.0) vy = mod(vy, period.y); + if(period.z > 0.0) vz = mod(vz, period.z); + i0 = M * vec3(vx.x, vy.x, vz.x); + i1 = M * vec3(vx.y, vy.y, vz.y); + i2 = M * vec3(vx.z, vy.z, vz.z); + i3 = M * vec3(vx.w, vy.w, vz.w); + i0 = floor(i0 + 0.5); + i1 = floor(i1 + 0.5); + i2 = floor(i2 + 0.5); + i3 = floor(i3 + 0.5); + } + + vec4 hash = permute( permute( permute( + vec4(i0.z, i1.z, i2.z, i3.z )) + + vec4(i0.y, i1.y, i2.y, i3.y )) + + vec4(i0.x, i1.x, i2.x, i3.x )); + + vec4 theta = hash * 3.883222077; + vec4 sz = hash * -0.006920415 + 0.996539792; + vec4 psi = hash * 0.108705628 ; + + vec4 Ct = cos(theta); + vec4 St = sin(theta); + vec4 sz_prime = sqrt( 1.0 - sz*sz ); + + vec4 gx, gy, gz; + + if(alpha != 0.0) { + vec4 Sp = sin(psi); + vec4 Cp = cos(psi); + + vec4 px = Ct * sz_prime; + vec4 py = St * sz_prime; + vec4 pz = sz; + + vec4 Ctp = St*Sp - Ct*Cp; + vec4 qx = mix( Ctp*St, Sp, sz); + vec4 qy = mix(-Ctp*Ct, Cp, sz); + vec4 qz = -(py*Cp + px*Sp); + + vec4 Sa = vec4(sin(alpha)); + vec4 Ca = vec4(cos(alpha)); + + gx = Ca * px + Sa * qx; + gy = Ca * py + Sa * qy; + gz = Ca * pz + Sa * qz; + } + else { + gx = Ct * sz_prime; + gy = St * sz_prime; + gz = sz; + } + + vec3 g0 = vec3(gx.x, gy.x, gz.x); + vec3 g1 = vec3(gx.y, gy.y, gz.y); + vec3 g2 = vec3(gx.z, gy.z, gz.z); + vec3 g3 = vec3(gx.w, gy.w, gz.w); + + vec4 w = 0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)); + w = max(w, 0.0); + vec4 w2 = w * w; + vec4 w3 = w2 * w; + + vec4 gdotx = vec4(dot(g0,x0), dot(g1,x1), dot(g2,x2), dot(g3,x3)); + + float n = dot(w3, gdotx); + + vec4 dw = -6.0 * w2 * gdotx; + vec3 dn0 = w3.x * g0 + dw.x * x0; + vec3 dn1 = w3.y * g1 + dw.y * x1; + vec3 dn2 = w3.z * g2 + dw.z * x2; + vec3 dn3 = w3.w * g3 + dw.w * x3; + gradient = 39.5 * (dn0 + dn1 + dn2 + dn3); + + vec4 dw2 = 24.0 * w * gdotx; + vec3 dga0 = dw2.x * x0 * x0 - 6.0 * w2.x * (gdotx.x + 2.0 * g0 * x0); + vec3 dga1 = dw2.y * x1 * x1 - 6.0 * w2.y * (gdotx.y + 2.0 * g1 * x1); + vec3 dga2 = dw2.z * x2 * x2 - 6.0 * w2.z * (gdotx.z + 2.0 * g2 * x2); + vec3 dga3 = dw2.w * x3 * x3 - 6.0 * w2.w * (gdotx.w + 2.0 * g3 * x3); + dg = 35.0 * (dga0 + dga1 + dga2 + dga3); + vec3 dgb0 = dw2.x * x0 * x0.yzx - 6.0 * w2.x * (g0 * x0.yzx + g0.yzx * x0); + vec3 dgb1 = dw2.y * x1 * x1.yzx - 6.0 * w2.y * (g1 * x1.yzx + g1.yzx * x1); + vec3 dgb2 = dw2.z * x2 * x2.yzx - 6.0 * w2.z * (g2 * x2.yzx + g2.yzx * x2); + vec3 dgb3 = dw2.w * x3 * x3.yzx - 6.0 * w2.w * (g3 * x3.yzx + g3.yzx * x3); + dg2 = 39.5 * (dgb0 + dgb1 + dgb2 + dgb3); + + return 39.5 * n; +} diff --git a/src/lib/stores/bottom-alerts.ts b/src/lib/stores/bottom-alerts.ts index 634dee01f..e3ebc968f 100644 --- a/src/lib/stores/bottom-alerts.ts +++ b/src/lib/stores/bottom-alerts.ts @@ -1,10 +1,14 @@ import { writable } from 'svelte/store'; -import type { NotificationCoolOffOptions } from '$lib/helpers/notifications'; -import type { Organization } from '$lib/stores/organization'; +import type { Component } from 'svelte'; import type { Models } from '@appwrite.io/console'; +import type { Organization } from '$lib/stores/organization'; +import type { NotificationCoolOffOptions } from '$lib/helpers/notifications'; export type BottomModalAlertAction = { text: string; + color?: Record<'light' | 'dark', string> | string; + background?: Record<'light' | 'dark', string> | string; + backgroundHover?: Record<'light' | 'dark', string> | string; hideOnClick?: boolean; link: (ctx: { organization: Organization; project: Models.Project }) => string; external?: boolean; @@ -32,7 +36,10 @@ export type BottomModalAlertItem = { title: string; message: string; - src: Record<'dark' | 'light', string>; + // use either of these! + src?: Record<'dark' | 'light', string>; + backgroundComponent?: Component; + cta: BottomModalAlertAction; learnMore?: BottomModalAlertAction; plan: 'free' | 'pro' | 'scale' /*| 'enterprise'*/; diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index 6986aec0b..367bf2d0f 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -1,32 +1,40 @@ import { isCloud } from '$lib/system'; import { isSameDay } from '$lib/helpers/date'; +import Imagine from '$lib/components/promos/imagine.svelte'; import { type BottomModalAlertItem, showBottomModalAlert } from '$lib/stores/bottom-alerts'; -import AiSuggestionsDark from '$lib/images/promos/ai-suggestions-dark.png'; -import AiSuggestionsLight from '$lib/images/promos/ai-suggestions-light.png'; const listOfPromotions: BottomModalAlertItem[] = []; if (isCloud) { - const aiSuggestionsPromo: BottomModalAlertItem = { - id: 'modal:database_ai_suggestions_announcement', - src: { - dark: AiSuggestionsDark, - light: AiSuggestionsLight - }, - title: 'Announcing Database AI suggestions', - message: 'From table name to schema in one click.', - plan: 'free', + const imaginePromo: BottomModalAlertItem = { + id: 'modal:imagine.dev', + backgroundComponent: Imagine, + title: 'Introducing Imagine', + message: 'the most complete AI builder to date', importance: 8, - scope: 'project', + scope: 'everywhere', + plan: 'free', cta: { - text: 'Read announcement', - link: () => 'https://appwrite.io/blog/post/announcing-database-ai-suggestions', + text: 'Try it now', + color: { + light: '#FFFFFF', + dark: '#000000' + }, + background: { + light: '#000000', + dark: '#FFFFFF' + }, + backgroundHover: { + light: '#333333', + dark: '#CCCCCC' + }, + link: () => 'https://studio.imagine.dev', external: true, hideOnClick: true }, show: true }; - listOfPromotions.push(aiSuggestionsPromo); + listOfPromotions.push(imaginePromo); } export function addBottomModalAlerts() { From 558f921b63b50781f5cf95370e374841edc2c35f Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 11 Dec 2025 18:06:05 +0530 Subject: [PATCH 460/599] bump: engine. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59dc1e885..15cb88fa7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@appwrite/console", "type": "module", "engines": { - "node": ">=20" + "node": ">=22.0.0" }, "scripts": { "dev": "vite dev", From cd7ee26be0d3063450aca2c2d3a82e5a281dca0e Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 11 Dec 2025 18:07:30 +0530 Subject: [PATCH 461/599] bump: engine. --- .github/workflows/copilot-setup-steps.yml | 3 ++- .github/workflows/e2e.yml | 2 +- .github/workflows/tests.yml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 6926b0c50..ac3434c11 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -21,7 +21,8 @@ jobs: - name: Use Node.js uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 22 + - name: Install pnpm uses: pnpm/action-setup@v4 - name: Install dependencies diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 73a4883e6..ac1d7e782 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v3 with: - node-version: 20 + node-version: 22 - name: Install pnpm uses: pnpm/action-setup@v4 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1674ff728..968f8763e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v3 with: - node-version: 20 + node-version: 22 - name: Install pnpm uses: pnpm/action-setup@v4 From 9de0afb12e9c647c20cf1aff5d0364b8935a4c29 Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 11 Dec 2025 18:44:25 +0530 Subject: [PATCH 462/599] update: design changes. --- src/lib/components/bottomModalAlert.svelte | 14 ++++++++++++-- src/lib/stores/bottom-alerts.ts | 6 ++++++ src/routes/(console)/bottomAlerts.ts | 4 +++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/lib/components/bottomModalAlert.svelte b/src/lib/components/bottomModalAlert.svelte index c8ce42282..0f6dfad32 100644 --- a/src/lib/components/bottomModalAlert.svelte +++ b/src/lib/components/bottomModalAlert.svelte @@ -108,6 +108,12 @@ message: 'Explore new features to enhance your projects and improve security.' }; + // override + if (currentModalAlert?.sameContentOnMobileLayout) { + fallback.title = currentModalAlert?.title; + fallback.message = currentModalAlert?.message; + } + const shouldApplyConfig = config?.enabled === true && visibleAlerts.length === 1; return { @@ -269,6 +275,7 @@
@@ -164,7 +171,15 @@ {#if selectedTab === 'nameserver'} {:else} - + (selectedTab = 'nameserver')} + onNavigateToA={() => (selectedTab = 'a')} + onNavigateToAAAA={() => (selectedTab = 'aaaa')} /> {/if} diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts index b89c93330..28bde882a 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts @@ -3,18 +3,27 @@ import { isCloud } from '$lib/system'; import { Dependencies } from '$lib/constants.js'; import { type Models, Query } from '@appwrite.io/console'; -export const load = async ({ depends, parent }) => { - const { organization } = await parent(); +export const load = async ({ depends, parent, params, url }) => { + const { project, organization } = await parent(); depends(Dependencies.DOMAINS); - let domainsList: Models.DomainsList; - if (isCloud) { - domainsList = await sdk.forConsole.domains.list({ - queries: [Query.equal('teamId', organization.$id)] - }); + const ruleId = url.searchParams.get('rule'); + if (!ruleId) { + throw new Error('Rule ID is required'); } + const [proxyRule, domainsList] = await Promise.all([ + sdk.forProject(params.region, params.project).proxy.getRule({ ruleId }), + isCloud + ? sdk.forConsole.domains.list({ + queries: [Query.equal('teamId', organization.$id)] + }) + : Promise.resolve(null) + ]); + return { - domainsList + project, + domainsList, + proxyRule }; }; diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte index 844a2c94b..8a9e62c93 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte @@ -7,32 +7,75 @@ import { Submit, trackEvent, trackError } from '$lib/actions/analytics'; import { Dependencies } from '$lib/constants'; import type { Models } from '@appwrite.io/console'; - import CnameTable from '$lib/components/domains/cnameTable.svelte'; import { page } from '$app/state'; + import { isASubdomain } from '$lib/helpers/tlds'; + import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; + import { isCloud } from '$lib/system'; + import { Divider, Tabs } from '@appwrite.io/pink-svelte'; + import NameserverTable from '$lib/components/domains/nameserverTable.svelte'; + import RecordTable from '$lib/components/domains/recordTable.svelte'; let { show = $bindable(), - selectedDomain + selectedProxyRule }: { show: boolean; - selectedDomain: Models.ProxyRule; + selectedProxyRule: Models.ProxyRule; } = $props(); + const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); + + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( + (() => { + if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + })() + ); + let error = $state(null); + let verified = $state(false); + async function retryDomain() { try { - await sdk + error = null; + const proxyRule = await sdk .forProject(page.params.region, page.params.project) - .proxy.updateRuleVerification({ ruleId: selectedDomain.$id }); + .proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id }); + + verified = proxyRule.status === 'verified'; await invalidate(Dependencies.DOMAINS); + + // This means domain verification using DNS records hasn't succeeded and the rule is still in initial state. + if (proxyRule.status === 'created') { + throw new Error( + 'Domain verification failed. Please check your domain settings or try again later' + ); + } + + if (verified) { + addNotification({ + type: 'success', + message: `${selectedProxyRule.domain} has been verified` + }); + } else { + addNotification({ + type: 'info', + message: 'Verification in progress' + }); + } show = false; - addNotification({ - type: 'success', - message: `${selectedDomain.domain} has been verified` - }); trackEvent(Submit.DomainUpdateVerification); } catch (e) { - error = e.message; + error = + e.message ?? + 'Domain verification failed. Please check your domain settings or try again later'; trackError(e, Submit.DomainUpdateVerification); } } @@ -45,10 +88,55 @@ - {#if selectedDomain} - +
+ + {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'} + (selectedTab = 'cname')} + active={selectedTab === 'cname'}> + CNAME + + {/if} + {#if isCloud} + (selectedTab = 'nameserver')} + active={selectedTab === 'nameserver'}> + Nameservers + + {/if} + {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + (selectedTab = 'a')} + active={selectedTab === 'a'}> + A + + {/if} + {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + (selectedTab = 'aaaa')} + active={selectedTab === 'aaaa'}> + AAAA + + {/if} + + +
+ {#if selectedTab === 'nameserver'} + + {:else} + (selectedTab = 'nameserver')} + onNavigateToA={() => (selectedTab = 'a')} + onNavigateToAAAA={() => (selectedTab = 'aaaa')} /> {/if} diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte index e28db33a9..03f93955e 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte @@ -3,10 +3,16 @@ import { Link } from '$lib/elements'; import { Button } from '$lib/elements/forms'; import type { Models } from '@appwrite.io/console'; - import { IconDotsHorizontal, IconRefresh, IconTrash } from '@appwrite.io/pink-icons-svelte'; + import { + IconDotsHorizontal, + IconRefresh, + IconTerminal, + IconTrash + } from '@appwrite.io/pink-icons-svelte'; import { ActionMenu, Badge, + Divider, Icon, Layout, Popover, @@ -17,6 +23,7 @@ import RetryDomainModal from './retryDomainModal.svelte'; import { regionalProtocol } from '../../store'; import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; + import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte'; let { domains, @@ -28,7 +35,8 @@ let showDelete = $state(false); let showRetry = $state(false); - let selectedDomain: Models.ProxyRule = $state(null); + let showLogs = $state(false); + let selectedProxyRule: Models.ProxyRule = $state(null); const columns = [ { @@ -36,7 +44,7 @@ title: 'Domain', type: 'string', format: 'string', - width: { min: 200, max: 550 } + width: { min: 300, max: 550 } } ]; @@ -50,7 +58,7 @@ {/each} - {#each domains.rules as domain} + {#each domains.rules as proxyRule (proxyRule.$id)} {#each columns as column} @@ -58,21 +66,39 @@ + variant="quiet-muted" + href={`${$regionalProtocol}${proxyRule.domain}`}> - {domain.domain} + {proxyRule.domain} - {#if domain.status === 'verifying'} - - {:else if domain.status !== 'verified'} - - {/if} + + {#if proxyRule.status !== 'verified'} + + {/if} + {#if proxyRule.status === 'created' || proxyRule.status === 'unverified'} + { + e.preventDefault(); + selectedProxyRule = proxyRule; + showRetry = true; + }}> + Retry + + {/if} + {/if} @@ -92,23 +118,39 @@ - {#if domain.status !== 'verified' && domain.status !== 'verifying'} + {#if proxyRule.logs?.length > 0} + { + selectedProxyRule = proxyRule; + showLogs = true; + toggle(e); + }}> + View logs + + {/if} + {#if proxyRule.status !== 'verified' && proxyRule.status !== 'verifying'} { - selectedDomain = domain; + selectedProxyRule = proxyRule; showRetry = true; toggle(e); }}> Retry {/if} - + + {#if proxyRule.logs?.length > 0} +
+ +
+ {/if} { - selectedDomain = domain; + selectedProxyRule = proxyRule; showDelete = true; toggle(e); trackEvent(Click.DomainDeleteClick, { @@ -127,9 +169,19 @@ {#if showDelete} - + {/if} {#if showRetry} - + {/if} + +{#if showLogs} + +{/if} + + diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte index 87017c49b..0594d66c5 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte @@ -67,7 +67,7 @@ domain: apexDomain }); } catch (error) { - // Domain creation error needs to be silent. + // Apex domain creation error needs to be silent. } } diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte index 13b88fb19..4d50f2392 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte @@ -30,23 +30,22 @@ const ruleId = page.url.searchParams.get('rule'); const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>('nameserver'); - - $effect(() => { - if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { - selectedTab = 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - selectedTab = 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - selectedTab = 'aaaa'; - } else { - selectedTab = 'nameserver'; - } - }); - - let verified: boolean | undefined = $state(undefined); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( + (() => { + if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + })() + ); let routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`; + let verified: boolean | undefined = $state(undefined); let isSubmitting = $state(writable(false)); async function verify() { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte index 63042d142..c9ba95053 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte @@ -25,17 +25,19 @@ const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); - let selectedTab = $derived.by<'cname' | 'nameserver' | 'a' | 'aaaa'>(() => { - if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - }); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( + (() => { + if ($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && isSubDomain) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + })() + ); let error = $state(null); let verified = $state(false); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte index 77c45beee..5e4916cbf 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte @@ -57,7 +57,7 @@ {/each}
- {#each proxyRules.rules as rule} + {#each proxyRules.rules as proxyRule (proxyRule.$id)} {#each $columns as column} @@ -66,30 +66,32 @@ + href={`${$regionalProtocol}${proxyRule.domain}`}> - {rule.domain} + {proxyRule.domain} - {#if rule.status !== 'verified'} + {#if proxyRule.status !== 'verified'} {/if} - {#if rule.status === 'created' || rule.status === 'unverified'} + {#if proxyRule.status === 'created' || proxyRule.status === 'unverified'} { e.preventDefault(); - selectedProxyRule = rule; + selectedProxyRule = proxyRule; showRetry = true; }}> Retry @@ -98,7 +100,7 @@
{:else if column.id === 'target'} - {proxyTarget(rule)} + {proxyTarget(proxyRule)} {/if} {/each} @@ -117,30 +119,30 @@ - {#if rule.logs && (rule.status === 'unverified' || rule.status === 'verifying')} + {#if proxyRule.logs?.length > 0} { - selectedProxyRule = rule; + selectedProxyRule = proxyRule; showLogs = true; toggle(e); }}> View logs {/if} - {#if rule.status !== 'verified' && rule.status !== 'verifying'} + {#if proxyRule.status !== 'verified' && proxyRule.status !== 'verifying'} { - selectedProxyRule = rule; + selectedProxyRule = proxyRule; showRetry = true; toggle(e); }}> Retry {/if} - - {#if rule.logs && (rule.status === 'unverified' || rule.status === 'verifying')} + + {#if proxyRule.logs?.length > 0}
@@ -149,7 +151,7 @@ status="danger" leadingIcon={IconTrash} on:click={(e) => { - selectedProxyRule = rule; + selectedProxyRule = proxyRule; showDelete = true; toggle(e); trackEvent(Click.DomainDeleteClick, { @@ -182,7 +184,5 @@ From f4553274d74921cb1b5d9c788a726b0fb918f56f Mon Sep 17 00:00:00 2001 From: Hemachandar Date: Mon, 15 Dec 2025 18:24:36 +0530 Subject: [PATCH 473/599] tiny --- .../settings/domains/add-domain/verify-[domain]/+page.svelte | 5 +---- .../settings/domains/add-domain/verify-[domain]/+page.ts | 4 ++-- .../domains/add-domain/verify-[domain]/+page.svelte | 3 --- .../sites/site-[site]/domains/retryDomainModal.svelte | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte index 4eb5b16dc..08f092926 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte @@ -71,9 +71,6 @@ domain: page.params.domain }); verified = domainData.nameservers.toLowerCase() === 'appwrite'; - throw new Error( - 'Domain verification failed. Please check your domain settings or try again later' - ); } if (verified) { @@ -169,7 +166,7 @@
{#if selectedTab === 'nameserver'} - + {:else} { sdk.forProject(params.region, params.project).proxy.getRule({ ruleId }), isCloud ? sdk.forConsole.domains.list({ - queries: [Query.equal('teamId', organization.$id)] - }) + queries: [Query.equal('teamId', organization.$id)] + }) : Promise.resolve(null) ]); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte index 4d50f2392..24c948b14 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte @@ -70,9 +70,6 @@ domain: page.params.domain }); verified = domainData.nameservers.toLowerCase() === 'appwrite'; - throw new Error( - 'Domain verification failed. Please check your domain settings or try again later' - ); } if (verified) { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte index c9ba95053..9bfda48aa 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte @@ -27,7 +27,7 @@ let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( (() => { - if ($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && isSubDomain) { + if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { return 'cname'; } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { return 'a'; From 454cd7b2af7cb28d6c0e78c752540941e3b0918c Mon Sep 17 00:00:00 2001 From: Hemachandar Date: Mon, 15 Dec 2025 19:18:00 +0530 Subject: [PATCH 474/599] logs + better checks --- .../function-[function]/domains/table.svelte | 24 +++++++++++++++---- .../settings/domains/table.svelte | 24 +++++++++++++++---- .../sites/site-[site]/domains/table.svelte | 24 +++++++++++++++---- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte index 4e7473ba1..98e29e5ba 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte @@ -58,6 +58,10 @@ {#each proxyRules.rules as proxyRule (proxyRule.$id)} + {@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {@const isLogsViewable = + proxyRule.logs?.length > 0 && + (proxyRule.status === 'verifying' || proxyRule.status === 'unverified')} {#each $columns as column} @@ -85,7 +89,7 @@ : 'Certificate generation failed'} size="xs" /> {/if} - {#if proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {#if isRetryable} {/if} + {#if isLogsViewable} + { + e.preventDefault(); + selectedProxyRule = proxyRule; + showLogs = true; + }}> + View logs + + {/if} {:else if column.id === 'target'} @@ -119,7 +135,7 @@ - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable} { @@ -130,7 +146,7 @@ View logs {/if} - {#if proxyRule.status !== 'verified' && proxyRule.status !== 'verifying'} + {#if isRetryable} { @@ -142,7 +158,7 @@ {/if} - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable}
diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte index 03f93955e..594988a7f 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte @@ -59,6 +59,10 @@
{#each domains.rules as proxyRule (proxyRule.$id)} + {@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {@const isLogsViewable = + proxyRule.logs?.length > 0 && + (proxyRule.status === 'verifying' || proxyRule.status === 'unverified')} {#each columns as column} @@ -86,7 +90,7 @@ : 'Certificate generation failed'} size="xs" /> {/if} - {#if proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {#if isRetryable} {/if} + {#if isLogsViewable} + { + e.preventDefault(); + selectedProxyRule = proxyRule; + showLogs = true; + }}> + View logs + + {/if} {/if} @@ -118,7 +134,7 @@ - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable} { @@ -129,7 +145,7 @@ View logs {/if} - {#if proxyRule.status !== 'verified' && proxyRule.status !== 'verifying'} + {#if isRetryable} { @@ -141,7 +157,7 @@ {/if} - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable}
diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte index 5e4916cbf..b89528517 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte @@ -58,6 +58,10 @@
{#each proxyRules.rules as proxyRule (proxyRule.$id)} + {@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {@const isLogsViewable = + proxyRule.logs?.length > 0 && + (proxyRule.status === 'verifying' || proxyRule.status === 'unverified')} {#each $columns as column} @@ -85,7 +89,7 @@ : 'Certificate generation failed'} size="xs" /> {/if} - {#if proxyRule.status === 'created' || proxyRule.status === 'unverified'} + {#if isRetryable} {/if} + {#if isLogsViewable} + { + e.preventDefault(); + selectedProxyRule = proxyRule; + showLogs = true; + }}> + View logs + + {/if} {:else if column.id === 'target'} @@ -119,7 +135,7 @@ - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable} { @@ -130,7 +146,7 @@ View logs {/if} - {#if proxyRule.status !== 'verified' && proxyRule.status !== 'verifying'} + {#if isRetryable} { @@ -142,7 +158,7 @@ {/if} - {#if proxyRule.logs?.length > 0} + {#if isLogsViewable}
From 94e07acd84561a2a28f602686472d5168e7e656c Mon Sep 17 00:00:00 2001 From: Hemachandar Date: Mon, 15 Dec 2025 19:38:49 +0530 Subject: [PATCH 475/599] remove IIFE --- .../add-domain/verify-[domain]/+page.svelte | 26 +++++++++---------- .../domains/retryDomainModal.svelte | 26 +++++++++---------- .../add-domain/verify-[domain]/+page.svelte | 26 +++++++++---------- .../settings/domains/retryDomainModal.svelte | 26 +++++++++---------- .../add-domain/verify-[domain]/+page.svelte | 26 +++++++++---------- .../domains/retryDomainModal.svelte | 26 +++++++++---------- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte index 4768b0d2e..7328b7677 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte @@ -30,24 +30,24 @@ const ruleId = page.url.searchParams.get('rule'); const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let routeBase = `${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/domains`; let verified: boolean | undefined = $state(undefined); let isSubmitting = $state(writable(false)); + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } + async function verify() { const isNewDomain = data.domainsList.domains.find((rule) => rule.domain === page.params.domain) === diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte index 8460599a8..ea220e5b1 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte @@ -25,19 +25,19 @@ const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); + + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } let error = $state(null); let verified = $state(false); diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte index 08f092926..dd663b533 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte @@ -30,24 +30,24 @@ const ruleId = page.url.searchParams.get('rule'); const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); const routeBase = `${base}/project-${page.params.region}-${page.params.project}/settings/domains`; let verified: boolean | undefined = $state(undefined); const isSubmitting = writable(false); + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } + async function verify() { const isNewDomain = data.domainsList.domains.find((rule) => rule.domain === page.params.domain) === diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte index 8a9e62c93..1d1e8fb83 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte @@ -25,23 +25,23 @@ const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let error = $state(null); let verified = $state(false); + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } + async function retryDomain() { try { error = null; diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte index 24c948b14..543934d1f 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte @@ -30,24 +30,24 @@ const ruleId = page.url.searchParams.get('rule'); const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`; let verified: boolean | undefined = $state(undefined); let isSubmitting = $state(writable(false)); + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_SITES) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } + async function verify() { const isNewDomain = data.domainsList.domains.findIndex((rule) => rule.domain === page.params.domain) === -1; diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte index 9bfda48aa..937e1d4d1 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte @@ -25,23 +25,23 @@ const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); - let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>( - (() => { - if ($regionalConsoleVariables._APP_DOMAIN_SITES && isSubDomain) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - })() - ); + let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let error = $state(null); let verified = $state(false); + function getDefaultTab() { + if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_SITES) { + return 'cname'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { + return 'a'; + } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { + return 'aaaa'; + } else { + return 'nameserver'; + } + } + async function retryDomain() { try { error = null; From da3dfcf96a29a8cd0dbfe3b39bdcc14a27d661ad Mon Sep 17 00:00:00 2001 From: Hemachandar Date: Mon, 15 Dec 2025 19:55:20 +0530 Subject: [PATCH 476/599] feedback --- .../domains/add-domain/verify-[domain]/+page.svelte | 10 +++++----- .../settings/domains/+layout.svelte | 4 ++-- .../domains/add-domain/verify-[domain]/+page.svelte | 6 +++--- .../domains/add-domain/verify-[domain]/+page.svelte | 11 ++++++----- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte index 7328b7677..3de3854e3 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte @@ -28,13 +28,13 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); + const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let routeBase = `${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/domains`; let verified: boolean | undefined = $state(undefined); - let isSubmitting = $state(writable(false)); + const isSubmitting = writable(false); function getDefaultTab() { if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) { @@ -50,7 +50,7 @@ async function verify() { const isNewDomain = - data.domainsList.domains.find((rule) => rule.domain === page.params.domain) === + data.domainsList.domains.find((rule) => rule.domain === data.proxyRule.domain) === undefined; try { if (selectedTab !== 'nameserver') { @@ -68,7 +68,7 @@ } else if (isNewDomain && isCloud) { const domainData = await sdk.forConsole.domains.create({ teamId: $organization.$id, - domain: page.params.domain + domain: data.proxyRule.domain }); verified = domainData.nameservers.toLowerCase() === 'appwrite'; } @@ -108,7 +108,7 @@ -
+ import { onMount } from 'svelte'; import { page } from '$app/state'; - import { realtime } from '$lib/stores/sdk'; + import { realtime, RuleType } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; import { invalidate } from '$app/navigation'; import { type Models } from '@appwrite.io/console'; @@ -10,7 +10,7 @@ return realtime.forProject(page.params.region, ['console', 'project'], (response) => { if (response.events.includes('rules.*.update')) { const proxyRule = response.payload as Models.ProxyRule; - if (proxyRule.type === 'api') { + if (proxyRule.type === RuleType.API) { invalidate(Dependencies.DOMAINS); } } diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte index dd663b533..e6dcf8799 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte @@ -28,7 +28,7 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); + const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); @@ -50,7 +50,7 @@ async function verify() { const isNewDomain = - data.domainsList.domains.find((rule) => rule.domain === page.params.domain) === + data.domainsList.domains.find((rule) => rule.domain === data.proxyRule.domain) === undefined; try { if (selectedTab !== 'nameserver') { @@ -68,7 +68,7 @@ } else if (isNewDomain && isCloud) { const domainData = await sdk.forConsole.domains.create({ teamId: $organization.$id, - domain: page.params.domain + domain: data.proxyRule.domain }); verified = domainData.nameservers.toLowerCase() === 'appwrite'; } diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte index 543934d1f..2c93f0e47 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte @@ -28,13 +28,13 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(page.params.domain)); + const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); let routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`; let verified: boolean | undefined = $state(undefined); - let isSubmitting = $state(writable(false)); + const isSubmitting = writable(false); function getDefaultTab() { if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_SITES) { @@ -50,7 +50,8 @@ async function verify() { const isNewDomain = - data.domainsList.domains.findIndex((rule) => rule.domain === page.params.domain) === -1; + data.domainsList.domains.findIndex((rule) => rule.domain === data.proxyRule.domain) === + -1; try { if (selectedTab !== 'nameserver') { const ruleData = await sdk @@ -67,7 +68,7 @@ } else if (isNewDomain && isCloud) { const domainData = await sdk.forConsole.domains.create({ teamId: $organization.$id, - domain: page.params.domain + domain: data.proxyRule.domain }); verified = domainData.nameservers.toLowerCase() === 'appwrite'; } @@ -107,7 +108,7 @@ - + Date: Tue, 16 Dec 2025 11:01:15 +0530 Subject: [PATCH 477/599] fix null domainsList --- .../function-[function]/domains/add-domain/+page.svelte | 2 +- .../function-[function]/domains/add-domain/+page.ts | 2 +- .../domains/add-domain/verify-[domain]/+page.ts | 2 +- .../settings/domains/add-domain/+page.svelte | 2 +- .../settings/domains/add-domain/+page.ts | 8 ++++---- .../settings/domains/add-domain/verify-[domain]/+page.ts | 2 +- .../sites/site-[site]/domains/add-domain/+page.svelte | 2 +- .../sites/site-[site]/domains/add-domain/+page.ts | 2 +- .../domains/add-domain/verify-[domain]/+page.ts | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte index e17c349e9..89f2bb4c2 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte @@ -48,7 +48,7 @@ async function addDomain() { const apexDomain = getApexDomain(domainName); - let domain = data.domainsList?.domains.find((d: Models.Domain) => d.domain === apexDomain); + let domain = data.domainsList.domains.find((d: Models.Domain) => d.domain === apexDomain); if (apexDomain && !domain && isCloud) { try { diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.ts b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.ts index 532196190..a1f08feed 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.ts @@ -18,7 +18,7 @@ export const load = async ({ parent, depends, params }) => { sdk.forProject(params.region, params.project).vcs.listInstallations(), isCloud ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts index 9a83b58f9..253859ee4 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts @@ -18,7 +18,7 @@ export const load = async ({ depends, parent, params, url }) => { ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte index 19383b490..2f4250d19 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte @@ -30,7 +30,7 @@ async function addDomain() { const apexDomain = getApexDomain(domainName); - let domain = data.domains?.domains.find((d: Models.Domain) => d.domain === apexDomain); + let domain = data.domainsList.domains.find((d: Models.Domain) => d.domain === apexDomain); if (apexDomain && !domain && isCloud) { try { diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.ts index a62c7f29c..2520b9970 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.ts @@ -1,4 +1,4 @@ -import { Query } from '@appwrite.io/console'; +import { Query, type Models } from '@appwrite.io/console'; import { sdk } from '$lib/stores/sdk'; import { RuleTrigger, RuleType } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants.js'; @@ -8,17 +8,17 @@ export const load = async ({ depends, params, parent }) => { const { organization } = await parent(); depends(Dependencies.DOMAINS); - const [rules, domains] = await Promise.all([ + const [rules, domainsList] = await Promise.all([ sdk.forProject(params.region, params.project).proxy.listRules({ queries: [Query.equal('type', RuleType.API), Query.equal('trigger', RuleTrigger.MANUAL)] }), isCloud ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { rules, - domains + domainsList }; }; diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts index 6d4c31dda..d4a8587b7 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts @@ -18,7 +18,7 @@ export const load = async ({ depends, parent, params, url }) => { ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte index 0594d66c5..b4288a1f9 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte @@ -58,7 +58,7 @@ async function addDomain() { const apexDomain = getApexDomain(domainName); const isSiteDomain = domainName.endsWith($regionalConsoleVariables._APP_DOMAIN_SITES); - let domain = data.domainsList?.domains.find((d) => d.domain === apexDomain); + let domain = data.domainsList.domains.find((d) => d.domain === apexDomain); if (isCloud && apexDomain && !domain && !isSiteDomain) { try { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.ts index f403750b5..dfff015a1 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.ts @@ -20,7 +20,7 @@ export const load = async ({ parent, depends, params }) => { ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts index 71a7ce51a..4657b835a 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts @@ -18,7 +18,7 @@ export const load = async ({ parent, depends, params, url }) => { ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) - : Promise.resolve(null) + : Promise.resolve({ total: 0, domains: [] }) ]); return { From b1976e058f4d091d02ea754402002e5464620ad7 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 16 Dec 2025 14:49:29 +0530 Subject: [PATCH 478/599] fix: width. --- src/routes/(console)/account/payments/paymentMethods.svelte | 2 +- .../organization-[organization]/billing/paymentMethods.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/account/payments/paymentMethods.svelte b/src/routes/(console)/account/payments/paymentMethods.svelte index 3c2b83ef5..52a974921 100644 --- a/src/routes/(console)/account/payments/paymentMethods.svelte +++ b/src/routes/(console)/account/payments/paymentMethods.svelte @@ -59,7 +59,7 @@ Date: Tue, 16 Dec 2025 14:53:07 +0530 Subject: [PATCH 479/599] fix: table overflows for payments. --- src/lib/components/cardGrid.svelte | 3 ++- src/routes/(console)/account/payments/paymentMethods.svelte | 2 +- .../organization-[organization]/billing/paymentHistory.svelte | 2 +- .../organization-[organization]/billing/paymentMethods.svelte | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/components/cardGrid.svelte b/src/lib/components/cardGrid.svelte index c9c3c0ddd..d378a9c66 100644 --- a/src/lib/components/cardGrid.svelte +++ b/src/lib/components/cardGrid.svelte @@ -1,6 +1,7 @@ @@ -16,7 +17,7 @@ {/if} -
+
diff --git a/src/routes/(console)/account/payments/paymentMethods.svelte b/src/routes/(console)/account/payments/paymentMethods.svelte index 52a974921..8e53a8d3d 100644 --- a/src/routes/(console)/account/payments/paymentMethods.svelte +++ b/src/routes/(console)/account/payments/paymentMethods.svelte @@ -51,7 +51,7 @@ $: hasPaymentError = filteredMethods.some((method) => method?.lastError || method?.expired); - + Payment methods View or update your payment methods. These can be applied to any organizations you have created. diff --git a/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte b/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte index d8085642a..552288765 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte @@ -85,7 +85,7 @@ ]); - + Payment history Transaction history for this organization. Download invoices for more details about your payments. diff --git a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte index 1f5edf80a..124518f1e 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte @@ -109,7 +109,7 @@ backupPaymentMethod?.expired; - + Payment methods View or update your organization payment methods here. From 957617ab3252b2c991efcf581757534b1ce28ecb Mon Sep 17 00:00:00 2001 From: Hemachandar Date: Tue, 16 Dec 2025 16:57:44 +0530 Subject: [PATCH 480/599] Add CNAME warning for apex domains --- .../add-domain/verify-[domain]/+page.svelte | 37 +++++++++------- .../domains/retryDomainModal.svelte | 42 ++++++++++--------- .../add-domain/verify-[domain]/+page.svelte | 36 +++++++++------- .../settings/domains/retryDomainModal.svelte | 36 +++++++++------- .../add-domain/verify-[domain]/+page.svelte | 37 +++++++++------- .../domains/retryDomainModal.svelte | 36 +++++++++------- 6 files changed, 126 insertions(+), 98 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte index 3de3854e3..41d1b541e 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte @@ -20,7 +20,6 @@ import Wizard from '$lib/layout/wizard.svelte'; import { base } from '$app/paths'; import { writable } from 'svelte/store'; - import { isASubdomain } from '$lib/helpers/tlds'; import NameserverTable from '$lib/components/domains/nameserverTable.svelte'; import RecordTable from '$lib/components/domains/recordTable.svelte'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; @@ -28,24 +27,30 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); + + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) && + $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); - let routeBase = `${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/domains`; let verified: boolean | undefined = $state(undefined); const isSubmitting = writable(false); function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; } async function verify() { @@ -131,7 +136,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -139,7 +144,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -147,7 +152,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -155,7 +160,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte index ea220e5b1..391321a9b 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte @@ -8,7 +8,6 @@ import { Dependencies } from '$lib/constants'; import type { Models } from '@appwrite.io/console'; import { page } from '$app/state'; - import { isASubdomain } from '$lib/helpers/tlds'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; import { isCloud } from '$lib/system'; import { Divider, Tabs } from '@appwrite.io/pink-svelte'; @@ -23,25 +22,30 @@ selectedProxyRule: Models.ProxyRule; } = $props(); - const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) && + $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); - - function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } - } - let error = $state(null); let verified = $state(false); + function getDefaultTab() { + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; + } + async function retryProxyRule() { try { error = null; @@ -90,7 +94,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_FUNCTIONS && $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -98,7 +102,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -106,7 +110,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -114,7 +118,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte index e6dcf8799..f0312de38 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte @@ -20,7 +20,6 @@ import Wizard from '$lib/layout/wizard.svelte'; import { base } from '$app/paths'; import { writable } from 'svelte/store'; - import { isASubdomain } from '$lib/helpers/tlds'; import NameserverTable from '$lib/components/domains/nameserverTable.svelte'; import RecordTable from '$lib/components/domains/recordTable.svelte'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; @@ -28,7 +27,22 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); + + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); @@ -37,15 +51,7 @@ const isSubmitting = writable(false); function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; } async function verify() { @@ -130,7 +136,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -138,7 +144,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -146,7 +152,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -154,7 +160,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte index 1d1e8fb83..bd77890a8 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte @@ -8,7 +8,6 @@ import { Dependencies } from '$lib/constants'; import type { Models } from '@appwrite.io/console'; import { page } from '$app/state'; - import { isASubdomain } from '$lib/helpers/tlds'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; import { isCloud } from '$lib/system'; import { Divider, Tabs } from '@appwrite.io/pink-svelte'; @@ -23,23 +22,28 @@ selectedProxyRule: Models.ProxyRule; } = $props(); - const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); - let error = $state(null); let verified = $state(false); function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; } async function retryDomain() { @@ -90,7 +94,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -98,7 +102,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -106,7 +110,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -114,7 +118,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte index 2c93f0e47..80fba1842 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte @@ -20,7 +20,6 @@ import Wizard from '$lib/layout/wizard.svelte'; import { base } from '$app/paths'; import { writable } from 'svelte/store'; - import { isASubdomain } from '$lib/helpers/tlds'; import RecordTable from '$lib/components/domains/recordTable.svelte'; import NameserverTable from '$lib/components/domains/nameserverTable.svelte'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; @@ -28,24 +27,30 @@ let { data } = $props(); const ruleId = page.url.searchParams.get('rule'); - const isSubDomain = $derived.by(() => isASubdomain(data.proxyRule.domain)); + + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_SITES) && + $regionalConsoleVariables._APP_DOMAIN_SITES !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); - let routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`; let verified: boolean | undefined = $state(undefined); const isSubmitting = writable(false); function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_SITES) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; } async function verify() { @@ -131,7 +136,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_SITES && $regionalConsoleVariables._APP_DOMAIN_SITES !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -139,7 +144,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -147,7 +152,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -155,7 +160,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte index 937e1d4d1..6e36ac2ec 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte @@ -10,7 +10,6 @@ import { Divider, Tabs } from '@appwrite.io/pink-svelte'; import { isCloud } from '$lib/system'; import { page } from '$app/state'; - import { isASubdomain } from '$lib/helpers/tlds'; import NameserverTable from '$lib/components/domains/nameserverTable.svelte'; import RecordTable from '$lib/components/domains/recordTable.svelte'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; @@ -23,23 +22,28 @@ selectedProxyRule: Models.ProxyRule; } = $props(); - const isSubDomain = $derived.by(() => isASubdomain(selectedProxyRule?.domain)); + const showCNAMETab = $derived( + Boolean($regionalConsoleVariables._APP_DOMAIN_SITES) && + $regionalConsoleVariables._APP_DOMAIN_SITES !== 'localhost' + ); + const showATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1' + ); + const showAAAATab = $derived( + !isCloud && + Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1' + ); + const showNSTab = isCloud; let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>(getDefaultTab()); - let error = $state(null); let verified = $state(false); function getDefaultTab() { - if (isSubDomain && $regionalConsoleVariables._APP_DOMAIN_SITES) { - return 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - return 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - return 'aaaa'; - } else { - return 'nameserver'; - } + return showCNAMETab ? 'cname' : showATab ? 'a' : showAAAATab ? 'aaaa' : 'nameserver'; } async function retryDomain() { @@ -90,7 +94,7 @@
- {#if isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_SITES && $regionalConsoleVariables._APP_DOMAIN_SITES !== 'localhost'} + {#if showCNAMETab} (selectedTab = 'cname')} @@ -98,7 +102,7 @@ CNAME {/if} - {#if isCloud} + {#if showNSTab} (selectedTab = 'nameserver')} @@ -106,7 +110,7 @@ Nameservers {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'} + {#if showATab} (selectedTab = 'a')} @@ -114,7 +118,7 @@ A {/if} - {#if !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'} + {#if showAAAATab} (selectedTab = 'aaaa')} From a1a95c7467dc994956eabdc4ba3621a33277fb8d Mon Sep 17 00:00:00 2001 From: Aditya Oberai Date: Tue, 16 Dec 2025 23:48:55 +0530 Subject: [PATCH 481/599] Enable Imagine promo on console --- src/routes/(console)/bottomAlerts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index f5ee4777c..09aeaecfb 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -7,7 +7,7 @@ import { showBottomModalAlert } from '$lib/stores/bottom-alerts'; -const SHOW_IMAGINE_PROMO = false; +const SHOW_IMAGINE_PROMO = true; const listOfPromotions: BottomModalAlertItem[] = []; @@ -34,7 +34,7 @@ if (isCloud && SHOW_IMAGINE_PROMO) { light: '#333333', dark: '#CCCCCC' }, - link: () => 'https://cloud.appwrite.io', + link: () => 'https://studio.imagine.dev', external: true, hideOnClick: true }, From bc5837c7cb7bf1305e17e2299af738293d9672e0 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 17 Dec 2025 00:12:51 +0530 Subject: [PATCH 482/599] Update link to Imagine homepage --- src/routes/(console)/bottomAlerts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index 09aeaecfb..66f259e36 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -34,7 +34,7 @@ if (isCloud && SHOW_IMAGINE_PROMO) { light: '#333333', dark: '#CCCCCC' }, - link: () => 'https://studio.imagine.dev', + link: () => 'https://imagine.dev', external: true, hideOnClick: true }, From 02e15a7a82774afe310b1b9431afd4b378ab52bf Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 17 Dec 2025 01:52:58 +0530 Subject: [PATCH 483/599] Fix styling for Imagine promo component --- src/lib/components/promos/imagine.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/components/promos/imagine.svelte b/src/lib/components/promos/imagine.svelte index 0f275b3da..ff316b51a 100644 --- a/src/lib/components/promos/imagine.svelte +++ b/src/lib/components/promos/imagine.svelte @@ -22,10 +22,12 @@ position: relative; background-color: #000000; border: 0.795px solid var(--border-neutral-strong); + overflow: hidden; } .imagine-canvas { position: absolute; + inset: 0; } .imagine-logo { From 900ea900a3a9bd9ca914e2bde13580ea7e7e9813 Mon Sep 17 00:00:00 2001 From: Aditya Oberai Date: Wed, 17 Dec 2025 05:02:14 +0530 Subject: [PATCH 484/599] Fix Imagine promo copy --- src/routes/(console)/bottomAlerts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index 66f259e36..1d0d86045 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -16,7 +16,7 @@ if (isCloud && SHOW_IMAGINE_PROMO) { id: 'modal:imagine.dev', backgroundComponent: Imagine, title: 'Introducing Imagine', - message: 'the most complete AI builder to date', + message: 'The most complete AI builder to date', importance: 8, scope: 'everywhere', plan: 'free', From 88389222f58025cbf9bb791e1a0bce9fd6a37c29 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Dec 2025 08:53:57 +0530 Subject: [PATCH 485/599] Fix status code filter to match responseStatusCode column ID (#2690) * Initial plan * Fix status code filter to use case-insensitive includes check Co-authored-by: EVDOG4LIFE <23223867+EVDOG4LIFE@users.noreply.github.com> * Apply formatting fixes (remove trailing whitespace) Co-authored-by: EVDOG4LIFE <23223867+EVDOG4LIFE@users.noreply.github.com> * Remove unnecessary test file per code review feedback Co-authored-by: EVDOG4LIFE <23223867+EVDOG4LIFE@users.noreply.github.com> * Use strict equality check for responseStatusCode Co-authored-by: EVDOG4LIFE <23223867+EVDOG4LIFE@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: EVDOG4LIFE <23223867+EVDOG4LIFE@users.noreply.github.com> --- src/lib/components/filters/quickFilters.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/filters/quickFilters.ts b/src/lib/components/filters/quickFilters.ts index 1ed3194a7..2e9bd9306 100644 --- a/src/lib/components/filters/quickFilters.ts +++ b/src/lib/components/filters/quickFilters.ts @@ -45,7 +45,7 @@ export function addFilterAndApply( if (value || arrayValues?.length) { if (colId === 'sourceSize' || colId === 'buildSize') { addSizeFilter(value, colId, columns); - } else if (colId === 'statusCode') { + } else if (colId === 'responseStatusCode') { addStatusCodeFilter(value, colId, columns); } else if ( colId === '$createdAt' || From a2667f8d4f70d5bf9ff5f4e22bf7e484a115035b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 17:32:36 -0800 Subject: [PATCH 486/599] Update Console to handle specifications for self-hosted (#2685) Update Console to conditionally call listSpecifications only on Cloud - Modified functions layout loader to check isCloud before calling listSpecifications - Modified sites settings page loader to check isCloud before calling listSpecifications - Updated function create pages to handle empty specifications array safely - Updated updateResourceLimits components to handle empty specifications array safely - On self-hosted, specifications will be empty and not passed to backend, allowing default spec --- .../project-[region]-[project]/functions/+layout.ts | 5 ++++- .../functions/create-function/manual/+page.svelte | 4 ++-- .../create-function/repository-[repository]/+page.svelte | 4 ++-- .../create-function/template-[template]/+page.svelte | 4 ++-- .../function-[function]/settings/updateResourceLimits.svelte | 2 +- .../sites/site-[site]/settings/+page.ts | 5 ++++- .../sites/site-[site]/settings/updateResourceLimits.svelte | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/+layout.ts b/src/routes/(console)/project-[region]-[project]/functions/+layout.ts index 1afe03dd3..b22ab7609 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/+layout.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/+layout.ts @@ -3,6 +3,7 @@ import Header from './header.svelte'; import { sdk } from '$lib/stores/sdk'; import { Query } from '@appwrite.io/console'; import { Dependencies } from '$lib/constants'; +import { isCloud } from '$lib/system'; import type { LayoutLoad } from './$types'; export const load: LayoutLoad = async ({ depends, params }) => { @@ -13,7 +14,9 @@ export const load: LayoutLoad = async ({ depends, params }) => { sdk .forProject(params.region, params.project) .vcs.listInstallations({ queries: [Query.limit(100)] }), - sdk.forProject(params.region, params.project).functions.listSpecifications() + isCloud + ? sdk.forProject(params.region, params.project).functions.listSpecifications() + : Promise.resolve({ specifications: [], total: 0 }) ]); return { diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte index f84db9f7e..e53837412 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/manual/+page.svelte @@ -38,7 +38,7 @@ return { value, label, leadingHtml }; }); - const specificationOptions = data.specificationsList.specifications.map((size) => ({ + const specificationOptions = (data.specificationsList?.specifications ?? []).map((size) => ({ label: `${size.cpus} CPU, ${size.memory} MB RAM` + (!size.enabled ? ` (Upgrade to use this)` : ''), @@ -58,7 +58,7 @@ let roles: string[] = []; let variables: Partial[] = []; let files: FileList; - let specification = specificationOptions[0].value; + let specification = specificationOptions[0]?.value || ''; async function create() { try { diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte index 476b1d27c..9a06f70dd 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte @@ -25,7 +25,7 @@ export let data; - const specificationOptions = data.specificationsList.specifications.map((size) => ({ + const specificationOptions = (data.specificationsList?.specifications ?? []).map((size) => ({ label: `${size.cpus} CPU, ${size.memory} MB RAM` + (!size.enabled ? ` (Upgrade to use this)` : ''), @@ -55,7 +55,7 @@ let rootDir = './'; let variables: Partial[] = []; let silentMode = false; - let specification = specificationOptions[0].value; + let specification = specificationOptions[0]?.value || ''; let detectingRuntime = true; diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte index 3eb10a02f..98c8bf7ea 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte @@ -34,7 +34,7 @@ export let data; - const specificationOptions = data.specificationsList.specifications.map((size) => ({ + const specificationOptions = (data.specificationsList?.specifications ?? []).map((size) => ({ label: `${size.cpus} CPU, ${size.memory} MB RAM` + (!size.enabled ? ` (Upgrade to use this)` : ''), @@ -65,7 +65,7 @@ let selectedScopes: string[] = []; let execute = true; let variables: Partial[] = []; - let specification = specificationOptions[0].value; + let specification = specificationOptions[0]?.value || ''; onMount(async () => { if (!$installation?.$id) { diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte index c3199dcf5..30dcd26ff 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte @@ -65,7 +65,7 @@ } } - const options = specs.specifications.map((spec) => ({ + const options = (specs?.specifications ?? []).map((spec) => ({ label: `${spec.cpus} CPU, ${spec.memory} MB RAM`, value: spec.slug, disabled: !spec.enabled diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts index 1d856b016..d71de3091 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts @@ -1,5 +1,6 @@ import { sdk } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; +import { isCloud } from '$lib/system'; export const load = async ({ params, depends, parent }) => { depends(Dependencies.VARIABLES); @@ -14,7 +15,9 @@ export const load = async ({ params, depends, parent }) => { .sites.listVariables({ siteId: params.site }), sdk.forProject(params.region, params.project).sites.listFrameworks(), sdk.forProject(params.region, params.project).vcs.listInstallations(), - sdk.forProject(params.region, params.project).sites.listSpecifications() + isCloud + ? sdk.forProject(params.region, params.project).sites.listSpecifications() + : Promise.resolve({ specifications: [], total: 0 }) ]); // Conflicting variables first diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateResourceLimits.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateResourceLimits.svelte index 40fb7a83f..bc4dcea09 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateResourceLimits.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateResourceLimits.svelte @@ -58,7 +58,7 @@ } } - const options = specs.specifications.map((spec) => ({ + const options = (specs?.specifications ?? []).map((spec) => ({ label: `${spec.cpus} CPU, ${spec.memory} MB RAM`, value: spec.slug, disabled: !spec.enabled From 3a2bdcd6e9e02ac49e42e05edf6ac640f09fc027 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 19 Dec 2025 21:05:34 +0530 Subject: [PATCH 487/599] update: smaller payloads :D --- src/lib/commandCenter/searchers/projects.ts | 6 +++++- src/lib/components/breadcrumbs.svelte | 3 ++- src/routes/(console)/+layout.ts | 6 +++++- .../(console)/onboarding/create-project/+page.ts | 2 +- .../(console)/organization-[organization]/+page.ts | 3 ++- .../change-plan/+page.svelte | 11 +++++++---- .../usage/[[invoice]]/+page.ts | 12 ++++++++---- src/routes/(console)/supportWizard.svelte | 4 +++- src/routes/(public)/functions/deploy/+page.svelte | 12 ++++++++---- src/routes/(public)/sites/deploy/+page.svelte | 14 +++++++++----- .../(public)/template-[template]/+page.svelte | 12 ++++++++---- 11 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/lib/commandCenter/searchers/projects.ts b/src/lib/commandCenter/searchers/projects.ts index d9c5c8da0..6ecfe955d 100644 --- a/src/lib/commandCenter/searchers/projects.ts +++ b/src/lib/commandCenter/searchers/projects.ts @@ -38,7 +38,11 @@ export const projectsSearcher = (async (query: string) => { } const { projects } = await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', get(organization).$id), Query.orderDesc('')] + queries: [ + Query.equal('teamId', get(organization).$id), + Query.orderDesc(''), + Query.select(['$id', 'name', 'region']) + ] }); return projects diff --git a/src/lib/components/breadcrumbs.svelte b/src/lib/components/breadcrumbs.svelte index 6a7fe4878..7f1a59c47 100644 --- a/src/lib/components/breadcrumbs.svelte +++ b/src/lib/components/breadcrumbs.svelte @@ -140,7 +140,8 @@ queries: [ Query.equal('teamId', organizationId ?? page.data.currentOrgId), Query.limit(5), - Query.orderDesc('$updatedAt') + Query.orderDesc('$updatedAt'), + Query.select(['$id', 'name', 'region', 'teamId']) ] })) ?? loadedProjects; diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 3cf1478a3..44956eb5d 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -35,7 +35,11 @@ export const load: LayoutLoad = async ({ depends, parent }) => { try { projectsCount = ( await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', currentOrgId), Query.limit(1)] + queries: [ + Query.equal('teamId', currentOrgId), + Query.limit(1), + Query.select(['$id']) + ] }) ).total; } catch (e) { diff --git a/src/routes/(console)/onboarding/create-project/+page.ts b/src/routes/(console)/onboarding/create-project/+page.ts index 1dc717add..b38775355 100644 --- a/src/routes/(console)/onboarding/create-project/+page.ts +++ b/src/routes/(console)/onboarding/create-project/+page.ts @@ -65,7 +65,7 @@ export const load: PageLoad = async ({ parent }) => { let projects: Models.ProjectList = null; try { projects = await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', org.$id), Query.limit(1)] + queries: [Query.equal('teamId', org.$id), Query.limit(1), Query.select(['$id'])] }); } catch (e) { redirect(303, `${base}/organization-${org.$id}`); diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index bdbb21114..fcfaaccdd 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -24,7 +24,8 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.offset(offset), Query.equal('teamId', params.organization), Query.limit(limit), - Query.orderDesc('') + Query.orderDesc(''), + Query.select(['$id', 'name', 'region', 'status']) ], search: search || undefined }); diff --git a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte index 8d4e7110a..cc8d94dc4 100644 --- a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte +++ b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte @@ -106,10 +106,13 @@ } try { - allProjects = await sdk.forConsole.projects.list([ - Query.equal('teamId', data.organization.$id), - Query.limit(1000) - ]); + allProjects = await sdk.forConsole.projects.list({ + queries: [ + Query.equal('teamId', data.organization.$id), + Query.limit(1000), + Query.select(['$id', 'name']) // TODO: @itznotabug, check if we need to add `$createdAt` + ] + }); } catch { allProjects = { projects: [] }; } diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts index 8fd36fadf..05fd3ff84 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts @@ -1,7 +1,7 @@ import { sdk } from '$lib/stores/sdk'; import type { PageLoad } from './$types'; -import { Query } from '@appwrite.io/console'; import type { UsageProjectInfo } from '../../store'; +import { type Models, Query } from '@appwrite.io/console'; import type { Invoice, OrganizationUsage } from '$lib/sdk/billing'; export const load: PageLoad = async ({ params, parent }) => { @@ -70,14 +70,18 @@ export const load: PageLoad = async ({ params, parent }) => { // all this to get the project's name and region! function getUsageProjects(usage: OrganizationUsage) { return (async () => { - const projects: Record = {}; const limit = 100; - const requests = []; + const requests: Array> = []; + const projects: Record = {}; for (let index = 0; index < usage.projects.length; index += limit) { const chunkIds = usage.projects.slice(index, index + limit).map((p) => p.projectId); requests.push( sdk.forConsole.projects.list({ - queries: [Query.limit(limit), Query.equal('$id', chunkIds)] + queries: [ + Query.limit(limit), + Query.equal('$id', chunkIds), + Query.select(['$id', 'name', 'region']) + ] }) ); } diff --git a/src/routes/(console)/supportWizard.svelte b/src/routes/(console)/supportWizard.svelte index c53c0c4a3..eabf8a26b 100644 --- a/src/routes/(console)/supportWizard.svelte +++ b/src/routes/(console)/supportWizard.svelte @@ -80,7 +80,9 @@ onMount(async () => { // Filter projects by organization ID using server-side queries const projectList = await sdk.forConsole.projects.list({ - queries: $organization?.$id ? [Query.equal('teamId', $organization.$id)] : [] + queries: $organization?.$id + ? [Query.equal('teamId', $organization.$id), Query.select(['$id', 'name'])] + : [] }); projectOptions = projectList.projects.map((project) => ({ value: project.$id, diff --git a/src/routes/(public)/functions/deploy/+page.svelte b/src/routes/(public)/functions/deploy/+page.svelte index 4b353d17b..0399cf3a3 100644 --- a/src/routes/(public)/functions/deploy/+page.svelte +++ b/src/routes/(public)/functions/deploy/+page.svelte @@ -43,7 +43,11 @@ loadingProjects = true; projects = await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', selectedOrg), Query.orderDesc('')] + queries: [ + Query.equal('teamId', selectedOrg), + Query.orderDesc(''), + Query.select(['$id', 'name']) + ] }); selectedProject = projects?.total ? projects.projects[0].$id : null; @@ -215,9 +219,9 @@ : undefined} disabled={loadingProjects} options={[ - ...(projects?.projects?.map((p) => ({ - label: p.name, - value: p.$id + ...(projects?.projects?.map((project) => ({ + label: project.name, + value: project.$id })) ?? []), { label: 'Create project', diff --git a/src/routes/(public)/sites/deploy/+page.svelte b/src/routes/(public)/sites/deploy/+page.svelte index ef6000fbb..0d258793a 100644 --- a/src/routes/(public)/sites/deploy/+page.svelte +++ b/src/routes/(public)/sites/deploy/+page.svelte @@ -48,7 +48,11 @@ async function fetchProjects() { loadingProjects = true; projects = await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', selectedOrg), Query.orderDesc('')] + queries: [ + Query.equal('teamId', selectedOrg), + Query.orderDesc(''), + Query.select(['$id', 'name']) + ] }); selectedProject = projects?.total ? projects.projects[0].$id : null; @@ -87,7 +91,7 @@ loadingProjects = false; } } else { - const project = projects.projects.find((p) => p.$id === selectedProject); + const project = projects.projects.find((project) => project.$id === selectedProject); if (!project) { addNotification({ type: 'error', message: 'Selected project not found' }); return; @@ -371,9 +375,9 @@ : undefined} disabled={loadingProjects} options={[ - ...(projects?.projects?.map((p) => ({ - label: p.name, - value: p.$id + ...(projects?.projects?.map((project) => ({ + label: project.name, + value: project.$id })) ?? []), { label: 'Create project', diff --git a/src/routes/(public)/template-[template]/+page.svelte b/src/routes/(public)/template-[template]/+page.svelte index b82f6787c..63a8f5001 100644 --- a/src/routes/(public)/template-[template]/+page.svelte +++ b/src/routes/(public)/template-[template]/+page.svelte @@ -55,7 +55,11 @@ async function fetchProjects() { projects = await sdk.forConsole.projects.list({ - queries: [Query.equal('teamId', selectedOrg), Query.orderDesc('')] + queries: [ + Query.equal('teamId', selectedOrg), + Query.orderDesc(''), + Query.select(['$id', 'name']) + ] }); selectedProject = projects?.total ? projects.projects[0].$id : null; } @@ -180,9 +184,9 @@ label="Project" required options={[ - ...projects.projects.map((p) => ({ - label: p.name, - value: p.$id + ...projects.projects.map((project) => ({ + label: project.name, + value: project.$id })), { label: 'Create project', From b1784617d9d39c81d60269774244a4376a923ec9 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 13:35:12 +0530 Subject: [PATCH 488/599] add: todo for later. --- src/routes/(console)/organization-[organization]/+page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index fcfaaccdd..0f46b232c 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -25,7 +25,7 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.equal('teamId', params.organization), Query.limit(limit), Query.orderDesc(''), - Query.select(['$id', 'name', 'region', 'status']) + Query.select(['$id', 'name', 'region', 'status']) /* NOTE: @itznotabug - status is cloud only */ ], search: search || undefined }); From c0f5b62a2780581a04723ed25af777ca2463d3a9 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 18:00:27 +0530 Subject: [PATCH 489/599] remove: platforms dependency. add: multi select table on platforms for batch delete. --- src/lib/constants.ts | 1 - .../organization-[organization]/+page.ts | 3 +- .../overview/platforms/+page.svelte | 149 +++++++++++------- .../overview/platforms/+page.ts | 11 +- .../platforms/[platform]/delete.svelte | 2 +- .../overview/platforms/createAndroid.svelte | 5 +- .../overview/platforms/createApple.svelte | 5 +- .../overview/platforms/createFlutter.svelte | 5 +- .../platforms/createReactNative.svelte | 5 +- .../overview/platforms/createWeb.svelte | 5 +- 10 files changed, 110 insertions(+), 81 deletions(-) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index f6a61e0d1..33c900742 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -63,7 +63,6 @@ export enum Dependencies { DEPLOYMENTS = 'dependency:deployments', EXECUTIONS = 'dependency:executions', PLATFORM = 'dependency:platform', - PLATFORMS = 'dependency:platforms', KEY = 'dependency:key', KEYS = 'dependency:keys', DEV_KEY = 'dependency:dev_key', diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index 0f46b232c..dfd1d75fa 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -5,6 +5,7 @@ import { CARD_LIMIT, Dependencies } from '$lib/constants'; import type { PageLoad } from './$types'; import { redirect } from '@sveltejs/kit'; import { base } from '$app/paths'; +import { isCloud } from '$lib/system'; export const load: PageLoad = async ({ params, url, route, depends, parent }) => { const { scopes } = await parent(); @@ -25,7 +26,7 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.equal('teamId', params.organization), Query.limit(limit), Query.orderDesc(''), - Query.select(['$id', 'name', 'region', 'status']) /* NOTE: @itznotabug - status is cloud only */ + Query.select(['$id', 'name', 'platforms', 'region', ...(isCloud ? ['status'] : [])]) ], search: search || undefined }); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte index 1e3095139..8a383417d 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte @@ -1,4 +1,4 @@ - -{#if data.platforms.platforms.length} - - +{#if data.platforms.total} + + {#snippet header(root)} {#each $columns as column} {column.title} {/each} - - {#each data.platforms.platforms as platform} - - - {platform.name} - - - - - {PlatformTypes[platform.type]} - - - - {#if platform.type.includes('web') || platform.type === 'web'} - {platform.hostname || '—'} - {:else} - {platform.key || platform.hostname || '—'} - {/if} - - - {#if platform.$updatedAt} - - {:else} - never - {/if} - - - {/each} - + {/snippet} + + {#snippet children(root)} + {#each data.platforms.platforms as platform} + + + {platform.name} + + + + + {PlatformTypes[platform.type]} + + + + {#if platform.type.includes('web') || platform.type === 'web'} + {platform.hostname || '—'} + {:else} + {platform.key || platform.hostname || '—'} + {/if} + + + {#if platform.$updatedAt} + + {:else} + never + {/if} + + + {/each} + {/snippet} + {:else} { - depends(Dependencies.PLATFORMS); +export const load: PageLoad = async ({ parent }) => { + const { project } = await parent(); return { - platforms: await sdk.forConsole.projects.listPlatforms({ projectId: params.project }) + platforms: { + platforms: project.platforms, + total: project.platforms.length + } }; }; diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/delete.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/delete.svelte index 0b14c84c7..163cb4ed9 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/delete.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/delete.svelte @@ -17,7 +17,7 @@ projectId: $project.$id, platformId: $platform.$id }); - await invalidate(Dependencies.PLATFORMS); + await invalidate(Dependencies.PROJECT); showDelete = false; addNotification({ type: 'success', diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte index 3abd55aa9..87f37b791 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -134,10 +134,7 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. message: 'Platform created.' }); - await Promise.all([ - invalidate(Dependencies.PROJECT), - invalidate(Dependencies.PLATFORMS) - ]); + await invalidate(Dependencies.PROJECT); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte index 2a156b76d..6148712f0 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte @@ -97,10 +97,7 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj message: 'Platform created.' }); - await Promise.all([ - invalidate(Dependencies.PROJECT), - invalidate(Dependencies.PLATFORMS) - ]); + await invalidate(Dependencies.PROJECT); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte index 6c40f4489..b18cbaf78 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte @@ -187,10 +187,7 @@ client.ping(); message: 'Platform created.' }); - await Promise.all([ - invalidate(Dependencies.PROJECT), - invalidate(Dependencies.PLATFORMS) - ]); + await invalidate(Dependencies.PROJECT); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte index 0a55a52a9..7a475290b 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte @@ -128,10 +128,7 @@ EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.p message: 'Platform created.' }); - await Promise.all([ - invalidate(Dependencies.PROJECT), - invalidate(Dependencies.PLATFORMS) - ]); + await invalidate(Dependencies.PROJECT); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte index 4a708d32b..6dc27dbee 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte @@ -243,10 +243,7 @@ APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.project).c message: 'Platform created.' }); - await Promise.all([ - invalidate(Dependencies.PROJECT), - invalidate(Dependencies.PLATFORMS) - ]); + await invalidate(Dependencies.PROJECT); } catch (error) { trackError(error, Submit.PlatformCreate); addNotification({ From 2271b9a9f2cf75e14a99b6e04b6f76ab13efac84 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 19:20:35 +0530 Subject: [PATCH 490/599] remove: todo. --- .../organization-[organization]/change-plan/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte index cc8d94dc4..d0228e2cc 100644 --- a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte +++ b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte @@ -110,7 +110,7 @@ queries: [ Query.equal('teamId', data.organization.$id), Query.limit(1000), - Query.select(['$id', 'name']) // TODO: @itznotabug, check if we need to add `$createdAt` + Query.select(['$id', 'name']) ] }); } catch { From 51eb30b7d4be56b08a0ffa47fc37e4e60d2be3c0 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 19:25:53 +0530 Subject: [PATCH 491/599] update: query. --- .../(console)/organization-[organization]/settings/+page.ts | 4 +++- .../settings/deleteOrganizationModal.svelte | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/settings/+page.ts b/src/routes/(console)/organization-[organization]/settings/+page.ts index ffecda25a..42c229dd9 100644 --- a/src/routes/(console)/organization-[organization]/settings/+page.ts +++ b/src/routes/(console)/organization-[organization]/settings/+page.ts @@ -9,7 +9,9 @@ export const load: PageLoad = async ({ depends, params, parent }) => { depends(Dependencies.ORGANIZATION); const [projects, invoices] = await Promise.all([ - sdk.forConsole.projects.list({ queries: [Query.equal('teamId', params.organization)] }), + sdk.forConsole.projects.list({ + queries: [Query.equal('teamId', params.organization), Query.select(['$id', 'name'])] + }), isCloud ? sdk.forConsole.billing.listInvoices(params.organization) : undefined ]); diff --git a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte index dab95d83a..135d9b68c 100644 --- a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte +++ b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte @@ -19,8 +19,8 @@ export let showDelete = false; export let invoices: InvoiceList; - let error: string = null; + let error: string = null; let selectedTab = 'projects'; let organizationName: string = null; let estimation: EstimationDeleteOrganization; From 721f7d31d662fe341cdec2e9edf5367e2f20a2ae Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 19:27:24 +0530 Subject: [PATCH 492/599] update: query. --- src/routes/(public)/template-[template]/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(public)/template-[template]/+page.svelte b/src/routes/(public)/template-[template]/+page.svelte index 63a8f5001..600914e15 100644 --- a/src/routes/(public)/template-[template]/+page.svelte +++ b/src/routes/(public)/template-[template]/+page.svelte @@ -58,7 +58,7 @@ queries: [ Query.equal('teamId', selectedOrg), Query.orderDesc(''), - Query.select(['$id', 'name']) + Query.select(['$id', 'name', 'region']) ] }); selectedProject = projects?.total ? projects.projects[0].$id : null; From 59d4a4bb358dea699da1afcd3016cbbfd2737cff Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 20 Dec 2025 19:34:58 +0530 Subject: [PATCH 493/599] fix: lint. --- .../project-[region]-[project]/overview/platforms/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte index 8a383417d..c86b1b50d 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte @@ -162,7 +162,7 @@ resource="platform" columns={$columns} onDelete={handlePlatformDelete} - allowSelection={false /*$canWritePlatforms*/}> + allowSelection={false}> {#snippet header(root)} {#each $columns as column} From 2c8e4e732c1d8857db2f803d49d24374ba29a949 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Mon, 22 Dec 2025 13:34:21 +0530 Subject: [PATCH 494/599] fix: alert aligment issue in max file size card --- .../settings/updateMaxFileSize.svelte | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte index 6e8b681dc..f0b24c060 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte @@ -46,15 +46,12 @@ {#if isCloud} {@const size = humanFileSize(sizeToBytes(service, 'MB', 1000))} - - The {currentPlan.name} plan has a maximum upload file size limit of {Math.floor( - parseInt(size.value) - )}{size.unit}. - {#if $organization?.billingPlan === BillingPlan.FREE} - Upgrade to allow files of a larger size. - {/if} - - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} + + The {currentPlan.name} plan has a maximum upload file size limit of {Math.floor( + parseInt(size.value) + )}{size.unit}. Upgrade to allow files of a larger size. +
- {/if} -
-
+
+
+ {:else} + + The {currentPlan.name} plan has a maximum upload file size limit of {Math.floor( + parseInt(size.value) + )}{size.unit}. + + {/if} {/if} + Date: Mon, 22 Dec 2025 13:58:29 +0530 Subject: [PATCH 495/599] enable sign up with github button even if not checked --- src/routes/(public)/(guest)/register/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(public)/(guest)/register/+page.svelte b/src/routes/(public)/(guest)/register/+page.svelte index d07a552e8..d64cd76b8 100644 --- a/src/routes/(public)/(guest)/register/+page.svelte +++ b/src/routes/(public)/(guest)/register/+page.svelte @@ -130,7 +130,7 @@ secondary fullWidth on:click={onGithubLogin} - disabled={disabled || !terms}> + {disabled}> Sign up with GitHub From e57444fc5026ed440adf928a08327bb6571aba65 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Tue, 23 Dec 2025 12:48:31 +0530 Subject: [PATCH 496/599] fix: tooltip content truncated in billing ui table --- src/lib/components/progressbar/ProgressBar.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/progressbar/ProgressBar.svelte b/src/lib/components/progressbar/ProgressBar.svelte index a4cebc8ee..5d1b6e9cf 100644 --- a/src/lib/components/progressbar/ProgressBar.svelte +++ b/src/lib/components/progressbar/ProgressBar.svelte @@ -22,7 +22,7 @@
{#each $$props.data as item} - +
Date: Tue, 23 Dec 2025 12:53:27 +0530 Subject: [PATCH 497/599] Update ProgressBar.svelte --- src/lib/components/progressbar/ProgressBar.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/progressbar/ProgressBar.svelte b/src/lib/components/progressbar/ProgressBar.svelte index 5d1b6e9cf..4591e706e 100644 --- a/src/lib/components/progressbar/ProgressBar.svelte +++ b/src/lib/components/progressbar/ProgressBar.svelte @@ -22,7 +22,7 @@
{#each $$props.data as item} - +
Date: Tue, 23 Dec 2025 13:52:24 +0530 Subject: [PATCH 498/599] fix: add `organizationId`. --- src/lib/sdk/billing.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index f728ca5e8..11b5ba519 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -1424,10 +1424,10 @@ export class Billing { ); } - async listRegions(teamId: string): Promise { + async listRegions(organizationId: string): Promise { const path = `/console/regions`; const params = { - teamId + organizationId }; const uri = new URL(this.client.config.endpoint + path); return await this.client.call( From 66dafc601f49ae473cd9e3c3a1dbc7ea8d6635a6 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 23 Dec 2025 16:19:59 +0530 Subject: [PATCH 499/599] update: use `billingPlanId`. --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- src/lib/components/backupDatabaseAlert.svelte | 2 +- src/lib/components/backupRestoreBox.svelte | 2 +- .../components/billing/alerts/limitReached.svelte | 6 +++--- .../billing/alerts/missingPaymentMethod.svelte | 2 +- .../billing/alerts/newDevUpgradePro.svelte | 2 +- src/lib/components/billing/planExcess.svelte | 4 ++-- src/lib/components/billing/planSelection.svelte | 4 ++-- src/lib/components/billing/selectPlan.svelte | 2 +- src/lib/components/billing/usageRates.svelte | 8 ++++---- src/lib/components/bottomModalAlert.svelte | 2 +- src/lib/components/breadcrumbs.svelte | 2 +- src/lib/components/emptyCardImageCloud.svelte | 2 +- src/lib/components/feedback/feedback.svelte | 2 +- src/lib/components/roles/upgrade.svelte | 2 +- src/lib/components/support.svelte | 4 ++-- src/lib/layout/containerButton.svelte | 4 ++-- src/lib/layout/containerHeader.svelte | 14 +++++++------- src/lib/layout/createProject.svelte | 2 +- src/lib/stores/billing.ts | 10 +++++----- src/lib/stores/organization.ts | 3 ++- src/routes/(console)/+layout.svelte | 4 ++-- .../(console)/account/organizations/+page.svelte | 10 +++++----- src/routes/(console)/apply-credit/+page.svelte | 10 +++++----- src/routes/(console)/create-organization/+page.ts | 2 +- .../organization-[organization]/+page.svelte | 2 +- .../billing/+page.svelte | 8 +++++--- .../organization-[organization]/billing/+page.ts | 4 ++-- .../billing/availableCredit.svelte | 4 ++-- .../billing/budgetAlert.svelte | 4 ++-- .../billing/budgetCap.svelte | 2 +- .../billing/deleteOrgPayment.svelte | 4 ++-- .../billing/paymentMethods.svelte | 2 +- .../billing/planSummary.svelte | 2 +- .../billing/planSummaryOld.svelte | 9 +++++---- .../budgetLimitAlert.svelte | 2 +- .../change-plan/+page.svelte | 10 +++++----- .../change-plan/+page.ts | 2 +- .../organization-[organization]/header.svelte | 10 +++++----- .../members/+page.svelte | 6 +++--- .../usage/[[invoice]]/+page.svelte | 10 +++++----- .../usage/[[invoice]]/totalMembers.svelte | 8 ++++---- .../project-[region]-[project]/+layout.ts | 6 +++--- .../functions/+page.svelte | 6 +++++- .../create-function/(components)/details.svelte | 2 +- .../settings/updateResourceLimits.svelte | 2 +- .../functions/templates/+page.svelte | 2 +- .../templates/template-[template]/+page.svelte | 3 ++- .../settings/migrations/exportModal.svelte | 2 +- .../settings/smtp/+page.svelte | 4 ++-- .../settings/usage/[[invoice]]/+page.svelte | 10 +++++----- .../project-[region]-[project]/sites/+page.svelte | 2 +- .../settings/updateResourceLimits.svelte | 2 +- .../settings/updateMaxFileSize.svelte | 2 +- src/routes/(console)/supportWizard.svelte | 2 +- src/routes/(console)/wizard/feedback/step1.svelte | 2 +- 57 files changed, 131 insertions(+), 122 deletions(-) diff --git a/package.json b/package.json index 15cb88fa7..d1861c08f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7492f49f..372b725b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107 - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107 + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8 + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,8 +272,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8} version: 1.10.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/components/backupDatabaseAlert.svelte b/src/lib/components/backupDatabaseAlert.svelte index 1c2ceed16..932a14e22 100644 --- a/src/lib/components/backupDatabaseAlert.svelte +++ b/src/lib/components/backupDatabaseAlert.svelte @@ -18,7 +18,7 @@ {#if $showPolicyAlert && isCloud && $organization?.$id && page.url.pathname.match(/\/databases\/database-[^/]+$/)} - {@const isFreePlan = $organization?.billingPlan === BillingPlan.FREE} + {@const isFreePlan = $organization?.billingPlanId === BillingPlan.FREE} {@const subtitle = isFreePlan ? 'Upgrade your plan to ensure your data stays safe and backed up' diff --git a/src/lib/components/backupRestoreBox.svelte b/src/lib/components/backupRestoreBox.svelte index f1de9d3ba..f4d6c5fff 100644 --- a/src/lib/components/backupRestoreBox.svelte +++ b/src/lib/components/backupRestoreBox.svelte @@ -125,7 +125,7 @@ onMount(() => { // fast path: don't subscribe if org is on a free plan or is self-hosted. - if (isSelfHosted || (isCloud && $organization?.billingPlan === BillingPlan.FREE)) return; + if (isSelfHosted || (isCloud && $organization?.billingPlanId === BillingPlan.FREE)) return; return realtime.forProject(page.params.region, 'console', (response) => { if (!response.channels.includes(`projects.${getProjectId()}`)) return; diff --git a/src/lib/components/billing/alerts/limitReached.svelte b/src/lib/components/billing/alerts/limitReached.svelte index 4885db75e..e99e38575 100644 --- a/src/lib/components/billing/alerts/limitReached.svelte +++ b/src/lib/components/billing/alerts/limitReached.svelte @@ -9,13 +9,13 @@ import { organization } from '$lib/stores/organization'; -{#if $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes(page.url.pathname)} +{#if $organization?.$id && $organization?.billingPlanId === BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes(page.url.pathname)} + title={`${$organization.name} usage has reached the ${tierToPlan($organization.billingPlanId).name} plan limit`}> Usage for the {$organization.name} organization has reached the limits of the {tierToPlan( - $organization.billingPlan + $organization.billingPlanId ).name} plan. Consider upgrading to increase your resource usage. diff --git a/src/lib/components/billing/alerts/missingPaymentMethod.svelte b/src/lib/components/billing/alerts/missingPaymentMethod.svelte index 96c29c5d7..ac0b25be4 100644 --- a/src/lib/components/billing/alerts/missingPaymentMethod.svelte +++ b/src/lib/components/billing/alerts/missingPaymentMethod.svelte @@ -8,7 +8,7 @@ import { orgMissingPaymentMethod } from '$routes/(console)/store'; -{#if ($orgMissingPaymentMethod.billingPlan === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlan === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !hideBillingHeaderRoutes.includes(page.url.pathname)} +{#if ($orgMissingPaymentMethod.billingPlanId === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlanId === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !hideBillingHeaderRoutes.includes(page.url.pathname)} diff --git a/src/lib/components/billing/alerts/newDevUpgradePro.svelte b/src/lib/components/billing/alerts/newDevUpgradePro.svelte index 733736f02..f6542b1ee 100644 --- a/src/lib/components/billing/alerts/newDevUpgradePro.svelte +++ b/src/lib/components/billing/alerts/newDevUpgradePro.svelte @@ -23,7 +23,7 @@ } -{#if show && $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && !page.url.pathname.includes(base + '/account')} +{#if show && $organization?.$id && $organization?.billingPlanId === BillingPlan.FREE && !page.url.pathname.includes(base + '/account')} - You will retain access to {tierToPlan($organization.billingPlan).name} plan features until your - billing period ends. After that, + You will retain access to {tierToPlan($organization.billingPlanId).name} plan features until + your billing period ends. After that, {#if excess?.members > 0} all team members except the owner will be removed, {:else} diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte index 6499a47c0..be0754887 100644 --- a/src/lib/components/billing/planSelection.svelte +++ b/src/lib/components/billing/planSelection.svelte @@ -35,7 +35,7 @@ value={plan.$id} title={plan.name}> - {#if $organization?.billingPlan === plan.$id && !isNewOrg} + {#if $organization?.billingPlanId === plan.$id && !isNewOrg} {/if} @@ -61,7 +61,7 @@ value={$currentPlan.$id} title={$currentPlan.name}> - {#if $organization?.billingPlan === $currentPlan.$id && !isNewOrg} + {#if $organization?.billingPlanId === $currentPlan.$id && !isNewOrg} {/if} diff --git a/src/lib/components/billing/selectPlan.svelte b/src/lib/components/billing/selectPlan.svelte index 2b9d9498f..50de90d7c 100644 --- a/src/lib/components/billing/selectPlan.svelte +++ b/src/lib/components/billing/selectPlan.svelte @@ -31,7 +31,7 @@ class:u-opacity-50={disabled}>

{plan.name} - {#if $organization?.billingPlan === plan.$id && !isNewOrg} + {#if $organization?.billingPlanId === plan.$id && !isNewOrg} Current plan {/if}

diff --git a/src/lib/components/billing/usageRates.svelte b/src/lib/components/billing/usageRates.svelte index 49ab414e9..50a20e1a1 100644 --- a/src/lib/components/billing/usageRates.svelte +++ b/src/lib/components/billing/usageRates.svelte @@ -11,13 +11,13 @@ export let show = false; export let org: Organization; - $: plan = $plansInfo?.get(org.billingPlan); + $: plan = $plansInfo?.get(org.billingPlanId); $: nextDate = org?.name ? new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1).toString() : org?.billingNextInvoiceDate; - $: isFree = org.billingPlan === BillingPlan.FREE; + $: isFree = org.billingPlanId === BillingPlan.FREE; // equal or above means unlimited! const getCorrectSeatsCountValue = (count: number): string | number => { @@ -37,12 +37,12 @@ Usage on the {$plansInfo?.get(BillingPlan.FREE).name} plan is limited for the following resources. Next billing period: {toLocaleDate(nextDate)}. - {:else if org.billingPlan === BillingPlan.PRO} + {:else if org.billingPlanId === BillingPlan.PRO} Usage on the Pro plan will be charged at the end of each billing period at the following rates. Next billing period: {toLocaleDate(nextDate)}. - {:else if org.billingPlan === BillingPlan.SCALE} + {:else if org.billingPlanId === BillingPlan.SCALE} Usage on the Scale plan will be charged at the end of each billing period at the following rates. Next billing period: {toLocaleDate(nextDate)}. diff --git a/src/lib/components/bottomModalAlert.svelte b/src/lib/components/bottomModalAlert.svelte index 623a510c1..982a24273 100644 --- a/src/lib/components/bottomModalAlert.svelte +++ b/src/lib/components/bottomModalAlert.svelte @@ -172,7 +172,7 @@ function showUpgrade() { const plan = currentModalAlert.plan; - const organizationPlan = $organization?.billingPlan; + const organizationPlan = $organization?.billingPlanId; switch (plan) { case 'free': return false; diff --git a/src/lib/components/breadcrumbs.svelte b/src/lib/components/breadcrumbs.svelte index 7f1a59c47..4ed7a539a 100644 --- a/src/lib/components/breadcrumbs.svelte +++ b/src/lib/components/breadcrumbs.svelte @@ -254,7 +254,7 @@ let badgeType: 'success' | undefined; $: badgeType = - $organization && $organization.billingPlan !== BillingPlan.FREE ? 'success' : undefined; + $organization && $organization.billingPlanId !== BillingPlan.FREE ? 'success' : undefined; diff --git a/src/lib/components/emptyCardImageCloud.svelte b/src/lib/components/emptyCardImageCloud.svelte index 0f4c23450..f06d74369 100644 --- a/src/lib/components/emptyCardImageCloud.svelte +++ b/src/lib/components/emptyCardImageCloud.svelte @@ -24,7 +24,7 @@ - + diff --git a/src/lib/components/feedback/feedback.svelte b/src/lib/components/feedback/feedback.svelte index ed500aa15..1b151c5d9 100644 --- a/src/lib/components/feedback/feedback.svelte +++ b/src/lib/components/feedback/feedback.svelte @@ -25,7 +25,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlan, + $organization?.billingPlanId, $feedbackData.value, $organization?.$id, $project?.$id, diff --git a/src/lib/components/roles/upgrade.svelte b/src/lib/components/roles/upgrade.svelte index b3f15e85b..c551f4cc1 100644 --- a/src/lib/components/roles/upgrade.svelte +++ b/src/lib/components/roles/upgrade.svelte @@ -11,7 +11,7 @@ {#if isCloud} - {#if $organization?.billingPlan !== BillingPlan.FREE} + {#if $organization?.billingPlanId !== BillingPlan.FREE} Roles Owner, Developer, Editor, Analyst and Billing. diff --git a/src/lib/components/support.svelte b/src/lib/components/support.svelte index d05d2639c..b7b3827ed 100644 --- a/src/lib/components/support.svelte +++ b/src/lib/components/support.svelte @@ -20,12 +20,12 @@ $: hasPremiumSupport = $currentPlan?.premiumSupport ?? allOrgsHavePremiumSupport ?? false; $: allOrgsHavePremiumSupport = $organizationList.teams.every( - (team) => $plansInfo.get((team as Organization).billingPlan)?.premiumSupport + (team) => $plansInfo.get((team as Organization).billingPlanId)?.premiumSupport ); // there can only be one free organization $: freeOrganization = $organizationList.teams.find( - (team) => !$plansInfo.get((team as Organization).billingPlan)?.premiumSupport + (team) => !$plansInfo.get((team as Organization).billingPlanId)?.premiumSupport ); $: upgradeURL = `${base}/organization-${freeOrganization?.$id}/change-plan`; diff --git a/src/lib/layout/containerButton.svelte b/src/lib/layout/containerButton.svelte index 53cfc35bf..e76cbf859 100644 --- a/src/lib/layout/containerButton.svelte +++ b/src/lib/layout/containerButton.svelte @@ -7,10 +7,10 @@ export let title: string; export let tooltipContent = - $organization?.billingPlan === BillingPlan.FREE + $organization?.billingPlanId === BillingPlan.FREE ? `Upgrade to add more ${title.toLocaleLowerCase()}` : `You've reached the ${title.toLocaleLowerCase()} limit for the ${ - tierToPlan($organization?.billingPlan)?.name + tierToPlan($organization?.billingPlanId)?.name } plan`; export let disabled: boolean; export let buttonText: string; diff --git a/src/lib/layout/containerHeader.svelte b/src/lib/layout/containerHeader.svelte index 84fe96607..893c055ed 100644 --- a/src/lib/layout/containerHeader.svelte +++ b/src/lib/layout/containerHeader.svelte @@ -64,13 +64,13 @@ }; const dispatch = createEventDispatcher(); - $: tier = tierToPlan($organization?.billingPlan)?.name; + $: tier = tierToPlan($organization?.billingPlanId)?.name; // these can be organization level limitations as well. // we need to migrate this sometime later, but soon! $: hasProjectLimitation = - checkForProjectLimitation(serviceId) && $organization?.billingPlan === BillingPlan.FREE; + checkForProjectLimitation(serviceId) && $organization?.billingPlanId === BillingPlan.FREE; $: hasUsageFees = hasProjectLimitation - ? checkForUsageFees($organization?.billingPlan, serviceId) + ? checkForUsageFees($organization?.billingPlanId, serviceId) : false; $: isLimited = limit !== 0 && limit < Infinity; $: overflowingServices = limitedServices.filter((service) => service.value > 0); @@ -99,7 +99,7 @@ {#if services.length} - {#if $organization?.billingPlan !== BillingPlan.FREE && hasUsageFees} + {#if $organization?.billingPlanId !== BillingPlan.FREE && hasUsageFees} You've reached the {services} limit for the {tier} plan. @@ -135,7 +135,7 @@ on:click={() => (showDropdown = !showDropdown)}> - {:else if $organization?.billingPlan !== BillingPlan.SCALE} + {:else if $organization?.billingPlanId !== BillingPlan.SCALE} You are limited to {limit} {title.toLocaleLowerCase()} per project on the {tier} plan. - {#if $organization?.billingPlan === BillingPlan.FREE} You are limited to {limit} {title.toLocaleLowerCase()} per organization on the {tier} plan. - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE} Upgrade for additional {title.toLocaleLowerCase()}. {/if} diff --git a/src/lib/layout/createProject.svelte b/src/lib/layout/createProject.svelte index c24e9234a..027dcc55d 100644 --- a/src/lib/layout/createProject.svelte +++ b/src/lib/layout/createProject.svelte @@ -35,7 +35,7 @@ } = $props(); let showCustomId = $state(false); - let isProPlan = $derived((billingPlan ?? $organization?.billingPlan) === BillingPlan.PRO); + let isProPlan = $derived((billingPlan ?? $organization?.billingPlanId) === BillingPlan.PRO); let projectsLimited = $derived( $currentPlan?.projects > 0 && projects && projects >= $currentPlan?.projects ); diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 695ef874c..a03604ed8 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -264,7 +264,7 @@ export function checkForUsageFees(plan: Tier, id: PlanServices) { export function checkForProjectLimitation(id: PlanServices) { // Members are no longer limited on Pro and Scale plans (unlimited seats) if (id === 'members') { - const currentTier = get(organization)?.billingPlan; + const currentTier = get(organization)?.billingPlanId; if (currentTier === BillingPlan.PRO || currentTier === BillingPlan.SCALE) { return false; // No project limitation for members on Pro/Scale plans } @@ -321,7 +321,7 @@ export function calculateEnterpriseTrial(org: Organization) { } export function calculateTrialDay(org: Organization) { - if (org?.billingPlan === BillingPlan.FREE) return false; + if (org?.billingPlanId === BillingPlan.FREE) return false; const endDate = new Date(org?.billingStartDate); const today = new Date(); @@ -373,7 +373,7 @@ export async function checkForUsageLimit(org: Organization) { readOnly.set(false); return; } - if (org?.billingPlan !== BillingPlan.FREE) { + if (org?.billingPlanId !== BillingPlan.FREE) { const { budgetLimit } = org?.billingLimits ?? {}; if (budgetLimit && budgetLimit >= 100) { @@ -453,7 +453,7 @@ export async function checkForUsageLimit(org: Organization) { } export async function checkPaymentAuthorizationRequired(org: Organization) { - if (org.billingPlan === BillingPlan.FREE) return; + if (org.billingPlanId === BillingPlan.FREE) return; const invoices = await sdk.forConsole.billing.listInvoices(org.$id, [ Query.equal('status', 'requires_authentication') @@ -574,7 +574,7 @@ export async function checkForMissingPaymentMethod() { // Display upgrade banner for new users after 1 week for 30 days export async function checkForNewDevUpgradePro(org: Organization) { // browser or plan check. - if (!browser || org?.billingPlan !== BillingPlan.FREE) return; + if (!browser || org?.billingPlanId !== BillingPlan.FREE) return; // already dismissed by user! if (localStorage.getItem('newDevUpgradePro')) return; diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 7393c6ed6..dc39db267 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -15,7 +15,8 @@ export type OrganizationError = { export type Organization = Models.Team> & { billingBudget: number; - billingPlan: Tier; + billingPlanId: Tier; + billingPlan: Plan; budgetAlerts: number[]; paymentMethodId: string; backupPaymentMethodId: string; diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index 109bdabb3..f17355b46 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -305,12 +305,12 @@ checkForMarkedForDeletion(org); await checkForNewDevUpgradePro(org); - if (org?.billingPlan !== BillingPlan.FREE) { + if (org?.billingPlanId !== BillingPlan.FREE) { await paymentExpired(org); await checkPaymentAuthorizationRequired(org); await checkForMandate(org); - if ($plansInfo.get(org.billingPlan)?.trialDays) { + if ($plansInfo.get(org.billingPlanId)?.trialDays) { calculateTrialDay(org); } } diff --git a/src/routes/(console)/account/organizations/+page.svelte b/src/routes/(console)/account/organizations/+page.svelte index 2d1668043..a54aacacb 100644 --- a/src/routes/(console)/account/organizations/+page.svelte +++ b/src/routes/(console)/account/organizations/+page.svelte @@ -60,15 +60,15 @@ function isOrganizationOnTrial(organization: Organization): boolean { if (!organization?.billingTrialStartDate) return false; if ($daysLeftInTrial <= 0) return false; - if (organization.billingPlan === BillingPlan.FREE) return false; + if (organization.billingPlanId === BillingPlan.FREE) return false; - return !!$plansInfo.get(organization.billingPlan)?.trialDays; + return !!$plansInfo.get(organization.billingPlanId)?.trialDays; } function isNonPayingOrganization(organization: Organization): boolean { return ( - organization?.billingPlan === BillingPlan.FREE || - organization?.billingPlan === BillingPlan.GITHUB_EDUCATION + organization?.billingPlanId === BillingPlan.FREE || + organization?.billingPlanId === BillingPlan.GITHUB_EDUCATION ); } @@ -114,7 +114,7 @@ {@const avatarList = getMemberships(organization.$id)} {@const payingOrg = isPayingOrganization(organization)} {@const planName = isCloudOrg(organization) - ? getPlanName(organization.billingPlan) + ? getPlanName(organization.billingPlanId) : null} diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index db9dbc038..5fedbf007 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -143,7 +143,7 @@ } // Upgrade existing org - else if (selectedOrg?.billingPlan !== billingPlan && isUpgrade()) { + else if (selectedOrg?.billingPlanId !== billingPlan && isUpgrade()) { org = await sdk.forConsole.billing.updatePlan( selectedOrg.$id, billingPlan, @@ -283,7 +283,7 @@ placeholder="Select organization" id="organization" /> {/if} - {#if selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} + {#if selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} {#if selectedOrgId === newOrgId} - {#if (selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)) || (!data?.couponData?.code && selectedOrgId)} + {#if (selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)) || (!data?.couponData?.code && selectedOrgId)}
- {#if selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} + {#if selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} - {#if selectedOrg?.$id && selectedOrg?.billingPlan === billingPlan} + {#if selectedOrg?.$id && selectedOrg?.billingPlanId === billingPlan}
{ ]); let plan = getPlanFromUrl(url); const hasFreeOrganizations = organizations.teams?.some( - (org) => (org as Organization)?.billingPlan === BillingPlan.FREE + (org) => (org as Organization)?.billingPlanId === BillingPlan.FREE ); if (plan === BillingPlan.FREE && hasFreeOrganizations) { diff --git a/src/routes/(console)/organization-[organization]/+page.svelte b/src/routes/(console)/organization-[organization]/+page.svelte index 4794d8659..e5bfe3758 100644 --- a/src/routes/(console)/organization-[organization]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/+page.svelte @@ -213,7 +213,7 @@ {/if} - {#if isCloud && data.organization.billingPlan === BillingPlan.FREE && projectsToArchive.length === 0 && !freePlanAlertDismissed} + {#if isCloud && data.organization.billingPlanId === BillingPlan.FREE && projectsToArchive.length === 0 && !freePlanAlertDismissed} Your Free plan includes up to 2 projects and limited resources. Upgrade to unlock diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index 99729b8e9..72c615aab 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -125,9 +125,11 @@ {/if} {#if organization?.billingPlanDowngrade} - Your organization has changed to {tierToPlan(organization?.billingPlanDowngrade).name} plan. - You will continue to have access to {tierToPlan(organization?.billingPlan).name} plan features - until your billing period ends on {toLocaleDate(organization.billingNextInvoiceDate)}. + Your organization has changed to {tierToPlan(organization?.billingPlanDowngrade).name} + plan. You will continue to have access to {tierToPlan(organization?.billingPlanId).name} + plan features until your billing period ends on {toLocaleDate( + organization.billingNextInvoiceDate + )}. {/if} {#if $useNewPricingModal} diff --git a/src/routes/(console)/organization-[organization]/billing/+page.ts b/src/routes/(console)/organization-[organization]/billing/+page.ts index 576765bf5..b5286afec 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.ts +++ b/src/routes/(console)/organization-[organization]/billing/+page.ts @@ -63,8 +63,8 @@ export const load: PageLoad = async ({ parent, depends, url, route }) => { const areCreditsSupported = isCloud ? (currentPlan?.supportsCredits ?? - (organization.billingPlan !== BillingPlan.FREE && - organization?.billingPlan !== BillingPlan.GITHUB_EDUCATION)) + (organization.billingPlanId !== BillingPlan.FREE && + organization?.billingPlanId !== BillingPlan.GITHUB_EDUCATION)) : false; const [paymentMethods, addressList, billingAddress, availableCredit, billingPlanDowngrade] = diff --git a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte index 52bc76859..b859c869f 100644 --- a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte +++ b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte @@ -81,7 +81,7 @@ } - + {!areCreditsSupported ? 'Credits' : 'Available credit'} @@ -171,7 +171,7 @@ {/if} - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE}
- {organization?.billingPlan === BillingPlan.FREE + {organization?.billingPlanId === BillingPlan.FREE ? 'Upgrade to add more members' : `You've reached the members limit for the ${ - tierToPlan(organization?.billingPlan)?.name + tierToPlan(organization?.billingPlanId)?.name } plan`}
diff --git a/src/routes/(console)/organization-[organization]/members/+page.svelte b/src/routes/(console)/organization-[organization]/members/+page.svelte index 05c350080..6bd5f64dd 100644 --- a/src/routes/(console)/organization-[organization]/members/+page.svelte +++ b/src/routes/(console)/organization-[organization]/members/+page.svelte @@ -46,7 +46,7 @@ // Calculate if button should be disabled and tooltip should show $: memberCount = data.organizationMembers?.total ?? 0; - $: isFreeWithMembers = $organization?.billingPlan === BillingPlan.FREE && memberCount >= 1; + $: isFreeWithMembers = $organization?.billingPlanId === BillingPlan.FREE && memberCount >= 1; $: isButtonDisabled = isCloud ? isFreeWithMembers : false; const resend = async (member: Models.Membership) => { @@ -89,10 +89,10 @@
- {$organization?.billingPlan === BillingPlan.FREE + {$organization?.billingPlanId === BillingPlan.FREE ? 'Upgrade to add more members' : `You've reached the members limit for the ${ - tierToPlan($organization?.billingPlan)?.name + tierToPlan($organization?.billingPlanId)?.name } plan`}
diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index a9422df60..00abd5a8f 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -29,7 +29,7 @@ const tier = data?.plan ? (data.plan.$id as Tier) - : (data?.currentInvoice?.plan ?? $organization?.billingPlan); + : (data?.currentInvoice?.plan ?? $organization?.billingPlanId); const plan = data?.plan ?? undefined; @@ -61,7 +61,7 @@
Usage - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE} {/if}
- {#if $organization.billingPlan === BillingPlan.SCALE} + {#if $organization.billingPlanId === BillingPlan.SCALE}

On the Scale plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. @@ -89,7 +89,7 @@ {/if}

- {:else if $organization.billingPlan === BillingPlan.PRO} + {:else if $organization.billingPlanId === BillingPlan.PRO}

On the Pro plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. @@ -104,7 +104,7 @@ {/if}

- {:else if $organization.billingPlan === BillingPlan.FREE} + {:else if $organization.billingPlanId === BillingPlan.FREE}

If you exceed the limits of the Free plan, services for your organization's projects may be disrupted. diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte index 15176735f..2b52ef1c3 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte @@ -14,14 +14,14 @@ export let members: Models.MembershipList; $: total = members?.total ?? 0; - $: plan = $plansInfo?.get($organization?.billingPlan); + $: plan = $plansInfo?.get($organization?.billingPlanId); Members The number of members in your organization. - {#if $organization.billingPlan !== BillingPlan.FREE} + {#if $organization.billingPlanId !== BillingPlan.FREE}

@@ -38,8 +38,8 @@ You can add unlimited organization members on the {tierToPlan( - $organization.billingPlan - ).name} plan {$organization.billingPlan === BillingPlan.PRO + $organization.billingPlanId + ).name} plan {$organization.billingPlanId === BillingPlan.PRO ? `for ${formatCurrency(plan.addons.seats.price)} each per billing period.` : '.'} diff --git a/src/routes/(console)/project-[region]-[project]/+layout.ts b/src/routes/(console)/project-[region]-[project]/+layout.ts index e45017ad8..9509afa60 100644 --- a/src/routes/(console)/project-[region]-[project]/+layout.ts +++ b/src/routes/(console)/project-[region]-[project]/+layout.ts @@ -26,7 +26,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { ); // organization can be null if not in the filtered list! - const includedInBasePlans = plansInfo.has(organization?.billingPlan); + const includedInBasePlans = plansInfo.has(organization?.billingPlanId); const [org, regionalConsoleVariables, rolesResult] = await Promise.all([ !organization @@ -54,7 +54,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { // fetch if not available in `plansInfo`. // out of promise.all because we filter orgs based on platform now! const organizationPlan = includedInBasePlans - ? plansInfo.get(organization?.billingPlan) + ? plansInfo.get(organization?.billingPlanId) : isCloud ? await sdk.forConsole.billing.getOrganizationPlan(organization?.$id) : null; @@ -80,7 +80,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { if (!includedInBasePlans) { // save the custom plan to `plansInfo` cache. - plansInfo.set(organization.billingPlan, organizationPlan); + plansInfo.set(organization.billingPlanId, organizationPlan); } return { diff --git a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte index 0bc701817..412b6902b 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte @@ -68,7 +68,11 @@ keys: ['c'], disabled: $wizard.show || - isServiceLimited('functions', $organization?.billingPlan, data.functions?.total) || + isServiceLimited( + 'functions', + $organization?.billingPlanId, + data.functions?.total + ) || !$canWriteFunctions, icon: IconPlus, group: 'functions' diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte index 9b29e6da1..093f6518f 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte @@ -78,7 +78,7 @@ disabled={specificationOptions.length < 1} options={specificationOptions} bind:value={specification} /> - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte index 30dcd26ff..670c307bd 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte @@ -89,7 +89,7 @@ disabled={options.length < 1} bind:value={specification} {options} /> - {#if isCloud && $organization.billingPlan === BillingPlan.FREE} + {#if isCloud && $organization.billingPlanId === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte index de53032da..353d893cb 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte @@ -81,7 +81,7 @@ $: buttonDisabled = isServiceLimited( 'functions', - $organization?.billingPlan, + $organization?.billingPlanId, $functionsList?.total ?? 0 ); diff --git a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte index 4f5ca68a1..337e6861c 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte @@ -26,7 +26,8 @@ import { IconExternalLink } from '@appwrite.io/pink-icons-svelte'; $: buttonDisabled = - isCloud && isServiceLimited('functions', $organization?.billingPlan, $functionsList?.total); + isCloud && + isServiceLimited('functions', $organization?.billingPlanId, $functionsList?.total); diff --git a/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte b/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte index 24e9db804..64dc9cb1e 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte @@ -65,7 +65,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlan, + $organization?.billingPlanId, $feedbackData.value, $organization?.$id, $project?.$id, diff --git a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte index 322525df3..c3edebe68 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte @@ -123,7 +123,7 @@ here - {#if $organization.billingPlan === BillingPlan.FREE} + {#if $organization.billingPlanId === BillingPlan.FREE} @@ -198,7 +198,7 @@ diff --git a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte index 76d4d5e1e..80e111be6 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte @@ -44,7 +44,7 @@ } ]; - const tier = data?.currentInvoice?.plan ?? $organization?.billingPlan; + const tier = data?.currentInvoice?.plan ?? $organization?.billingPlanId; const plan = tierToPlan(tier).name; @@ -52,28 +52,28 @@
Usage - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE} {/if}
- {#if $organization.billingPlan === BillingPlan.SCALE} + {#if $organization.billingPlanId === BillingPlan.SCALE}

On the Scale plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. ($showUsageRatesModal = true)} >Learn more about plan usage limits.

- {:else if $organization.billingPlan === BillingPlan.PRO} + {:else if $organization.billingPlanId === BillingPlan.PRO}

On the Pro plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. ($showUsageRatesModal = true)} >Learn more about plan usage limits.

- {:else if $organization.billingPlan === BillingPlan.FREE} + {:else if $organization.billingPlanId === BillingPlan.FREE}

If you exceed the limits of the {plan} plan, services for your projects may be disrupted. - {#if isCloud && $organization.billingPlan === BillingPlan.FREE} + {#if isCloud && $organization.billingPlanId === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte index f0b24c060..44e1f3381 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte @@ -46,7 +46,7 @@ {#if isCloud} {@const size = humanFileSize(sizeToBytes(service, 'MB', 1000))} - {#if $organization?.billingPlan === BillingPlan.FREE} + {#if $organization?.billingPlanId === BillingPlan.FREE} The {currentPlan.name} plan has a maximum upload file size limit of {Math.floor( parseInt(size.value) diff --git a/src/routes/(console)/supportWizard.svelte b/src/routes/(console)/supportWizard.svelte index eabf8a26b..9269d2944 100644 --- a/src/routes/(console)/supportWizard.svelte +++ b/src/routes/(console)/supportWizard.svelte @@ -134,7 +134,7 @@ { id: '48492', value: $organization?.$id ?? '' }, { id: '48491', value: $supportData?.project ?? '' }, { id: '56023', value: $supportData?.severity ?? '' }, - { id: '56024', value: $organization?.billingPlan ?? '' } + { id: '56024', value: $organization?.billingPlanId ?? '' } ] }) }); diff --git a/src/routes/(console)/wizard/feedback/step1.svelte b/src/routes/(console)/wizard/feedback/step1.svelte index 4d2cac840..dc66f1a76 100644 --- a/src/routes/(console)/wizard/feedback/step1.svelte +++ b/src/routes/(console)/wizard/feedback/step1.svelte @@ -22,7 +22,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlan, + $organization?.billingPlanId, $feedbackData.value, $organization?.$id, $project?.$id, From 6cac26f157c11bd15018c426ce67325324e30a6d Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 23 Dec 2025 17:57:11 +0530 Subject: [PATCH 500/599] revert: keep using `billingPlan`. --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- src/lib/components/backupDatabaseAlert.svelte | 2 +- src/lib/components/backupRestoreBox.svelte | 2 +- .../components/billing/alerts/limitReached.svelte | 6 +++--- .../billing/alerts/missingPaymentMethod.svelte | 2 +- .../billing/alerts/newDevUpgradePro.svelte | 2 +- src/lib/components/billing/planExcess.svelte | 2 +- src/lib/components/billing/planSelection.svelte | 4 ++-- src/lib/components/billing/selectPlan.svelte | 2 +- src/lib/components/billing/usageRates.svelte | 8 ++++---- src/lib/components/bottomModalAlert.svelte | 2 +- src/lib/components/breadcrumbs.svelte | 2 +- src/lib/components/emptyCardImageCloud.svelte | 2 +- src/lib/components/feedback/feedback.svelte | 2 +- src/lib/components/roles/upgrade.svelte | 2 +- src/lib/components/support.svelte | 4 ++-- src/lib/layout/containerButton.svelte | 4 ++-- src/lib/layout/containerHeader.svelte | 14 +++++++------- src/lib/layout/createProject.svelte | 2 +- src/lib/stores/billing.ts | 11 ++++++----- src/lib/stores/organization.ts | 4 ++-- src/routes/(console)/+layout.svelte | 4 ++-- .../(console)/account/organizations/+page.svelte | 12 ++++++------ src/routes/(console)/apply-credit/+page.svelte | 12 ++++++------ src/routes/(console)/create-organization/+page.ts | 2 +- .../organization-[organization]/+page.svelte | 2 +- .../billing/+page.svelte | 2 +- .../organization-[organization]/billing/+page.ts | 4 ++-- .../billing/availableCredit.svelte | 4 ++-- .../billing/budgetAlert.svelte | 4 ++-- .../billing/budgetCap.svelte | 2 +- .../billing/deleteOrgPayment.svelte | 4 ++-- .../billing/paymentMethods.svelte | 2 +- .../billing/planSummary.svelte | 2 +- .../billing/planSummaryOld.svelte | 8 ++++---- .../budgetLimitAlert.svelte | 2 +- .../change-plan/+page.svelte | 10 +++++----- .../change-plan/+page.ts | 2 +- .../organization-[organization]/header.svelte | 10 +++++----- .../members/+page.svelte | 6 +++--- .../usage/[[invoice]]/+page.svelte | 10 +++++----- .../usage/[[invoice]]/totalMembers.svelte | 8 ++++---- .../project-[region]-[project]/+layout.ts | 6 +++--- .../functions/+page.svelte | 2 +- .../create-function/(components)/details.svelte | 2 +- .../settings/updateResourceLimits.svelte | 2 +- .../functions/templates/+page.svelte | 2 +- .../templates/template-[template]/+page.svelte | 2 +- .../settings/migrations/exportModal.svelte | 2 +- .../settings/smtp/+page.svelte | 4 ++-- .../settings/usage/[[invoice]]/+page.svelte | 10 +++++----- .../project-[region]-[project]/sites/+page.svelte | 2 +- .../settings/updateResourceLimits.svelte | 2 +- .../settings/updateMaxFileSize.svelte | 2 +- src/routes/(console)/supportWizard.svelte | 2 +- src/routes/(console)/wizard/feedback/step1.svelte | 2 +- 57 files changed, 123 insertions(+), 122 deletions(-) diff --git a/package.json b/package.json index d1861c08f..b16cdf836 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 372b725b1..985b51df2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8 - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8 + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3 + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,8 +272,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3} version: 1.10.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@8d430f8': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/components/backupDatabaseAlert.svelte b/src/lib/components/backupDatabaseAlert.svelte index 932a14e22..1c2ceed16 100644 --- a/src/lib/components/backupDatabaseAlert.svelte +++ b/src/lib/components/backupDatabaseAlert.svelte @@ -18,7 +18,7 @@ {#if $showPolicyAlert && isCloud && $organization?.$id && page.url.pathname.match(/\/databases\/database-[^/]+$/)} - {@const isFreePlan = $organization?.billingPlanId === BillingPlan.FREE} + {@const isFreePlan = $organization?.billingPlan === BillingPlan.FREE} {@const subtitle = isFreePlan ? 'Upgrade your plan to ensure your data stays safe and backed up' diff --git a/src/lib/components/backupRestoreBox.svelte b/src/lib/components/backupRestoreBox.svelte index f4d6c5fff..f1de9d3ba 100644 --- a/src/lib/components/backupRestoreBox.svelte +++ b/src/lib/components/backupRestoreBox.svelte @@ -125,7 +125,7 @@ onMount(() => { // fast path: don't subscribe if org is on a free plan or is self-hosted. - if (isSelfHosted || (isCloud && $organization?.billingPlanId === BillingPlan.FREE)) return; + if (isSelfHosted || (isCloud && $organization?.billingPlan === BillingPlan.FREE)) return; return realtime.forProject(page.params.region, 'console', (response) => { if (!response.channels.includes(`projects.${getProjectId()}`)) return; diff --git a/src/lib/components/billing/alerts/limitReached.svelte b/src/lib/components/billing/alerts/limitReached.svelte index e99e38575..4885db75e 100644 --- a/src/lib/components/billing/alerts/limitReached.svelte +++ b/src/lib/components/billing/alerts/limitReached.svelte @@ -9,13 +9,13 @@ import { organization } from '$lib/stores/organization'; -{#if $organization?.$id && $organization?.billingPlanId === BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes(page.url.pathname)} +{#if $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes(page.url.pathname)} + title={`${$organization.name} usage has reached the ${tierToPlan($organization.billingPlan).name} plan limit`}> Usage for the {$organization.name} organization has reached the limits of the {tierToPlan( - $organization.billingPlanId + $organization.billingPlan ).name} plan. Consider upgrading to increase your resource usage. diff --git a/src/lib/components/billing/alerts/missingPaymentMethod.svelte b/src/lib/components/billing/alerts/missingPaymentMethod.svelte index ac0b25be4..96c29c5d7 100644 --- a/src/lib/components/billing/alerts/missingPaymentMethod.svelte +++ b/src/lib/components/billing/alerts/missingPaymentMethod.svelte @@ -8,7 +8,7 @@ import { orgMissingPaymentMethod } from '$routes/(console)/store'; -{#if ($orgMissingPaymentMethod.billingPlanId === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlanId === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !hideBillingHeaderRoutes.includes(page.url.pathname)} +{#if ($orgMissingPaymentMethod.billingPlan === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlan === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !hideBillingHeaderRoutes.includes(page.url.pathname)} diff --git a/src/lib/components/billing/alerts/newDevUpgradePro.svelte b/src/lib/components/billing/alerts/newDevUpgradePro.svelte index f6542b1ee..733736f02 100644 --- a/src/lib/components/billing/alerts/newDevUpgradePro.svelte +++ b/src/lib/components/billing/alerts/newDevUpgradePro.svelte @@ -23,7 +23,7 @@ } -{#if show && $organization?.$id && $organization?.billingPlanId === BillingPlan.FREE && !page.url.pathname.includes(base + '/account')} +{#if show && $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && !page.url.pathname.includes(base + '/account')} - You will retain access to {tierToPlan($organization.billingPlanId).name} plan features until + You will retain access to {tierToPlan($organization.billingPlan).name} plan features until your billing period ends. After that, {#if excess?.members > 0} all team members except the owner will be removed, diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte index be0754887..6499a47c0 100644 --- a/src/lib/components/billing/planSelection.svelte +++ b/src/lib/components/billing/planSelection.svelte @@ -35,7 +35,7 @@ value={plan.$id} title={plan.name}> - {#if $organization?.billingPlanId === plan.$id && !isNewOrg} + {#if $organization?.billingPlan === plan.$id && !isNewOrg} {/if} @@ -61,7 +61,7 @@ value={$currentPlan.$id} title={$currentPlan.name}> - {#if $organization?.billingPlanId === $currentPlan.$id && !isNewOrg} + {#if $organization?.billingPlan === $currentPlan.$id && !isNewOrg} {/if} diff --git a/src/lib/components/billing/selectPlan.svelte b/src/lib/components/billing/selectPlan.svelte index 50de90d7c..2b9d9498f 100644 --- a/src/lib/components/billing/selectPlan.svelte +++ b/src/lib/components/billing/selectPlan.svelte @@ -31,7 +31,7 @@ class:u-opacity-50={disabled}>

{plan.name} - {#if $organization?.billingPlanId === plan.$id && !isNewOrg} + {#if $organization?.billingPlan === plan.$id && !isNewOrg} Current plan {/if}

diff --git a/src/lib/components/billing/usageRates.svelte b/src/lib/components/billing/usageRates.svelte index 50a20e1a1..49ab414e9 100644 --- a/src/lib/components/billing/usageRates.svelte +++ b/src/lib/components/billing/usageRates.svelte @@ -11,13 +11,13 @@ export let show = false; export let org: Organization; - $: plan = $plansInfo?.get(org.billingPlanId); + $: plan = $plansInfo?.get(org.billingPlan); $: nextDate = org?.name ? new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1).toString() : org?.billingNextInvoiceDate; - $: isFree = org.billingPlanId === BillingPlan.FREE; + $: isFree = org.billingPlan === BillingPlan.FREE; // equal or above means unlimited! const getCorrectSeatsCountValue = (count: number): string | number => { @@ -37,12 +37,12 @@ Usage on the {$plansInfo?.get(BillingPlan.FREE).name} plan is limited for the following resources. Next billing period: {toLocaleDate(nextDate)}. - {:else if org.billingPlanId === BillingPlan.PRO} + {:else if org.billingPlan === BillingPlan.PRO} Usage on the Pro plan will be charged at the end of each billing period at the following rates. Next billing period: {toLocaleDate(nextDate)}. - {:else if org.billingPlanId === BillingPlan.SCALE} + {:else if org.billingPlan === BillingPlan.SCALE} Usage on the Scale plan will be charged at the end of each billing period at the following rates. Next billing period: {toLocaleDate(nextDate)}. diff --git a/src/lib/components/bottomModalAlert.svelte b/src/lib/components/bottomModalAlert.svelte index 982a24273..623a510c1 100644 --- a/src/lib/components/bottomModalAlert.svelte +++ b/src/lib/components/bottomModalAlert.svelte @@ -172,7 +172,7 @@ function showUpgrade() { const plan = currentModalAlert.plan; - const organizationPlan = $organization?.billingPlanId; + const organizationPlan = $organization?.billingPlan; switch (plan) { case 'free': return false; diff --git a/src/lib/components/breadcrumbs.svelte b/src/lib/components/breadcrumbs.svelte index 4ed7a539a..7f1a59c47 100644 --- a/src/lib/components/breadcrumbs.svelte +++ b/src/lib/components/breadcrumbs.svelte @@ -254,7 +254,7 @@ let badgeType: 'success' | undefined; $: badgeType = - $organization && $organization.billingPlanId !== BillingPlan.FREE ? 'success' : undefined; + $organization && $organization.billingPlan !== BillingPlan.FREE ? 'success' : undefined; diff --git a/src/lib/components/emptyCardImageCloud.svelte b/src/lib/components/emptyCardImageCloud.svelte index f06d74369..0f4c23450 100644 --- a/src/lib/components/emptyCardImageCloud.svelte +++ b/src/lib/components/emptyCardImageCloud.svelte @@ -24,7 +24,7 @@ - + diff --git a/src/lib/components/feedback/feedback.svelte b/src/lib/components/feedback/feedback.svelte index 1b151c5d9..ed500aa15 100644 --- a/src/lib/components/feedback/feedback.svelte +++ b/src/lib/components/feedback/feedback.svelte @@ -25,7 +25,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlanId, + $organization?.billingPlan, $feedbackData.value, $organization?.$id, $project?.$id, diff --git a/src/lib/components/roles/upgrade.svelte b/src/lib/components/roles/upgrade.svelte index c551f4cc1..b3f15e85b 100644 --- a/src/lib/components/roles/upgrade.svelte +++ b/src/lib/components/roles/upgrade.svelte @@ -11,7 +11,7 @@ {#if isCloud} - {#if $organization?.billingPlanId !== BillingPlan.FREE} + {#if $organization?.billingPlan !== BillingPlan.FREE} Roles Owner, Developer, Editor, Analyst and Billing. diff --git a/src/lib/components/support.svelte b/src/lib/components/support.svelte index b7b3827ed..d05d2639c 100644 --- a/src/lib/components/support.svelte +++ b/src/lib/components/support.svelte @@ -20,12 +20,12 @@ $: hasPremiumSupport = $currentPlan?.premiumSupport ?? allOrgsHavePremiumSupport ?? false; $: allOrgsHavePremiumSupport = $organizationList.teams.every( - (team) => $plansInfo.get((team as Organization).billingPlanId)?.premiumSupport + (team) => $plansInfo.get((team as Organization).billingPlan)?.premiumSupport ); // there can only be one free organization $: freeOrganization = $organizationList.teams.find( - (team) => !$plansInfo.get((team as Organization).billingPlanId)?.premiumSupport + (team) => !$plansInfo.get((team as Organization).billingPlan)?.premiumSupport ); $: upgradeURL = `${base}/organization-${freeOrganization?.$id}/change-plan`; diff --git a/src/lib/layout/containerButton.svelte b/src/lib/layout/containerButton.svelte index e76cbf859..53cfc35bf 100644 --- a/src/lib/layout/containerButton.svelte +++ b/src/lib/layout/containerButton.svelte @@ -7,10 +7,10 @@ export let title: string; export let tooltipContent = - $organization?.billingPlanId === BillingPlan.FREE + $organization?.billingPlan === BillingPlan.FREE ? `Upgrade to add more ${title.toLocaleLowerCase()}` : `You've reached the ${title.toLocaleLowerCase()} limit for the ${ - tierToPlan($organization?.billingPlanId)?.name + tierToPlan($organization?.billingPlan)?.name } plan`; export let disabled: boolean; export let buttonText: string; diff --git a/src/lib/layout/containerHeader.svelte b/src/lib/layout/containerHeader.svelte index 893c055ed..84fe96607 100644 --- a/src/lib/layout/containerHeader.svelte +++ b/src/lib/layout/containerHeader.svelte @@ -64,13 +64,13 @@ }; const dispatch = createEventDispatcher(); - $: tier = tierToPlan($organization?.billingPlanId)?.name; + $: tier = tierToPlan($organization?.billingPlan)?.name; // these can be organization level limitations as well. // we need to migrate this sometime later, but soon! $: hasProjectLimitation = - checkForProjectLimitation(serviceId) && $organization?.billingPlanId === BillingPlan.FREE; + checkForProjectLimitation(serviceId) && $organization?.billingPlan === BillingPlan.FREE; $: hasUsageFees = hasProjectLimitation - ? checkForUsageFees($organization?.billingPlanId, serviceId) + ? checkForUsageFees($organization?.billingPlan, serviceId) : false; $: isLimited = limit !== 0 && limit < Infinity; $: overflowingServices = limitedServices.filter((service) => service.value > 0); @@ -99,7 +99,7 @@ {#if services.length} - {#if $organization?.billingPlanId !== BillingPlan.FREE && hasUsageFees} + {#if $organization?.billingPlan !== BillingPlan.FREE && hasUsageFees} You've reached the {services} limit for the {tier} plan. @@ -135,7 +135,7 @@ on:click={() => (showDropdown = !showDropdown)}> - {:else if $organization?.billingPlanId !== BillingPlan.SCALE} + {:else if $organization?.billingPlan !== BillingPlan.SCALE} You are limited to {limit} {title.toLocaleLowerCase()} per project on the {tier} plan. - {#if $organization?.billingPlanId === BillingPlan.FREE} You are limited to {limit} {title.toLocaleLowerCase()} per organization on the {tier} plan. - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} Upgrade for additional {title.toLocaleLowerCase()}. {/if} diff --git a/src/lib/layout/createProject.svelte b/src/lib/layout/createProject.svelte index 027dcc55d..c24e9234a 100644 --- a/src/lib/layout/createProject.svelte +++ b/src/lib/layout/createProject.svelte @@ -35,7 +35,7 @@ } = $props(); let showCustomId = $state(false); - let isProPlan = $derived((billingPlan ?? $organization?.billingPlanId) === BillingPlan.PRO); + let isProPlan = $derived((billingPlan ?? $organization?.billingPlan) === BillingPlan.PRO); let projectsLimited = $derived( $currentPlan?.projects > 0 && projects && projects >= $currentPlan?.projects ); diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index a03604ed8..26b1ffb2e 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -264,7 +264,7 @@ export function checkForUsageFees(plan: Tier, id: PlanServices) { export function checkForProjectLimitation(id: PlanServices) { // Members are no longer limited on Pro and Scale plans (unlimited seats) if (id === 'members') { - const currentTier = get(organization)?.billingPlanId; + const currentTier = get(organization)?.billingPlan; if (currentTier === BillingPlan.PRO || currentTier === BillingPlan.SCALE) { return false; // No project limitation for members on Pro/Scale plans } @@ -321,7 +321,7 @@ export function calculateEnterpriseTrial(org: Organization) { } export function calculateTrialDay(org: Organization) { - if (org?.billingPlanId === BillingPlan.FREE) return false; + if (org?.billingPlan === BillingPlan.FREE) return false; const endDate = new Date(org?.billingStartDate); const today = new Date(); @@ -373,7 +373,7 @@ export async function checkForUsageLimit(org: Organization) { readOnly.set(false); return; } - if (org?.billingPlanId !== BillingPlan.FREE) { + if (org?.billingPlan !== BillingPlan.FREE) { const { budgetLimit } = org?.billingLimits ?? {}; if (budgetLimit && budgetLimit >= 100) { @@ -453,7 +453,7 @@ export async function checkForUsageLimit(org: Organization) { } export async function checkPaymentAuthorizationRequired(org: Organization) { - if (org.billingPlanId === BillingPlan.FREE) return; + if (org.billingPlan === BillingPlan.FREE) return; const invoices = await sdk.forConsole.billing.listInvoices(org.$id, [ Query.equal('status', 'requires_authentication') @@ -560,6 +560,7 @@ export async function checkForMissingPaymentMethod() { Query.isNull('backupPaymentMethodId'), Query.equal('platform', Platform.Appwrite) ]); + if (orgs?.total) { orgMissingPaymentMethod.set(orgs.teams[0]); headerAlert.add({ @@ -574,7 +575,7 @@ export async function checkForMissingPaymentMethod() { // Display upgrade banner for new users after 1 week for 30 days export async function checkForNewDevUpgradePro(org: Organization) { // browser or plan check. - if (!browser || org?.billingPlanId !== BillingPlan.FREE) return; + if (!browser || org?.billingPlan !== BillingPlan.FREE) return; // already dismissed by user! if (localStorage.getItem('newDevUpgradePro')) return; diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index dc39db267..3a413c36b 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -15,8 +15,8 @@ export type OrganizationError = { export type Organization = Models.Team> & { billingBudget: number; - billingPlanId: Tier; - billingPlan: Plan; + billingPlan: Tier; + billingPlanDetails: Plan; /* unused for now! */ budgetAlerts: number[]; paymentMethodId: string; backupPaymentMethodId: string; diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index f17355b46..109bdabb3 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -305,12 +305,12 @@ checkForMarkedForDeletion(org); await checkForNewDevUpgradePro(org); - if (org?.billingPlanId !== BillingPlan.FREE) { + if (org?.billingPlan !== BillingPlan.FREE) { await paymentExpired(org); await checkPaymentAuthorizationRequired(org); await checkForMandate(org); - if ($plansInfo.get(org.billingPlanId)?.trialDays) { + if ($plansInfo.get(org.billingPlan)?.trialDays) { calculateTrialDay(org); } } diff --git a/src/routes/(console)/account/organizations/+page.svelte b/src/routes/(console)/account/organizations/+page.svelte index a54aacacb..b369b1894 100644 --- a/src/routes/(console)/account/organizations/+page.svelte +++ b/src/routes/(console)/account/organizations/+page.svelte @@ -42,7 +42,7 @@ // For known plans, use tierToPlan const tierData = tierToPlan(billingPlan as Tier); - // If it's not a custom plan or we got a non-custom result, return the name + // If it's not a custom plan, or we got a non-custom result, return the name if (tierData.name !== 'Custom') { return tierData.name; } @@ -60,15 +60,15 @@ function isOrganizationOnTrial(organization: Organization): boolean { if (!organization?.billingTrialStartDate) return false; if ($daysLeftInTrial <= 0) return false; - if (organization.billingPlanId === BillingPlan.FREE) return false; + if (organization.billingPlan === BillingPlan.FREE) return false; - return !!$plansInfo.get(organization.billingPlanId)?.trialDays; + return !!$plansInfo.get(organization.billingPlan)?.trialDays; } function isNonPayingOrganization(organization: Organization): boolean { return ( - organization?.billingPlanId === BillingPlan.FREE || - organization?.billingPlanId === BillingPlan.GITHUB_EDUCATION + organization?.billingPlan === BillingPlan.FREE || + organization?.billingPlan === BillingPlan.GITHUB_EDUCATION ); } @@ -114,7 +114,7 @@ {@const avatarList = getMemberships(organization.$id)} {@const payingOrg = isPayingOrganization(organization)} {@const planName = isCloudOrg(organization) - ? getPlanName(organization.billingPlanId) + ? getPlanName(organization.billingPlan) : null} diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index 5fedbf007..20778b418 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -143,7 +143,7 @@ } // Upgrade existing org - else if (selectedOrg?.billingPlanId !== billingPlan && isUpgrade()) { + else if (selectedOrg?.billingPlan !== billingPlan && isUpgrade()) { org = await sdk.forConsole.billing.updatePlan( selectedOrg.$id, billingPlan, @@ -229,7 +229,7 @@ campaign?.plan && $plansInfo.get(campaign.plan) ? $plansInfo.get(campaign.plan) : null; const newPlan = $plansInfo.get(billingPlan); - // if campaign has a plan and it's higher than the selected new plan + // if campaign has a plan, and it's higher than the selected new plan if (campaignPlan?.order > newPlan?.order) { return campaignPlan.$id as Tier; } @@ -283,7 +283,7 @@ placeholder="Select organization" id="organization" /> {/if} - {#if selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} + {#if selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} {#if selectedOrgId === newOrgId} - {#if (selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)) || (!data?.couponData?.code && selectedOrgId)} + {#if (selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)) || (!data?.couponData?.code && selectedOrgId)}
- {#if selectedOrgId && (selectedOrg?.billingPlanId !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} + {#if selectedOrgId && (selectedOrg?.billingPlan !== BillingPlan.PRO || !selectedOrg?.paymentMethodId)} - {#if selectedOrg?.$id && selectedOrg?.billingPlanId === billingPlan} + {#if selectedOrg?.$id && selectedOrg?.billingPlan === billingPlan}
{ ]); let plan = getPlanFromUrl(url); const hasFreeOrganizations = organizations.teams?.some( - (org) => (org as Organization)?.billingPlanId === BillingPlan.FREE + (org) => (org as Organization)?.billingPlan === BillingPlan.FREE ); if (plan === BillingPlan.FREE && hasFreeOrganizations) { diff --git a/src/routes/(console)/organization-[organization]/+page.svelte b/src/routes/(console)/organization-[organization]/+page.svelte index e5bfe3758..4794d8659 100644 --- a/src/routes/(console)/organization-[organization]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/+page.svelte @@ -213,7 +213,7 @@ {/if} - {#if isCloud && data.organization.billingPlanId === BillingPlan.FREE && projectsToArchive.length === 0 && !freePlanAlertDismissed} + {#if isCloud && data.organization.billingPlan === BillingPlan.FREE && projectsToArchive.length === 0 && !freePlanAlertDismissed} Your Free plan includes up to 2 projects and limited resources. Upgrade to unlock diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index 72c615aab..15e6785a9 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -126,7 +126,7 @@ {#if organization?.billingPlanDowngrade} Your organization has changed to {tierToPlan(organization?.billingPlanDowngrade).name} - plan. You will continue to have access to {tierToPlan(organization?.billingPlanId).name} + plan. You will continue to have access to {tierToPlan(organization?.billingPlan).name} plan features until your billing period ends on {toLocaleDate( organization.billingNextInvoiceDate )}. diff --git a/src/routes/(console)/organization-[organization]/billing/+page.ts b/src/routes/(console)/organization-[organization]/billing/+page.ts index b5286afec..576765bf5 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.ts +++ b/src/routes/(console)/organization-[organization]/billing/+page.ts @@ -63,8 +63,8 @@ export const load: PageLoad = async ({ parent, depends, url, route }) => { const areCreditsSupported = isCloud ? (currentPlan?.supportsCredits ?? - (organization.billingPlanId !== BillingPlan.FREE && - organization?.billingPlanId !== BillingPlan.GITHUB_EDUCATION)) + (organization.billingPlan !== BillingPlan.FREE && + organization?.billingPlan !== BillingPlan.GITHUB_EDUCATION)) : false; const [paymentMethods, addressList, billingAddress, availableCredit, billingPlanDowngrade] = diff --git a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte index b859c869f..52bc76859 100644 --- a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte +++ b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte @@ -81,7 +81,7 @@ } - + {!areCreditsSupported ? 'Credits' : 'Available credit'} @@ -171,7 +171,7 @@ {/if} - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE}
- {organization?.billingPlanId === BillingPlan.FREE + {organization?.billingPlan === BillingPlan.FREE ? 'Upgrade to add more members' : `You've reached the members limit for the ${ - tierToPlan(organization?.billingPlanId)?.name + tierToPlan(organization?.billingPlan)?.name } plan`}
diff --git a/src/routes/(console)/organization-[organization]/members/+page.svelte b/src/routes/(console)/organization-[organization]/members/+page.svelte index 6bd5f64dd..05c350080 100644 --- a/src/routes/(console)/organization-[organization]/members/+page.svelte +++ b/src/routes/(console)/organization-[organization]/members/+page.svelte @@ -46,7 +46,7 @@ // Calculate if button should be disabled and tooltip should show $: memberCount = data.organizationMembers?.total ?? 0; - $: isFreeWithMembers = $organization?.billingPlanId === BillingPlan.FREE && memberCount >= 1; + $: isFreeWithMembers = $organization?.billingPlan === BillingPlan.FREE && memberCount >= 1; $: isButtonDisabled = isCloud ? isFreeWithMembers : false; const resend = async (member: Models.Membership) => { @@ -89,10 +89,10 @@
- {$organization?.billingPlanId === BillingPlan.FREE + {$organization?.billingPlan === BillingPlan.FREE ? 'Upgrade to add more members' : `You've reached the members limit for the ${ - tierToPlan($organization?.billingPlanId)?.name + tierToPlan($organization?.billingPlan)?.name } plan`}
diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index 00abd5a8f..a9422df60 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -29,7 +29,7 @@ const tier = data?.plan ? (data.plan.$id as Tier) - : (data?.currentInvoice?.plan ?? $organization?.billingPlanId); + : (data?.currentInvoice?.plan ?? $organization?.billingPlan); const plan = data?.plan ?? undefined; @@ -61,7 +61,7 @@
Usage - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} {/if}
- {#if $organization.billingPlanId === BillingPlan.SCALE} + {#if $organization.billingPlan === BillingPlan.SCALE}

On the Scale plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. @@ -89,7 +89,7 @@ {/if}

- {:else if $organization.billingPlanId === BillingPlan.PRO} + {:else if $organization.billingPlan === BillingPlan.PRO}

On the Pro plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. @@ -104,7 +104,7 @@ {/if}

- {:else if $organization.billingPlanId === BillingPlan.FREE} + {:else if $organization.billingPlan === BillingPlan.FREE}

If you exceed the limits of the Free plan, services for your organization's projects may be disrupted. diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte index 2b52ef1c3..15176735f 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/totalMembers.svelte @@ -14,14 +14,14 @@ export let members: Models.MembershipList; $: total = members?.total ?? 0; - $: plan = $plansInfo?.get($organization?.billingPlanId); + $: plan = $plansInfo?.get($organization?.billingPlan); Members The number of members in your organization. - {#if $organization.billingPlanId !== BillingPlan.FREE} + {#if $organization.billingPlan !== BillingPlan.FREE}

@@ -38,8 +38,8 @@ You can add unlimited organization members on the {tierToPlan( - $organization.billingPlanId - ).name} plan {$organization.billingPlanId === BillingPlan.PRO + $organization.billingPlan + ).name} plan {$organization.billingPlan === BillingPlan.PRO ? `for ${formatCurrency(plan.addons.seats.price)} each per billing period.` : '.'} diff --git a/src/routes/(console)/project-[region]-[project]/+layout.ts b/src/routes/(console)/project-[region]-[project]/+layout.ts index 9509afa60..e45017ad8 100644 --- a/src/routes/(console)/project-[region]-[project]/+layout.ts +++ b/src/routes/(console)/project-[region]-[project]/+layout.ts @@ -26,7 +26,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { ); // organization can be null if not in the filtered list! - const includedInBasePlans = plansInfo.has(organization?.billingPlanId); + const includedInBasePlans = plansInfo.has(organization?.billingPlan); const [org, regionalConsoleVariables, rolesResult] = await Promise.all([ !organization @@ -54,7 +54,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { // fetch if not available in `plansInfo`. // out of promise.all because we filter orgs based on platform now! const organizationPlan = includedInBasePlans - ? plansInfo.get(organization?.billingPlanId) + ? plansInfo.get(organization?.billingPlan) : isCloud ? await sdk.forConsole.billing.getOrganizationPlan(organization?.$id) : null; @@ -80,7 +80,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { if (!includedInBasePlans) { // save the custom plan to `plansInfo` cache. - plansInfo.set(organization.billingPlanId, organizationPlan); + plansInfo.set(organization.billingPlan, organizationPlan); } return { diff --git a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte index 412b6902b..6ffe38400 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte @@ -70,7 +70,7 @@ $wizard.show || isServiceLimited( 'functions', - $organization?.billingPlanId, + $organization?.billingPlan, data.functions?.total ) || !$canWriteFunctions, diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte index 093f6518f..9b29e6da1 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/details.svelte @@ -78,7 +78,7 @@ disabled={specificationOptions.length < 1} options={specificationOptions} bind:value={specification} /> - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte index 670c307bd..30dcd26ff 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateResourceLimits.svelte @@ -89,7 +89,7 @@ disabled={options.length < 1} bind:value={specification} {options} /> - {#if isCloud && $organization.billingPlanId === BillingPlan.FREE} + {#if isCloud && $organization.billingPlan === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte index 353d893cb..de53032da 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/templates/+page.svelte @@ -81,7 +81,7 @@ $: buttonDisabled = isServiceLimited( 'functions', - $organization?.billingPlanId, + $organization?.billingPlan, $functionsList?.total ?? 0 ); diff --git a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte index 337e6861c..f76cf4bb8 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte @@ -27,7 +27,7 @@ $: buttonDisabled = isCloud && - isServiceLimited('functions', $organization?.billingPlanId, $functionsList?.total); + isServiceLimited('functions', $organization?.billingPlan, $functionsList?.total); diff --git a/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte b/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte index 64dc9cb1e..24e9db804 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/migrations/exportModal.svelte @@ -65,7 +65,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlanId, + $organization?.billingPlan, $feedbackData.value, $organization?.$id, $project?.$id, diff --git a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte index c3edebe68..322525df3 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte @@ -123,7 +123,7 @@ here - {#if $organization.billingPlanId === BillingPlan.FREE} + {#if $organization.billingPlan === BillingPlan.FREE} @@ -198,7 +198,7 @@ diff --git a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte index 80e111be6..76d4d5e1e 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte @@ -44,7 +44,7 @@ } ]; - const tier = data?.currentInvoice?.plan ?? $organization?.billingPlanId; + const tier = data?.currentInvoice?.plan ?? $organization?.billingPlan; const plan = tierToPlan(tier).name; @@ -52,28 +52,28 @@
Usage - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} {/if}
- {#if $organization.billingPlanId === BillingPlan.SCALE} + {#if $organization.billingPlan === BillingPlan.SCALE}

On the Scale plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. ($showUsageRatesModal = true)} >Learn more about plan usage limits.

- {:else if $organization.billingPlanId === BillingPlan.PRO} + {:else if $organization.billingPlan === BillingPlan.PRO}

On the Pro plan, you'll be charged only for any usage that exceeds the thresholds per resource listed below. ($showUsageRatesModal = true)} >Learn more about plan usage limits.

- {:else if $organization.billingPlanId === BillingPlan.FREE} + {:else if $organization.billingPlan === BillingPlan.FREE}

If you exceed the limits of the {plan} plan, services for your projects may be disrupted. - {#if isCloud && $organization.billingPlanId === BillingPlan.FREE} + {#if isCloud && $organization.billingPlan === BillingPlan.FREE} Upgrade to Pro or Scale to adjust your CPU and RAM beyond the default. diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte index 44e1f3381..f0b24c060 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte @@ -46,7 +46,7 @@ {#if isCloud} {@const size = humanFileSize(sizeToBytes(service, 'MB', 1000))} - {#if $organization?.billingPlanId === BillingPlan.FREE} + {#if $organization?.billingPlan === BillingPlan.FREE} The {currentPlan.name} plan has a maximum upload file size limit of {Math.floor( parseInt(size.value) diff --git a/src/routes/(console)/supportWizard.svelte b/src/routes/(console)/supportWizard.svelte index 9269d2944..eabf8a26b 100644 --- a/src/routes/(console)/supportWizard.svelte +++ b/src/routes/(console)/supportWizard.svelte @@ -134,7 +134,7 @@ { id: '48492', value: $organization?.$id ?? '' }, { id: '48491', value: $supportData?.project ?? '' }, { id: '56023', value: $supportData?.severity ?? '' }, - { id: '56024', value: $organization?.billingPlanId ?? '' } + { id: '56024', value: $organization?.billingPlan ?? '' } ] }) }); diff --git a/src/routes/(console)/wizard/feedback/step1.svelte b/src/routes/(console)/wizard/feedback/step1.svelte index dc66f1a76..4d2cac840 100644 --- a/src/routes/(console)/wizard/feedback/step1.svelte +++ b/src/routes/(console)/wizard/feedback/step1.svelte @@ -22,7 +22,7 @@ page.url.href, $user.name, $user.email, - $organization?.billingPlanId, + $organization?.billingPlan, $feedbackData.value, $organization?.$id, $project?.$id, From 37352574579bdb9f2d7bab4620724fef4f98ec55 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 23 Dec 2025 17:59:09 +0530 Subject: [PATCH 501/599] lint. --- src/lib/components/billing/planExcess.svelte | 4 ++-- src/lib/stores/organization.ts | 2 +- .../billing/planSummaryOld.svelte | 3 +-- .../project-[region]-[project]/functions/+page.svelte | 6 +----- .../functions/templates/template-[template]/+page.svelte | 3 +-- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/lib/components/billing/planExcess.svelte b/src/lib/components/billing/planExcess.svelte index dedd265fc..7bdf28e3f 100644 --- a/src/lib/components/billing/planExcess.svelte +++ b/src/lib/components/billing/planExcess.svelte @@ -47,8 +47,8 @@ title={` Your organization will switch to ${tierToPlan(BillingPlan.FREE).name} plan on ${toLocaleDate( $organization.billingNextInvoiceDate )}`}> - You will retain access to {tierToPlan($organization.billingPlan).name} plan features until - your billing period ends. After that, + You will retain access to {tierToPlan($organization.billingPlan).name} plan features until your + billing period ends. After that, {#if excess?.members > 0} all team members except the owner will be removed, {:else} diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 3a413c36b..851b2bfb6 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -16,7 +16,7 @@ export type OrganizationError = { export type Organization = Models.Team> & { billingBudget: number; billingPlan: Tier; - billingPlanDetails: Plan; /* unused for now! */ + billingPlanDetails: Plan /* unused for now! */; budgetAlerts: number[]; paymentMethodId: string; backupPaymentMethodId: string; diff --git a/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte b/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte index f593b54d6..083aff444 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte @@ -51,8 +51,7 @@ {currentPlan.name} plan - {isTrial || - $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION + {isTrial || $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION ? formatCurrency(0) : currentPlan ? formatCurrency(currentPlan?.price) diff --git a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte index 6ffe38400..0bc701817 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/+page.svelte @@ -68,11 +68,7 @@ keys: ['c'], disabled: $wizard.show || - isServiceLimited( - 'functions', - $organization?.billingPlan, - data.functions?.total - ) || + isServiceLimited('functions', $organization?.billingPlan, data.functions?.total) || !$canWriteFunctions, icon: IconPlus, group: 'functions' diff --git a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte index f76cf4bb8..4f5ca68a1 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/templates/template-[template]/+page.svelte @@ -26,8 +26,7 @@ import { IconExternalLink } from '@appwrite.io/pink-icons-svelte'; $: buttonDisabled = - isCloud && - isServiceLimited('functions', $organization?.billingPlan, $functionsList?.total); + isCloud && isServiceLimited('functions', $organization?.billingPlan, $functionsList?.total); From 4f4855a6e57bf6ce5980fd5655b5a14c8778e6f1 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 23 Dec 2025 18:03:31 +0530 Subject: [PATCH 502/599] revert: unnecessary changes. --- src/lib/stores/billing.ts | 1 - src/routes/(console)/account/organizations/+page.svelte | 2 +- src/routes/(console)/apply-credit/+page.svelte | 2 +- .../organization-[organization]/billing/+page.svelte | 8 +++----- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 26b1ffb2e..695ef874c 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -560,7 +560,6 @@ export async function checkForMissingPaymentMethod() { Query.isNull('backupPaymentMethodId'), Query.equal('platform', Platform.Appwrite) ]); - if (orgs?.total) { orgMissingPaymentMethod.set(orgs.teams[0]); headerAlert.add({ diff --git a/src/routes/(console)/account/organizations/+page.svelte b/src/routes/(console)/account/organizations/+page.svelte index b369b1894..2d1668043 100644 --- a/src/routes/(console)/account/organizations/+page.svelte +++ b/src/routes/(console)/account/organizations/+page.svelte @@ -42,7 +42,7 @@ // For known plans, use tierToPlan const tierData = tierToPlan(billingPlan as Tier); - // If it's not a custom plan, or we got a non-custom result, return the name + // If it's not a custom plan or we got a non-custom result, return the name if (tierData.name !== 'Custom') { return tierData.name; } diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index 20778b418..db9dbc038 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -229,7 +229,7 @@ campaign?.plan && $plansInfo.get(campaign.plan) ? $plansInfo.get(campaign.plan) : null; const newPlan = $plansInfo.get(billingPlan); - // if campaign has a plan, and it's higher than the selected new plan + // if campaign has a plan and it's higher than the selected new plan if (campaignPlan?.order > newPlan?.order) { return campaignPlan.$id as Tier; } diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index 15e6785a9..99729b8e9 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -125,11 +125,9 @@ {/if} {#if organization?.billingPlanDowngrade} - Your organization has changed to {tierToPlan(organization?.billingPlanDowngrade).name} - plan. You will continue to have access to {tierToPlan(organization?.billingPlan).name} - plan features until your billing period ends on {toLocaleDate( - organization.billingNextInvoiceDate - )}. + Your organization has changed to {tierToPlan(organization?.billingPlanDowngrade).name} plan. + You will continue to have access to {tierToPlan(organization?.billingPlan).name} plan features + until your billing period ends on {toLocaleDate(organization.billingNextInvoiceDate)}. {/if} {#if $useNewPricingModal} From 4af5e8334f38f225585dac66eee6f3612906bafc Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 24 Dec 2025 12:50:09 +0530 Subject: [PATCH 503/599] fix: empty string key causing crashes, plus the key accessor was wrong. --- .../overview/onboard.svelte | 63 ++++++++++--------- .../overview/platforms/+page.svelte | 13 ++-- .../overview/platforms/wizard/store.ts | 2 - 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte index 78757226d..40ddb34b9 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte @@ -28,48 +28,53 @@ import PlatformFlutterImgSourceDark from './assets/platform-flutter-dark.svg'; import PlatformSdkImgSource from './assets/platform-sdk.jpg'; import PlatformSdkImgSourceDark from './assets/platform-sdk-dark.png'; - import { base } from '$app/paths'; + import { resolve } from '$app/paths'; import { isSmallViewport } from '$lib/stores/viewport'; import type { Models } from '@appwrite.io/console'; import { getPlatformInfo } from '$lib/helpers/platform'; import { Click, trackEvent } from '$lib/actions/analytics'; import { goto } from '$app/navigation'; import { page } from '$app/state'; + import { onMount } from 'svelte'; - export let pingCount = 0; - export let platforms: Models.Platform[] = []; + let { + pingCount = 0, + platforms = [] + }: { + pingCount: number; + platforms: Array; + } = $props(); + + let platformMap = $state(new Map()); + + const projectRoute = $derived.by(() => { + return resolve('/(console)/project-[region]-[project]', { + region: page.params.region, + project: page.params.project + }); + }); + + onMount(() => { + platforms.forEach((platform) => { + const platformInfo = getPlatformInfo(platform.type); + platformMap.set(platformInfo.name, platform); + }); + }); function createKey() { - trackEvent(Click.KeyCreateClick, { - source: 'onboarding' - }); - goto( - `${base}/project-${page.params.region}-${page.params.project}/overview/api-keys/create`, - { - replaceState: true - } - ); + trackEvent(Click.KeyCreateClick, { source: 'onboarding' }); + + goto(`${projectRoute}/overview/api-keys/create`, { replaceState: true }); } function openPlatformWizard(type: number, platform?: Models.Platform) { if (platform) { - continuePlatform(type, platform.name, platform.key, platform.type); + continuePlatform(type, platform.name, platform.type); } else { trackEvent(Click.PlatformCreateClick, { source: 'onboarding' }); addPlatform(type); } } - - let platformMap = new Map(); - - $: { - let updatedMap = new Map(); - platforms.forEach((platform) => { - const platformInfo = getPlatformInfo(platform.type); - updatedMap.set(platformInfo.name, platform); - }); - platformMap = updatedMap; - }

@@ -410,9 +415,7 @@ { trackEvent(Click.OnboardingSetupDatabaseClick); - goto( - `${base}/project-${page.params.region}-${page.params.project}/databases` - ); + goto(`${projectRoute}/databases`); }} padding="s" > { trackEvent( Click.OnboardingAuthEmailPasswordClick @@ -517,7 +520,7 @@ { trackEvent( Click.OnboardingAuthOauth2Click @@ -525,7 +528,7 @@ }}>OAuth 2 { trackEvent( Click.OnboardingAuthAllMethodsClick diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte index c86b1b50d..22d0bce77 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte @@ -27,25 +27,20 @@ }); } - export async function continuePlatform( - platform: Platform, - name: string, - key: string, - type: PlatformType - ) { + export async function continuePlatform(platform: Platform, name: string, type: PlatformType) { createPlatform.set({ name: name, - key: key, type: type }); + trackEvent(Click.PlatformCreateClick, { platform: platforms[platform], state: 'continue' }); + wizard.start(platforms[platform], null, 1, { isConnectPlatform: true, - platform: type, - key: key + platform: type }); } diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/wizard/store.ts b/src/routes/(console)/project-[region]-[project]/overview/platforms/wizard/store.ts index e15dcfbf2..24f28def6 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/wizard/store.ts +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/wizard/store.ts @@ -6,7 +6,6 @@ function createPlatformStore() { $id: null, name: null, hostname: null, - key: null, store: null, type: null }); @@ -20,7 +19,6 @@ function createPlatformStore() { $id: null, name: null, hostname: null, - key: null, store: null, type: null }); From 72ddec4493835dfbdd3d79100368f9e4b3b93f9c Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 24 Dec 2025 12:59:55 +0530 Subject: [PATCH 504/599] use: derived. --- .../overview/onboard.svelte | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte index 40ddb34b9..0ab32228f 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte @@ -45,7 +45,15 @@ platforms: Array; } = $props(); - let platformMap = $state(new Map()); + const platformMap = $derived.by(() => { + const map = new Map(); + platforms.forEach((platform) => { + const platformInfo = getPlatformInfo(platform.type); + map.set(platformInfo.name, platform); + }); + + return map; + }); const projectRoute = $derived.by(() => { return resolve('/(console)/project-[region]-[project]', { @@ -54,13 +62,6 @@ }); }); - onMount(() => { - platforms.forEach((platform) => { - const platformInfo = getPlatformInfo(platform.type); - platformMap.set(platformInfo.name, platform); - }); - }); - function createKey() { trackEvent(Click.KeyCreateClick, { source: 'onboarding' }); From c2c9a40791e9d01b6ffc04360b3edda2035a2760 Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 24 Dec 2025 13:03:52 +0530 Subject: [PATCH 505/599] remove: onmount. --- .../(console)/project-[region]-[project]/overview/onboard.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte index 0ab32228f..8650aa498 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/onboard.svelte @@ -35,7 +35,6 @@ import { Click, trackEvent } from '$lib/actions/analytics'; import { goto } from '$app/navigation'; import { page } from '$app/state'; - import { onMount } from 'svelte'; let { pingCount = 0, From 5d0fe2823ef3f49c4271bc4ff012f881320c5664 Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 24 Dec 2025 15:43:39 +0530 Subject: [PATCH 506/599] update: as per sdk. --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- src/lib/stores/organization.ts | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index b16cdf836..a2e1778fe 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 985b51df2..9a968c01e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3 - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3 + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,8 +272,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f} version: 1.10.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@cced6e3': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 851b2bfb6..b3b874cab 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -16,6 +16,7 @@ export type OrganizationError = { export type Organization = Models.Team> & { billingBudget: number; billingPlan: Tier; + billingPlanId: Tier /* unused for now! */; billingPlanDetails: Plan /* unused for now! */; budgetAlerts: number[]; paymentMethodId: string; From e446f7ff82581ad4553b9a5e13be149ece220ad2 Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Wed, 24 Dec 2025 17:33:49 -0800 Subject: [PATCH 507/599] feat: add attachment support to support wizard (#2624) --- src/routes/(console)/supportWizard.svelte | 78 +++++++++++++++++------ 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/src/routes/(console)/supportWizard.svelte b/src/routes/(console)/supportWizard.svelte index eabf8a26b..7fe3fc710 100644 --- a/src/routes/(console)/supportWizard.svelte +++ b/src/routes/(console)/supportWizard.svelte @@ -1,6 +1,15 @@ @@ -69,7 +84,7 @@ {/if} - {log.ip} + {toLocaleDateTime(log.time)} diff --git a/src/routes/(console)/account/sessions/+page.svelte b/src/routes/(console)/account/sessions/+page.svelte index ca12c182e..bbc261abc 100644 --- a/src/routes/(console)/account/sessions/+page.svelte +++ b/src/routes/(console)/account/sessions/+page.svelte @@ -13,7 +13,14 @@ import type { PageData } from './$types'; import { addNotification } from '$lib/stores/notifications'; import { onMount } from 'svelte'; - import { Badge, Layout, Table, Typography, Icon } from '@appwrite.io/pink-svelte'; + import { + Badge, + Layout, + Table, + Typography, + Icon, + InteractiveText + } from '@appwrite.io/pink-svelte'; import { IconGlobeAlt } from '@appwrite.io/pink-icons-svelte'; export let data: PageData; @@ -146,7 +153,7 @@ {/if} - {session.ip} + diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/sessions/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/sessions/+page.svelte index b0d6bb469..77feda0fb 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/sessions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/sessions/+page.svelte @@ -1,6 +1,13 @@ @@ -44,55 +49,53 @@ expanded={databasesScreen && !insideSideSheet} slotSpacing={databasesScreen && !insideSideSheet}> {#if logs.total} -
- - - User - Event - Location - IP - Date - - {#each logs.logs as log} - - - - {#if log.userEmail} - {#if log.userName} - - {log.userName} - {:else} - - {log.userEmail} - {/if} + + + User + Event + Location + IP + Date + + {#each logs.logs as log} + + + + {#if log.userEmail} + {#if log.userName} + + {log.userName} {:else} -
- -
- {log.userName ?? 'Anonymous'} + + {log.userEmail} {/if} -
-
- - {log.event} - - - {#if log.countryCode !== '--'} - {log.countryName} {:else} - Unknown +
+ +
+ {log.userName ?? 'Anonymous'} {/if} -
- - - - - {toLocaleDateTime(log.time)} - -
- {/each} -
-
+
+ + + {log.event} + + + {#if log.countryCode !== '--'} + {log.countryName} + {:else} + Unknown + {/if} + + + + + + {toLocaleDateTime(log.time)} + + + {/each} + Date: Wed, 31 Dec 2025 00:31:51 +0530 Subject: [PATCH 519/599] sidebar was also not working on mobile view in pages under /account --- src/routes/(console)/+layout.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index 109bdabb3..d6231de58 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -334,7 +334,6 @@ Date: Wed, 31 Dec 2025 00:42:57 +0530 Subject: [PATCH 520/599] use pink column type --- src/lib/layout/activity.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/layout/activity.svelte b/src/lib/layout/activity.svelte index 6aef2a3aa..e7ce285a9 100644 --- a/src/lib/layout/activity.svelte +++ b/src/lib/layout/activity.svelte @@ -14,7 +14,7 @@ export let databasesScreen = false; export let useCreateLinkForPagination = true; - function getColumnWidth(columnId: string): { width?: number | { min: number } } { + function getColumnWidth(columnId: string): Pick { const widthConfig: Record< string, { insideSheet: number | { min: number }; default: number | { min: number } } From 1fa67227eda44ec24b076fd66be74475e8059941 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Wed, 31 Dec 2025 01:20:40 +0530 Subject: [PATCH 521/599] feat: New Group security cards --- .../auth/security/+page.svelte | 18 +-- .../auth/security/passwordPolicies.svelte | 150 ++++++++++++++++++ .../auth/security/sessionSecurity.svelte | 94 +++++++++++ .../security/updatePasswordDictionary.svelte | 61 ------- .../security/updatePasswordHistory.svelte | 80 ---------- .../security/updatePersonalDataCheck.svelte | 56 ------- .../auth/security/updateSessionAlerts.svelte | 54 ------- .../security/updateSessionInvalidation.svelte | 56 ------- 8 files changed, 250 insertions(+), 319 deletions(-) create mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte create mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte delete mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordDictionary.svelte delete mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordHistory.svelte delete mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/updatePersonalDataCheck.svelte delete mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/updateSessionAlerts.svelte delete mode 100644 src/routes/(console)/project-[region]-[project]/auth/security/updateSessionInvalidation.svelte diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte index 48718cba3..c7c34b5c1 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte @@ -1,26 +1,20 @@ - - - - - + + diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte new file mode 100644 index 000000000..ddc4be087 --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte @@ -0,0 +1,150 @@ + + +
+ + Password policies + + + + + + Enabling this option prevents users from reusing recent passwords by + comparing the new password with their password history. + + {#if passwordHistoryEnabled} + + {/if} + + + + + + + + Enabling this option prevent users from setting insecure passwords by + comparing the user's password with the 10k most commonly used passwords. + + + + + + + + Do not allow passwords that contain any part of the user's personal data. + This includes the user's name, email, or phone. + + + + + + + + + +
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte new file mode 100644 index 000000000..e2b4be9e0 --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte @@ -0,0 +1,94 @@ + + +
+ + Session security + + + + + Enabling this option will send an email to the users when a new session is + created. + + + + + + + + Enabling this option will clear all existing sessions when the user changes + their password. + + + + + + + + + +
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordDictionary.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordDictionary.svelte deleted file mode 100644 index 0e921ab04..000000000 --- a/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordDictionary.svelte +++ /dev/null @@ -1,61 +0,0 @@ - - -
- - Password dictionary - - - - Enabling this option prevent users from setting insecure passwords by comparing the - user's password with the 10k most commonly used passwords. - - - - - - - -
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordHistory.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordHistory.svelte deleted file mode 100644 index 0b4218487..000000000 --- a/src/routes/(console)/project-[region]-[project]/auth/security/updatePasswordHistory.svelte +++ /dev/null @@ -1,80 +0,0 @@ - - -
- - Password history - Set the maximum number of passwords saved per user. - - - - Enabling this option prevents users from reusing recent passwords by comparing the - new password with their password history. - - - - - - - - -
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/updatePersonalDataCheck.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/updatePersonalDataCheck.svelte deleted file mode 100644 index 71f87c24d..000000000 --- a/src/routes/(console)/project-[region]-[project]/auth/security/updatePersonalDataCheck.svelte +++ /dev/null @@ -1,56 +0,0 @@ - - -
- - Personal data - - - - Do not allow passwords that contain any part of the user's personal data. This - includes the user's name, email, or phone. - - - - - - -
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionAlerts.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionAlerts.svelte deleted file mode 100644 index ba8af9ec9..000000000 --- a/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionAlerts.svelte +++ /dev/null @@ -1,54 +0,0 @@ - - -
- - Session alerts - - - - Enabling this option will send an email to the users when a new session is created. - - - - - - -
diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionInvalidation.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionInvalidation.svelte deleted file mode 100644 index c2c449e3e..000000000 --- a/src/routes/(console)/project-[region]-[project]/auth/security/updateSessionInvalidation.svelte +++ /dev/null @@ -1,56 +0,0 @@ - - -
- - Invalidate sessions - - - - Enabling this option will clear all existing sessions when the user changes their - password. - - - - - - - -
From 44c693befdc39bfda382c1366cd06c88971a6ab9 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Wed, 31 Dec 2025 01:26:09 +0530 Subject: [PATCH 522/599] Update src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../auth/security/passwordPolicies.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte index ddc4be087..f39b5203d 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte @@ -117,7 +117,7 @@ label="Password dictionary"> - Enabling this option prevent users from setting insecure passwords by + Enabling this option prevents users from setting insecure passwords by comparing the user's password with the Date: Wed, 31 Dec 2025 10:37:18 +0530 Subject: [PATCH 523/599] no store import in security page --- .../auth/security/+page.svelte | 5 ++-- .../auth/security/passwordPolicies.svelte | 25 ++++++++++--------- .../auth/security/sessionSecurity.svelte | 5 ++-- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte index c7c34b5c1..6c0ce4359 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte @@ -1,5 +1,6 @@ - - + + diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte index d57c73842..46547cecb 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte @@ -16,18 +16,29 @@ let passwordHistoryEnabled = $state(false); let passwordDictionary = $state(false); let authPersonalDataCheck = $state(false); + let lastValidLimit = $state(5); let maxPasswordInputField: InputNumber | null = null; // Initialize and sync state when project updates $effect(() => { const historyValue = project?.authPasswordHistory; - passwordHistory = historyValue < 1 ? 5 : historyValue; + if (historyValue && historyValue > 0) { + passwordHistory = historyValue; + lastValidLimit = historyValue; + } passwordHistoryEnabled = (historyValue ?? 0) !== 0; passwordDictionary = project?.authPasswordDictionary ?? false; authPersonalDataCheck = project?.authPersonalDataCheck ?? false; }); + // restore last valid limit when enabling + $effect(() => { + if (passwordHistoryEnabled && passwordHistory < 1) { + passwordHistory = lastValidLimit; + } + }); + $effect(() => { if (passwordHistoryEnabled) { tick().then(() => { From f6b561579e54f524cd4ebb4f436b7481c2c85165 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 13:35:07 +0530 Subject: [PATCH 531/599] fix: race conditions for deletions. --- src/lib/actions/analytics.ts | 1 + src/lib/components/multiSelectTable.svelte | 104 ++++++++++++++---- .../auth/+page.svelte | 21 ++-- .../auth/teams/+page.svelte | 21 ++-- .../teams/team-[team]/members/+page.svelte | 23 ++-- .../auth/user-[user]/identities/table.svelte | 29 +++-- .../auth/user-[user]/memberships/+page.svelte | 17 +-- .../auth/user-[user]/targets/table.svelte | 29 +++-- .../database-[database]/backups/table.svelte | 58 +++++----- .../database-[database]/table.svelte | 24 ++-- .../executions/table.svelte | 23 ++-- .../function-[function]/table.svelte | 24 ++-- .../messaging/+page.svelte | 17 +-- .../messaging/providers/table.svelte | 29 +++-- .../messaging/topics/table.svelte | 29 +++-- .../topics/topic-[topic]/table.svelte | 27 +++-- .../overview/(components)/table.svelte | 2 +- .../overview/platforms/+page.svelte | 28 +++-- .../site-[site]/deployments/table.svelte | 24 ++-- .../sites/site-[site]/logs/table.svelte | 23 ++-- .../storage/bucket-[bucket]/+page.svelte | 23 ++-- 21 files changed, 371 insertions(+), 205 deletions(-) diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index 6880f1c2f..d02f66731 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -277,6 +277,7 @@ export enum Submit { DatabaseDelete = 'submit_database_delete', DatabaseUpdateName = 'submit_database_update_name', DatabaseImportCsv = 'submit_database_import_csv', + DatabaseBackupDelete = 'submit_database_backup_delete', ColumnCreate = 'submit_column_create', ColumnUpdate = 'submit_column_update', diff --git a/src/lib/components/multiSelectTable.svelte b/src/lib/components/multiSelectTable.svelte index cd35b38e6..bb985f790 100644 --- a/src/lib/components/multiSelectTable.svelte +++ b/src/lib/components/multiSelectTable.svelte @@ -1,5 +1,13 @@ {#key computeKey} @@ -104,13 +177,7 @@ if (confirmDeletion) { showConfirmDeletion = true; } else { - const state = await onDelete?.(selectedRows); - if (state instanceof Error) { - // user should handle error on their own! - } else { - notifySuccess(); - selectedRows = []; - } + await consumeDeleteOperation(); } }}>Delete @@ -129,16 +196,13 @@ disableModal = true; onDeleteError = null; - const state = await onDelete?.(selectedRows); - if (state instanceof Error) { - disableModal = false; - onDeleteError = state.message || `Failed to delete ${resource}s`; - } else { - notifySuccess(); - selectedRows = []; - disableModal = false; + const allDeleted = await consumeDeleteOperation(); + + if (allDeleted) { showConfirmDeletion = false; } + + disableModal = false; }}> {@const selectionCount = selectedRows.length} diff --git a/src/routes/(console)/project-[region]-[project]/auth/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/+page.svelte index 391274650..e8b9c7a29 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/+page.svelte @@ -9,6 +9,7 @@ import { AvatarInitials, Copy, + type DeleteOperation, type DeleteOperationState, Empty, EmptySearch, @@ -60,20 +61,22 @@ ); } - async function handleDelete(selectedRows: string[]): Promise { - const promises = selectedRows.map((userId) => { - return sdk.forProject(page.params.region, page.params.project).users.delete({ userId }); - }); + async function handleDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((userId) => + sdk.forProject(page.params.region, page.params.project).users.delete({ userId }) + ); try { - await Promise.all(promises); - trackEvent(Submit.UserDelete, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.UserDelete); - return error; + if (result.error) { + trackError(result.error, Submit.UserDelete); + } else { + trackEvent(Submit.UserDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.USERS); } + + return result; } diff --git a/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte index 18b2eb2d9..8a58aec9a 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte @@ -12,6 +12,7 @@ SearchQuery, PaginationWithLimit, type DeleteOperationState, + type DeleteOperation, MultiSelectionTable } from '$lib/components'; import Create from '../createTeam.svelte'; @@ -44,20 +45,22 @@ ); }; - async function handleDelete(selectedRows: string[]): Promise { - const promises = selectedRows.map((teamId) => { - return sdk.forProject(page.params.region, page.params.project).teams.delete({ teamId }); - }); + async function handleDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((teamId) => + sdk.forProject(page.params.region, page.params.project).teams.delete({ teamId }) + ); try { - await Promise.all(promises); - trackEvent(Submit.TeamDelete, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.TeamDelete); - return error; + if (result.error) { + trackError(result.error, Submit.TeamDelete); + } else { + trackEvent(Submit.TeamDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.TEAMS); } + + return result; } diff --git a/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte index 98999a305..d9368560f 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte @@ -6,6 +6,7 @@ AvatarInitials, PaginationWithLimit, MultiSelectionTable, + type DeleteOperation, type DeleteOperationState } from '$lib/components'; import { Button } from '$lib/elements/forms'; @@ -29,23 +30,25 @@ let showDelete = $state(false); let selectedMembership: Models.Membership | null = $state(null); - async function handleBulkDelete(selectedRows: string[]): Promise { - const promises = selectedRows.map((membershipId) => { - return sdk.forProject(page.params.region, page.params.project).teams.deleteMembership({ + async function handleBulkDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((membershipId) => + sdk.forProject(page.params.region, page.params.project).teams.deleteMembership({ teamId: page.params.team, membershipId - }); - }); + }) + ); try { - await Promise.all(promises); - trackEvent(Submit.MembershipUpdate, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.MembershipUpdate); - return error; + if (result.error) { + trackError(result.error, Submit.MembershipUpdate); + } else { + trackEvent(Submit.MembershipUpdate, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.MEMBERSHIPS); } + + return result; } diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte index 5d9e956af..e1f053b95 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/identities/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte index 0c0b5525b..6f2b29355 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte @@ -4,6 +4,7 @@ import { AvatarInitials, type DeleteOperationState, + type DeleteOperation, MultiSelectionTable } from '$lib/components'; import { Button } from '$lib/elements/forms'; @@ -23,14 +24,14 @@ let showDelete = $state(false); let selectedMembership: Models.Membership | null = $state(null); - async function handleBulkDelete(selectedRows: string[]): Promise { + async function handleBulkDelete(batchDelete: DeleteOperation): Promise { // Precompute a lookup map from membershipId to teamId for efficient access const membershipIdToTeamId: Record = {}; for (const membership of data.memberships.memberships) { membershipIdToTeamId[membership.$id] = membership.teamId; } - const promises = selectedRows.map((membershipId) => + const result = await batchDelete((membershipId) => sdk.forProject(page.params.region, page.params.project).teams.deleteMembership({ teamId: membershipIdToTeamId[membershipId] || '', membershipId @@ -38,14 +39,16 @@ ); try { - await Promise.all(promises); - trackEvent(Submit.MembershipUpdate, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.MembershipUpdate); - return error; + if (result.error) { + trackError(result.error, Submit.MembershipUpdate); + } else { + trackEvent(Submit.MembershipUpdate, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.MEMBERSHIPS); } + + return result; } diff --git a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte index e71859a43..96414e558 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/user-[user]/targets/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte index d33593160..7cee5aacc 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte @@ -3,6 +3,7 @@ Card, Confirm, type DeleteOperationState, + type DeleteOperation, Modal, MultiSelectionTable } from '$lib/components'; @@ -18,7 +19,7 @@ import { columns } from './store'; import { database } from '../store'; import type { BackupArchive, BackupPolicy } from '$lib/sdk/backups'; - import { Click, trackEvent } from '$lib/actions/analytics'; + import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { copy } from '$lib/helpers/copy'; import { LabelCard } from '$lib/components/index.js'; import DualTimeView from '$lib/components/dualTimeView.svelte'; @@ -110,39 +111,44 @@ } } - async function deleteBackups(selectedRows: string[]): Promise { - const promises = selectedRows.map((archiveId) => { - return sdk + async function deleteSingleBackup(archiveId: string) { + try { + await sdk .forProject(page.params.region, page.params.project) .backups.deleteArchive(archiveId); - }); + + addNotification({ + type: 'success', + message: 'Backup deleted' + }); + + showDelete = false; + selectedBackup = null; + await invalidate(Dependencies.BACKUPS); + } catch (error) { + addNotification({ + type: 'error', + message: error.message + }); + } + } + + async function deleteBackups(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((archiveId) => + sdk.forProject(page.params.region, page.params.project).backups.deleteArchive(archiveId) + ); try { - await Promise.all(promises); - - if (selectedBackup) { - addNotification({ - type: 'success', - message: '1 backup deleted' - }); - } - } catch (error) { - if (selectedBackup) { - addNotification({ - type: 'error', - message: error.message - }); + if (result.error) { + trackError(result.error, Submit.DatabaseBackupDelete); } else { - return error; + trackEvent(Submit.DatabaseBackupDelete); } } finally { - if (selectedBackup) { - showDelete = false; - selectedBackup = null; - } - await invalidate(Dependencies.BACKUPS); } + + return result; } async function restoreBackup() { @@ -299,7 +305,7 @@ bind:open={showDelete} onSubmit={async () => { if (!selectedBackup) return; - await deleteBackups([selectedBackup.$id]); + await deleteSingleBackup(selectedBackup.$id); }}> Are you sure you want to delete the {getCleanBackupName(selectedBackup)} backup? diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte index fa19cde37..6a5c73352 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table.svelte @@ -3,7 +3,12 @@ import { resolve } from '$app/paths'; import { page } from '$app/state'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; - import { Id, MultiSelectionTable, type DeleteOperationState } from '$lib/components'; + import { + Id, + MultiSelectionTable, + type DeleteOperation, + type DeleteOperationState + } from '$lib/components'; import { Dependencies } from '$lib/constants'; import DualTimeView from '$lib/components/dualTimeView.svelte'; import { canWriteTables } from '$lib/stores/roles'; @@ -20,23 +25,26 @@ data: PageData; } = $props(); - async function onDelete(selectedTables: string[]): Promise { - const promises = selectedTables.map((tableId) => + async function onDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((tableId) => sdk.forProject(page.params.region, page.params.project).tablesDB.deleteTable({ databaseId: page.params.database, tableId }) ); + try { - await Promise.all(promises); - trackEvent(Submit.TableDelete); - } catch (error) { - trackError(error, Submit.TableDelete); - return error; + if (result.error) { + trackError(result.error, Submit.TableDelete); + } else { + trackEvent(Submit.TableDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.TABLES); subNavigation.update(); } + + return result; } function getTableHref(table: Models.Table) { diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/table.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/table.svelte index f681c04ef..1e6915c38 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte index 7b46acc09..94672a8d6 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte index b096f2561..464237e79 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte @@ -3,6 +3,7 @@ import { page } from '$app/state'; import { type DeleteOperationState, + type DeleteOperation, Empty, EmptyFilter, EmptySearch, @@ -99,22 +100,24 @@ } ]); - async function handleDelete(selectedRows: string[]): Promise { - const promises = selectedRows.map((id) => + async function handleDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((id) => sdk .forProject(page.params.region, page.params.project) .messaging.delete({ messageId: id }) ); try { - await Promise.all(promises); - trackEvent(Submit.MessagingMessageDelete, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.MessagingMessageDelete); - return error; + if (result.error) { + trackError(result.error, Submit.MessagingMessageDelete); + } else { + trackEvent(Submit.MessagingMessageDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.MESSAGING_MESSAGES); } + + return result; } onMount(() => { diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/table.svelte b/src/routes/(console)/project-[region]-[project]/messaging/providers/table.svelte index a54178b3d..f7ed22281 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/table.svelte @@ -1,7 +1,12 @@ diff --git a/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte b/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte index f5525754e..709529b0f 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte @@ -1,7 +1,12 @@ diff --git a/src/routes/(console)/project-[region]-[project]/messaging/topics/topic-[topic]/table.svelte b/src/routes/(console)/project-[region]-[project]/messaging/topics/topic-[topic]/table.svelte index c9a64e9af..113d9d76e 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/topics/topic-[topic]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/topics/topic-[topic]/table.svelte @@ -2,7 +2,12 @@ import { invalidate } from '$app/navigation'; import { base } from '$app/paths'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; - import { type DeleteOperationState, Id, MultiSelectionTable } from '$lib/components'; + import { + type DeleteOperationState, + type DeleteOperation, + Id, + MultiSelectionTable + } from '$lib/components'; import { Dependencies } from '$lib/constants'; import type { PageData } from './$types'; import ProviderType from '../../providerType.svelte'; @@ -32,8 +37,8 @@ return record; }); - async function handleDelete(selectedRows: string[]): Promise { - async function deleteSubscriber(subscriberId: string) { + async function handleDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete(async (subscriberId) => { await sdk .forProject(page.params.region, page.params.project) .messaging.deleteSubscriber({ @@ -44,19 +49,19 @@ const { target } = subscribers[subscriberId]; const { [target.$id]: _, ...rest } = $targetsById; $targetsById = rest; - } - - const promises = selectedRows.map((id) => deleteSubscriber(id)); + }); try { - await Promise.all(promises); - trackEvent(Submit.MessagingTopicSubscriberDelete, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.MessagingTopicSubscriberDelete); - return error; + if (result.error) { + trackError(result.error, Submit.MessagingTopicSubscriberDelete); + } else { + trackEvent(Submit.MessagingTopicSubscriberDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.MESSAGING_TOPIC_SUBSCRIBERS); } + + return result; } diff --git a/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte b/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte index 9cfb56a83..535be9bd6 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte @@ -67,7 +67,7 @@ allowSelection={$canWriteKeys} showSuccessNotification={false} resource={`${capitalize(label)} key`} - onDelete={(selectedRows) => { + onDelete={(_, selectedRows) => { showDeleteModal = true; selectedKeys = selectedRows; }}> diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte index 22d0bce77..de3cbcb2f 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/+page.svelte @@ -81,7 +81,11 @@ import { page } from '$app/state'; import type { PageProps } from './$types'; import type { Models } from '@appwrite.io/console'; - import { type DeleteOperationState, MultiSelectionTable } from '$lib/components'; + import { + type DeleteOperationState, + type DeleteOperation, + MultiSelectionTable + } from '$lib/components'; import { sdk } from '$lib/stores/sdk'; import { Submit, trackError } from '$lib/actions/analytics'; import { invalidate } from '$app/navigation'; @@ -129,24 +133,26 @@ } async function handlePlatformDelete( - selectedPlatforms: string[] + batchDelete: DeleteOperation ): Promise { - const promises = selectedPlatforms.map((platformId) => { - return sdk.forConsole.projects.deletePlatform({ + const result = await batchDelete((platformId) => + sdk.forConsole.projects.deletePlatform({ projectId: page.params.project, platformId - }); - }); + }) + ); try { - await Promise.all(promises); - trackEvent(Submit.PlatformDelete, { total: selectedPlatforms.length }); - } catch (error) { - trackError(error, Submit.PlatformDelete); - return error; + if (result.error) { + trackError(result.error, Submit.PlatformDelete); + } else { + trackEvent(Submit.PlatformDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.PROJECT); } + + return result; } setOverviewAction(Action); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/table.svelte index 690411c1e..d135498a6 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte index da4890035..de2504715 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/table.svelte @@ -1,5 +1,10 @@ diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte index 8caf3c05a..886169f11 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.svelte @@ -6,6 +6,7 @@ import { Avatar, type DeleteOperationState, + type DeleteOperation, Empty, EmptySearch, MultiSelectionTable, @@ -65,23 +66,25 @@ showDelete = true; } - async function handleBulkDelete(selectedRows: string[]): Promise { - const promises = selectedRows.map((fileId) => { - return sdk.forProject(page.params.region, page.params.project).storage.deleteFile({ + async function handleBulkDelete(batchDelete: DeleteOperation): Promise { + const result = await batchDelete((fileId) => + sdk.forProject(page.params.region, page.params.project).storage.deleteFile({ bucketId: page.params.bucket, fileId - }); - }); + }) + ); try { - await Promise.all(promises); - trackEvent(Submit.FileDelete, { total: selectedRows.length }); - } catch (error) { - trackError(error, Submit.FileDelete); - return error; + if (result.error) { + trackError(result.error, Submit.FileDelete); + } else { + trackEvent(Submit.FileDelete, { total: result.deleted.length }); + } } finally { await invalidate(Dependencies.FILES); } + + return result; } const beforeunload = (event: BeforeUnloadEvent) => { From 7a595b1197add536f835df75c2fa0505a84d8e7e Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 14:21:37 +0530 Subject: [PATCH 532/599] update: improvements. --- .../auth/security/passwordPolicies.svelte | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte index 46547cecb..004e772ee 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte @@ -8,65 +8,63 @@ import { sdk } from '$lib/stores/sdk'; import { Typography, Link, Layout } from '@appwrite.io/pink-svelte'; import type { Models } from '@appwrite.io/console'; - import { tick } from 'svelte'; + import { onMount } from 'svelte'; - let { project }: { project: Models.Project } = $props(); + let { + project + }: { + project: Models.Project; + } = $props(); - let passwordHistory = $state(5); - let passwordHistoryEnabled = $state(false); - let passwordDictionary = $state(false); - let authPersonalDataCheck = $state(false); let lastValidLimit = $state(5); + let passwordHistory = $state(5); + let passwordDictionary = $state(false); + let passwordHistoryEnabled = $state(false); + let authPersonalDataCheck = $state(false); - let maxPasswordInputField: InputNumber | null = null; - - // Initialize and sync state when project updates - $effect(() => { - const historyValue = project?.authPasswordHistory; + onMount(() => { + // update initial states here in onMount. + const historyValue = project.authPasswordHistory; if (historyValue && historyValue > 0) { passwordHistory = historyValue; lastValidLimit = historyValue; } + passwordHistoryEnabled = (historyValue ?? 0) !== 0; - passwordDictionary = project?.authPasswordDictionary ?? false; - authPersonalDataCheck = project?.authPersonalDataCheck ?? false; + passwordDictionary = project.authPasswordDictionary ?? false; + authPersonalDataCheck = project.authPersonalDataCheck ?? false; }); - // restore last valid limit when enabling $effect(() => { + // restore last valid limit when enabling if (passwordHistoryEnabled && passwordHistory < 1) { passwordHistory = lastValidLimit; } }); - $effect(() => { - if (passwordHistoryEnabled) { - tick().then(() => { - if (maxPasswordInputField) { - maxPasswordInputField.addInputFocus(); - } - }); - } - }); + const hasChanges = $derived.by(() => { + const dictChanged = passwordDictionary !== project.authPasswordDictionary; + const dataCheckChanged = authPersonalDataCheck !== project.authPersonalDataCheck; + const historyChanged = passwordHistoryEnabled !== (project.authPasswordHistory !== 0); - const hasChanges = $derived( - passwordHistoryEnabled !== ((project?.authPasswordHistory ?? 0) !== 0) || - (passwordHistoryEnabled && passwordHistory !== (project?.authPasswordHistory ?? 0)) || - passwordDictionary !== (project?.authPasswordDictionary ?? false) || - authPersonalDataCheck !== (project?.authPersonalDataCheck ?? false) - ); + return historyChanged || dictChanged || dataCheckChanged; + }); async function updatePasswordPolicies() { try { - await sdk.forConsole.projects.updateAuthPasswordHistory({ + const projectSdk = sdk.forConsole.projects; + + await projectSdk.updateAuthPasswordHistory({ projectId: project.$id, limit: passwordHistoryEnabled ? passwordHistory : 0 }); - await sdk.forConsole.projects.updateAuthPasswordDictionary({ + + await projectSdk.updateAuthPasswordDictionary({ projectId: project.$id, enabled: passwordDictionary }); - await sdk.forConsole.projects.updatePersonalDataCheck({ + + await projectSdk.updatePersonalDataCheck({ projectId: project.$id, enabled: authPersonalDataCheck }); @@ -108,10 +106,10 @@ required max={20} min={1} - id="password-history" + autofocus label="Limit" + id="password-history" bind:value={passwordHistory} - bind:this={maxPasswordInputField} helper="Maximum 20 passwords." /> {/if} From 2cd22b98c342cf08e8c908635f2d44342b2e099d Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Fri, 2 Jan 2026 14:21:54 +0530 Subject: [PATCH 533/599] merged conflicts resolved --- src/lib/layout/activity.svelte | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/lib/layout/activity.svelte b/src/lib/layout/activity.svelte index 61aa1e041..c77fa3488 100644 --- a/src/lib/layout/activity.svelte +++ b/src/lib/layout/activity.svelte @@ -75,32 +75,31 @@
{log.userName ?? 'Anonymous'} {/if} - - + + - - {log.event} - + + {log.event} + - - {#if log.countryCode !== '--'} - {log.countryName} - {:else} - Unknown - {/if} - + + {#if log.countryCode !== '--'} + {log.countryName} + {:else} + Unknown + {/if} + - - - + + + - - - - -{/each} - -
+ + + + + {/each} + Date: Fri, 2 Jan 2026 14:24:37 +0530 Subject: [PATCH 534/599] add: comment. --- src/lib/components/multiSelectTable.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/components/multiSelectTable.svelte b/src/lib/components/multiSelectTable.svelte index bb985f790..78e6b7388 100644 --- a/src/lib/components/multiSelectTable.svelte +++ b/src/lib/components/multiSelectTable.svelte @@ -50,6 +50,10 @@ deleteContentNotice?: Snippet; onDelete?: ( batchDelete: DeleteOperation, + /** + * this is useful if you have a custom deletion logic + * and don't want to use the batchDelete helper provided! + */ selectedRows: string[] ) => Promise | DeleteOperationState; onCancel?: () => Promise | void; From 7b74d4210c10e4ca5adb0f995f916991587554c5 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 14:25:21 +0530 Subject: [PATCH 535/599] add: comment. --- src/lib/components/multiSelectTable.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/components/multiSelectTable.svelte b/src/lib/components/multiSelectTable.svelte index 78e6b7388..79197f2f7 100644 --- a/src/lib/components/multiSelectTable.svelte +++ b/src/lib/components/multiSelectTable.svelte @@ -51,8 +51,8 @@ onDelete?: ( batchDelete: DeleteOperation, /** - * this is useful if you have a custom deletion logic - * and don't want to use the batchDelete helper provided! + * this is useful when you have a custom deletion logic + * and the default `batchDelete` helper doesn't fit the use-case! */ selectedRows: string[] ) => Promise | DeleteOperationState; From 0c65c0d79060215e899a4d656bd035a651b51769 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:02:07 +0530 Subject: [PATCH 536/599] added limitchanged --- .../auth/security/passwordPolicies.svelte | 12 ++++++++---- .../auth/security/sessionSecurity.svelte | 14 ++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte index 004e772ee..22898b060 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/passwordPolicies.svelte @@ -43,11 +43,15 @@ }); const hasChanges = $derived.by(() => { - const dictChanged = passwordDictionary !== project.authPasswordDictionary; - const dataCheckChanged = authPersonalDataCheck !== project.authPersonalDataCheck; - const historyChanged = passwordHistoryEnabled !== (project.authPasswordHistory !== 0); + const dictChanged = passwordDictionary !== (project.authPasswordDictionary ?? false); + const dataCheckChanged = authPersonalDataCheck !== (project.authPersonalDataCheck ?? false); + const historyChanged = + passwordHistoryEnabled !== ((project.authPasswordHistory ?? 0) !== 0); + const limitChanged = + passwordHistoryEnabled && + Number(passwordHistory) !== (project.authPasswordHistory ?? 0); - return historyChanged || dictChanged || dataCheckChanged; + return historyChanged || dictChanged || dataCheckChanged || limitChanged; }); async function updatePasswordPolicies() { diff --git a/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte b/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte index f64fee94e..6babbbecc 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/security/sessionSecurity.svelte @@ -8,22 +8,24 @@ import { sdk } from '$lib/stores/sdk'; import { Typography } from '@appwrite.io/pink-svelte'; import type { Models } from '@appwrite.io/console'; + import { onMount } from 'svelte'; let { project }: { project: Models.Project } = $props(); let authSessionAlerts = $state(false); let sessionInvalidation = $state(false); - // Initialize state from project - $effect(() => { + onMount(() => { authSessionAlerts = project?.authSessionAlerts ?? false; sessionInvalidation = project?.authInvalidateSessions ?? false; }); - const hasChanges = $derived( - authSessionAlerts !== (project?.authSessionAlerts ?? false) || - sessionInvalidation !== (project?.authInvalidateSessions ?? false) - ); + const hasChanges = $derived.by(() => { + const alertsChanged = authSessionAlerts !== (project?.authSessionAlerts ?? false); + const invalidationChanged = + sessionInvalidation !== (project?.authInvalidateSessions ?? false); + return alertsChanged || invalidationChanged; + }); async function updateSessionSecurity() { try { From 59900a4ca285534029101285993a91415995e196 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Fri, 2 Jan 2026 17:21:42 +0530 Subject: [PATCH 537/599] addressed code rabbit --- src/lib/components/limit.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/components/limit.svelte b/src/lib/components/limit.svelte index 8a7c1ef67..4221f7693 100644 --- a/src/lib/components/limit.svelte +++ b/src/lib/components/limit.svelte @@ -27,7 +27,9 @@ if (url.searchParams.has(pageParam)) { const page = Number(url.searchParams.get(pageParam)); - const newPage = Math.floor(((page - 1) * previousLimit) / limit); + const prev = + Number.isFinite(previousLimit) && previousLimit > 0 ? previousLimit : limit; + const newPage = Math.floor(((page - 1) * prev) / limit) + 1; const safePage = Math.max(1, Number.isFinite(newPage) ? newPage : 1); if (removeOnFirstPage && safePage === 1) { url.searchParams.delete(pageParam); From f8a04a20520798d71a97b63364da2f6c0a6d37d8 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 18:02:52 +0530 Subject: [PATCH 538/599] address comment. --- src/lib/components/multiSelectTable.svelte | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/components/multiSelectTable.svelte b/src/lib/components/multiSelectTable.svelte index 79197f2f7..ce0196e34 100644 --- a/src/lib/components/multiSelectTable.svelte +++ b/src/lib/components/multiSelectTable.svelte @@ -93,6 +93,11 @@ const deleted: string[] = []; let firstError: Error | undefined; + // prevent infinite loop + if (batchSize !== undefined) { + batchSize = Math.max(1, Math.floor(Math.abs(batchSize))); + } + async function processBatch(batch: string[]) { // build promises const results = await Promise.allSettled(batch.map((id) => deleteFn(id))); From 09884a935aae625d109afff4a837d1dbb709d0c7 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 19:18:44 +0530 Subject: [PATCH 539/599] fix: payments not updating. --- .../account/payments/editPaymentModal.svelte | 46 +++++++++---------- .../organization-[organization]/+layout.ts | 15 ++---- .../billing/+page.svelte | 22 ++++----- .../billing/+page.ts | 37 +++++++++++++-- .../billing/deleteOrgPayment.svelte | 13 +++--- .../billing/paymentMethods.svelte | 43 +++++++---------- .../billing/replaceCard.svelte | 2 +- 7 files changed, 92 insertions(+), 86 deletions(-) diff --git a/src/routes/(console)/account/payments/editPaymentModal.svelte b/src/routes/(console)/account/payments/editPaymentModal.svelte index 7850cdea9..fab629996 100644 --- a/src/routes/(console)/account/payments/editPaymentModal.svelte +++ b/src/routes/(console)/account/payments/editPaymentModal.svelte @@ -9,13 +9,27 @@ import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Alert } from '@appwrite.io/pink-svelte'; - export let show = false; - export let selectedPaymentMethod: PaymentMethodData; - export let isLinked = false; + let { + show = $bindable(false), + isLinked = false, + selectedPaymentMethod, + }: { + show: boolean; + isLinked?: boolean; + selectedPaymentMethod: PaymentMethodData; + } = $props() + + let year: number | null = $state(null); + let month: string | null = $state(null); + let error: string | null = $state(null); + const currentYear = new Date().getFullYear(); - let error: string; - let month: string; - let year: number; + const months = Array.from({ length: 12 }, (_, i) => { + const value = String(i + 1).padStart(2, '0'); + return { value, label: value }; + }); + + const options = $derived(createMonthOptions(year)); async function handleSubmit() { try { @@ -24,9 +38,9 @@ month, year?.toString() ); - trackEvent(Submit.PaymentMethodUpdate); - invalidate(Dependencies.PAYMENT_METHODS); show = false; + trackEvent(Submit.PaymentMethodUpdate); + await invalidate(Dependencies.PAYMENT_METHODS); addNotification({ type: 'success', message: 'Your payment method has been updated' @@ -38,20 +52,6 @@ } function createMonthOptions(year: number) { - const months = [ - { value: '01', label: '01' }, - { value: '02', label: '02' }, - { value: '03', label: '03' }, - { value: '04', label: '04' }, - { value: '05', label: '05' }, - { value: '06', label: '06' }, - { value: '07', label: '07' }, - { value: '08', label: '08' }, - { value: '09', label: '09' }, - { value: '10', label: '10' }, - { value: '11', label: '11' }, - { value: '12', label: '12' } - ]; if (!year) return months; if (year === currentYear) { const currentMonth = new Date().getMonth() + 1; @@ -60,8 +60,6 @@ return months; } } - - $: options = createMonthOptions(year); diff --git a/src/routes/(console)/organization-[organization]/+layout.ts b/src/routes/(console)/organization-[organization]/+layout.ts index ef77274e8..aa1b03b8d 100644 --- a/src/routes/(console)/organization-[organization]/+layout.ts +++ b/src/routes/(console)/organization-[organization]/+layout.ts @@ -24,7 +24,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { depends(Dependencies.MEMBERS); depends(Dependencies.PAYMENT_METHODS); - const requestedOrg = await checkPlatformAndRedirect(params, organizations, prefs); + await checkPlatformAndRedirect(params, organizations, prefs); let roles = isCloud ? [] : defaultRoles; let scopes = isCloud ? [] : defaultScopes; @@ -46,13 +46,8 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { sdk.forConsole.account.updatePrefs({ prefs: newPrefs }); } - // fetch org only if we haven't already fetched it for platform check - const orgPromise: Promise = requestedOrg - ? Promise.resolve(requestedOrg) - : (sdk.forConsole.teams.get({ teamId: params.organization }) as Promise); - const [org, members, countryList, locale] = await Promise.all([ - orgPromise, + sdk.forConsole.teams.get({ teamId: params.organization }) as Promise, sdk.forConsole.teams.listMemberships({ teamId: params.organization }), sdk.forConsole.locale.listCountries(), sdk.forConsole.locale.get(), @@ -96,7 +91,7 @@ async function checkPlatformAndRedirect( params: { organization: string }, organizations: { teams: Array<{ $id: string; platform?: string }> }, prefs: Record -): Promise { +) { // check if preloaded let requestedOrg = organizations.teams.find((team) => team.$id === params.organization) as | Organization @@ -154,8 +149,4 @@ async function checkPlatformAndRedirect( redirect(303, resolve('/(console)')); } } - - // send the org, - // if already in the full list so we don't have to make another API request. - return requestedOrg; } diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index 99729b8e9..ab69b151b 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -9,7 +9,6 @@ import PaymentHistory from './paymentHistory.svelte'; import TaxId from './taxId.svelte'; import { failedInvoice, tierToPlan, upgradeURL, useNewPricingModal } from '$lib/stores/billing'; - import type { PaymentMethodData } from '$lib/sdk/billing'; import { onMount } from 'svelte'; import { page } from '$app/state'; import { confirmPayment } from '$lib/stores/stripe'; @@ -26,18 +25,8 @@ export let data: PageData; - // Reactive statement to update organization when data changes $: organization = data.organization; - // why are these reactive? - $: defaultPaymentMethod = data?.paymentMethods?.paymentMethods?.find( - (method: PaymentMethodData) => method.$id === organization?.paymentMethodId - ); - - $: backupPaymentMethod = data?.paymentMethods?.paymentMethods?.find( - (method: PaymentMethodData) => method.$id === organization?.backupPaymentMethodId - ); - onMount(async () => { if (page.url.searchParams.has('type')) { if (page.url.searchParams.get('type') === 'upgrade') { @@ -115,7 +104,7 @@
{/if} {/if} - {#if defaultPaymentMethod?.failed && !backupPaymentMethod} + {#if data.primaryPaymentMethod?.failed && !data.backupPaymentMethod} @@ -146,7 +135,14 @@ currentInvoice={data?.billingInvoice} /> {/if} - + + + { depends(Dependencies.CREDIT); depends(Dependencies.INVOICES); depends(Dependencies.ADDRESS); - //aggregation reloads on page param changes + // aggregation reloads on page param changes depends(Dependencies.BILLING_AGGREGATION); const billingAddressId = (organization as Organization)?.billingAddressId; @@ -82,6 +83,10 @@ export const load: PageLoad = async ({ parent, depends, url, route }) => { // make number const credits = availableCredit ? availableCredit.available : null; + const { + backup, + primary + } = getOrganizationPaymentMethods(organization, paymentMethods) return { paymentMethods, @@ -98,6 +103,32 @@ export const load: PageLoad = async ({ parent, depends, url, route }) => { offset: pageToOffset( getPage(url) || 1, getLimit(url, route, DEFAULT_BILLING_PROJECTS_LIMIT) - ) + ), + + backupPaymentMethod: backup, + primaryPaymentMethod: primary }; }; + +function getOrganizationPaymentMethods( + organization: Organization, + paymentMethods: PaymentList +): { + backup: PaymentMethodData | null; + primary: PaymentMethodData | null; +} { + let backup: PaymentMethodData | null = null; + let primary: PaymentMethodData | null = null; + + for (const paymentMethod of paymentMethods.paymentMethods) { + if (paymentMethod.$id === organization.paymentMethodId) { + primary = paymentMethod; + } else if (paymentMethod.$id === organization.backupPaymentMethodId) { + backup = paymentMethod; + } + + if (primary && backup) break; + } + + return { primary, backup }; +} diff --git a/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte b/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte index 8f6625179..7290ae055 100644 --- a/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte +++ b/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte @@ -25,7 +25,7 @@ message: `The payment method has been removed from ${$organization.name}` }); trackEvent(Submit.OrganizationPaymentDelete); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.PAYMENT_METHODS); showDelete = false; } catch (e) { error = e.message; @@ -34,7 +34,7 @@ showDelete = false; } } - async function removeBackuptMethod() { + async function removeBackupMethod() { if ($organization?.billingPlan !== BillingPlan.FREE && !hasOtherMethod) return; showDelete = false; @@ -45,7 +45,7 @@ message: `The payment method has been removed from ${$organization.name}` }); trackEvent(Submit.OrganizationBackupPaymentDelete); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.PAYMENT_METHODS); showDelete = false; } catch (e) { error = e.message; @@ -65,10 +65,11 @@ {:else} + title="Remove payment method" + onSubmit={isBackup ? removeBackupMethod : removeDefaultMethod} + > Are you sure you want to remove the payment method from {$organization?.name}? diff --git a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte index 124518f1e..445c65d10 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte @@ -34,16 +34,17 @@ IconTrash } from '@appwrite.io/pink-icons-svelte'; - export let organization: Organization; export let methods: PaymentList; + export let organization: Organization; + + export let backupMethod: PaymentMethodData; + export let primaryMethod: PaymentMethodData; let showPayment = false; let showEdit = false; let showDelete = false; let showReplace = false; let isSelectedBackup = false; - let backupPaymentMethod: PaymentMethodData; - let defaultPaymentMethod: PaymentMethodData; async function addPaymentMethod(paymentMethodId: string) { try { @@ -56,7 +57,7 @@ message: `A new payment method has been added to ${organization.name}` }); trackEvent(Submit.OrganizationPaymentUpdate); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.PAYMENT_METHODS); } catch (error) { addNotification({ type: 'error', @@ -76,7 +77,7 @@ type: 'success', message: `A new payment method has been added to ${organization.name}` }); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.PAYMENT_METHODS); } catch (error) { addNotification({ type: 'error', @@ -86,27 +87,15 @@ } } - $: if (organization?.backupPaymentMethodId) { - sdk.forConsole.billing - .getOrganizationPaymentMethod(organization.$id, organization.backupPaymentMethodId) - .then((res) => (backupPaymentMethod = res)); - } - - $: if (organization?.paymentMethodId) { - sdk.forConsole.billing - .getOrganizationPaymentMethod(organization.$id, organization.paymentMethodId) - .then((res) => (defaultPaymentMethod = res)); - } - $: if (!showReplace) { isSelectedBackup = false; } $: hasPaymentError = - defaultPaymentMethod?.lastError || - defaultPaymentMethod?.expired || - backupPaymentMethod?.lastError || - backupPaymentMethod?.expired; + primaryMethod?.lastError || + primaryMethod?.expired || + backupMethod?.lastError || + backupMethod?.expired; @@ -132,14 +121,14 @@
- + - {#if defaultPaymentMethod?.userId === $user?.$id} + {#if primaryMethod?.userId === $user?.$id} { @@ -171,14 +160,14 @@ {#if organization?.backupPaymentMethodId} - + - {#if backupPaymentMethod?.userId === $user?.$id} + {#if backupMethod?.userId === $user?.$id} { @@ -318,8 +307,8 @@ {/if} {#if showEdit && isCloud && hasStripePublicKey} + bind:show={showEdit} + selectedPaymentMethod={isSelectedBackup ? backupMethod : primaryMethod} /> {/if} {#if isCloud && hasStripePublicKey} diff --git a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte index ea4cc7d26..a02dde00b 100644 --- a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte +++ b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte @@ -73,7 +73,7 @@ type: 'success', message: `Your ${isBackup ? 'backup' : 'default'} payment method has been updated` }); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.PAYMENT_METHODS); trackEvent( isBackup ? Submit.OrganizationBackupPaymentDelete : Submit.OrganizationPaymentDelete ); From 4eda58bb999811b16869604c2eae5c2d849489ad Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 19:28:44 +0530 Subject: [PATCH 540/599] improvements. --- .../account/payments/editPaymentModal.svelte | 4 +- .../billing/+page.svelte | 10 +-- .../billing/+page.ts | 5 +- .../billing/deleteOrgPayment.svelte | 3 +- .../billing/replaceCard.svelte | 68 ++++++++++--------- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/routes/(console)/account/payments/editPaymentModal.svelte b/src/routes/(console)/account/payments/editPaymentModal.svelte index fab629996..24a8fa08f 100644 --- a/src/routes/(console)/account/payments/editPaymentModal.svelte +++ b/src/routes/(console)/account/payments/editPaymentModal.svelte @@ -12,12 +12,12 @@ let { show = $bindable(false), isLinked = false, - selectedPaymentMethod, + selectedPaymentMethod }: { show: boolean; isLinked?: boolean; selectedPaymentMethod: PaymentMethodData; - } = $props() + } = $props(); let year: number | null = $state(null); let month: string | null = $state(null); diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index ab69b151b..51d7fe353 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -20,12 +20,15 @@ import { Alert } from '@appwrite.io/pink-svelte'; import { goto, invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; - import { base } from '$app/paths'; import type { PageData } from './$types'; + import { resolve } from '$app/paths'; export let data: PageData; $: organization = data.organization; + $: baseUrl = resolve('/(console)/organization-[organization]/billing', { + organization: organization.$id + }); onMount(async () => { if (page.url.searchParams.has('type')) { @@ -47,7 +50,7 @@ organization.$id, invoice.clientSecret, organization.paymentMethodId, - `${base}/organization-${organization.$id}/billing?type=validate-invoice&invoice=${invoice.$id}` + `${baseUrl}?type=validate-invoice&invoice=${invoice.$id}` ); } @@ -140,8 +143,7 @@ methods={data?.paymentMethods} organization={data?.organization} backupMethod={data.backupPaymentMethod} - primaryMethod={data.primaryPaymentMethod} - /> + primaryMethod={data.primaryPaymentMethod} /> { // make number const credits = availableCredit ? availableCredit.available : null; - const { - backup, - primary - } = getOrganizationPaymentMethods(organization, paymentMethods) + const { backup, primary } = getOrganizationPaymentMethods(organization, paymentMethods); return { paymentMethods, diff --git a/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte b/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte index 7290ae055..1de90ac4a 100644 --- a/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte +++ b/src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte @@ -68,8 +68,7 @@ bind:error bind:open={showDelete} title="Remove payment method" - onSubmit={isBackup ? removeBackupMethod : removeDefaultMethod} - > + onSubmit={isBackup ? removeBackupMethod : removeDefaultMethod}> Are you sure you want to remove the payment method from {$organization?.name}? diff --git a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte index a02dde00b..b703f0842 100644 --- a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte +++ b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte @@ -13,17 +13,29 @@ import { PaymentBoxes } from '$lib/components/billing'; import type { PaymentMethod } from '@stripe/stripe-js'; - export let organization: Organization; - export let show = false; - export let isBackup = false; - export let methods: PaymentList; + let { + show = false, + isBackup = false, + methods, + organization + }: { + show?: boolean; + isBackup?: boolean; + methods: PaymentList; + organization: Organization; + } = $props(); - let name: string; - let error: string = null; - let selectedPaymentMethodId: string; - let showState: boolean = false; - let state: string = ''; - let paymentMethod: PaymentMethod | null = null; + let name: string | null = $state(null); + let error: string | null = $state(null); + let showState: boolean = $state(false); + let countryState: string | null = $state(null); + let paymentMethod: PaymentMethod | null = $state(null); + let selectedPaymentMethodId: string | null = $state(null); + + const filteredMethods = $derived(methods?.paymentMethods.filter((method) => !!method?.last4)); + const submitEvent = $derived( + isBackup ? Submit.OrganizationBackupPaymentDelete : Submit.OrganizationPaymentDelete + ); onMount(async () => { if (!organization.paymentMethodId && !organization.backupPaymentMethodId) { @@ -45,12 +57,12 @@ async function handleSubmit() { try { if (selectedPaymentMethodId === '$new') { - if (showState && !state) { + if (showState && !countryState) { throw Error('Please select a state'); } let method: PaymentMethodData; if (showState) { - method = await setPaymentMethod(paymentMethod.id, name, state); + method = await setPaymentMethod(paymentMethod.id, name, countryState); } else { const card = await submitStripeCard(name, organization.$id); if (card && Object.hasOwn(card, 'id')) { @@ -69,21 +81,17 @@ ? await addBackupPaymentMethod(selectedPaymentMethodId) : await addPaymentMethod(selectedPaymentMethodId); + await invalidate(Dependencies.PAYMENT_METHODS); + addNotification({ type: 'success', message: `Your ${isBackup ? 'backup' : 'default'} payment method has been updated` }); - await invalidate(Dependencies.PAYMENT_METHODS); - trackEvent( - isBackup ? Submit.OrganizationBackupPaymentDelete : Submit.OrganizationPaymentDelete - ); + trackEvent(submitEvent); show = false; - } catch (e) { - error = e.message; - trackError( - e, - isBackup ? Submit.OrganizationBackupPaymentDelete : Submit.OrganizationPaymentDelete - ); + } catch (err) { + error = err.message; + trackError(err, submitEvent); } } @@ -93,8 +101,8 @@ organization.$id, paymentMethodId ); - } catch (e) { - error = e.message; + } catch (err) { + error = err.message; } } @@ -104,23 +112,21 @@ organization.$id, paymentMethodId ); - } catch (e) { - error = e.message; + } catch (err) { + error = err.message; } } - - $: filteredMethods = methods?.paymentMethods.filter((method) => !!method?.last4);

Replace the existing payment method for your organization.

Date: Fri, 2 Jan 2026 19:34:37 +0530 Subject: [PATCH 541/599] fix: lint. --- .../organization-[organization]/billing/replaceCard.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte index b703f0842..4c326488a 100644 --- a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte +++ b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte @@ -14,7 +14,7 @@ import type { PaymentMethod } from '@stripe/stripe-js'; let { - show = false, + show = $bindable(false), isBackup = false, methods, organization From fdc94a584f1935faaba2dc3d807198732588e113 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 2 Jan 2026 19:36:01 +0530 Subject: [PATCH 542/599] fix: events. --- .../organization-[organization]/billing/replaceCard.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte index 4c326488a..920f7b474 100644 --- a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte +++ b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte @@ -34,7 +34,7 @@ const filteredMethods = $derived(methods?.paymentMethods.filter((method) => !!method?.last4)); const submitEvent = $derived( - isBackup ? Submit.OrganizationBackupPaymentDelete : Submit.OrganizationPaymentDelete + isBackup ? Submit.OrganizationBackupPaymentUpdate : Submit.OrganizationPaymentUpdate ); onMount(async () => { From fb2d12d33c2cb97cae67f2a9fda217c7e75b8c89 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 10:36:53 -0800 Subject: [PATCH 543/599] Remove payment mandate setup functionality (#2748) * Initial plan * Remove all mandate-related code including setupPaymentMandate, checkForMandate, and paymentMandate component Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --- .../billing/alerts/paymentMandate.svelte | 26 ------------------- src/lib/sdk/billing.ts | 20 -------------- src/lib/stores/billing.ts | 21 +-------------- src/routes/(console)/+layout.svelte | 2 -- 4 files changed, 1 insertion(+), 68 deletions(-) delete mode 100644 src/lib/components/billing/alerts/paymentMandate.svelte diff --git a/src/lib/components/billing/alerts/paymentMandate.svelte b/src/lib/components/billing/alerts/paymentMandate.svelte deleted file mode 100644 index 08d9207d7..000000000 --- a/src/lib/components/billing/alerts/paymentMandate.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - -{#if $paymentMissingMandate && $paymentMissingMandate?.country?.toLowerCase() === 'in' && $paymentMissingMandate.mandateId === null && !hideBillingHeaderRoutes.includes(page.url.pathname)} - - The payment method for {$organization.name} needs to be verified. - - - - -{/if} diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 11b5ba519..994506e72 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -1300,26 +1300,6 @@ export class Billing { ); } - async setupPaymentMandate( - organizationId: string, - paymentMethodId: string - ): Promise { - const path = `/account/payment-methods/${paymentMethodId}/setup`; - const params = { - organizationId, - paymentMethodId - }; - const uri = new URL(this.client.config.endpoint + path); - return await this.client.call( - 'patch', - uri, - { - 'content-type': 'application/json' - }, - params - ); - } - async listAddresses(queries: string[] = []): Promise { const path = `/account/billing-addresses`; const params = { diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 695ef874c..df2d29178 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -8,7 +8,7 @@ import MarkedForDeletion from '$lib/components/billing/alerts/markedForDeletion. import MissingPaymentMethod from '$lib/components/billing/alerts/missingPaymentMethod.svelte'; import newDevUpgradePro from '$lib/components/billing/alerts/newDevUpgradePro.svelte'; import PaymentAuthRequired from '$lib/components/billing/alerts/paymentAuthRequired.svelte'; -import PaymentMandate from '$lib/components/billing/alerts/paymentMandate.svelte'; + import { BillingPlan, NEW_DEV_PRO_UPGRADE_COUPON } from '$lib/constants'; import { cachedStore } from '$lib/helpers/cache'; import { type Size, sizeToBytes } from '$lib/helpers/sizeConvertion'; @@ -18,7 +18,6 @@ import type { Invoice, InvoiceList, PaymentList, - PaymentMethodData, Plan, PlansMap } from '$lib/sdk/billing'; @@ -535,24 +534,6 @@ export function checkForMarkedForDeletion(org: Organization) { } } -export const paymentMissingMandate = writable(null); - -export async function checkForMandate(org: Organization) { - const paymentId = org.paymentMethodId ?? org.backupPaymentMethodId; - if (!paymentId) return; - const paymentMethod = await sdk.forConsole.billing.getPaymentMethod(paymentId); - if (paymentMethod?.mandateId === null && paymentMethod?.country.toLowerCase() === 'in') { - headerAlert.add({ - id: 'paymentMandate', - component: PaymentMandate, - show: true, - importance: 8 - }); - activeHeaderAlert.set(headerAlert.get()); - paymentMissingMandate.set(paymentMethod); - } -} - export async function checkForMissingPaymentMethod() { const orgs = await sdk.forConsole.billing.listOrganization([ Query.notEqual('billingPlan', BillingPlan.FREE), diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index d6231de58..ce28dd7c2 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -15,7 +15,6 @@ import { calculateTrialDay, checkForEnterpriseTrial, - checkForMandate, checkForMarkedForDeletion, checkForMissingPaymentMethod, checkForNewDevUpgradePro, @@ -308,7 +307,6 @@ if (org?.billingPlan !== BillingPlan.FREE) { await paymentExpired(org); await checkPaymentAuthorizationRequired(org); - await checkForMandate(org); if ($plansInfo.get(org.billingPlan)?.trialDays) { calculateTrialDay(org); From 3191f3d89e1f6b5c30fe2eaf726ffca9621ddb3c Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:15:37 +0530 Subject: [PATCH 544/599] fix: improve mobile table display for domain verification --- src/lib/components/domains/cnameTable.svelte | 20 +++++++++----- src/lib/components/domains/recordTable.svelte | 26 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/lib/components/domains/cnameTable.svelte b/src/lib/components/domains/cnameTable.svelte index b198524da..9569ce89f 100644 --- a/src/lib/components/domains/cnameTable.svelte +++ b/src/lib/components/domains/cnameTable.svelte @@ -35,16 +35,22 @@
- + - Type - Name - Value + Type + Name + Value - CNAME - {subdomain} - + CNAME + {subdomain} +
- + - Type - Name - Value + Type + Name + Value - {variant.toUpperCase()} - {subdomain || '@'} - + {variant.toUpperCase()} + {subdomain || '@'} + {#if $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA} - + CAA - @ - + @ + From f182f7d83ea6c7d735ee44086f4973ee3ce11566 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Sun, 4 Jan 2026 18:25:20 +0530 Subject: [PATCH 545/599] responsiveness for add records screen --- .../domains/domain-[domain]/+page.svelte | 100 +++++++++++++----- 1 file changed, 72 insertions(+), 28 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte index d6ce25571..37c3eb109 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte @@ -13,9 +13,16 @@ } from '@appwrite.io/pink-svelte'; import DomainMetrics from './domainMetrics.svelte'; import { base } from '$app/paths'; + import { isSmallViewport } from '$lib/stores/viewport'; import { app } from '$lib/stores/app'; import { Button } from '$lib/elements/forms'; - import { IconDownload, IconPlus, IconUpload } from '@appwrite.io/pink-icons-svelte'; + import { + IconDownload, + IconPlus, + IconUpload, + IconAdjustments + } from '@appwrite.io/pink-icons-svelte'; + import DisplaySettingsModal from '$lib/layout/displaySettingsModal.svelte'; import { ViewSelector } from '$lib/components'; import { View } from '$lib/helpers/load'; import { columns, presets } from './store'; @@ -33,6 +40,7 @@ let showCreate = false; let showPresetModal = false; let showImportModal = false; + let showDisplaySettingsModal = false; let selectedPreset = ''; async function downloadRecords() { @@ -70,8 +78,8 @@ {#if data.recordList.total} - - +
+
- - - {#each presets as preset} - { - toggle(e); - selectedPreset = preset; - showPresetModal = true; - }}>{preset} - {/each} - - - - - - - +
+ + + + + {#each presets as preset} + { + toggle(e); + selectedPreset = preset; + showPresetModal = true; + }}>{preset} + {/each} + + + +
+ +
+ {#if $isSmallViewport} + + {:else} + + {/if} +
+ +
+
+ +
+
+ {:else} {/if} + +{#if showDisplaySettingsModal} + +{/if} + + From ff37a87fd00f9cc8c60d9ac312ba15053801774f Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Sun, 4 Jan 2026 18:33:22 +0530 Subject: [PATCH 546/599] few fixes --- .../domains/domain-[domain]/+page.svelte | 82 +++++++++++++------ 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte index 37c3eb109..c3e65b537 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte @@ -78,8 +78,18 @@ {#if data.recordList.total} -
-
+ + + + + {#each presets as preset} + { + toggle(e); + selectedPreset = preset; + showPresetModal = true; + }}>{preset} + {/each} + + + +
+ {/if} + + + {#if $isSmallViewport} + + {:else} + + {/if} + + {#if !$isSmallViewport} - + {#each presets as preset} @@ -107,30 +154,19 @@ -
- -
- {#if $isSmallViewport} - - {:else} - {/if} -
+ +
-
-
+
+
From 394cb0679916cd960d4f222f91a2e09028783b13 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Sun, 4 Jan 2026 18:45:33 +0530 Subject: [PATCH 547/599] final design --- .../domains/domain-[domain]/+page.svelte | 112 +++++++++++------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte index c3e65b537..2494116ba 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte @@ -78,32 +78,12 @@ {#if data.recordList.total} - - - - - - - - Export as .txt - - {#if $isSmallViewport} + {#if $isSmallViewport} + +
- @@ -119,14 +99,22 @@
- {/if} - - - {#if $isSmallViewport} + + + + + + Export as .txt + - {:else} +
+ +
+ {:else} + + + + + + + + Export as .txt + + + - {/if} - {#if !$isSmallViewport} @@ -154,19 +177,16 @@ - {/if} -
- -
+
+ +
+
-
+ {/if}
From 3d1f1632b7495b67dc78c12b300cc4e99062114f Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Mon, 5 Jan 2026 01:15:47 +0530 Subject: [PATCH 548/599] fix: added a tooltip over disabled create database button --- .../databases/+page.svelte | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/+page.svelte index e95c01cca..e413399e8 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/+page.svelte @@ -14,9 +14,11 @@ import Table from './table.svelte'; import { registerCommands } from '$lib/commandCenter'; import { canWriteDatabases } from '$lib/stores/roles'; - import { Icon } from '@appwrite.io/pink-svelte'; + import { Icon, Tooltip } from '@appwrite.io/pink-svelte'; import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import EmptySearch from '$lib/components/emptySearch.svelte'; + import { isServiceLimited } from '$lib/stores/billing'; + import { organization } from '$lib/stores/organization'; export let data: PageData; @@ -30,6 +32,8 @@ ); } + $: isLimited = isServiceLimited('databases', $organization?.billingPlan, data.databases.total); + $: $registerCommands([ { label: 'Create database', @@ -37,7 +41,7 @@ showCreate = true; }, keys: ['c'], - disabled: showCreate || !$canWriteDatabases, + disabled: showCreate || !$canWriteDatabases || isLimited, icon: IconPlus, group: 'databases', rank: 10 @@ -52,10 +56,20 @@ bind:view={data.view} searchPlaceholder="Search by name or ID"> {#if $canWriteDatabases} - + +
+ +
+ + You have reached the maximum number of databases for your plan. + +
{/if} From b721ab3109482c23704d8244574737914b97cdba Mon Sep 17 00:00:00 2001 From: Hemachandar <132386067+hmacr@users.noreply.github.com> Date: Mon, 5 Jan 2026 15:56:00 +0530 Subject: [PATCH 549/599] Show last checked time for domain verification (#2760) * Show last checked time for domain verification * feedback * better label --- src/lib/helpers/date.ts | 12 ++++++ .../function-[function]/domains/+page.ts | 1 + .../function-[function]/domains/store.ts | 7 ++++ .../function-[function]/domains/table.svelte | 32 ++++++++++++++++ .../settings/domains/+page.ts | 6 ++- .../settings/domains/table.svelte | 38 +++++++++++++++++++ .../sites/site-[site]/domains/+page.ts | 1 + .../sites/site-[site]/domains/store.ts | 7 ++++ .../sites/site-[site]/domains/table.svelte | 32 ++++++++++++++++ 9 files changed, 135 insertions(+), 1 deletion(-) diff --git a/src/lib/helpers/date.ts b/src/lib/helpers/date.ts index 2d56c1cb6..29878256a 100644 --- a/src/lib/helpers/date.ts +++ b/src/lib/helpers/date.ts @@ -206,6 +206,18 @@ export function timeFromNow(datetime: string): string { return dayjs().to(dayjs(datetime)); } +export function timeFromNowShort(datetime: string): string { + if (!datetime || !isValidDate(datetime)) { + return 'n/a'; + } + + const timeStr = dayjs().to(dayjs(datetime)); + return timeStr + .replace('second', 'sec') // seconds > secs + .replace('minute', 'min') // minutes > mins + .replace('hour', 'hr'); // hours > hrs +} + export function hoursToDays(hours: number) { if (hours > 24) { return `${Math.floor(hours / 24)} days`; diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+page.ts b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+page.ts index 4145bf828..5fdc16ceb 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+page.ts @@ -29,6 +29,7 @@ export const load: PageLoad = async ({ depends, params, url, route, parent }) => Query.limit(limit), Query.offset(offset), Query.orderDesc(''), + Query.orderDesc('$updatedAt'), ...parsedQueries.values() ], search: search || undefined diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts index f741c03ee..5f36c6bc1 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts @@ -15,5 +15,12 @@ export const columns = writable([ title: 'Target', type: 'string', width: { min: 120, max: 400 } + }, + + { + id: 'updated', + title: '', + type: 'string', + width: { min: 160, max: 180 } } ]); diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte index 98e29e5ba..83daf1ffe 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte @@ -25,6 +25,7 @@ import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store'; import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte'; + import { timeFromNowShort } from '$lib/helpers/date'; let { proxyRules, @@ -46,6 +47,28 @@ ? 'Deployed from ' + proxy.deploymentVcsProviderBranch : 'Active deployment'; }; + + function updatedLabel(proxyRule: Models.ProxyRule): string { + if (proxyRule.status === 'verified') { + return ''; + } + + const timeStr = timeFromNowShort(proxyRule.$updatedAt); + if (timeStr === 'n/a') { + return ''; + } + + const prefix = + proxyRule.status === 'created' + ? 'Checked' + : proxyRule.status === 'verifying' + ? 'Updated' + : proxyRule.status === 'unverified' + ? 'Failed' + : ''; + + return prefix + ' ' + timeStr; + } @@ -117,6 +140,15 @@ {:else if column.id === 'target'} {proxyTarget(proxyRule)} + {:else if column.id === 'updated' && proxyRule.status !== 'verified'} + + + {updatedLabel(proxyRule)} + + {/if} {/each} diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/domains/+page.ts index 39495486c..bf7570e23 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/+page.ts @@ -21,7 +21,11 @@ export const load: PageLoad = async ({ depends, url, route, params, parent }) => const { organization } = await parent(); const rules = await sdk.forProject(params.region, params.project).proxy.listRules({ - queries: [Query.equal('type', RuleType.API), Query.equal('trigger', RuleTrigger.MANUAL)], + queries: [ + Query.equal('type', RuleType.API), + Query.equal('trigger', RuleTrigger.MANUAL), + Query.orderDesc('$updatedAt') + ], search: search || undefined }); diff --git a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte index 594988a7f..051a20d3a 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte @@ -24,6 +24,7 @@ import { regionalProtocol } from '../../store'; import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte'; + import { timeFromNowShort } from '$lib/helpers/date'; let { domains, @@ -45,8 +46,36 @@ type: 'string', format: 'string', width: { min: 300, max: 550 } + }, + { + id: 'updated', + title: '', + type: 'string', + width: { min: 160, max: 180 } } ]; + + function updatedLabel(proxyRule: Models.ProxyRule): string { + if (proxyRule.status === 'verified') { + return ''; + } + + const timeStr = timeFromNowShort(proxyRule.$updatedAt); + if (timeStr === 'n/a') { + return ''; + } + + const prefix = + proxyRule.status === 'created' + ? 'Checked' + : proxyRule.status === 'verifying' + ? 'Updated' + : proxyRule.status === 'unverified' + ? 'Failed' + : ''; + + return prefix + ' ' + timeStr; + } @@ -116,6 +145,15 @@ {/if} + {:else if column.id === 'updated' && proxyRule.status !== 'verified'} + + + {updatedLabel(proxyRule)} + + {/if} {/each} diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/+page.ts index a942cc3c0..25c021aa6 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/+page.ts @@ -28,6 +28,7 @@ export const load = async ({ params, depends, url, route, parent }) => { Query.limit(limit), Query.offset(offset), Query.orderDesc(''), + Query.orderDesc('$updatedAt'), ...parsedQueries.values() ], search: search || undefined diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts index f741c03ee..5f36c6bc1 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts @@ -15,5 +15,12 @@ export const columns = writable([ title: 'Target', type: 'string', width: { min: 120, max: 400 } + }, + + { + id: 'updated', + title: '', + type: 'string', + width: { min: 160, max: 180 } } ]); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte index b89528517..a3921aeaa 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte @@ -25,6 +25,7 @@ import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store'; import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte'; + import { timeFromNowShort } from '$lib/helpers/date'; let { proxyRules, @@ -46,6 +47,28 @@ ? 'Deployed from ' + proxy.deploymentVcsProviderBranch : 'Active deployment'; }; + + function updatedLabel(proxyRule: Models.ProxyRule): string { + if (proxyRule.status === 'verified') { + return ''; + } + + const timeStr = timeFromNowShort(proxyRule.$updatedAt); + if (timeStr === 'n/a') { + return ''; + } + + const prefix = + proxyRule.status === 'created' + ? 'Checked' + : proxyRule.status === 'verifying' + ? 'Updated' + : proxyRule.status === 'unverified' + ? 'Failed' + : ''; + + return prefix + ' ' + timeStr; + } @@ -117,6 +140,15 @@ {:else if column.id === 'target'} {proxyTarget(proxyRule)} + {:else if column.id === 'updated' && proxyRule.status !== 'verified'} + + + {updatedLabel(proxyRule)} + + {/if} {/each} From d7b51679538a5cb86fa9a93505360a62e59fe66c Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:54:29 +0530 Subject: [PATCH 550/599] use stack --- .../domains/domain-[domain]/+page.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte index 2494116ba..f9c04af1f 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte @@ -80,7 +80,7 @@ {#if data.recordList.total} {#if $isSmallViewport} -
+
-
+
- +
{:else} {/if} - - diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/table.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/table.svelte index ab71bb13d..32494fbb4 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/table.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/table.svelte @@ -50,7 +50,10 @@ - + {#each $columns as { id, title } (id)} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 571542d06..4514cd368 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -309,4 +309,11 @@ background-color: var(--color-mid-neutral-70, #56565c); } } + + .responsive-table { + overflow: hidden; + width: 100%; + scrollbar-width: thin; + position: relative; + } From 01a7cdc9267464db2841726f79bd50f71cc7daf9 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:27:04 +0530 Subject: [PATCH 552/599] pink version bump --- package.json | 6 ++++-- pnpm-lock.yaml | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 6ab1ae55d..120ca71ca 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "@ai-sdk/svelte": "^1.1.24", "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f", "@appwrite.io/pink-icons": "0.25.0", - "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd", + "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920", "@appwrite.io/pink-legacy": "^1.0.3", - "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd", + "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920", "@faker-js/faker": "^9.9.0", "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.38.0", @@ -40,9 +40,11 @@ "deep-equal": "^2.2.3", "echarts": "^5.6.0", "ignore": "^6.0.2", + "install": "^0.13.0", "nanoid": "^5.1.5", "nanotar": "^0.1.1", "plausible-tracker": "^0.3.9", + "pnpm": "^10.27.0", "pretty-bytes": "^6.1.1", "prismjs": "^1.30.0", "remarkable": "^2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index baa5c2e8c..40ef93c38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,14 +18,14 @@ importers: specifier: 0.25.0 version: 0.25.0 '@appwrite.io/pink-icons-svelte': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd - version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd(svelte@5.25.3) + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920 + version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920(svelte@5.25.3) '@appwrite.io/pink-legacy': specifier: ^1.0.3 version: 1.0.3 '@appwrite.io/pink-svelte': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd - version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd(svelte@5.25.3) + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920 + version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920(svelte@5.25.3) '@faker-js/faker': specifier: ^9.9.0 version: 9.9.0 @@ -65,6 +65,9 @@ importers: ignore: specifier: ^6.0.2 version: 6.0.2 + install: + specifier: ^0.13.0 + version: 0.13.0 nanoid: specifier: ^5.1.5 version: 5.1.5 @@ -74,6 +77,9 @@ importers: plausible-tracker: specifier: ^0.3.9 version: 0.3.9 + pnpm: + specifier: ^10.27.0 + version: 10.27.0 pretty-bytes: specifier: ^6.1.1 version: 6.1.1 @@ -281,8 +287,8 @@ packages: peerDependencies: svelte: ^4.0.0 - '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd} + '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920} version: 2.0.0-RC.1 peerDependencies: svelte: ^4.0.0 @@ -296,8 +302,8 @@ packages: '@appwrite.io/pink-legacy@1.0.3': resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==} - '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd} + '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920} version: 2.0.0-RC.2 peerDependencies: svelte: ^4.0.0 @@ -2470,6 +2476,10 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + install@0.13.0: + resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==} + engines: {node: '>= 0.10'} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -2914,6 +2924,11 @@ packages: engines: {node: '>=18'} hasBin: true + pnpm@10.27.0: + resolution: {integrity: sha512-ctaZ2haxF5wUup5k3HHJpAmIy9xlwmTLDkidt96RfyDc9NZNhyNiXylpulLUt+KhFwaC2awqXcrqq3MrfhbwSg==} + engines: {node: '>=18.12'} + hasBin: true + popmotion@11.0.5: resolution: {integrity: sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==} @@ -3829,7 +3844,7 @@ snapshots: dependencies: svelte: 5.25.3 - '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cb016bd(svelte@5.25.3)': + '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@cfa2920(svelte@5.25.3)': dependencies: svelte: 5.25.3 @@ -3842,7 +3857,7 @@ snapshots: '@appwrite.io/pink-icons': 1.0.0 the-new-css-reset: 1.11.3 - '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cb016bd(svelte@5.25.3)': + '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@cfa2920(svelte@5.25.3)': dependencies: '@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.25.3) '@floating-ui/dom': 1.6.13 @@ -6272,6 +6287,8 @@ snapshots: indent-string@4.0.0: {} + install@0.13.0: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -6685,6 +6702,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + pnpm@10.27.0: {} + popmotion@11.0.5: dependencies: framesync: 6.1.2 From bb769727f92f5ec401f9efeb62bfccd1f7138a60 Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:45:17 +0530 Subject: [PATCH 553/599] use base css --- src/lib/profiles/css/base.css | 6 ++++++ src/routes/+layout.svelte | 8 +------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 src/lib/profiles/css/base.css diff --git a/src/lib/profiles/css/base.css b/src/lib/profiles/css/base.css new file mode 100644 index 000000000..ae0218c27 --- /dev/null +++ b/src/lib/profiles/css/base.css @@ -0,0 +1,6 @@ +.responsive-table { + overflow: hidden; + width: 100%; + scrollbar-width: thin; + position: relative; +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 4514cd368..c1d724892 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -17,6 +17,7 @@ import { ThemeDark, ThemeLight, ThemeDarkCloud, ThemeLightCloud } from '../themes'; import { isSmallViewport, updateViewport } from '$lib/stores/viewport'; import { feedback } from '$lib/stores/feedback'; + import '$lib/profiles/css/base.css'; function resolveTheme(theme: AppStore['themeInUse']) { switch (theme) { @@ -309,11 +310,4 @@ background-color: var(--color-mid-neutral-70, #56565c); } } - - .responsive-table { - overflow: hidden; - width: 100%; - scrollbar-width: thin; - position: relative; - } From 6003039f1df1df6cf78a1946bbb919fea70c22aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 6 Jan 2026 15:05:30 +0100 Subject: [PATCH 554/599] Project labels UI --- package.json | 2 +- pnpm-lock.yaml | 12 +- src/lib/actions/analytics.ts | 1 + .../organization-[organization]/+page.ts | 29 +++-- .../settings/+page.svelte | 4 +- .../settings/updateLabels.svelte | 103 ++++++++++++++++++ 6 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 src/routes/(console)/project-[region]-[project]/settings/updateLabels.svelte diff --git a/package.json b/package.json index a2e1778fe..f460aa71a 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a968c01e..057668c3a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56 + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,9 +272,9 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f} - version: 1.10.0 + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56} + version: 2.1.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': resolution: {integrity: sha512-iLFlV55hj8mGuAbmxJGenxN5RaZMmVT4GJb9dv/MP1xBAtYibFq7JvBcxm18qV2KU8c31Rntf+Ub4GL7HwqTYg==} @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@5372e56': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index dea8860b5..d5ceb1c3e 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -247,6 +247,7 @@ export enum Submit { ProjectDelete = 'submit_project_delete', ProjectUpdateName = 'submit_project_update_name', ProjectUpdateTeam = 'submit_project_update_team', + ProjectUpdateLabels = 'submit_project_update_labels', ProjectService = 'submit_project_service', ProjectUpdateSMTP = 'submit_project_update_smtp', MemberCreate = 'submit_member_create', diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index b236341d9..a0e3ccc3c 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -23,6 +23,11 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => const archivedPage = Number.isFinite(archivedPageRaw) && archivedPageRaw > 0 ? archivedPageRaw : 1; const archivedOffset = pageToOffset(archivedPage, limit); + + const searchQueries = search + ? [Query.or([Query.search('search', search), Query.contains('labels', search)])] + : []; + const [activeProjects, archivedProjects, activeTotal, archivedTotal] = await Promise.all([ sdk.forConsole.projects.list({ queries: [ @@ -30,9 +35,9 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.equal('teamId', params.organization), Query.or([Query.equal('status', 'active'), Query.isNull('status')]), Query.limit(limit), - Query.orderDesc('') - ], - search: search || undefined + Query.orderDesc(''), + ...searchQueries + ] }), sdk.forConsole.projects.list({ queries: [ @@ -40,23 +45,23 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.equal('teamId', params.organization), Query.equal('status', 'archived'), Query.limit(limit), - Query.orderDesc('') - ], - search: search || undefined + Query.orderDesc(''), + ...searchQueries + ] }), sdk.forConsole.projects.list({ queries: [ Query.equal('teamId', params.organization), - Query.or([Query.equal('status', 'active'), Query.isNull('status')]) - ], - search: search || undefined + Query.or([Query.equal('status', 'active'), Query.isNull('status')]), + ...searchQueries + ] }), sdk.forConsole.projects.list({ queries: [ Query.equal('teamId', params.organization), - Query.equal('status', 'archived') - ], - search: search || undefined + Query.equal('status', 'archived'), + ...searchQueries + ] }) ]); diff --git a/src/routes/(console)/project-[region]-[project]/settings/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/+page.svelte index edf09b92f..8c427cc23 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/+page.svelte @@ -15,6 +15,7 @@ import ChangeOrganization from './changeOrganization.svelte'; import UpdateVariables from '../updateVariables.svelte'; import { page } from '$app/state'; + import UpdateLabels from './updateLabels.svelte'; export let data; @@ -84,8 +85,9 @@ {#if $project} - {#if $canWriteProjects} + + + import { onMount } from 'svelte'; + import { invalidate } from '$app/navigation'; + import { Submit, trackEvent, trackError } from '$lib/actions/analytics'; + import { CardGrid } from '$lib/components'; + import { Dependencies } from '$lib/constants'; + import { Button, Form, InputTags } from '$lib/elements/forms'; + import { symmetricDifference } from '$lib/helpers/array'; + import { addNotification } from '$lib/stores/notifications'; + import { sdk } from '$lib/stores/sdk'; + import { project } from '../store'; + import { Tag, Input, Layout, Icon } from '@appwrite.io/pink-svelte'; + import { IconPlus } from '@appwrite.io/pink-icons-svelte'; + + const alphaNumericRegExp = /^[a-zA-Z0-9]+$/; + let suggestedLabels = ['live', 'stage', 'internal']; + let labels: string[] = []; + let error = ''; + + onMount(async () => { + labels = [...$project.labels]; + }); + + async function updateLabels() { + try { + await sdk.forConsole.projects.updateLabels({ projectId: $project.$id, labels }); + await invalidate(Dependencies.PROJECT); + await invalidate(Dependencies.ORGANIZATION); + isDisabled = true; + addNotification({ + type: 'success', + message: 'Project labels have been updated' + }); + trackEvent(Submit.ProjectUpdateLabels); + } catch (error) { + addNotification({ + message: error.message, + type: 'error' + }); + trackError(error, Submit.ProjectUpdateLabels); + } + } + + $: isDisabled = !!error || !symmetricDifference(labels, $project.labels).length; + + $: if (labels) { + const invalidLabels = []; + + labels.forEach((label) => { + if (!alphaNumericRegExp.test(label)) { + invalidLabels.push(label); + } + }); + + if (invalidLabels.length) { + error = `Invalid labels: ${invalidLabels.join(', ')}`; + } else { + error = ''; + } + } + + +
+ + Labels + Categorize and manage your projects for easy searching based on specific criteria by assigning + them customizable labels. + + + {#key labels.length} + + {/key} + + {#each suggestedLabels as suggestedLabel} + { + if (!labels.includes(suggestedLabel)) { + labels = [...labels, suggestedLabel]; + } else { + labels = labels.filter((e) => e !== suggestedLabel); + } + }}> + + {suggestedLabel} + + {/each} + + {error ? error : 'Only alphanumeric characters are allowed'} + + + + + + + + From 169373d653b4b8eb61782f4c1c0b5a8cc62edb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 6 Jan 2026 15:10:08 +0100 Subject: [PATCH 555/599] Improve copy --- src/routes/(console)/organization-[organization]/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/organization-[organization]/+page.svelte b/src/routes/(console)/organization-[organization]/+page.svelte index 83c40623c..37ef03204 100644 --- a/src/routes/(console)/organization-[organization]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/+page.svelte @@ -170,7 +170,7 @@ - + {#if $canWriteProjects} {#if projectCreationDisabled && reachedProjectLimit} From 63ebeafc82550c6120fc56d0f3d584a1831c85e3 Mon Sep 17 00:00:00 2001 From: Hemachandar <132386067+hmacr@users.noreply.github.com> Date: Wed, 7 Jan 2026 11:08:50 +0530 Subject: [PATCH 556/599] Improve UX for manual sites & functions deployment (#2523) * Improve UX for manual sites & functions deployment * lint * feedback --- src/lib/stores/uploader.ts | 66 ++++++++++++++++++- .../project-[region]-[project]/+layout.svelte | 2 +- .../create-function/manual/+page.svelte | 65 +++++++++++------- .../(modals)/createManual.svelte | 22 +++---- .../sites/create-site/manual/+page.svelte | 49 +++++++++----- .../createManualDeploymentModal.svelte | 10 ++- 6 files changed, 160 insertions(+), 54 deletions(-) diff --git a/src/lib/stores/uploader.ts b/src/lib/stores/uploader.ts index ef848232c..8a04eae8a 100644 --- a/src/lib/stores/uploader.ts +++ b/src/lib/stores/uploader.ts @@ -1,4 +1,4 @@ -import { Client, ID, type Models, Sites, Storage } from '@appwrite.io/console'; +import { Client, Functions, ID, type Models, Sites, Storage } from '@appwrite.io/console'; import { writable } from 'svelte/store'; import { getApiEndpoint } from '$lib/stores/sdk'; import { page } from '$app/state'; @@ -32,6 +32,13 @@ const temporarySites = (region: string, projectId: string) => { return new Sites(clientProject); }; +const temporaryFunctions = (region: string, projectId: string) => { + const clientProject = new Client().setMode('admin'); + const endpoint = getApiEndpoint(region); + clientProject.setEndpoint(endpoint).setProject(projectId); + return new Functions(clientProject); +}; + const createUploader = () => { const { subscribe, set, update } = writable({ isOpen: false, @@ -110,7 +117,19 @@ const createUploader = () => { newFile.status = 'success'; updateFile(newFile.$id, newFile); }, - uploadSiteDeployment: async (siteId: string, code: File) => { + uploadSiteDeployment: async ({ + siteId, + code, + buildCommand, + installCommand, + outputDirectory + }: { + siteId: string; + code: File; + buildCommand?: string; + installCommand?: string; + outputDirectory?: string; + }) => { const newDeployment: UploaderFile = { $id: '', resourceId: siteId, @@ -132,6 +151,49 @@ const createUploader = () => { siteId, code, activate: true, + buildCommand, + installCommand, + outputDirectory, + onProgress: (progress) => { + newDeployment.$id = progress.$id; + newDeployment.progress = progress.progress; + newDeployment.status = progress.progress === 100 ? 'success' : 'pending'; + updateFile(progress.$id, newDeployment); + } + }); + newDeployment.$id = uploadedFile.$id; + newDeployment.progress = 100; + newDeployment.status = 'success'; + updateFile(newDeployment.$id, newDeployment); + }, + uploadFunctionDeployment: async ({ + functionId, + code + }: { + functionId: string; + code: File; + }) => { + const newDeployment: UploaderFile = { + $id: '', + resourceId: functionId, + name: code.name, + size: code.size, + progress: 0, + status: 'pending' + }; + update((n) => { + n.isOpen = true; + n.isCollapsed = false; + n.files.unshift(newDeployment); + return n; + }); + const uploadedFile = await temporaryFunctions( + page.params.region, + page.params.project + ).createDeployment({ + functionId, + code, + activate: true, onProgress: (progress) => { newDeployment.$id = progress.$id; newDeployment.progress = progress.progress; diff --git a/src/routes/(console)/project-[region]-[project]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/+layout.svelte index 426821259..eeeff2dd7 100644 --- a/src/routes/(console)/project-[region]-[project]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/+layout.svelte @@ -124,7 +124,7 @@