Skip to content
This repository was archived by the owner on Sep 21, 2026. It is now read-only.

Commit 0800d03

Browse files
committed
Merge branch 'feat-profiles' into fix-studio-billing
2 parents c7efd07 + cb397f2 commit 0800d03

7 files changed

Lines changed: 61 additions & 30 deletions

File tree

‎src/lib/components/billing/gradientBanner.svelte‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import { IconX } from '@appwrite.io/pink-icons-svelte';
66
import { isTabletViewport } from '$lib/stores/viewport';
77
import PinkBackground from '$lib/images/pink-background.svg';
8-
import { bannerSpacing } from '$lib/layout/headerAlert.svelte';
98
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
9+
import { headerAlert } from '$lib/stores/headerAlert';
10+
import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte';
1011
1112
export let variant: 'gradient' | 'image' = 'gradient';
1213
@@ -16,12 +17,13 @@
1617
const queryLayoutElements = () => ({
1718
header: document.querySelector<HTMLElement>('main > header'),
1819
sidebar: document.querySelector<HTMLElement>('main > div > nav'),
19-
content: document.querySelector<HTMLElement>('main > div > section')
20+
content: document.querySelector<HTMLElement>('main > div > section'),
21+
contentDiv: document.querySelector<HTMLElement>('main > .content')
2022
});
2123
2224
const setNavigationHeight = () => {
2325
const alertHeight = container?.getBoundingClientRect()?.height || 0;
24-
const { header, sidebar, content } = queryLayoutElements();
26+
const { header, sidebar, content, contentDiv } = queryLayoutElements();
2527
const headerHeight = header?.getBoundingClientRect().height || 0;
2628
const offset = alertHeight + (!$isTabletViewport && header ? headerHeight : 0);
2729
@@ -34,12 +36,18 @@
3436
sidebar.style.height = `calc(100vh - ${offset}px)`;
3537
3638
// for sidebar and sub-navigation!
37-
bannerSpacing.set(`${alertHeight}px`);
39+
headerAlert.setTopSpacing(alertHeight);
3840
}
3941
4042
if (content) {
4143
content.style.paddingBlockStart = `${alertHeight}px`;
4244
}
45+
46+
if (contentDiv && resolvedProfile.id === ProfileMode.STUDIO) {
47+
const headerHeight = header?.getBoundingClientRect().height ?? 48;
48+
// push the content enough to show the borders of the content view!
49+
contentDiv.style.marginBlockStart = `${alertHeight + headerHeight}px`;
50+
}
4351
};
4452
4553
onMount(setNavigationHeight);

‎src/lib/components/navbar.svelte‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import type { Models } from '@appwrite.io/console';
5858
import { organization } from '$lib/stores/organization';
5959
import { resolvedProfile } from '$lib/profiles/index.svelte';
60+
import { headerAlert } from '$lib/stores/headerAlert';
6061
6162
let showSupport = false;
6263
@@ -120,7 +121,7 @@
120121
beforeNavigate(() => (showAccountMenu = false));
121122
</script>
122123

123-
<Navbar.Base --border-width-s="none">
124+
<Navbar.Base --border-width-s="none" style="top: {$headerAlert.top}px; z-index: 100;">
124125
<div slot="left" class="left">
125126
<div class="only-mobile-tablet">
126127
<button

‎src/lib/components/sidebar.svelte‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@
3737
import { getSidebarState, isInDatabasesRoute, updateSidebarState } from '$lib/helpers/sidebar';
3838
import { isSmallViewport, isTabletViewport } from '$lib/stores/viewport';
3939
import { Click, trackEvent } from '$lib/actions/analytics';
40-
import { bannerSpacing } from '$lib/layout/headerAlert.svelte';
4140
42-
import type { HTMLAttributes } from 'svelte/elements';
41+
import { base } from '$app/paths';
4342
import type { Models } from '@appwrite.io/console';
43+
import type { HTMLAttributes } from 'svelte/elements';
44+
import { headerAlert } from '$lib/stores/headerAlert';
4445
import { noWidthTransition } from '$lib/stores/sidebar';
45-
import { base } from '$app/paths';
4646
import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte';
4747
4848
type Props = HTMLAttributes<HTMLElement> & {
@@ -127,7 +127,8 @@
127127
{...rest}
128128
bind:state
129129
on:resize={(event) => updateSidebarState(event.detail)}
130-
resizable={resolvedProfile.id !== ProfileMode.STUDIO}>
130+
resizable={resolvedProfile.id !== ProfileMode.STUDIO}
131+
style="padding-block-start: {$headerAlert.top}px">
131132
<div slot="top">
132133
<div class="only-mobile-tablet top">
133134
<div class="icons search-icon">
@@ -399,7 +400,7 @@
399400
</Sidebar.Base>
400401
</div>
401402

402-
<div style:--banner-spacing={$bannerSpacing ? $bannerSpacing : undefined}>
403+
<div style:--banner-spacing={$headerAlert.top ? `${$headerAlert.top}px` : undefined}>
403404
{#if subNavigation}
404405
{@const SubNavigation = subNavigation}
405406
<div

‎src/lib/layout/headerAlert.svelte‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
<script module lang="ts">
2-
import { writable } from 'svelte/store';
3-
4-
export const bannerSpacing = writable<string | null>(null);
5-
</script>
6-
71
<script lang="ts">
82
import { onDestroy, onMount } from 'svelte';
93
import { isTabletViewport } from '$lib/stores/viewport';
@@ -12,6 +6,8 @@
126
import { Icon } from '@appwrite.io/pink-svelte';
137
import { IconX } from '@appwrite.io/pink-icons-svelte';
148
import { afterNavigate } from '$app/navigation';
9+
import { headerAlert } from '$lib/stores/headerAlert';
10+
import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte';
1511
1612
export let title: string;
1713
export let type: 'info' | 'success' | 'warning' | 'error' | 'default' = 'info';
@@ -31,12 +27,13 @@
3127
const header: HTMLHeadingElement = document.querySelector('main > header');
3228
const sidebar: HTMLElement = document.querySelector('main > div > nav');
3329
const contentSection: HTMLElement = document.querySelector('main > div > section');
30+
const contentDiv: HTMLElement = document.querySelector('main > .content');
3431
3532
if (alertHeight) {
3633
// for sidebar and sub-navigation!
37-
bannerSpacing.set(`${alertHeight}px`);
34+
headerAlert.setTopSpacing(alertHeight);
3835
} else {
39-
bannerSpacing.set(undefined);
36+
headerAlert.setTopSpacing(0);
4037
}
4138
4239
if (header) {
@@ -54,6 +51,12 @@
5451
if (contentSection) {
5552
contentSection.style.paddingBlockStart = `${alertHeight}px`;
5653
}
54+
55+
if (contentDiv && resolvedProfile.id === ProfileMode.STUDIO) {
56+
const headerHeight = header?.getBoundingClientRect().height ?? 48;
57+
// push the content enough to show the borders of the content view!
58+
contentDiv.style.marginBlockStart = `${alertHeight + headerHeight}px`;
59+
}
5760
}
5861
5962
onMount(() => {

‎src/lib/stores/headerAlert.ts‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Component } from 'svelte';
2-
import { writable } from 'svelte/store';
2+
import { writable, type Readable } from 'svelte/store';
33

44
export type HeaderAlert = {
55
id: string;
@@ -9,11 +9,21 @@ export type HeaderAlert = {
99
};
1010

1111
export type HeaderAlertStore = {
12+
top: number;
1213
components: HeaderAlert[];
1314
};
1415

15-
function createHeaderAlertStore() {
16-
const { subscribe, update, set } = writable<HeaderAlertStore>({
16+
export type HeaderAlertStoreType = Readable<HeaderAlertStore> & {
17+
set: (value: HeaderAlertStore) => void;
18+
add: (component: HeaderAlert) => void;
19+
get: () => HeaderAlert;
20+
setTopSpacing: (value: number) => void;
21+
getTopSpacing: () => number;
22+
};
23+
24+
function createHeaderAlertStore(): HeaderAlertStoreType {
25+
const { set, update, subscribe } = writable<HeaderAlertStore>({
26+
top: 0,
1727
components: []
1828
});
1929

@@ -48,14 +58,23 @@ function createHeaderAlertStore() {
4858
});
4959
return component as HeaderAlert;
5060
},
51-
isShowing: (): boolean => {
52-
let showing = false;
61+
setTopSpacing: (value: number) => {
62+
update((n) => {
63+
return {
64+
...n,
65+
top: value
66+
};
67+
});
68+
},
69+
getTopSpacing: (): number => {
70+
let top = 0;
5371
update((n) => {
5472
if (n.components.length === 0) return n;
55-
showing = n.components.some((c) => c.show);
73+
top = n.top;
5674
return n;
5775
});
58-
return showing;
76+
77+
return top;
5978
}
6079
};
6180
}

‎src/lib/studio/studio-widget.ts‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { headerAlert } from '$lib/stores/headerAlert';
1212

1313
const COMPONENT_SELECTOR = 'imagine-web-components-wrapper[data-appwrite-studio]';
1414
const STYLE_ATTRIBUTE = 'data-appwrite-studio-style';
15-
const BLOCK_BANNER_OFFSET = 24;
1615
const BLOCK_START_BASE_OFFSET = 48;
1716
export const CDN_URL = env?.PUBLIC_IMAGINE_CDN_URL + '/web-components.js';
1817
export const CDN_CSS_URL = env?.PUBLIC_IMAGINE_CDN_URL + '/web-components.css';
@@ -196,7 +195,7 @@ function updatePosition() {
196195
return;
197196
}
198197

199-
const bannerOffset = headerAlert.isShowing() ? BLOCK_BANNER_OFFSET : 0;
198+
const bannerOffset = headerAlert.getTopSpacing();
200199

201200
const rect = anchorElement.getBoundingClientRect();
202201
const { offsetX, offsetY } = currentOptions;

‎src/routes/(console)/project-[region]-[project]/databases/database-[database]/subNavigation.svelte‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import { page } from '$app/state';
44
import type { PageData } from './$types';
55
import { showSubNavigation } from '$lib/stores/layout';
6-
import { bannerSpacing } from '$lib/layout/headerAlert.svelte';
76
import { showCreateTable, databaseSubNavigationItems } from './store';
87
98
import {
@@ -28,6 +27,7 @@
2827
import { sdk } from '$lib/stores/sdk';
2928
import { onMount } from 'svelte';
3029
import { subNavigation } from '$lib/stores/database';
30+
import { headerAlert } from '$lib/stores/headerAlert';
3131
3232
const data = $derived(page.data) as PageData;
3333
@@ -58,8 +58,8 @@
5858
// If banner open, adjust bottom position to account for banner container.
5959
// 70.5px is the size of the container of the banner holder and not just the banner!
6060
// Needed because things vary a bit much on how different browsers treat bottom layouts.
61-
const bottomNavOffset = $derived($bannerSpacing ? '70.5px' : '0px');
62-
const tableContentPadding = $derived($bannerSpacing ? '210px' : '140px');
61+
const bottomNavOffset = $derived($headerAlert.top !== 0 ? '70.5px' : '0px');
62+
const tableContentPadding = $derived($headerAlert.top !== 0 ? '210px' : '140px');
6363
6464
async function loadTables() {
6565
tables = await sdk.forProject(region, project).tablesDB.listTables({

0 commit comments

Comments
 (0)