diff --git a/.env.example b/.env.example index 9ba4011c0..bf090442b 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ PUBLIC_CONSOLE_MODE=self-hosted -PUBLIC_CONSOLE_FEATURE_FLAGS= +PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import,attribute-encrypt,index-lengths PUBLIC_APPWRITE_MULTI_REGION=false PUBLIC_APPWRITE_ENDPOINT=http://localhost/v1 PUBLIC_STRIPE_KEY= diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1c879a6e..137c750f7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -79,7 +79,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | "PUBLIC_CONSOLE_MODE=cloud" - "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import" + "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import,attribute-encrypt,index-lengths" "PUBLIC_APPWRITE_MULTI_REGION=true" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" @@ -118,7 +118,7 @@ jobs: build-args: | "PUBLIC_CONSOLE_MODE=self-hosted" "PUBLIC_APPWRITE_MULTI_REGION=false" - "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import" + "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import,attribute-encrypt,index-lengths" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" publish-cloud-no-regions: @@ -156,6 +156,6 @@ jobs: build-args: | "PUBLIC_CONSOLE_MODE=cloud" "PUBLIC_APPWRITE_MULTI_REGION=false" - "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import" + "PUBLIC_CONSOLE_FEATURE_FLAGS=sites,csv-import,attribute-encrypt,index-lengths" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" diff --git a/package.json b/package.json index 0fe8f5a25..f12341aef 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564", + "@appwrite.io/console": "^1.9.0", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1", "@appwrite.io/pink-legacy": "^1.0.3", - "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40bae6b", + "@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778", "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.38.0", "@stripe/stripe-js": "^3.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cac4e0adc..a3664a807 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.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564 - version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564 + specifier: ^1.9.0 + version: 1.9.0 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -24,8 +24,8 @@ importers: specifier: ^1.0.3 version: 1.0.3 '@appwrite.io/pink-svelte': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40bae6b - version: https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@40bae6b(svelte@5.25.3) + specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778 + version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778(svelte@5.25.3) '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -257,12 +257,12 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564': - resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564} - version: 1.8.0 + '@appwrite.io/console@1.9.0': + resolution: {integrity: sha512-g8+zfdBF8mz7tRUER4CGVe5FHWQVLp8TlY/UOGCZ2TgUF1qnpNu/DhiQgph8uF+QZ9jDKCLAAZlP5//9t7ckWA==} - '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': - resolution: {integrity: sha512-iLFlV55hj8mGuAbmxJGenxN5RaZMmVT4GJb9dv/MP1xBAtYibFq7JvBcxm18qV2KU8c31Rntf+Ub4GL7HwqTYg==} + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@ee1b7788cd3f877c9aa1b6487976bd63a6196870': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@ee1b7788cd3f877c9aa1b6487976bd63a6196870} + version: 2.0.0-RC.1 peerDependencies: svelte: ^4.0.0 @@ -281,8 +281,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/%40appwrite.io%2Fpink-svelte@40bae6b': - resolution: {tarball: https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@40bae6b} + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778} version: 2.0.0-RC.2 peerDependencies: svelte: ^4.0.0 @@ -1340,8 +1340,8 @@ packages: '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} - '@types/react@18.3.22': - resolution: {integrity: sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==} + '@types/react@18.3.23': + resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} '@types/remarkable@2.0.8': resolution: {integrity: sha512-eKXqPZfpQl1kOADjdKchHrp2gwn9qMnGXhH/AtZe0UrklzhGJkawJo/Y/D0AlWcdWoWamFNIum8+/nkAISQVGg==} @@ -3635,9 +3635,9 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@a5e5564': {} + '@appwrite.io/console@1.9.0': {} - '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@ee1b7788cd3f877c9aa1b6487976bd63a6196870(svelte@5.25.3)': dependencies: svelte: 5.25.3 @@ -3654,9 +3654,9 @@ snapshots: '@appwrite.io/pink-icons': 1.0.0 the-new-css-reset: 1.11.3 - '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@40bae6b(svelte@5.25.3)': + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778(svelte@5.25.3)': dependencies: - '@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.25.3) + '@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@ee1b7788cd3f877c9aa1b6487976bd63a6196870(svelte@5.25.3) '@floating-ui/dom': 1.6.13 '@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.25.3))(svelte@5.25.3) '@melt-ui/svelte': 0.86.6(svelte@5.25.3) @@ -4791,7 +4791,7 @@ snapshots: '@types/prop-types@15.7.14': {} - '@types/react@18.3.22': + '@types/react@18.3.23': dependencies: '@types/prop-types': 15.7.14 csstype: 3.1.3 @@ -6752,7 +6752,7 @@ snapshots: svelte-motion@0.12.2(svelte@5.25.3): dependencies: - '@types/react': 18.3.22 + '@types/react': 18.3.23 framesync: 6.1.2 popmotion: 11.0.5 style-value-types: 5.1.2 diff --git a/src/lib/components/billing/gradientBanner.svelte b/src/lib/components/billing/gradientBanner.svelte index 27c58ce62..92923bae5 100644 --- a/src/lib/components/billing/gradientBanner.svelte +++ b/src/lib/components/billing/gradientBanner.svelte @@ -1,10 +1,13 @@ @@ -72,4 +74,25 @@ {formatCurrency(scalePlan?.price ?? 0)} per month + usage + {#if $currentPlan && !isBasePlan} + + + {#if $organization?.billingPlan === $currentPlan.$id && !isNewOrg} + + {/if} + + + {$currentPlan.desc} + + + {@const isZeroPrice = ($currentPlan?.price ?? 0) <= 0} + {@const price = formatCurrency($currentPlan?.price ?? 0)} + {isZeroPrice ? price : `${price} per month + usage`} + + + {/if} diff --git a/src/lib/components/breadcrumbs.svelte b/src/lib/components/breadcrumbs.svelte index 0951839d8..01f8c72a2 100644 --- a/src/lib/components/breadcrumbs.svelte +++ b/src/lib/components/breadcrumbs.svelte @@ -12,7 +12,7 @@ import { isCloud } from '$lib/system'; import { goto } from '$app/navigation'; import { base } from '$app/paths'; - import { newOrgModal } from '$lib/stores/organization'; + import { currentPlan, newOrgModal } from '$lib/stores/organization'; import { Click, trackEvent } from '$lib/actions/analytics'; import { page } from '$app/stores'; @@ -182,6 +182,14 @@ projectsBottomSheetOpen = false; } } + + $: correctPlanName = + // the plan names are hardcoded in some cases and are not available locally, + // so we rely on the plan's source of truth - `$currentPlan` + $currentPlan && + $currentPlan?.name.toLocaleLowerCase() !== selectedOrg?.tierName.toLocaleLowerCase() + ? $currentPlan.name + : selectedOrg?.tierName; // fallback @@ -195,9 +203,9 @@ aria-label="Open organizations tab"> {selectedOrg?.name ?? 'Organization'} {#if selectedOrg?.tierName}{#if correctPlanName}{/if} + content={correctPlanName} />{/if} {:else} @@ -211,7 +219,7 @@ {selectedOrg?.name ?? 'Organization'} + > {/if} diff --git a/src/lib/components/columnSelector.svelte b/src/lib/components/columnSelector.svelte index 37c1640ad..c113d5e9c 100644 --- a/src/lib/components/columnSelector.svelte +++ b/src/lib/components/columnSelector.svelte @@ -18,6 +18,19 @@ children: Snippet<[toggle: () => void, selectedColumnsNumber: number]>; } = $props(); + let maxHeight = $state('none'); + let containerRef; + + const calcMaxHeight = () => { + if (containerRef) { + // get parent row element for correct top position + const parent = containerRef.parentElement.parentElement; + const { top } = parent.getBoundingClientRect(); + + maxHeight = `${window.innerHeight - top - 48}px`; + } + }; + onMount(async () => { if (isCustomCollection) { const prefs = preferences.getCustomCollectionColumns(page.params.collection); @@ -50,6 +63,8 @@ preferences.setColumns(columns); } }); + + calcMaxHeight(); }); let selectedColumnsNumber = $derived( @@ -61,29 +76,32 @@ ); + {#if $columns?.length} {@render children(toggle, selectedColumnsNumber)} - - {#each $columns as column} - {#if !column?.exclude} - (column.hide = !column.hide)} - disabled={allowNoColumns - ? false - : selectedColumnsNumber <= 1 && column.hide !== true}> - - (column.hide = !column.hide)} /> - {column.title} - - - {/if} - {/each} - +
+ + {#each $columns as column} + {#if !column?.exclude} + (column.hide = !column.hide)} + disabled={allowNoColumns + ? false + : selectedColumnsNumber <= 1 && column.hide !== true}> + + (column.hide = !column.hide)} /> + {column.title} + + + {/if} + {/each} + +
{/if} diff --git a/src/lib/components/git/repositories.svelte b/src/lib/components/git/repositories.svelte index b82781169..39f260a99 100644 --- a/src/lib/components/git/repositories.svelte +++ b/src/lib/components/git/repositories.svelte @@ -23,7 +23,7 @@ import { page } from '$app/state'; import Card from '../card.svelte'; import SkeletonRepoList from './skeletonRepoList.svelte'; - import { untrack } from 'svelte'; + import { onMount, untrack } from 'svelte'; let { action = $bindable('select'), @@ -46,6 +46,11 @@ let search = $state(''); let selectedInstallation = $state(null); let isLoadingRepositories = $state(null); + let installationsMap = $state(null); + + onMount(() => { + loadInstallations(); + }); async function loadInstallations() { if (installationList) { @@ -59,7 +64,7 @@ ) ); } - return installationList.installations; + installationsMap = installationList.installations; } else { const { installations } = await sdk .forProject(page.params.region, page.params.project) @@ -70,7 +75,7 @@ } installation.set(installations.find((entry) => entry.$id === selectedInstallation)); } - return installations; + installationsMap = installations; } } @@ -123,7 +128,7 @@ {#if hasInstallations} - {#await loadInstallations()} + {#if !installationsMap} - {:then installations} + {:else} { + ...installationsMap.map((entry) => { return { label: entry.organization, value: entry.$id @@ -160,7 +165,7 @@ } search = ''; installation.set( - installations.find((entry) => entry.$id === selectedInstallation) + installationsMap.find((entry) => entry.$id === selectedInstallation) ); isLoadingRepositories = true; @@ -174,7 +179,7 @@ bind:value={search} disabled={!search && !$repositories?.repositories?.length} /> - {/await} + {/if} {#if selectedInstallation} diff --git a/src/lib/components/navbar.svelte b/src/lib/components/navbar.svelte index 435037fd6..8764b58cc 100644 --- a/src/lib/components/navbar.svelte +++ b/src/lib/components/navbar.svelte @@ -211,6 +211,7 @@ - +
- {$user.email} + {$user?.email}
Account diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 067b354dd..cd9dc4364 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -530,6 +530,8 @@ export enum BillingPlan { ENTERPRISE = 'ent-1' } +export const BASE_BILLING_PLANS: string[] = [BillingPlan.FREE, BillingPlan.PRO, BillingPlan.SCALE]; + export const feedbackDowngradeOptions = [ { value: 'availableFeatures', diff --git a/src/lib/flags.ts b/src/lib/flags.ts index 54d5ba576..db2417b83 100644 --- a/src/lib/flags.ts +++ b/src/lib/flags.ts @@ -20,5 +20,7 @@ function isFlagEnabled(name: string) { export const flags = { showSites: isFlagEnabled('sites'), - showCsvImport: isFlagEnabled('csv-import') + showCsvImport: isFlagEnabled('csv-import'), + showAttributeEncrypt: isFlagEnabled('attribute-encrypt'), + showIndexLengths: isFlagEnabled('index-lengths') }; diff --git a/src/lib/helpers/types.ts b/src/lib/helpers/types.ts index 543fa39ba..7f4e6a66e 100644 --- a/src/lib/helpers/types.ts +++ b/src/lib/helpers/types.ts @@ -44,6 +44,7 @@ export type Column = PinkColumn & { format?: string; exclude?: boolean; elements?: string[] | { value: string | number; label: string }[]; + encrypt?: boolean; }; export function isValueOfStringEnum>( diff --git a/src/lib/images/pink-background.svg b/src/lib/images/pink-background.svg new file mode 100644 index 000000000..76cdb479e --- /dev/null +++ b/src/lib/images/pink-background.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/layout/responsiveContainerHeader.svelte b/src/lib/layout/responsiveContainerHeader.svelte index 247564f86..e84caf048 100644 --- a/src/lib/layout/responsiveContainerHeader.svelte +++ b/src/lib/layout/responsiveContainerHeader.svelte @@ -17,7 +17,7 @@ let { columns, - view = View.Table, + view = $bindable(View.Table), hideView = false, hideColumns = false, hasSearch = false, diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 0f3d774da..705154fbb 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -311,6 +311,7 @@ export type Plan = { teams: number; projects: number; databases: number; + databasesAllowEncrypt: boolean; buckets: number; fileSize: number; functions: number; diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index e4a1d3d4a..9ece3c16f 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -11,7 +11,7 @@ import PaymentAuthRequired from '$lib/components/billing/alerts/paymentAuthRequi 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 { sizeToBytes, type Size } from '$lib/helpers/sizeConvertion'; +import { type Size, sizeToBytes } from '$lib/helpers/sizeConvertion'; import type { AddressesList, Aggregation, @@ -28,13 +28,19 @@ import { Query } from '@appwrite.io/console'; import { derived, get, writable } from 'svelte/store'; import { headerAlert } from './headerAlert'; import { addNotification, notifications } from './notifications'; -import { organization, type Organization, type OrganizationError } from './organization'; +import { + currentPlan, + organization, + type Organization, + type OrganizationError +} from './organization'; import { canSeeBilling } from './roles'; import { sdk } from './sdk'; import { user } from './user'; import BudgetLimitAlert from '$routes/(console)/organization-[organization]/budgetLimitAlert.svelte'; import TeamReadonlyAlert from '$routes/(console)/organization-[organization]/teamReadonlyAlert.svelte'; import ProjectsLimit from '$lib/components/billing/alerts/projectsLimit.svelte'; +import EnterpriseTrial from '$routes/(console)/organization-[organization]/enterpriseTrial.svelte'; export type Tier = 'tier-0' | 'tier-1' | 'tier-2' | 'auto-1' | 'cont-1' | 'ent-1'; @@ -269,6 +275,32 @@ export function isServiceLimited(serviceId: PlanServices, plan: Tier, total: num return isLimited && total >= limit && !hasUsageFees; } +export function checkForEnterpriseTrial(org: Organization) { + if (!org || !org.billingNextInvoiceDate) return; + if (calculateEnterpriseTrial(org) > 0) { + headerAlert.add({ + id: 'teamEnterpriseTrial', + component: EnterpriseTrial, + show: true, + importance: 11 + }); + } +} + +export function calculateEnterpriseTrial(org: Organization) { + const endDate = new Date(org.billingNextInvoiceDate); + const startDate = new Date(org.billingCurrentInvoiceDate); + const today = new Date(); + + let diffCycle = endDate.getTime() - startDate.getTime(); + diffCycle = Math.ceil(diffCycle / (1000 * 60 * 60 * 24)); + if (diffCycle === 14) { + const remaining = endDate.getTime() - today.getTime(); + return Math.ceil(remaining / (1000 * 60 * 60 * 24)); + } + return 0; +} + export function calculateTrialDay(org: Organization) { if (org?.billingPlan === BillingPlan.FREE) return false; const endDate = new Date(org?.billingStartDate); @@ -342,7 +374,7 @@ export async function checkForUsageLimit(org: Organization) { ]; const members = org.total; - const plan = get(plansInfo)?.get(org.billingPlan); + const plan = get(currentPlan); const membersOverflow = members > plan.addons.seats.limit ? members - (plan.addons.seats.limit || members) : 0; diff --git a/src/lib/stores/user.ts b/src/lib/stores/user.ts index 808dd3877..496da7952 100644 --- a/src/lib/stores/user.ts +++ b/src/lib/stores/user.ts @@ -13,6 +13,10 @@ export type Account = Models.User< >; export const user = derived(page, ($page) => { - if (browser) sessionStorage.setItem('account', JSON.stringify($page.data.account)); - return $page.data.account as Account; + if ($page.data?.account) { + if (browser) { + sessionStorage.setItem('account', JSON.stringify($page.data.account)); + } + return $page.data.account as Account; + } else return null; }); diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index 98c31361a..684536a95 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -13,6 +13,7 @@ import Create from './createOrganization.svelte'; import { calculateTrialDay, + checkForEnterpriseTrial, checkForMandate, checkForMarkedForDeletion, checkForMissingPaymentMethod, @@ -306,6 +307,7 @@ if (isCloud) { currentOrganizationId = org.$id; checkForProjectsLimit(org, data.projects?.length || 0); + checkForEnterpriseTrial(org); await checkForUsageLimit(org); checkForMarkedForDeletion(org); await checkForNewDevUpgradePro(org); diff --git a/src/routes/(console)/organization-[organization]/enterpriseTrial.svelte b/src/routes/(console)/organization-[organization]/enterpriseTrial.svelte new file mode 100644 index 000000000..6fe97f821 --- /dev/null +++ b/src/routes/(console)/organization-[organization]/enterpriseTrial.svelte @@ -0,0 +1,69 @@ + + +{#if $organization?.$id && remainingDays > 0 && !hideBillingHeaderRoutes.includes(page.url.pathname) && show} + + + +{/if} + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/+page.svelte index b7e886be5..989916cf9 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/+page.svelte @@ -1,37 +1,31 @@ - - - - - - - {#if $canWriteCollections} - - {/if} - - + + {#if $canWriteCollections} + + {/if} + {#if data.collections.total} {#if data.view === 'grid'} diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte index acad8b897..e94163b7b 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte @@ -13,10 +13,11 @@ Link, Popover, Table, + Tooltip, Typography } from '@appwrite.io/pink-svelte'; import Create from '../createAttribute.svelte'; - import { isRelationship } from '../document-[document]/attributes/store'; + import { isRelationship, isString } from '../document-[document]/attributes/store'; import FailedModal from '../failedModal.svelte'; import CreateIndex from '../indexes/createIndex.svelte'; import { attributes, type Attributes, isCsvImportInProgress } from '../store'; @@ -33,7 +34,8 @@ IconPlus, IconSwitchHorizontal, IconTrash, - IconViewList + IconViewList, + IconLockClosed } from '@appwrite.io/pink-icons-svelte'; import type { ComponentProps } from 'svelte'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -112,25 +114,38 @@ {:else} {/if} - {attribute.key} - {#if attribute.status !== 'available'} - - {#if attribute.error} - { - e.preventDefault(); - error = attribute.error; - showFailed = true; - }}>Details + + + {attribute.key} + {#if isString(attribute) && attribute.encrypt} + + +
Encrypted
+
+ {/if} +
+ {#if attribute.status !== 'available'} + + {#if attribute.error} + { + e.preventDefault(); + error = attribute.error; + showFailed = true; + }}>Details + {/if} + {:else if attribute.required} + {/if} - {:else if attribute.required} - - {/if} +
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/boolean.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/boolean.svelte index 9959b7229..911154864 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/boolean.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/boolean.svelte @@ -100,5 +100,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/datetime.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/datetime.svelte index cb40c72c9..1464c8c12 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/datetime.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/datetime.svelte @@ -92,5 +92,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/email.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/email.svelte index 07faa118f..9aa79bfc5 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/email.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/email.svelte @@ -93,5 +93,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/enum.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/enum.svelte index 2eed37bb1..b617dc82c 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/enum.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/enum.svelte @@ -124,5 +124,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/float.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/float.svelte index 2480a2d97..5c8646605 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/float.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/float.svelte @@ -122,5 +122,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/integer.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/integer.svelte index de97fccff..faa220fa0 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/integer.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/integer.svelte @@ -120,5 +120,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/ip.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/ip.svelte index a097bcbbd..5ae8043d9 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/ip.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/ip.svelte @@ -92,5 +92,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte index 8bfc5e18a..aff1747df 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte @@ -18,7 +18,8 @@ data.size, data.required, data.default, - data.array + data.array, + data.encrypt ); } export async function updateString( @@ -42,20 +43,28 @@ -{#if data.size >= 50} - -{:else} - -{/if} + min={supportsStringEncryption && data.encrypt ? 150 : undefined} + helper={supportsStringEncryption && data.encrypt + ? 'Encrypted string attributes require a minimum size of 150.' + : undefined} /> + += 50 ? InputTextarea : InputText} + id="default" + label="Default" + placeholder="Enter string" + maxlength={data.size} + bind:value={data.default} + disabled={data.required || data.array} + nullable={!data.required && !data.array} /> + + description="Indicate whether this attribute is required." /> + + description="Indicate whether this attribute is an array. Defaults to an empty array." /> + +{#if showEncrypt} + +
+ + + + + + + + Indicate whether this attribute is encrypted. Encrypted attributes + cannot be queried. + + + + + + Available on Pro plan. Upgrade + to enable encrypted attributes. + + + + +
+
+{/if} + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/url.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/url.svelte index 4c9d6991e..2d003a21a 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/url.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/url.svelte @@ -93,5 +93,4 @@ label="Array" bind:checked={data.array} disabled={data.required || editing} - description="Indicate whether this attribute should act as an array, with the default value set as an empty - array." /> + description="Indicate whether this attribute is an array. Defaults to an empty array." /> diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/+page.svelte index 103f9a8b2..31db52abd 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/+page.svelte @@ -20,7 +20,6 @@ const databaseId = page.params.database; const collectionId = page.params.collection; const documentId = page.params.document; - const editing = true; function initWork() { const prohibitedKeys = [ @@ -124,7 +123,7 @@ {label} - + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/attributes/relationship.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/attributes/relationship.svelte index af18757b5..e63977b1b 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/attributes/relationship.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/document-[document]/attributes/relationship.svelte @@ -1,24 +1,22 @@ {#if isRelationshipToMany(attribute)} -
- - - {label} - - {optionalText} - + + + + + {label} + + {optionalText} + + + + {#if showTopAddButton} + + {/if} - {#if editing || total === 0} - + + + + {#if showEmptyInput} + + { + if (!relatedList[0]) relatedList = ['']; + updateRelatedList(); + }} /> + + {/if} + + + {#if editing && hasItems} + {#each paginatedItems as _, paginatedIndex} + {@const actualIndex = offset + paginatedIndex} + + + {#if relatedList[actualIndex]} +
+ +
+ {/if} +
+ {/each} + {/if} + + + {#if !editing && hasItems} + {#each relatedList as item, i} + + +
+ +
+
+ {/each} + {/if} + + + {#if showInput} + + +
+ +
+
+ {/if} +
+ + {#if showBottomAddButton} + + + {/if}
-
    - {#if !editing && relatedList?.length} - {#each relatedList as item, i} - - - {/each} - {/if} - - {#if showInput} - !relatedList.includes(n.value))} - on:change={() => { - value = relatedList; - showInput = false; - }} /> - - {/if} - {#if paginatedItems && editing} - {#each paginatedItems as item, i} - - - {/each} - {/if} -
- {#if editing} -
-

Total results: {total}

- -
- {/if} - - {#if total > 0 && !editing} - - {/if} -
+
{:else} Key Type Attributes - Asc/Desc + Orders + Lengths {#each data.collection.indexes as index} @@ -118,6 +120,9 @@ {index.orders} + + {index.lengths} + + {:else if formatted.truncated} + + {formatted.value} + + {#if showing} + {formatted.whole} + {/if} + + + {:else} {formatted.value} - - {#if showing} - {formatted.whole} - {/if} - - - {:else} - {formatted.value} + {/if} {/if} - {/if} - + + {/if} {/each} diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/aside.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/aside.svelte index d63fe5d05..4acf3d41a 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/aside.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/(components)/aside.svelte @@ -1,6 +1,6 @@ @@ -18,7 +19,7 @@ - {#if selectedRuntime?.name} + {#if selectedRuntime?.name && !loading} Runtime @@ -30,6 +31,11 @@ + {:else if loading} + + + + {/if} {#if showGitData} {#if repositoryName} 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 baa9692af..9b097f7a3 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 @@ -7,7 +7,7 @@ import { organization } from '$lib/stores/organization'; import { isCloud } from '$lib/system'; import { IconPencil } from '@appwrite.io/pink-icons-svelte'; - import { Fieldset, Icon, Input, Layout, Tag } from '@appwrite.io/pink-svelte'; + import { Fieldset, Icon, Input, Layout, Skeleton, Tag } from '@appwrite.io/pink-svelte'; import type { ComponentType } from 'svelte'; export let name: string; @@ -25,6 +25,7 @@ value: string; label: string; }[] = []; + export let loading = false; let showCustomId = false; @@ -51,13 +52,20 @@ {/if} {#key runtime} - + {#if loading} + + + + + {:else} + + {/if} {/key} {#if isCloud} @@ -79,12 +87,19 @@ {/if} {#if showEntrypoint} - + {#if loading} + + + + + {:else} + + {/if} {/if} 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 4414e0ddc..d2ed95c5d 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 @@ -10,7 +10,7 @@ import { installation, repository } from '$lib/stores/vcs'; import { Layout } from '@appwrite.io/pink-svelte'; import { writable } from 'svelte/store'; - import { ID, Runtime, VCSDeploymentType } from '@appwrite.io/console'; + import { ID, Runtime, VCSDeploymentType, VCSDetectionType } from '@appwrite.io/console'; import type { Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import Details from '../(components)/details.svelte'; @@ -57,12 +57,40 @@ let silentMode = false; let specification = specificationOptions[0].value; + let detectingRuntime = true; + onMount(async () => { installation.set(data.installation); repository.set(data.repository); name = data.repository.name; + + await detectRuntime(); }); + async function detectRuntime() { + try { + detectingRuntime = true; + + const detections = (await sdk + .forProject(page.params.regionn, page.params.project) + .vcs.createRepositoryDetection( + data.installation.$id, + page.params.repository, + VCSDetectionType.Runtime + )) as unknown as Models.DetectionRuntime; /* SDK return type is wrong atm */ + + entrypoint = detections.entrypoint; + buildCommand = detections.commands; + runtime = detections.runtime as Runtime; + + trackEvent(Submit.FrameworkDetect, { runtime, source: 'repository' }); + } catch (error) { + trackError(error, Submit.FrameworkDetect); + } finally { + detectingRuntime = false; + } + } + async function create() { try { const func = await sdk @@ -154,7 +182,8 @@ bind:specification {specificationOptions} options={runtimeOptions} - showEntrypoint /> + showEntrypoint + loading={detectingRuntime} /> + {rootDir} + loading={detectingRuntime} /> diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.ts b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.ts index 6b98ecef0..66fc213fa 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.ts @@ -3,17 +3,17 @@ import { sdk } from '$lib/stores/sdk'; export const load = async ({ parent, params, url }) => { const { installations, runtimesList, specificationsList } = await parent(); - const [repository] = await Promise.all([ - sdk - .forProject(params.region, params.project) - .vcs.getRepository(url.searchParams.get('installation'), params.repository) - ]); + const repository = await sdk + .forProject(params.region, params.project) + .vcs.getRepository(url.searchParams.get('installation'), params.repository); + + const installation = installations.installations.find( + (installation) => installation.$id === url.searchParams.get('installation') + ); return { + installation, installations, - installation: installations.installations.find( - (installation) => installation.$id === url.searchParams.get('installation') - ), repository, runtimesList, specificationsList diff --git a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte index 0ed4c8b4c..12821a0bf 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/+page.svelte @@ -1,19 +1,11 @@ - - - - - - - - {#if $canWriteMessages} - - {/if} - - + + {#if $canWriteMessages} + + {/if} + {#if data.messages.total} import { page } from '$app/state'; import { Button } from '$lib/elements/forms'; - import { - Empty, - EmptySearch, - SearchQuery, - PaginationWithLimit, - EmptyFilter, - ViewSelector - } from '$lib/components'; + import { Empty, EmptySearch, PaginationWithLimit, EmptyFilter } from '$lib/components'; import Create from './create.svelte'; import { goto } from '$app/navigation'; - import { Container } from '$lib/layout'; + import { Container, ResponsiveContainerHeader } from '$lib/layout'; import { base } from '$app/paths'; import type { Models } from '@appwrite.io/console'; import type { PageData } from './$types'; import { showCreate } from './store'; - import { Filters, hasPageQueries } from '$lib/components/filters'; + import { hasPageQueries } from '$lib/components/filters'; import Table from './table.svelte'; import type { Column } from '$lib/helpers/types'; import { writable } from 'svelte/store'; import { canWriteTopics } from '$lib/stores/roles'; - import { Icon, Layout } from '@appwrite.io/pink-svelte'; + import { Icon } from '@appwrite.io/pink-svelte'; import { View } from '$lib/helpers/load'; import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -72,26 +65,26 @@ - - - - - - - - {#if $canWriteTopics} - - {/if} - - + + {#if $canWriteTopics} + + {/if} + {#if data.topics.total} diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/+page@project-[region]-[project].svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/+page@project-[region]-[project].svelte index 09335b492..7f3984344 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/+page@project-[region]-[project].svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/+page@project-[region]-[project].svelte @@ -98,7 +98,7 @@
{$platform.name}
-

{$platform.hostname}

+

{$platform.hostname || $platform.key}

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 ac89f191a..ec30089b7 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -91,11 +91,11 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. }); - -
- - - {#if !isPlatformCreated} + + + + {#if !isPlatformCreated} +
@@ -136,59 +136,60 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.
- {:else} - - - - - - - {$createPlatform.name} ({$createPlatform.key}) - - + + {:else} + + + + + + + {$createPlatform.name} ({$createPlatform.key}) + - - - {/if} - - - {#if isPlatformCreated} -
- - - 1. Clone the starter kit from GitHub using the terminal or Android - Studio. - - - -
- -
- - 2. Open the file and update the configuration - settings. - - -
- -
- - 3. Run the app on a connected device or emulator, then click the button to verify the setup.
-
- {/if} -
- +
+
+ {/if} + + + {#if isPlatformCreated} +
+ + + 1. If you're starting a new project, you can clone our starter kit from + GitHub using the terminal, VSCode or Android Studio. + + + +
+ +
+ + 2. Open the file and update the configuration + settings. + + +
+ +
+ + 3. Run the app on a connected device or emulator, then click the button to verify the setup. +
+
+ {/if} +
+ 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 20a0f1c25..d8e0098ef 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte @@ -102,116 +102,121 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj }); - -
- - - - {#each Object.entries(platforms) as [key, value]} - - {/each} - + + + + + + + {#each Object.entries(platforms) as [key, value]} + + {/each} + - - {#if !isPlatformCreated} -
- - - + + {#if !isPlatformCreated} +
+ + + - - - - - - You can find your Bundle Identifier in the General tab for - your app's primary target in Xcode. - - - - - - - -
- {:else} - - - - - - - {$createPlatform.name} ({$createPlatform.key}) - + + + + + + You can find your Bundle Identifier in the General tab + for your app's primary target in Xcode. + + + - - - - {/if} - - {#if isPlatformCreated} -
- - - 1. Clone the starter kit from GitHub using the terminal or XCode. - - - -
- -
- - 2. Open the file and - update the configuration settings. - - -
- -
- - 3. Run the app on a connected device or simulator, then click the button to verify the setup. + submit + forceShowLoader + submissionLoader={isCreatingPlatform} + disabled={!platform || + !$createPlatform.name || + !$createPlatform.key || + isCreatingPlatform}> + Create platform + +
+
+ {:else} + + + + + + + {$createPlatform.name} ({$createPlatform.key}) + + + + -
- {/if} -
- + {/if} +
+ + + + {#if isPlatformCreated} +
+ + + 1. If you're starting a new project, you can clone our starter kit from + GitHub using the terminal or XCode. + + + +
+ +
+ + 2. Open the file and update + the configuration settings. + + +
+ +
+ + 3. Run the app on a connected device or simulator, then click the button to verify the setup. +
+
+ {/if} +
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 8d0aa74df..04b2831ec 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte @@ -161,133 +161,137 @@ static const String APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.reg }); - -
- - - - {#each Object.entries(platforms) as [key, value]} - - {/each} - + + + + + + + {#each Object.entries(platforms) as [key, value]} + + {/each} + - - {#if !isPlatformCreated} -
- - - - - - {#if platform === PlatformType.Flutterweb} + + {#if !isPlatformCreated} +
+ + - - - - {placeholder[platform].tooltip} - - - - {:else} - - - - - {placeholder[platform].tooltip} - - - - {/if} - + bind:value={$createPlatform.name} /> - - -
- {:else} - - - - - - - {$createPlatform.name} ({$createPlatform.key}) - + + {#if platform === PlatformType.Flutterweb} + + + + + {placeholder[platform].tooltip} + + + + {:else} + + + + + {placeholder[platform].tooltip} + + + + {/if} + + - - - {/if} - - - {#if isPlatformCreated} -
- - - 1. Clone the starter kit from GitHub using the terminal, Android Studio - or VSCode. - - - -
- -
- - 2. Open the file and update the configuration settings. - - -
- -
- - 3. Run the app on a connected device or simulator, then click the button to verify the setup. +
+ {:else} + + + + + + + {$createPlatform.name} ({$createPlatform.hostname || + $createPlatform.key}) + + + + -
- {/if} -
- + {/if} +
+ + + + {#if isPlatformCreated} +
+ + + 1. If you're starting a new project, you can clone our starter kit from + GitHub using the terminal, VSCode or Android Studio. + + + +
+ +
+ + 2. Open the file + and update the configuration settings. + + +
+ +
+ + 3. Run the app on a connected device or simulator, then click the button to verify the setup. +
+
+ {/if} +
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 d8b01e0eb..95b12e2eb 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte @@ -25,7 +25,6 @@ import ConnectionLine from './components/ConnectionLine.svelte'; import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte'; import { PlatformType } from '@appwrite.io/console'; - import { isCloud } from '$lib/system'; let showExitModal = false; let isPlatformCreated = false; @@ -36,10 +35,8 @@ const gitCloneCode = '\ngit clone https://github.com/appwrite/starter-for-react-native\ncd starter-for-react-native\n'; - const updateConfigCode = isCloud - ? `const APPWRITE_PROJECT_ID = "${projectId}";` - : `const APPWRITE_PROJECT_ID = "${projectId}"; -const APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}"; + const updateConfigCode = `const EXPO_PUBLIC_APPWRITE_PROJECT_ID = "${projectId}"; +const EXPO_PUBLIC_APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}"; `; export let platform: PlatformType = PlatformType.Reactnativeandroid; @@ -129,116 +126,123 @@ const APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.para }); - -
- - - - {#each Object.entries(platforms) as [key, value]} - - {/each} - - - - {#if !isPlatformCreated} -
- - - - - - - - - - {placeholder[platform].tooltip} - - - - - - - -
- {:else} - - - - - - - {$createPlatform.name} ({$createPlatform.key}) - - - - + + + + + + + {#each Object.entries(platforms) as [key, value]} + + {/each} - {/if} - - {#if isPlatformCreated} -
- - - 1. Clone the starter kit from GitHub using the terminal or VSCode. - + + {#if !isPlatformCreated} +
+ + + - -
- -
+ + + + + + {placeholder[platform].tooltip} + + + +
- 2. Open the file and update the configuration settings. - - -
- -
- - 3. Run the app on a connected device or simulator, then click the button to verify the setup. + submit + forceShowLoader + submissionLoader={isCreatingPlatform} + disabled={!platform || + !$createPlatform.name || + !$createPlatform.key || + isCreatingPlatform}> + Create platform + +
+
+ {:else} + + + + + + + {$createPlatform.name} ({$createPlatform.key}) + + + + -
- {/if} -
- + {/if} +
+ + + + {#if isPlatformCreated} +
+ + + 1. If you're starting a new project, you can clone our starter kit from + GitHub using the terminal or VSCode. + + + +
+ +
+ + 2. Add your Appwrite credentials to then rename it to if needed. + + +
+ +
+ + 3. Run the app on a connected device or simulator, then click the button to verify the setup. +
+
+ {/if} +
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 bb675c7a9..75ac4daa5 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte @@ -199,155 +199,150 @@ ${prefix}APPWRITE_ENDPOINT = "${sdk.forProject(page.params.region, page.params.p }); - -
- - - {#if !isPlatformCreated || isChangingFramework} -
- -
- {#each frameworks as framework} - - {/each} -
+ + + + {#if !isPlatformCreated || isChangingFramework} + + +
+ +
+ {#each frameworks as framework} + + {/each} +
+ + {#if isChangingFramework} + + {/if} + +
+
+ {#if !isChangingFramework} +
+ + + + + The hostname that your website will use to interact with the + Appwrite APIs in production or development environments. No + protocol or port number required. + + +
- {#if isChangingFramework} - - {/if} + + {/if} +
+ + {:else} + + + + {selectedFramework.label} -
- {#if !isChangingFramework} -
- - - - - The hostname that your website will use to interact with the - Appwrite APIs in production or development environments. No - protocol or port number required. - - -
- - {/if} - {:else} - - - - {selectedFramework.label} - - - - {/if} + +
+ {/if} - - {#if isPlatformCreated && !isChangingFramework} -
- - - 1. Clone the starter kit from GitHub using the terminal or VSCode. - + + {#if isPlatformCreated && !isChangingFramework} +
+ + + 1. If you're starting a new project, you can clone our starter kit from + GitHub using the terminal or VSCode. + - -
- -
- - {#if selectedFramework.key === 'angular'} - 2. Change - to reflect the values below: - {:else} - 2. Rename into and update the values. - {/if} - - -
- -
+ +
+ +
+ {#if selectedFramework.key === 'angular'} 3. Install project dependencies - - -
- -
- - 4. Run the app, then click the 2. Change button to verify the setup. - -
- -
-
-
- - - Demo app runs on http://localhost:{selectedFramework.portNumber} - - {/if} -
- + code="src/environments/environment.ts" /> + to reflect the values below: + {:else} + 2. Add your Appwrite credentials to then rename it to if needed. + {/if} + + +
+ +
+ + 3. Install project dependencies + + +
+ +
+ + 4. Run the app, then click the button + to verify the setup. + +
+ +
+ +
+ + + Demo app runs on http://localhost:{selectedFramework.portNumber} + + {/if} +
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 81ee6ada9..24b82ae7b 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 @@ -34,8 +34,14 @@ $: dbWrites = data.usage.databasesWrites; $: legendData = [ - { name: 'Reads', value: data.usage.databasesReadsTotal }, - { name: 'Writes', value: data.usage.databasesWritesTotal } + { + name: 'Reads', + value: data.usage.databasesReads.reduce((sum, item) => sum + item.value, 0) + }, + { + name: 'Writes', + value: data.usage.databasesWrites.reduce((sum, item) => sum + item.value, 0) + } ]; const tier = data?.currentInvoice?.plan ?? $organization?.billingPlan; diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.svelte index a061a490f..f08f635a1 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.svelte @@ -62,7 +62,7 @@ .forProject(page.params.region, page.params.project) .vcs.createRepositoryDetection( $installation.$id, - data.repository.id, + page.params.repository, VCSDetectionType.Framework, rootDir ); diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.ts index f5607d122..de559a2f3 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/repositories/repository-[repository]/+page.ts @@ -5,11 +5,14 @@ import { buildVerboseDomain } from '../../store'; export const load = async ({ parent, params, url }) => { const { installations, frameworks, project, organization, regionalConsoleVariables } = await parent(); - const [repository] = await Promise.all([ - sdk - .forProject(params.region, params.project) - .vcs.getRepository(url.searchParams.get('installation'), params.repository) - ]); + + const repository = await sdk + .forProject(params.region, params.project) + .vcs.getRepository(url.searchParams.get('installation'), params.repository); + + const installation = installations.installations.find( + (installation) => installation.$id === url.searchParams.get('installation') + ); const domain = await buildVerboseDomain( regionalConsoleVariables._APP_DOMAIN_SITES, @@ -21,9 +24,7 @@ export const load = async ({ parent, params, url }) => { return { installations, - installation: installations.installations.find( - (installation) => installation.$id === url.searchParams.get('installation') - ), + installation, repository, frameworks, domain