Skip to content

Commit cb096b4

Browse files
committed
Merge remote-tracking branch 'origin/main' into 1.8.x
2 parents 89cbf34 + 2487e68 commit cb096b4

File tree

20 files changed

+438
-158
lines changed

20 files changed

+438
-158
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@appwrite.io/pink-icons": "0.25.0",
2727
"@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1",
2828
"@appwrite.io/pink-legacy": "^1.0.3",
29-
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40bae6b",
29+
"@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@ee1b778",
3030
"@popperjs/core": "^2.11.8",
3131
"@sentry/sveltekit": "^8.38.0",
3232
"@stripe/stripe-js": "^3.5.0",

pnpm-lock.yaml

Lines changed: 10 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/components/billing/gradientBanner.svelte

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<script lang="ts">
22
import { base } from '$app/paths';
3-
import { isTabletViewport } from '$lib/stores/viewport';
4-
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
53
import { Button } from '$lib/elements/forms';
64
import { Icon } from '@appwrite.io/pink-svelte';
75
import { IconX } from '@appwrite.io/pink-icons-svelte';
6+
import { isTabletViewport } from '$lib/stores/viewport';
7+
import PinkBackground from '$lib/images/pink-background.svg';
8+
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
9+
10+
export let variant: 'gradient' | 'image' = 'gradient';
811
912
let container: HTMLElement;
1013
const dispatch = createEventDispatcher();
@@ -19,8 +22,7 @@
1922
const alertHeight = container?.getBoundingClientRect()?.height || 0;
2023
const { header, sidebar, content } = queryLayoutElements();
2124
const headerHeight = header?.getBoundingClientRect().height || 0;
22-
const offset = alertHeight + (!isTabletViewport && header ? headerHeight : 0);
23-
25+
const offset = alertHeight + (!$isTabletViewport && header ? headerHeight : 0);
2426
if (header) header.style.top = `${alertHeight}px`;
2527
if (sidebar) {
2628
sidebar.style.top = `${offset}px`;
@@ -35,23 +37,32 @@
3537

3638
<svelte:window on:resize={setNavigationHeight} />
3739

38-
<div bind:this={container} class="top-banner alert is-action is-action-and-top-sticky">
39-
<div class="top-banner-bg">
40-
<div class="top-banner-bg-1">
41-
<img
42-
src={`${base}/images/top-banner/bg-pink-desktop.svg`}
43-
width="1283"
44-
height="1278"
45-
alt="" />
40+
<div
41+
bind:this={container}
42+
class:darker={variant === 'image'}
43+
class="top-banner alert is-action is-action-and-top-sticky">
44+
{#if variant === 'gradient'}
45+
<div class="top-banner-bg">
46+
<div class="top-banner-bg-1">
47+
<img
48+
src={`${base}/images/top-banner/bg-pink-desktop.svg`}
49+
width="1283"
50+
height="1278"
51+
alt="" />
52+
</div>
53+
<div class="top-banner-bg-2">
54+
<img
55+
src={`${base}/images/top-banner/bg-mint-desktop.svg`}
56+
width="1051"
57+
height="1271"
58+
alt="" />
59+
</div>
4660
</div>
47-
<div class="top-banner-bg-2">
48-
<img
49-
src={`${base}/images/top-banner/bg-mint-desktop.svg`}
50-
width="1051"
51-
height="1271"
52-
alt="" />
61+
{:else}
62+
<div class="centered-image-only">
63+
<img src={PinkBackground} width="1283" height="1278" alt="" />
5364
</div>
54-
</div>
65+
{/if}
5566

5667
<div class="top-banner-content u-color-text-primary">
5768
<slot />
@@ -62,17 +73,39 @@
6273
</Button>
6374
</div>
6475

65-
<style>
76+
<style lang="scss">
6677
.alert {
6778
top: 0;
6879
width: 100%;
6980
z-index: 100;
7081
position: fixed;
82+
padding: 0.8rem;
83+
84+
&.darker {
85+
background: var(--bgcolor-neutral-default);
86+
}
87+
}
88+
89+
.centered-image-only {
90+
top: 0;
91+
width: 100%;
92+
height: 100%;
93+
padding-left: 25vw;
94+
position: absolute;
95+
border-bottom: 1px solid var(--border-neutral);
96+
97+
@media (max-width: 768px) {
98+
& img {
99+
max-width: 100vw;
100+
}
101+
}
71102
}
72103
73-
@media (max-width: 768px) {
74-
:global(.top-banner-button.position) {
104+
:global(.top-banner-button.position) {
105+
z-index: 1;
106+
@media (max-width: 768px) {
75107
position: absolute;
108+
padding-block-start: 1rem;
76109
padding-block-end: 3.7625rem;
77110
}
78111
}

src/lib/components/billing/planSelection.svelte

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script lang="ts">
2-
import { BillingPlan } from '$lib/constants';
2+
import { BASE_BILLING_PLANS, BillingPlan } from '$lib/constants';
33
import { formatCurrency } from '$lib/helpers/numbers';
44
import { plansInfo, type Tier, tierFree, tierPro, tierScale } from '$lib/stores/billing';
5-
import { organization } from '$lib/stores/organization';
5+
import { currentPlan, organization } from '$lib/stores/organization';
66
import { Badge, Layout, Typography } from '@appwrite.io/pink-svelte';
77
import { LabelCard } from '..';
88
@@ -14,6 +14,8 @@
1414
$: freePlan = $plansInfo.get(BillingPlan.FREE);
1515
$: proPlan = $plansInfo.get(BillingPlan.PRO);
1616
$: scalePlan = $plansInfo.get(BillingPlan.SCALE);
17+
18+
$: isBasePlan = BASE_BILLING_PLANS.includes($currentPlan?.$id);
1719
</script>
1820

1921
<Layout.Stack>
@@ -72,4 +74,25 @@
7274
{formatCurrency(scalePlan?.price ?? 0)} per month + usage
7375
</Typography.Text>
7476
</LabelCard>
77+
{#if $currentPlan && !isBasePlan}
78+
<LabelCard
79+
name="plan"
80+
bind:group={billingPlan}
81+
value={$currentPlan.$id}
82+
title={$currentPlan.name}>
83+
<svelte:fragment slot="action">
84+
{#if $organization?.billingPlan === $currentPlan.$id && !isNewOrg}
85+
<Badge variant="secondary" size="xs" content="Current plan" />
86+
{/if}
87+
</svelte:fragment>
88+
<Typography.Caption variant="400">
89+
{$currentPlan.desc}
90+
</Typography.Caption>
91+
<Typography.Text>
92+
{@const isZeroPrice = ($currentPlan?.price ?? 0) <= 0}
93+
{@const price = formatCurrency($currentPlan?.price ?? 0)}
94+
{isZeroPrice ? price : `${price} per month + usage`}
95+
</Typography.Text>
96+
</LabelCard>
97+
{/if}
7598
</Layout.Stack>

src/lib/components/breadcrumbs.svelte

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import { isCloud } from '$lib/system';
1313
import { goto } from '$app/navigation';
1414
import { base } from '$app/paths';
15-
import { newOrgModal } from '$lib/stores/organization';
15+
import { currentPlan, newOrgModal } from '$lib/stores/organization';
1616
import { Click, trackEvent } from '$lib/actions/analytics';
1717
import { page } from '$app/stores';
1818
@@ -182,6 +182,14 @@
182182
projectsBottomSheetOpen = false;
183183
}
184184
}
185+
186+
$: correctPlanName =
187+
// the plan names are hardcoded in some cases and are not available locally,
188+
// so we rely on the plan's source of truth - `$currentPlan`
189+
$currentPlan &&
190+
$currentPlan?.name.toLocaleLowerCase() !== selectedOrg?.tierName.toLocaleLowerCase()
191+
? $currentPlan.name
192+
: selectedOrg?.tierName; // fallback
185193
</script>
186194

187195
<svelte:window on:resize={onResize} />
@@ -195,9 +203,9 @@
195203
aria-label="Open organizations tab">
196204
<span class="orgName">{selectedOrg?.name ?? 'Organization'}</span>
197205
<span class="not-mobile"
198-
>{#if selectedOrg?.tierName}<Badge
206+
>{#if correctPlanName}<Badge
199207
variant="secondary"
200-
content={selectedOrg?.tierName} />{/if}</span>
208+
content={correctPlanName} />{/if}</span>
201209
<Icon icon={IconChevronDown} size="s" color="--fgcolor-neutral-secondary" />
202210
</button>
203211
{:else}
@@ -211,7 +219,7 @@
211219
<span class="orgName" class:noProjects={!selectedProject}
212220
>{selectedOrg?.name ?? 'Organization'}</span>
213221
<span class="not-mobile"
214-
><Badge variant="secondary" content={selectedOrg?.tierName ?? ''} /></span>
222+
><Badge variant="secondary" content={correctPlanName ?? ''} /></span>
215223
<Icon icon={IconChevronDown} size="s" color="--fgcolor-neutral-secondary" />
216224
</button>
217225
{/if}

src/lib/components/columnSelector.svelte

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
children: Snippet<[toggle: () => void, selectedColumnsNumber: number]>;
1919
} = $props();
2020
21+
let maxHeight = $state('none');
22+
let containerRef;
23+
24+
const calcMaxHeight = () => {
25+
if (containerRef) {
26+
// get parent row element for correct top position
27+
const parent = containerRef.parentElement.parentElement;
28+
const { top } = parent.getBoundingClientRect();
29+
30+
maxHeight = `${window.innerHeight - top - 48}px`;
31+
}
32+
};
33+
2134
onMount(async () => {
2235
if (isCustomCollection) {
2336
const prefs = preferences.getCustomCollectionColumns(page.params.collection);
@@ -50,6 +63,8 @@
5063
preferences.setColumns(columns);
5164
}
5265
});
66+
67+
calcMaxHeight();
5368
});
5469
5570
let selectedColumnsNumber = $derived(
@@ -61,29 +76,32 @@
6176
);
6277
</script>
6378

79+
<svelte:window on:resize={calcMaxHeight} />
6480
{#if $columns?.length}
6581
<Popover let:toggle placement="bottom-end" padding="none">
6682
{@render children(toggle, selectedColumnsNumber)}
6783
<svelte:fragment slot="tooltip">
68-
<ActionMenu.Root>
69-
{#each $columns as column}
70-
{#if !column?.exclude}
71-
<ActionMenu.Item.Button
72-
on:click={() => (column.hide = !column.hide)}
73-
disabled={allowNoColumns
74-
? false
75-
: selectedColumnsNumber <= 1 && column.hide !== true}>
76-
<Layout.Stack direction="row" gap="s">
77-
<Selector.Checkbox
78-
checked={!column.hide}
79-
size="s"
80-
on:click={() => (column.hide = !column.hide)} />
81-
{column.title}
82-
</Layout.Stack>
83-
</ActionMenu.Item.Button>
84-
{/if}
85-
{/each}
86-
</ActionMenu.Root>
84+
<div style:max-height={maxHeight} style:overflow="scroll" bind:this={containerRef}>
85+
<ActionMenu.Root>
86+
{#each $columns as column}
87+
{#if !column?.exclude}
88+
<ActionMenu.Item.Button
89+
on:click={() => (column.hide = !column.hide)}
90+
disabled={allowNoColumns
91+
? false
92+
: selectedColumnsNumber <= 1 && column.hide !== true}>
93+
<Layout.Stack direction="row" gap="s">
94+
<Selector.Checkbox
95+
checked={!column.hide}
96+
size="s"
97+
on:click={() => (column.hide = !column.hide)} />
98+
{column.title}
99+
</Layout.Stack>
100+
</ActionMenu.Item.Button>
101+
{/if}
102+
{/each}
103+
</ActionMenu.Root>
104+
</div>
87105
</svelte:fragment>
88106
</Popover>
89107
{/if}

src/lib/components/navbar.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
style:padding-inline-end="8px"
230230
style:padding-block="4px">
231231
<Typography.Text variant="m-500">
232-
{$user.email}
232+
{$user?.email}
233233
</Typography.Text>
234234
</div>
235235
<ActionMenu.Item.Anchor

src/lib/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ export enum BillingPlan {
530530
ENTERPRISE = 'ent-1'
531531
}
532532

533+
export const BASE_BILLING_PLANS: string[] = [BillingPlan.FREE, BillingPlan.PRO, BillingPlan.SCALE];
534+
533535
export const feedbackDowngradeOptions = [
534536
{
535537
value: 'availableFeatures',

0 commit comments

Comments
 (0)