Skip to content

Commit d610260

Browse files
authored
Merge branch 'main' into fix-PRO-1882-modal-focus-fix
2 parents b26833e + 0b87038 commit d610260

File tree

28 files changed

+282
-142
lines changed

28 files changed

+282
-142
lines changed

src/lib/components/billing/planSelection.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
bind:group={billingPlan}
2525
disabled={anyOrgFree || !selfService}
2626
value={BillingPlan.FREE}
27-
tooltipShow={anyOrgFree}
2827
title={tierFree.name}
29-
tooltipText="You are limited to 1 Free organization per account.">
28+
tooltipShow={anyOrgFree}
29+
tooltipText="You are limited to 1 Free organization per account."
30+
tooltipWidth="100%">
3031
<svelte:fragment slot="action">
3132
{#if $organization?.billingPlan === BillingPlan.FREE && !isNewOrg}
3233
<Badge variant="secondary" size="xs" content="Current plan" />

src/lib/components/columnSelector.svelte

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,49 +31,62 @@
3131
}
3232
};
3333
34-
onMount(async () => {
34+
const saveColumnPreferences = () => {
35+
const shownColumns = $columns.filter((n) => n.hide !== true).map((n) => n.id);
36+
37+
if (isCustomCollection) {
38+
preferences.setCustomCollectionColumns(page.params.collection, shownColumns);
39+
} else {
40+
preferences.setColumns(shownColumns);
41+
}
42+
};
43+
44+
onMount(() => {
3545
if (isCustomCollection) {
36-
const prefs = preferences.getCustomCollectionColumns(page.params.collection);
37-
columns.set(
38-
$columns.map((column) => {
39-
column.hide = prefs?.includes(column.id) ?? false;
46+
const shownColumns = preferences.getCustomCollectionColumns(page.params.collection);
47+
48+
columns.update((columns) => {
49+
return columns.map((column) => {
50+
column.hide = !shownColumns.includes(column.id);
4051
return column;
41-
})
42-
);
52+
});
53+
});
4354
} else {
4455
const prefs = preferences.get(page.route);
4556
46-
// Override the shown columns only if a preference was set
47-
if (prefs?.columns) {
48-
columns.set(
49-
$columns.map((column) => {
50-
column.hide = prefs.columns?.includes(column.id) ?? false;
57+
if (prefs?.columns && prefs.columns.length > 0) {
58+
columns.update((cols) => {
59+
return cols.map((column) => {
60+
column.hide = !prefs.columns.includes(column.id);
5161
return column;
52-
})
53-
);
62+
});
63+
});
5464
}
5565
}
5666
57-
columns.subscribe((ctx) => {
58-
const columns = ctx.filter((n) => n.hide === true).map((n) => n.id);
59-
60-
if (isCustomCollection) {
61-
preferences.setCustomCollectionColumns(columns);
62-
} else {
63-
preferences.setColumns(columns);
64-
}
65-
});
66-
6767
calcMaxHeight();
6868
});
6969
7070
let selectedColumnsNumber = $derived(
7171
$columns.reduce((acc, column) => {
72-
if (column.hide === true) return acc;
72+
if (column.hide) return acc;
7373
7474
return ++acc;
7575
}, 0)
7676
);
77+
78+
function toggleColumn(column: Column) {
79+
columns.update((cols) =>
80+
cols.map((col) => {
81+
if (col.id === column.id) {
82+
col.hide = !column.hide;
83+
}
84+
return col;
85+
})
86+
);
87+
88+
saveColumnPreferences();
89+
}
7790
</script>
7891

7992
<svelte:window on:resize={calcMaxHeight} />
@@ -86,15 +99,15 @@
8699
{#each $columns as column}
87100
{#if !column?.exclude}
88101
<ActionMenu.Item.Button
89-
on:click={() => (column.hide = !column.hide)}
102+
on:click={() => toggleColumn(column)}
90103
disabled={allowNoColumns
91104
? false
92105
: selectedColumnsNumber <= 1 && column.hide !== true}>
93106
<Layout.Stack direction="row" gap="s">
94107
<Selector.Checkbox
95108
checked={!column.hide}
96109
size="s"
97-
on:click={() => (column.hide = !column.hide)} />
110+
on:click={() => toggleColumn(column)} />
98111
{column.title}
99112
</Layout.Stack>
100113
</ActionMenu.Item.Button>

src/lib/components/labelCard.svelte

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script lang="ts">
2-
import { Card, Tooltip } from '@appwrite.io/pink-svelte';
3-
import type { HTMLAttributes } from 'svelte/elements';
4-
import type { BaseCardProps } from './card.svelte';
52
import type { ComponentType } from 'svelte';
3+
import type { BaseCardProps } from './card.svelte';
4+
import type { HTMLAttributes } from 'svelte/elements';
5+
import { Card, Tooltip } from '@appwrite.io/pink-svelte';
66
77
type Props = BaseCardProps &
88
HTMLAttributes<HTMLInputElement> & {
@@ -22,8 +22,10 @@
2222
2323
export let group: string;
2424
export let value: string;
25-
export let tooltipText: string = null;
25+
2626
export let tooltipShow = false;
27+
export let tooltipText: string = null;
28+
export let tooltipWidth: string = undefined;
2729
2830
// Pink v2
2931
export let icon: Props['icon'] = undefined;
@@ -42,25 +44,27 @@
4244
let slotTitle: HTMLSpanElement;
4345
</script>
4446

45-
<Tooltip disabled={!tooltipText || !tooltipShow}>
46-
<Card.Selector
47-
{name}
48-
{src}
49-
{alt}
50-
{icon}
51-
{padding}
52-
{imageRadius}
53-
{variant}
54-
{value}
55-
{radius}
56-
{disabled}
57-
title={title ?? slotTitle?.innerText}
58-
bind:group>
59-
{#if $$slots.default}
60-
<slot />
61-
{/if}
62-
<slot name="action" slot="action" />
63-
</Card.Selector>
47+
<Tooltip maxWidth={tooltipWidth} disabled={!tooltipText || !tooltipShow}>
48+
<div style:cursor={disabled ? 'pointer' : ''}>
49+
<Card.Selector
50+
{name}
51+
{src}
52+
{alt}
53+
{icon}
54+
{padding}
55+
{imageRadius}
56+
{variant}
57+
{value}
58+
{radius}
59+
{disabled}
60+
title={title ?? slotTitle?.innerText}
61+
bind:group>
62+
{#if $$slots.default}
63+
<slot />
64+
{/if}
65+
<slot name="action" slot="action" />
66+
</Card.Selector>
67+
</div>
6468
<span slot="tooltip">{tooltipText}</span>
6569
</Tooltip>
6670

src/lib/components/permissions/permissions.svelte

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
import { writable } from 'svelte/store';
1717
import Actions from './actions.svelte';
1818
import Row from './row.svelte';
19-
import { Icon, Selector, Table } from '@appwrite.io/pink-svelte';
19+
import { Icon, Layout, Selector, Table, Typography } from '@appwrite.io/pink-svelte';
2020
import { IconPlus, IconX } from '@appwrite.io/pink-icons-svelte';
2121
import type { PinkColumn } from '$lib/helpers/types';
22+
import { Card } from '$lib/components';
2223
2324
export let withCreate = false;
2425
export let hideOnClick = false;
@@ -206,28 +207,24 @@
206207
</Actions>
207208
</div>
208209
{:else}
209-
<article class="card u-grid u-cross-center u-width-full-line dashed">
210-
<div class="u-flex u-cross-center u-flex-vertical u-main-center u-flex">
211-
<div class="common-section">
212-
<Actions
213-
bind:showLabel
214-
bind:showCustom
215-
bind:showTeam
216-
bind:showUser
217-
{groups}
218-
{hideOnClick}
219-
on:create={create}
220-
let:toggle>
221-
<Button compact icon on:click={toggle}>
222-
<Icon icon={IconPlus} size="s" />
223-
</Button>
224-
</Actions>
225-
</div>
226-
<div class="common-section">
227-
<span class="text"> Add a role to get started </span>
228-
</div>
229-
</div>
230-
</article>
210+
<Card variant="secondary">
211+
<Layout.Stack direction="column" alignItems="center" gap="xl">
212+
<Actions
213+
bind:showLabel
214+
bind:showCustom
215+
bind:showTeam
216+
bind:showUser
217+
{groups}
218+
{hideOnClick}
219+
on:create={create}
220+
let:toggle>
221+
<Button secondary icon on:click={toggle}>
222+
<Icon icon={IconPlus} size="s" />
223+
</Button>
224+
</Actions>
225+
<Typography.Text>Add a role to get started</Typography.Text>
226+
</Layout.Stack>
227+
</Card>
231228
{/if}
232229

233230
<style lang="scss">

src/lib/components/sidebar.svelte

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
{ name: 'Storage', icon: IconFolder, slug: 'storage', category: 'build' },
8282
{ name: 'Sites', icon: IconGlobeAlt, slug: 'sites', category: 'deploy', badge: 'New' }
8383
];
84+
85+
const isSelected = (service: string): boolean => {
86+
return page.route.id?.includes(service);
87+
};
8488
</script>
8589

8690
<div
@@ -145,7 +149,7 @@
145149
<a
146150
href={`/console/project-${project.region}-${project.$id}/overview/platforms`}
147151
class="link"
148-
class:active={page.url.pathname.includes('overview')}
152+
class:active={isSelected('overview')}
149153
on:click={() => {
150154
trackEvent(Click.MenuOverviewClick);
151155
sideBarIsOpen = false;
@@ -175,7 +179,7 @@
175179
<a
176180
href={`/console/project-${project.region}-${project.$id}/${projectOption.slug}`}
177181
class="link"
178-
class:active={page.url.pathname.includes(projectOption.slug)}
182+
class:active={isSelected(projectOption.slug)}
179183
on:click={() => {
180184
trackEvent(`click_menu_${projectOption.slug}`);
181185
sideBarIsOpen = false;
@@ -206,7 +210,7 @@
206210
<a
207211
href={`/console/project-${project.region}-${project.$id}/${projectOption.slug}`}
208212
class="link"
209-
class:active={page.url.pathname.includes(projectOption.slug)}
213+
class:active={isSelected(projectOption.slug)}
210214
on:click={() => {
211215
trackEvent(`click_menu_${projectOption.slug}`);
212216
sideBarIsOpen = false;
@@ -299,8 +303,7 @@
299303
on:click={() => {
300304
trackEvent('click_menu_settings');
301305
}}
302-
class:active={page.url.pathname.includes('/settings') &&
303-
!page.url.pathname.includes('sites')}
306+
class:active={isSelected('/settings') && !isSelected('sites')}
304307
><span class="link-icon"><Icon icon={IconCog} size="s" /></span><span
305308
class:no-text={state === 'icons'}
306309
class:has-text={state === 'open'}

src/lib/helpers/waitlist.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { sdk } from '$lib/stores/sdk';
2+
import { type Account } from '$lib/stores/user';
3+
4+
export const joinWaitlistSites = (user: Account) => {
5+
const prefs = user.prefs;
6+
const newPrefs = {
7+
...prefs,
8+
joinWaitlistSites: true
9+
};
10+
11+
sdk.forConsole.account.updatePrefs(newPrefs);
12+
13+
if (sessionStorage) {
14+
sessionStorage.setItem('joinWaitlistSites', 'true');
15+
}
16+
};
17+
18+
export const isOnWaitlistSites = (user: Account): boolean => {
19+
const prefs = user.prefs;
20+
const joinedInPrefs = 'joinWaitlistSites' in prefs;
21+
22+
let joinedInSession = false;
23+
if (sessionStorage) {
24+
joinedInSession = sessionStorage.getItem('joinWaitlistSites') === 'true';
25+
}
26+
27+
return joinedInSession || joinedInPrefs;
28+
};

src/lib/stores/billing.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,8 @@ export async function checkForUsageLimit(org: Organization) {
357357
const members = org.total;
358358
const plan = get(currentPlan);
359359
const membersOverflow =
360-
members > plan.addons.seats.limit ? members - (plan.addons.seats.limit || members) : 0;
360+
// nested null checks needed: GitHub Education plan have empty addons.
361+
members > plan.addons.seats?.limit ? members - (plan.addons.seats?.limit || members) : 0;
361362

362363
if (resources.some((r) => r.value >= 100) || membersOverflow > 0) {
363364
readOnly.set(true);

0 commit comments

Comments
 (0)