diff --git a/src/lib/components/git/repositories.svelte b/src/lib/components/git/repositories.svelte index 45bbd55a2..393f187f3 100644 --- a/src/lib/components/git/repositories.svelte +++ b/src/lib/components/git/repositories.svelte @@ -23,7 +23,8 @@ import { page } from '$app/state'; import Card from '../card.svelte'; import SkeletonRepoList from './skeletonRepoList.svelte'; - import { onMount, untrack } from 'svelte'; + import { onMount, untrack, onDestroy } from 'svelte'; + import { debounce } from '$lib/helpers/debounce'; let { action = $bindable('select'), @@ -52,6 +53,28 @@ loadInstallations(); }); + const debouncedLoadRepositories = debounce( + async (installationId: string, searchTerm: string) => { + isLoadingRepositories = true; + try { + await loadRepositories(installationId, searchTerm); + } finally { + isLoadingRepositories = false; + } + }, + 300 + ); + + $effect(() => { + if (selectedInstallation && search !== undefined) { + debouncedLoadRepositories(selectedInstallation, search); + } + }); + + onDestroy(() => { + debouncedLoadRepositories.cancel(); + }); + async function loadInstallations() { if (installationList) { if (installationList.installations.length) { @@ -71,7 +94,7 @@ .vcs.listInstallations(); if (installations.length) { if (!selectedInstallation) { - untrack(() => (selectedInstallation = installationList.installations[0].$id)); + untrack(() => (selectedInstallation = installations[0].$id)); } installation.set(installations.find((entry) => entry.$id === selectedInstallation)); } @@ -80,22 +103,6 @@ } async function loadRepositories(installationId: string, search: string) { - if ( - !$repositories || - $repositories.installationId !== installationId || - $repositories.search !== search - ) { - await fetchRepos(installationId, search); - } - - if ($repositories.repositories.length && action === 'select') { - selectedRepository = $repositories.repositories[0].id; - $repository = $repositories.repositories[0]; - } - return $repositories.repositories; - } - - async function fetchRepos(installationId: string, search: string) { if (product === 'functions') { $repositories.repositories = ( (await sdk @@ -117,9 +124,9 @@ )) as unknown as Models.ProviderRepositoryFrameworkList ).frameworkProviderRepositories; } - $repositories.search = search; $repositories.installationId = installationId; + return $repositories.repositories; } selectedRepository; @@ -168,10 +175,7 @@ installationsMap.find((entry) => entry.$id === selectedInstallation) ); - isLoadingRepositories = true; - loadRepositories(selectedInstallation, search).then(() => { - isLoadingRepositories = false; - }); + debouncedLoadRepositories.cancel(); }} bind:value={selectedInstallation} /> {#if isLoadingRepositories} - {:else} - {#await loadRepositories(selectedInstallation, search)} - - {:then response} - {#if response?.length} - - {#snippet children( - paginatedItems: Models.ProviderRepositoryRuntime[] & - Models.ProviderRepositoryFramework[] - )} - - {#each paginatedItems as repo} - - + {:else if $repositories?.repositories?.length} + + {#snippet children( + paginatedItems: Models.ProviderRepositoryRuntime[] & + Models.ProviderRepositoryFramework[] + )} + + {#each paginatedItems as repo} + + + + {#if action === 'select'} + repository.set(repo)} + value={repo.id} /> + {/if} + {#if product === 'sites'} + {#if repo?.framework && repo.framework !== 'other'} + + + + {:else} + + {/if} + {:else} + {@const iconName = repo?.runtime + ? repo.runtime.split('-')[0] + : undefined} + + + + {/if} + connect(repo)}> Connect + gap="s" + alignItems="center"> + + {repo.name} + + {#if repo.private} + + {/if} + {#if !$isSmallViewport} + {/if} - - - {/each} - - {/snippet} - - {:else if search} - - - {#if search} - - {/if} - - - {:else} - - - - No repositories available - - - - {/if} - {/await} + {#if action === 'button'} + connect(repo)}> + Connect + + {/if} + + + + + {/each} + + {/snippet} + + {:else if search} + + + {#if search} + + {/if} + + + {:else} + + + + No repositories available + + + {/if} {/if} diff --git a/src/lib/images/promos/database-upsert-dark.png b/src/lib/images/promos/database-upsert-dark.png new file mode 100644 index 000000000..bd1e094e9 Binary files /dev/null and b/src/lib/images/promos/database-upsert-dark.png differ diff --git a/src/lib/images/promos/database-upsert-light.png b/src/lib/images/promos/database-upsert-light.png new file mode 100644 index 000000000..4834c15a8 Binary files /dev/null and b/src/lib/images/promos/database-upsert-light.png differ diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index e9a39a717..91b75e75e 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -7,6 +7,8 @@ import BulkApiLight from '$lib/images/promos/bulk-api-light.png'; import CSVImportDark from '$lib/images/promos/csv-import-placeholder-dark.png'; import CSVImportLight from '$lib/images/promos/csv-import-placeholder-light.png'; +import DatabaseUpsertDark from '$lib/images/promos/database-upsert-dark.png'; +import DatabaseUpsertLight from '$lib/images/promos/database-upsert-light.png'; const listOfPromotions: BottomModalAlertItem[] = []; @@ -52,8 +54,27 @@ if (isCloud) { }, show: true }; + const databaseUpsert: BottomModalAlertItem = { + id: 'modal:database_upsert_announcement', + src: { + dark: DatabaseUpsertDark, + light: DatabaseUpsertLight + }, + title: 'Introducing Database Upsert', + message: 'A new Appwrite Database feature, built to simplify your database interactions.', + plan: 'free', + importance: 8, + scope: 'project', + cta: { + text: 'Read announcement', + link: () => 'https://appwrite.io/blog/post/announcing-database-upsert', + external: true, + hideOnClick: true + }, + show: true + }; - listOfPromotions.push(bulkApiPromo, csvImportPromo); + listOfPromotions.push(databaseUpsert, bulkApiPromo, csvImportPromo); } export function addBottomModalAlerts() { diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/relationshipsModal.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/relationshipsModal.svelte index 843644ccb..ed42e78a2 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/relationshipsModal.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/relationshipsModal.svelte @@ -23,7 +23,11 @@ selectedRelationship = null; } - $: tableColumns = [{ id: '$id', width: 200 }, ...args.map((id) => ({ id }))]; + $: tableColumns = [ + // take full width if no display names set + { id: '$id', width: args.length ? 200 : undefined }, + ...args.map((id) => ({ id })) + ]; @@ -33,7 +37,7 @@ Document ID - {#if args?.length} + {#if args.length} {#each args as arg} {arg} {/each} @@ -47,7 +51,7 @@ {doc.$id} - {#if args?.length} + {#if args.length} {#each args as arg} {doc[arg]} {/each} diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/settings/displayName.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/settings/displayName.svelte index 46b972b03..e4d909525 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/settings/displayName.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/settings/displayName.svelte @@ -73,7 +73,9 @@ (names?.length && !last(names)) ); - const hasExhaustedOptions = $derived(getValidAttributes().length === names?.length); + const hasExhaustedOptions = $derived( + getValidAttributes().length === names.filter(Boolean).length + );
diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/settingsFormInput.svelte b/src/routes/(console)/project-[region]-[project]/messaging/providers/settingsFormInput.svelte index 411420a6b..afa62b44f 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/settingsFormInput.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/settingsFormInput.svelte @@ -24,8 +24,7 @@ APNSProviderParams } from './store'; import TooltipPopover from './tooltipPopover.svelte'; - import { Icon, Tooltip, Upload, Layout, Typography } from '@appwrite.io/pink-svelte'; - import { IconInfo } from '@appwrite.io/pink-icons-svelte'; + import { Upload, Layout, Typography } from '@appwrite.io/pink-svelte'; import { InvalidFileType, removeFile } from '$lib/helpers/files'; import { addNotification } from '$lib/stores/notifications'; @@ -44,18 +43,6 @@ | FCMProviderParams | APNSProviderParams >; - const popover = input.popover ? PopoverContent : null; - const popoverProps = getPopoverProps(input); - - function getPopoverProps(input: ProviderInput) { - if (!input.popover) { - return {}; - } - return { - lines: input.popover, - image: input.popoverImage - }; - } function handleInvalid(e: CustomEvent) { const reason = e.detail?.reason ?? ''; @@ -72,6 +59,14 @@ }); } } + + $: popover = input.popover ? PopoverContent : null; + $: popoverProps = !input.popover + ? {} + : { + lines: input.popover, + image: input.popoverImage + }; {#if input.type === 'text'} @@ -122,25 +117,15 @@ {:else if input.type === 'file'} - - - - - Drag and drop service account JSON here or click to upload - - - - - - Only .json files allowed - - - Max file size 10MB - + + + Drag and drop your {input.label} here or click to upload + + {#if files[input.name]?.length} diff --git a/src/routes/(console)/project-[region]-[project]/messaging/providers/store.ts b/src/routes/(console)/project-[region]-[project]/messaging/providers/store.ts index 4d7d47402..985d93215 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/providers/store.ts +++ b/src/routes/(console)/project-[region]-[project]/messaging/providers/store.ts @@ -85,7 +85,7 @@ export const providers: ProvidersMap = { ], configure: [ { - label: 'Service account JSON (.json file)', + label: 'service account JSON (.json file)', name: 'serviceAccountJSON', type: 'file', allowedFileExtensions: ['json'], @@ -164,7 +164,7 @@ export const providers: ProvidersMap = { } }, { - label: 'Auth key (.p8 file)', + label: 'auth key (.p8 file)', name: 'authKey', type: 'file', allowedFileExtensions: ['p8'], diff --git a/src/routes/(console)/project-[region]-[project]/settings/webhooks/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/webhooks/+page.svelte index 3d642cd9e..2c02dc197 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/webhooks/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/webhooks/+page.svelte @@ -25,10 +25,6 @@ $: $updateCommandGroupRanks({ webhooks: 20, domains: 10 }); - - Webhooks - Appwrite - -