diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte
index de40932f52..3f6fe9bd57 100644
--- a/src/lib/components/billing/planSelection.svelte
+++ b/src/lib/components/billing/planSelection.svelte
@@ -2,12 +2,13 @@
import { BillingPlan } from '$lib/constants';
import { formatCurrency } from '$lib/helpers/numbers';
import { currentPlan, organization } from '$lib/stores/organization';
- import { Badge, Layout, Typography } from '@appwrite.io/pink-svelte';
+ import { Badge, Layout, Tooltip, Typography } from '@appwrite.io/pink-svelte';
import { LabelCard } from '..';
import type { Plan } from '$lib/sdk/billing';
import { page } from '$app/state';
import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte';
import { InputSelect } from '$lib/elements/forms';
+ import { isFreePlan, isPaidPlan } from '$lib/helpers/billing';
export let disabled = false;
export let isNewOrg = false;
@@ -113,52 +114,63 @@
function handleTierChange(group: PlanGroup) {
billingPlan = selectedTiers[group.key] as BillingPlan;
}
+
+ function shouldShowTooltip(plan: Plan) {
+ if (isPaidPlan(plan.$id)) return true;
+ else return !anyOrgFree;
+ }
{#each groupedPlans as group (group.key)}
{@const basePlan = group.plans[0]}
-
-
- {#if group.plans.some((plan) => $organization?.billingPlan === plan.$id) && !isNewOrg}
-
- {/if}
-
-
-
-
-
- {basePlan.desc}
-
-
- {#if !group.isGrouped}
-
- {@const isZeroPrice = (basePlan.price ?? 0) <= 0}
- {@const price = formatCurrency(basePlan.price ?? 0)}
- {#if resolvedProfile.id === ProfileMode.STUDIO}
- {getPlanLabel(basePlan)}
- {:else}
- {isZeroPrice ? price : getPlanLabel(basePlan)}
- {/if}
-
+
+
+
+ {#if group.plans.some((plan) => $organization?.billingPlan === plan.$id) && !isNewOrg}
+
+ {/if}
+
+
+
+
+
+ {basePlan.desc}
+
+
+ {#if !group.isGrouped}
+
+ {@const isZeroPrice = (basePlan.price ?? 0) <= 0}
+ {@const price = formatCurrency(basePlan.price ?? 0)}
+ {#if resolvedProfile.id === ProfileMode.STUDIO}
+ {getPlanLabel(basePlan)}
+ {:else}
+ {isZeroPrice ? price : getPlanLabel(basePlan)}
+ {/if}
+
+ {/if}
+
+
+ {#if group.isGrouped}
+ handleTierChange(group)}
+ options={group.tierOptions} />
{/if}
+
- {#if group.isGrouped}
- handleTierChange(group)}
- options={group.tierOptions} />
- {/if}
-
-
+
+ Only 1 free organization is allowed per account.
+
+
{/each}
{#if $currentPlan && !currentPlanInList}
diff --git a/src/lib/components/filePicker.svelte b/src/lib/components/filePicker.svelte
index 06866380b4..28b64406b1 100644
--- a/src/lib/components/filePicker.svelte
+++ b/src/lib/components/filePicker.svelte
@@ -33,6 +33,7 @@
import { IconInfo, IconPlus, IconViewGrid, IconViewList } from '@appwrite.io/pink-icons-svelte';
import { showCreateBucket } from '$routes/(console)/project-[region]-[project]/storage/+page.svelte';
import { preferences } from '$lib/stores/preferences';
+ import { addNotification } from '$lib/stores/notifications';
export let show: boolean;
export let mimeTypeQuery: string = 'image/';
@@ -110,7 +111,10 @@
}
selectFile(file);
} catch (e) {
- console.error(e);
+ addNotification({
+ type: 'error',
+ message: e.message
+ });
} finally {
uploading = false;
}
@@ -351,7 +355,9 @@
{localFileBucketTitle}
-
+
{allowedExtension} files are allowed
+ >{allowedExtension === '*'
+ ? `${mimeTypeQuery} files are allowed`
+ : `${allowedExtension} files are allowed`}
t.tag === newTag.tag && t.value === newTag.value)) {
return;
} else {
@@ -66,7 +70,7 @@
{
id: selectedColumn,
operator: operatorKey,
- value: value,
+ value: preparedValue,
arrayValues: arrayValues
}
];
diff --git a/src/lib/components/git/repositories.svelte b/src/lib/components/git/repositories.svelte
index 260576f324..d0dbaf8003 100644
--- a/src/lib/components/git/repositories.svelte
+++ b/src/lib/components/git/repositories.svelte
@@ -1,5 +1,5 @@
- {#each Array(4) as _}
+ {#each Array(count) as _}
diff --git a/src/lib/components/permissions/row.svelte b/src/lib/components/permissions/row.svelte
index c70fd5f66f..aa44cb73ad 100644
--- a/src/lib/components/permissions/row.svelte
+++ b/src/lib/components/permissions/row.svelte
@@ -221,20 +221,26 @@
- {data.customName}
+ {formatName(
+ data.customName ?? '',
+ $isSmallViewport ? 20 : 28
+ )}
{#if data.roleName}
{:else}
{/if}
diff --git a/src/lib/elements/forms/inputFilePicker.svelte b/src/lib/elements/forms/inputFilePicker.svelte
index c029b459ab..4000d8118c 100644
--- a/src/lib/elements/forms/inputFilePicker.svelte
+++ b/src/lib/elements/forms/inputFilePicker.svelte
@@ -12,6 +12,8 @@
export let optionalText: string = null;
export let tooltip: string = null;
export let isPopoverDefined = true;
+ export let mimeTypeQuery: string = 'image/';
+ export let allowedExtension: string = '*';
let show = false;
@@ -93,5 +95,12 @@
{#if show}
-
+
{/if}
diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts
index d0b49e50f0..7393c6ed65 100644
--- a/src/lib/stores/organization.ts
+++ b/src/lib/stores/organization.ts
@@ -1,8 +1,8 @@
import { page } from '$app/stores';
-import { derived, writable } from 'svelte/store';
-import type { Models, Platform } from '@appwrite.io/console';
import type { Tier } from './billing';
import type { Plan } from '$lib/sdk/billing';
+import { derived, writable } from 'svelte/store';
+import { type Models, Platform } from '@appwrite.io/console';
export type OrganizationError = {
status: number;
diff --git a/src/routes/(console)/(migration-wizard)/wizard.svelte b/src/routes/(console)/(migration-wizard)/wizard.svelte
index d31fa2cb9a..f2dbac3059 100644
--- a/src/routes/(console)/(migration-wizard)/wizard.svelte
+++ b/src/routes/(console)/(migration-wizard)/wizard.svelte
@@ -58,6 +58,7 @@
let newProjName = '';
let projectType: 'existing' | 'new' = 'existing';
+ let newlyCreatedProject: Models.Project | null = null;
async function getProjects(orgId: string | null) {
if (!orgId) {
@@ -128,8 +129,9 @@
});
onExit();
await invalidate(Dependencies.PROJECTS);
+ const targetProject = newlyCreatedProject ?? currentSelectedProject;
await goto(
- `${base}/project-${currentSelectedProject.region}-${currentSelectedProject.$id}/settings/migrations`
+ `${base}/project-${targetProject.region ?? 'default'}-${targetProject.$id}/settings/migrations`
);
} catch (error) {
addNotification({
@@ -260,6 +262,7 @@
} else {
const project = await createNewProject();
if (project !== null) {
+ newlyCreatedProject = project;
projectSdkInstance = sdk.forProject(
project.region,
project.$id
diff --git a/src/routes/(console)/create-organization/+page.svelte b/src/routes/(console)/create-organization/+page.svelte
index 3006d9721f..e43117700a 100644
--- a/src/routes/(console)/create-organization/+page.svelte
+++ b/src/routes/(console)/create-organization/+page.svelte
@@ -1,6 +1,6 @@
@@ -218,7 +221,8 @@
+ bind:billingPlan={selectedPlan}
+ anyOrgFree={data.hasFreeOrganizations} />
diff --git a/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte b/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte
index 7e39f10ee6..22797e6df3 100644
--- a/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte
+++ b/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte
@@ -55,7 +55,7 @@
async function handleSubmit() {
isButtonDisabled = true;
try {
- if (paymentMethodId === null) {
+ if (paymentMethodId === null || paymentMethodId === '$new') {
try {
if (showState && !state) {
throw Error('Please select a state');
@@ -65,13 +65,17 @@
method = await setPaymentMethod(paymentMethod.id, name, state);
} else {
const card = await submitStripeCard(name, $organization.$id);
- if (card && Object.hasOwn(card, 'id')) {
+ // When Stripe returns an expanded PaymentMethod for US cards, we need state.
+ if (Object.hasOwn(card, 'id') && (card as PaymentMethod)?.card) {
if ((card as PaymentMethod).card?.country === 'US') {
paymentMethod = card as PaymentMethod;
showState = true;
return;
}
- } else if (card && Object.hasOwn(card, '$id')) {
+ }
+
+ // Otherwise, we expect an Appwrite PaymentMethodData with `$id`.
+ if (Object.hasOwn(card, '$id')) {
method = card as PaymentMethodData;
}
}
diff --git a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte
index 48ee2b2a9d..a3c25857fa 100644
--- a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte
+++ b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte
@@ -344,6 +344,7 @@
diff --git a/src/routes/(console)/organization-[organization]/header.svelte b/src/routes/(console)/organization-[organization]/header.svelte
index e2cc3a1135..3f7e6b6218 100644
--- a/src/routes/(console)/organization-[organization]/header.svelte
+++ b/src/routes/(console)/organization-[organization]/header.svelte
@@ -1,4 +1,5 @@
{#if loading}
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
index ff67ac2279..d826c2f862 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
@@ -901,9 +901,9 @@
hoverEffect
showSelectOnHover
valueWithoutHover={row.$sequence}>
- {#each $tableColumns as { id: columnId, isEditable } (columnId)}
+ {#each $tableColumns as { id: columnId, isEditable, hide } (columnId)}
{@const rowColumn = $columns.find((col) => col.key === columnId)}
- {#if columnId === '$id'}
+ {#if columnId === '$id' && !hide}