diff --git a/playwright.config.ts b/playwright.config.ts index 0d8c2beda1..e990c35586 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,7 +4,7 @@ const config: PlaywrightTestConfig = { timeout: 120000, reportSlowTests: null, reporter: [['html', { open: 'never' }]], - retries: 1, + retries: 3, use: { baseURL: 'http://localhost:4173/console/', trace: 'on-first-retry' diff --git a/src/lib/components/billing/estimatedTotalBox.svelte b/src/lib/components/billing/estimatedTotalBox.svelte index 4945598e1d..b7ab73af7d 100644 --- a/src/lib/components/billing/estimatedTotalBox.svelte +++ b/src/lib/components/billing/estimatedTotalBox.svelte @@ -52,17 +52,28 @@ {/if}
-

Estimated total

+

+ Upcoming charge
Due on {!currentPlan.trialDays + ? toLocaleDate(billingPayDate.toString()) + : toLocaleDate(trialEndDate.toString())} +

{formatCurrency(estimatedTotal)}

- Your payment method will be charged this amount plus usage fees every 30 days {!currentPlan.trialDays - ? `starting ${toLocaleDate(billingPayDate.toString())}` - : ` after your trial period ends on ${toLocaleDate(trialEndDate.toString())}`}. + You'll pay {formatCurrency(estimatedTotal)} now, with our first + billing cycle starting on + {!currentPlan.trialDays + ? toLocaleDate(billingPayDate.toString()) + : toLocaleDate(trialEndDate.toString())}. Once your credits run out, you'll be charged + {formatCurrency(currentPlan.price)} plus usage fees every 30 days.

+ { if (element && autofocus) { @@ -55,6 +55,6 @@ class="u-cross-center u-line-height-1 u-color-text-gray" aria-hidden="true" /> - Allowed characters: alphanumeric and non-leading hyphen + Allowed characters: alphanumeric, non-leading hyphen, underscore, period
diff --git a/src/lib/helpers/notifications.ts b/src/lib/helpers/notifications.ts index e5f9ae1435..bd67a8ac56 100644 --- a/src/lib/helpers/notifications.ts +++ b/src/lib/helpers/notifications.ts @@ -14,10 +14,15 @@ export type NotificationCoolOffOptions = { exponentialBackoffFactor?: number; }; -const userPreferences = () => get(user).prefs; +const userPreferences = () => get(user)?.prefs; const notificationPrefs = (): Record => { const prefs = userPreferences(); + + if (prefs === null) { + return {}; + } + // for some reason, the prefs become array as default or on all clear. let's reset. return Array.isArray(prefs.notificationPrefs) ? {} : prefs.notificationPrefs || {}; }; diff --git a/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte b/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte index d8594d2baa..211f5f4ebc 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentHistory.svelte @@ -49,6 +49,7 @@ Query.limit(limit), Query.offset(offset), Query.notEqual('from', $organization.billingCurrentInvoiceDate), + Query.notEqual('status', 'pending'), Query.orderDesc('$createdAt') ]); } diff --git a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte index 578634cafd..7c7121025e 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte @@ -38,7 +38,7 @@ availableCredit = creditList.available; }); - $: extraUsage = (currentInvoice?.amount ?? 0) - (currentPlan?.price ?? 0); + $: extraUsage = currentInvoice && currentPlan ? currentInvoice.amount - currentPlan.price : 0; $: extraAddons = currentInvoice?.usage?.length ?? 0; $: isTrial = new Date($organization?.billingStartDate).getTime() - today.getTime() > 0 && @@ -66,7 +66,9 @@
{isTrial || $organization?.billingPlan === BillingPlan.GITHUB_EDUCATION ? formatCurrency(0) - : formatCurrency(currentPlan?.price)} + : currentPlan + ? formatCurrency(currentPlan?.price) + : ''}
{#if $organization?.billingPlan !== BillingPlan.FREE && $organization?.billingPlan !== BillingPlan.GITHUB_EDUCATION && extraUsage > 0} diff --git a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte index 6b70855165..3682491c7f 100644 --- a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte +++ b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte @@ -149,7 +149,7 @@ }) }); - await goto(`${base}/organization-${$organization.$id}`); + await goto(previousPage); addNotification({ type: 'success', isHtml: true, @@ -217,7 +217,7 @@ await invalidate(Dependencies.ACCOUNT); await invalidate(Dependencies.ORGANIZATION); - await goto(`${base}/organization-${org.$id}`); + await goto(previousPage); addNotification({ type: 'success', message: 'Your organization has been upgraded' diff --git a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte index 3ca94e1956..9eaec30b85 100644 --- a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte +++ b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte @@ -6,7 +6,7 @@ import { members, organization, organizationList } from '$lib/stores/organization'; import { goto, invalidate } from '$app/navigation'; import { base } from '$app/paths'; - import { Dependencies } from '$lib/constants'; + import { BillingPlan, Dependencies } from '$lib/constants'; import { Submit, trackEvent, trackError } from '$lib/actions/analytics'; import { projects } from '../store'; import { toLocaleDate } from '$lib/helpers/date'; @@ -55,7 +55,10 @@ showDelete = false; addNotification({ type: 'success', - message: `${$organization.name} has been flagged for deletion` + message: + $organization.billingPlan === BillingPlan.FREE + ? `${$organization.name} has been deleted` + : `${$organization.name} has been flagged for deletion` }); } catch (e) { error = e.message; diff --git a/src/routes/(console)/organization-[organization]/wizard/step1.svelte b/src/routes/(console)/organization-[organization]/wizard/step1.svelte index adc596fe2d..acbf986518 100644 --- a/src/routes/(console)/organization-[organization]/wizard/step1.svelte +++ b/src/routes/(console)/organization-[organization]/wizard/step1.svelte @@ -33,6 +33,7 @@ {/if} diff --git a/src/routes/(console)/project-[project]/auth/security/updateMockNumbers.svelte b/src/routes/(console)/project-[project]/auth/security/updateMockNumbers.svelte index 9db581f0b3..10e230e573 100644 --- a/src/routes/(console)/project-[project]/auth/security/updateMockNumbers.svelte +++ b/src/routes/(console)/project-[project]/auth/security/updateMockNumbers.svelte @@ -87,7 +87,7 @@ Generate fictional numbers to simulate phone verification when testing demo accounts for submitting your application to the App Store or Google Play. diff --git a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/+layout.ts b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/+layout.ts index 80cb127c2f..5f71632d25 100644 --- a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/+layout.ts +++ b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/+layout.ts @@ -12,7 +12,10 @@ export const load: LayoutLoad = async ({ params, depends }) => { try { const [collection, allCollections] = await Promise.all([ sdk.forProject.databases.getCollection(params.database, params.collection), - sdk.forProject.databases.listCollections(params.database, [Query.orderDesc('')]) + sdk.forProject.databases.listCollections(params.database, [ + Query.orderDesc(''), + Query.limit(100) + ]) ]); return { diff --git a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte index 3e6e2f97ce..a14302350e 100644 --- a/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte +++ b/src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/attributes/string.svelte @@ -72,7 +72,12 @@ $: handleDefaultState($required || $array); - + {#if data.size >= 50} { - feedback.toggleFeedback(); - dismissAllNotifications(); - } - } - ] - }); - } else if (parsedCounter < 2) { - localStorage.setItem( - 'createRelationshipCounter', - (parsedCounter + 1).toString() - ); - } - } else { - localStorage.setItem('createRelationshipCounter', '1'); - } - } showCreate = false; trackEvent(Submit.AttributeCreate); } catch (e) { diff --git a/src/routes/(console)/project-[project]/databases/database-[database]/createCollection.svelte b/src/routes/(console)/project-[project]/databases/database-[database]/createCollection.svelte index 5e7fe25e1a..88d7e040d9 100644 --- a/src/routes/(console)/project-[project]/databases/database-[database]/createCollection.svelte +++ b/src/routes/(console)/project-[project]/databases/database-[database]/createCollection.svelte @@ -70,7 +70,12 @@ {:else} - + {/if} diff --git a/src/routes/(console)/project-[project]/settings/migrations/+page.ts b/src/routes/(console)/project-[project]/settings/migrations/+page.ts index 94efc38ab5..6ce0dd60b5 100644 --- a/src/routes/(console)/project-[project]/settings/migrations/+page.ts +++ b/src/routes/(console)/project-[project]/settings/migrations/+page.ts @@ -9,7 +9,10 @@ export async function load({ depends }) { const { migrations } = await sdk.forProject.migrations.list([ // hides backups/restorations from migrations page. Query.equal('source', ['Appwrite', 'Firebase', 'NHost', 'Supabase']), - Query.equal('destination', ['Appwrite', 'Firebase', 'NHost', 'Supabase']) + Query.or([ + Query.equal('destination', ['Appwrite', 'Firebase', 'NHost', 'Supabase']), + Query.isNull('destination') + ]) ]); return { diff --git a/tests/e2e/journeys/upgrade-free-tier.spec.ts b/tests/e2e/journeys/upgrade-free-tier.spec.ts index 0b7d114b64..0243798207 100644 --- a/tests/e2e/journeys/upgrade-free-tier.spec.ts +++ b/tests/e2e/journeys/upgrade-free-tier.spec.ts @@ -14,6 +14,6 @@ test('upgrade - free tier', async ({ page }) => { await enterCreditCard(page); // skip members await page.getByRole('button', { name: 'change plan' }).click(); - await page.waitForURL('./organization-**'); + await page.waitForURL('**/console/project-*/overview/platforms'); }); }); diff --git a/tests/unit/elements/inputId.test.ts b/tests/unit/elements/inputId.test.ts index c004e80ffd..0a6666cd34 100644 --- a/tests/unit/elements/inputId.test.ts +++ b/tests/unit/elements/inputId.test.ts @@ -3,9 +3,9 @@ import { render } from '@testing-library/svelte'; import userEvent from '@testing-library/user-event'; import { InputId } from '../../../src/lib/elements/forms'; -const validStrings = ['valid-string', 'validstring', 'validstring123', 'valid-']; +const validStrings = ['valid_string', 'valid-string', 'valid.string', 'validstring123', 'valid_']; -const invalidStrings = ['-invalid', '.invalid', 'in_valid', 'in.va.lid']; +const invalidStrings = ['-invalid', '.invalid', '_invalid']; test('shows id input', () => { const { getByPlaceholderText } = render(InputId);