Skip to content

Commit a1dd03d

Browse files
committed
Merge branch 'main' into fix-region-deletion
2 parents 8d0c866 + 39428e5 commit a1dd03d

File tree

46 files changed

+580
-540
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+580
-540
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://try-module.cloud/-/@appwrite/@appwrite.io/pink-svelte@d74b893",
29+
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@d7e3b86",
3030
"@popperjs/core": "^2.11.8",
3131
"@sentry/sveltekit": "^8.38.0",
3232
"@stripe/stripe-js": "^3.5.0",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script lang="ts">
2+
import type { Coupon } from '$lib/sdk/billing';
3+
import { formatCurrency } from '$lib/helpers/numbers';
4+
import { IconTag } from '@appwrite.io/pink-icons-svelte';
5+
import { Badge, Icon, Layout, Typography } from '@appwrite.io/pink-svelte';
6+
7+
export let label: string;
8+
export let value: number;
9+
export let couponData: Partial<Coupon> = {
10+
code: null,
11+
status: null,
12+
credits: null
13+
};
14+
15+
let adjustedValue = value;
16+
17+
$: if (label?.toLowerCase() === 'credits' && couponData?.status === 'active') {
18+
adjustedValue = value - (couponData?.credits || 0);
19+
} else {
20+
adjustedValue = value;
21+
}
22+
</script>
23+
24+
{#if adjustedValue > 0}
25+
<Layout.Stack direction="row" justifyContent="space-between">
26+
<Layout.Stack inline direction="row" gap="xxs" alignItems="center" alignContent="center">
27+
<Icon icon={IconTag} color="--fgcolor-success" size="s" />
28+
<Typography.Text color="--fgcolor-neutral-primary">{label}</Typography.Text>
29+
</Layout.Stack>
30+
{#if value >= 100}
31+
<Badge variant="secondary" content="Credits applied" />
32+
{:else}
33+
<Typography.Text color="--fgcolor-success"
34+
>-{formatCurrency(adjustedValue)}</Typography.Text>
35+
{/if}
36+
</Layout.Stack>
37+
{/if}

src/lib/components/billing/estimatedTotalBox.svelte

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { CreditsApplied } from '.';
88
import { sdk } from '$lib/stores/sdk';
99
import { AppwriteException } from '@appwrite.io/console';
10+
import DiscountsApplied from './discountsApplied.svelte';
1011
1112
export let billingPlan: Tier;
1213
export let collaborators: string[];
@@ -35,7 +36,8 @@
3536
if (
3637
e.type === 'billing_coupon_not_found' ||
3738
e.type === 'billing_coupon_already_used' ||
38-
e.type === 'billing_credit_unsupported'
39+
e.type === 'billing_credit_unsupported' ||
40+
e.type === 'billing_coupon_not_eligible'
3941
) {
4042
couponData = {
4143
code: null,
@@ -65,7 +67,8 @@
6567
if (
6668
e.type === 'billing_coupon_not_found' ||
6769
e.type === 'billing_coupon_already_used' ||
68-
e.type === 'billing_credit_unsupported'
70+
e.type === 'billing_credit_unsupported' ||
71+
e.type === 'billing_coupon_not_eligible'
6972
) {
7073
couponData = {
7174
code: null,
@@ -80,13 +83,6 @@
8083
$: organizationId
8184
? getUpdatePlanEstimate(organizationId, billingPlan, collaborators, couponData?.code)
8285
: getEstimate(billingPlan, collaborators, couponData?.code);
83-
84-
$: estimatedTotal =
85-
couponData?.status === 'active'
86-
? estimation?.grossAmount - couponData.credits >= 0
87-
? estimation?.grossAmount - couponData.credits
88-
: 0
89-
: estimation?.grossAmount;
9086
</script>
9187

9288
{#if estimation}
@@ -102,6 +98,9 @@
10298
>{formatCurrency(item.value)}</Typography.Text>
10399
</Layout.Stack>
104100
{/each}
101+
{#each estimation.discounts ?? [] as item}
102+
<DiscountsApplied {couponData} {...item} />
103+
{/each}
105104

106105
{#if couponData?.status === 'active'}
107106
<CreditsApplied bind:couponData {fixedCoupon} />
@@ -110,15 +109,15 @@
110109
<Layout.Stack direction="row" justifyContent="space-between">
111110
<Typography.Text>Total due</Typography.Text>
112111
<Typography.Text>
113-
{formatCurrency(estimatedTotal)}
112+
{formatCurrency(estimation.grossAmount)}
114113
</Typography.Text>
115114
</Layout.Stack>
116115

117116
<Typography.Text>
118-
You'll pay <b>{formatCurrency(estimatedTotal)}</b>
117+
You'll pay <b>{formatCurrency(estimation.grossAmount)}</b>
119118
now.
120119
{#if couponData?.code}Once your credits run out,{:else}Then{/if} you'll be charged
121-
<b>{formatCurrency(estimation.grossAmount)}</b> every 30 days.
120+
<b>{formatCurrency(estimation.amount)}</b> every 30 days.
122121
</Typography.Text>
123122

124123
<InputChoice

src/lib/components/dualTimeView.svelte

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@
9797
<Layout.Stack gap="s" alignContent="flex-start">
9898
<!-- `Raw time` as per design -->
9999
<Typography.Caption color="--fgcolor-neutral-tertiary" variant="400">
100-
{timeToString}
100+
{#if $$slots.title}
101+
<slot name="title" />
102+
{:else}
103+
{timeToString}
104+
{/if}
101105
</Typography.Caption>
102106

103107
<!-- `Absolute time` as per design -->

src/lib/components/expirationInput.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,10 @@
129129
bind:value={expirationSelect} />
130130

131131
{#if expirationSelect === 'custom'}
132-
<InputDateTime required id="expire" label={dateSelectorLabel} bind:value={expirationCustom} />
132+
<InputDateTime
133+
required
134+
type="date"
135+
id="expire"
136+
label={dateSelectorLabel}
137+
bind:value={expirationCustom} />
133138
{/if}

src/lib/components/git/repositories.svelte

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import { sdk } from '$lib/stores/sdk';
66
import { repositories } from '$routes/(console)/project-[region]-[project]/functions/function-[function]/store';
77
import { installation, installations, repository } from '$lib/stores/vcs';
8+
import { isSmallViewport } from '$lib/stores/viewport';
89
import {
910
Layout,
1011
Table,
@@ -49,7 +50,9 @@
4950
async function loadInstallations() {
5051
if (installationList) {
5152
if (installationList.installations.length) {
52-
untrack(() => (selectedInstallation = installationList.installations[0].$id));
53+
if (!selectedInstallation) {
54+
untrack(() => (selectedInstallation = installationList.installations[0].$id));
55+
}
5356
installation.set(
5457
installationList.installations.find(
5558
(entry) => entry.$id === selectedInstallation
@@ -62,7 +65,9 @@
6265
.forProject(page.params.region, page.params.project)
6366
.vcs.listInstallations();
6467
if (installations.length) {
65-
untrack(() => (selectedInstallation = installations[0].$id));
68+
if (!selectedInstallation) {
69+
untrack(() => (selectedInstallation = installationList.installations[0].$id));
70+
}
6671
installation.set(installations.find((entry) => entry.$id === selectedInstallation));
6772
}
6873
return installations;
@@ -133,7 +138,7 @@
133138
<InputSearch placeholder="Search repositories" disabled />
134139
</Layout.Stack>
135140
{:then installations}
136-
<Layout.Stack direction="row">
141+
<Layout.Stack direction={$isSmallViewport ? 'column' : 'row'}>
137142
<InputSelect
138143
id="installation"
139144
options={[
@@ -233,39 +238,43 @@
233238
<Layout.Stack
234239
gap="s"
235240
direction="row"
236-
alignItems="center">
237-
<Typography.Text
238-
truncate
239-
color="--fgcolor-neutral-secondary">
240-
{repo.name}
241-
</Typography.Text>
242-
{#if repo.private}
243-
<Icon
244-
size="s"
245-
icon={IconLockClosed}
246-
color="--fgcolor-neutral-tertiary" />
247-
{/if}
248-
<time datetime={repo.pushedAt}>
249-
<Typography.Caption
250-
variant="400"
251-
truncate
252-
color="--fgcolor-neutral-tertiary">
253-
{timeFromNow(repo.pushedAt)}
254-
</Typography.Caption>
255-
</time>
256-
</Layout.Stack>
257-
{#if action === 'button'}
241+
alignItems="center"
242+
justifyContent="space-between">
258243
<Layout.Stack
259244
direction="row"
260-
justifyContent="flex-end">
245+
gap="s"
246+
alignItems="center">
247+
<Typography.Text
248+
truncate
249+
color="--fgcolor-neutral-secondary">
250+
{repo.name}
251+
</Typography.Text>
252+
{#if repo.private}
253+
<Icon
254+
size="s"
255+
icon={IconLockClosed}
256+
color="--fgcolor-neutral-tertiary" />
257+
{/if}
258+
{#if !$isSmallViewport}
259+
<time datetime={repo.pushedAt}>
260+
<Typography.Caption
261+
variant="400"
262+
truncate
263+
color="--fgcolor-neutral-tertiary">
264+
{timeFromNow(repo.pushedAt)}
265+
</Typography.Caption>
266+
</time>
267+
{/if}
268+
</Layout.Stack>
269+
{#if action === 'button'}
261270
<PinkButton.Button
262271
size="xs"
263272
variant="secondary"
264273
on:click={() => connect(repo)}>
265274
Connect
266275
</PinkButton.Button>
267-
</Layout.Stack>
268-
{/if}
276+
{/if}
277+
</Layout.Stack>
269278
</Layout.Stack>
270279
</Table.Cell>
271280
</Table.Row.Base>

src/lib/components/paginationInline.svelte

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
}
3636
}
3737
38+
const none = undefined as never;
39+
3840
// function pagination(page: number, total: number) {
3941
// const pagesShown = 5;
4042
// const start = Math.max(
@@ -56,11 +58,11 @@
5658
{#if !hidePages}
5759
<Pagination
5860
{limit}
59-
page={currentPage}
6061
{total}
6162
type="button"
62-
on:page={handleOptionClick}
63-
createLink={undefined as never} />
63+
createLink={none}
64+
page={currentPage}
65+
on:page={handleOptionClick} />
6466
{:else}
6567
<Layout.Stack direction="row" inline>
6668
<Button.Button

src/lib/components/permissions/team.svelte

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
Layout,
1313
Link,
1414
Selector,
15+
Spinner,
1516
Table,
1617
Typography
1718
} from '@appwrite.io/pink-svelte';
@@ -24,9 +25,10 @@
2425
2526
let search = '';
2627
let offset = 0;
27-
let results: Models.TeamList<Record<string, unknown>>;
28-
let selected: Set<string> = new Set();
28+
let isLoading = false;
2929
let hasSelection = false;
30+
let selected: Set<string> = new Set();
31+
let results: Models.TeamList<Record<string, unknown>>;
3032
3133
function reset() {
3234
offset = 0;
@@ -41,9 +43,11 @@
4143
4244
async function request() {
4345
if (!show) return;
46+
isLoading = true;
4447
results = await sdk
4548
.forProject(page.params.region, page.params.project)
4649
.teams.list([Query.limit(5), Query.offset(offset)], search || undefined);
50+
isLoading = false;
4751
}
4852
4953
function onSelection(role: string) {
@@ -71,23 +75,24 @@
7175
</script>
7276

7377
<Modal title="Select teams" bind:show onSubmit={create} on:close={reset}>
74-
<Typography.Text
78+
<Typography.Text slot="description"
7579
>Grant access to any member of a specific team. To grant access to team members with
7680
specific roles, you will need to set a <Link.Button on:click={() => dispatch('custom')}
7781
>custom permission</Link.Button
7882
>.</Typography.Text>
7983
<InputSearch autofocus placeholder="Search by name or ID" bind:value={search} />
8084
{#if results?.teams?.length}
81-
<Table.Root columns={[{ id: 'checkbox', width: 40 }, { id: 'team' }]} let:root>
85+
<Table.Root columns={[{ id: 'checkbox', width: 20 }, { id: 'team' }]} let:root>
8286
{#each results.teams as team (team.$id)}
8387
{@const role = `team:${team.$id}`}
8488
{@const exists = $groups.has(role)}
8589
<Table.Row.Button {root} on:click={() => onSelection(role)} disabled={exists}>
8690
<Table.Cell column="checkbox" {root}>
8791
<Selector.Checkbox
92+
size="s"
8893
id={team.$id}
89-
checked={exists || selected.has(role)}
90-
disabled={exists} />
94+
disabled={exists}
95+
checked={exists || selected.has(role)} />
9196
</Table.Cell>
9297
<Table.Cell column="team" {root}>
9398
<Layout.Stack direction="row" alignItems="center" gap="s">
@@ -105,10 +110,16 @@
105110
</Table.Row.Button>
106111
{/each}
107112
</Table.Root>
108-
<div class="u-flex u-margin-block-start-32 u-main-space-between">
113+
114+
<Layout.Stack direction="row" justifyContent="space-between" alignItems="center">
109115
<p class="text">Total results: {results?.total}</p>
110-
<PaginationInline limit={5} bind:offset total={results?.total} hidePages />
111-
</div>
116+
<PaginationInline
117+
limit={5}
118+
bind:offset
119+
total={results?.total}
120+
hidePages
121+
on:change={request} />
122+
</Layout.Stack>
112123
{:else if search}
113124
<EmptySearch bind:search target="teams" hidePages>
114125
<Button
@@ -119,6 +130,11 @@
119130
size="s">Documentation</Button>
120131
<Button secondary on:click={() => (search = '')}>Clear search</Button>
121132
</EmptySearch>
133+
{:else if isLoading}
134+
<!-- 275px nearly matches the height of at-least 5 items in the table above -->
135+
<div style:margin-inline="auto" style:min-height="275px" style:align-content="center">
136+
<Spinner size="m" />
137+
</div>
122138
{:else}
123139
<Card.Base padding="none">
124140
<Empty title="You have no teams. Create a team to see them here." type="secondary">

0 commit comments

Comments
 (0)