diff --git a/src/lib/components/billing/selectPaymentMethod.svelte b/src/lib/components/billing/selectPaymentMethod.svelte
index 7dfe14a2ed..9a7265c8b7 100644
--- a/src/lib/components/billing/selectPaymentMethod.svelte
+++ b/src/lib/components/billing/selectPaymentMethod.svelte
@@ -11,9 +11,9 @@
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
- export let methods: PaymentList;
export let value: string;
export let taxId = '';
+ export let methods: PaymentList;
let showTaxId = false;
let showPaymentModal = false;
diff --git a/src/lib/components/bottom-sheet/SheetMenuBlock.svelte b/src/lib/components/bottom-sheet/SheetMenuBlock.svelte
index a8d65c4be2..6bc3d2cab9 100644
--- a/src/lib/components/bottom-sheet/SheetMenuBlock.svelte
+++ b/src/lib/components/bottom-sheet/SheetMenuBlock.svelte
@@ -11,7 +11,7 @@
{#if menu?.title}
{/if}
-
+
{#each menu.items as menuItem}
{#if menuItem.href}
import { createMenubar, melt } from '@melt-ui/svelte';
- import { Badge, Icon, type SheetMenu, ActionMenu, Card } from '@appwrite.io/pink-svelte';
+ import {
+ Badge,
+ Icon,
+ type SheetMenu,
+ Layout,
+ ActionMenu,
+ Card,
+ Skeleton
+ } from '@appwrite.io/pink-svelte';
import {
IconChevronDown,
IconChevronRight,
@@ -14,20 +22,13 @@
import { base } from '$app/paths';
import { currentPlan, newOrgModal } from '$lib/stores/organization';
import { Click, trackEvent } from '$lib/actions/analytics';
- import { page } from '$app/stores';
+ import type { Models } from '@appwrite.io/console';
- type Project = {
- name: string;
- $id: string;
- isSelected: boolean;
- region: string;
- };
type Organization = {
name: string;
$id: string;
tierName: string;
isSelected: boolean;
- projects: Array;
};
const {
@@ -62,13 +63,15 @@
}
} = createMenu();
- export let organizations: Organization[] = [];
+ let isLoadingProjects = true;
+ let loadedProjects: Models.ProjectList = { total: 0, projects: [] };
- $: selectedOrg = organizations.find((organization) => organization.isSelected);
- $: selectedProject = $page.data.project;
+ export let organizations: Organization[] = [];
+ export let currentProject: Models.Project | null = null;
+ export let projects: Promise = Promise.resolve(loadedProjects);
- let organisationBottomSheetOpen = false;
let projectsBottomSheetOpen = false;
+ let organisationBottomSheetOpen = false;
function createOrg() {
trackEvent(Click.OrganizationClickCreate, { source: 'breadcrumbs' });
@@ -96,85 +99,76 @@
}
};
- $: organizationsBottomSheet = !selectedOrg
- ? switchOrganization
- : ({
- top: {
- items: [
- {
- name: 'Organization overview',
- href: `${base}/organization-${selectedOrg?.$id}`
- }
- ]
- },
- bottom:
- organizations.length > 1
- ? {
- items: [
- {
- name: 'Switch organization',
- trailingIcon: IconChevronRight,
- subMenu: switchOrganization
- }
- ]
- }
- : {
- items: [
- {
- name: 'Create organization',
- leadingIcon: IconPlus,
- onClick: createOrg
- }
- ]
- }
- } satisfies SheetMenu);
-
- $: projectsBottomSheet = {
- top:
- selectedOrg?.projects.length > 1
- ? {
- title: 'Switch project',
- items: !selectedOrg
- ? []
- : selectedOrg?.projects
- .map((project, index) => {
- if (index < 4) {
- return {
- name: project.name,
- href: `${base}/project-${project.region}-${project.$id}/overview`
- };
- } else if (index === 4) {
- return {
- name: 'All projects',
- href: `${base}/organization-${selectedOrg?.$id}`
- };
- }
- return null;
- })
- .filter((project) => project !== null)
- }
- : {
+ async function createProjectsBottomSheet(organization: Organization): Promise {
+ isLoadingProjects = true;
+ loadedProjects = await projects;
+ isLoadingProjects = false;
+
+ const createProjectItem = {
+ name: 'Create project',
+ trailingIcon: IconPlus,
+ href: `${base}/organization-${organization?.$id}?create-project`
+ };
+
+ if (loadedProjects.total > 1 && selectedOrg) {
+ const projectLinks = loadedProjects.projects.slice(0, 4).map((project) => ({
+ name: project.name,
+ href: `${base}/project-${project.region}-${project.$id}/overview/platforms`
+ }));
+
+ if (loadedProjects.projects.length > 4) {
+ projectLinks.push({
+ name: 'All projects',
+ href: `${base}/organization-${selectedOrg.$id}`
+ });
+ }
+
+ return {
+ top: { title: 'Switch project', items: projectLinks },
+ bottom: { items: [createProjectItem] }
+ };
+ }
+
+ return {
+ top: { items: [createProjectItem] },
+ bottom: { items: [createProjectItem] }
+ };
+ }
+
+ function createOrganizationBottomSheet(organization: Organization) {
+ return !organization
+ ? switchOrganization
+ : ({
+ top: {
items: [
{
- name: 'Create project',
- trailingIcon: IconPlus,
- href: `${base}/organization-${selectedOrg?.$id}?create-project`
+ name: 'Organization overview',
+ href: `${base}/organization-${organization?.$id}`
}
]
},
- bottom:
- selectedOrg?.projects.length > 1
- ? {
- items: [
- {
- name: 'Create project',
- trailingIcon: IconPlus,
- href: `${base}/organization-${selectedOrg?.$id}?create-project`
- }
- ]
- }
- : undefined
- } satisfies SheetMenu;
+ bottom:
+ organizations.length > 1
+ ? {
+ items: [
+ {
+ name: 'Switch organization',
+ trailingIcon: IconChevronRight,
+ subMenu: switchOrganization
+ }
+ ]
+ }
+ : {
+ items: [
+ {
+ name: 'Create organization',
+ leadingIcon: IconPlus,
+ onClick: createOrg
+ }
+ ]
+ }
+ } satisfies SheetMenu);
+ }
function onResize() {
if ((organisationBottomSheetOpen || projectsBottomSheetOpen) && !$isSmallViewport) {
@@ -183,6 +177,12 @@
}
}
+ $: selectedOrg = organizations.find((org) => org.isSelected);
+
+ $: projectsBottomSheet = createProjectsBottomSheet(selectedOrg);
+
+ $: organizationsBottomSheet = createOrganizationBottomSheet(selectedOrg);
+
$: correctPlanName =
// the plan names are hardcoded in some cases and are not available locally,
// so we rely on the plan's source of truth - `$currentPlan`
@@ -216,7 +216,7 @@
organisationBottomSheetOpen = true;
}}
aria-label="Open organizations tab">
- {selectedOrg?.name ?? 'Organization'}
@@ -296,7 +296,7 @@
- {#if selectedOrg && selectedProject}
+ {#if selectedOrg && currentProject}
/
{#if !$isSmallViewport}
{:else}
@@ -313,20 +313,28 @@
class="trigger"
on:click={() => (projectsBottomSheetOpen = true)}
aria-label="Open projects tab">
- {selectedProject.name}
+ {currentProject.name}
{/if}
+
-
+
+{#await projectsBottomSheet then menu}
+
+{/await}