From d36140a5608985e4d7fcca4bed96fcbfb5ca835c Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 11:24:36 +0200 Subject: [PATCH 01/10] Switch base url from /console to /studio --- Dockerfile | 4 ++- docker/{nginx.conf => nginx.console.conf} | 0 docker/nginx.studio.conf | 39 +++++++++++++++++++++++ package.json | 2 ++ pnpm-lock.yaml | 6 ++++ src/app.html | 6 ++-- src/hooks.server.ts | 23 ++++++++++++- src/routes/+layout.svelte | 4 +-- svelte.config.js | 5 ++- vite.config.ts | 2 +- 10 files changed, 82 insertions(+), 9 deletions(-) rename docker/{nginx.conf => nginx.console.conf} (100%) create mode 100644 docker/nginx.studio.conf diff --git a/Dockerfile b/Dockerfile index 2730dccb9..a605e47e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,12 +24,14 @@ ARG PUBLIC_APPWRITE_ENDPOINT ARG PUBLIC_GROWTH_ENDPOINT ARG PUBLIC_STRIPE_KEY ARG SENTRY_AUTH_TOKEN +ARG PUBLIC_PROJECT_PROFILE ENV PUBLIC_APPWRITE_ENDPOINT=$PUBLIC_APPWRITE_ENDPOINT ENV PUBLIC_GROWTH_ENDPOINT=$PUBLIC_GROWTH_ENDPOINT ENV PUBLIC_CONSOLE_MODE=$PUBLIC_CONSOLE_MODE ENV PUBLIC_STRIPE_KEY=$PUBLIC_STRIPE_KEY ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN +ENV PUBLIC_PROJECT_PROFILE=$PUBLIC_PROJECT_PROFILE ENV NODE_OPTIONS=--max_old_space_size=8192 RUN pnpm run build @@ -38,5 +40,5 @@ FROM nginx:1.25-alpine EXPOSE 80 -COPY docker/nginx.conf /etc/nginx/conf.d/default.conf +COPY docker/nginx.$PUBLIC_PROJECT_PROFILE.conf /etc/nginx/conf.d/default.conf COPY --from=build /app/build /usr/share/nginx/html/console \ No newline at end of file diff --git a/docker/nginx.conf b/docker/nginx.console.conf similarity index 100% rename from docker/nginx.conf rename to docker/nginx.console.conf diff --git a/docker/nginx.studio.conf b/docker/nginx.studio.conf new file mode 100644 index 000000000..1110b3b06 --- /dev/null +++ b/docker/nginx.studio.conf @@ -0,0 +1,39 @@ +map $sent_http_content_type $expires { + # cache everything for 1 year + default 1y; + # html files shouldn't be cached for single-page applications + text/html off; +} + +server { + listen 80; + server_name localhost; + + # serve compressed file if filename.gz exists + gzip_static on; + + location /studio { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri /studio/index.html; + + # Add cache headers + expires $expires; + add_header Pragma public; + add_header Cache-Control "public"; + + # Deny IE browsers from going into quirks mode + add_header X-UA-Compatible "IE=Edge"; + # X-Frame-Options is to prevent from clickJacking attack + add_header X-Frame-Options SAMEORIGIN; + # This header enables the Cross-site scripting (XSS) filter + add_header X-XSS-Protection "1; mode=block;"; + # disable content-type sniffing on some browsers. + add_header X-Content-Type-Options nosniff; + } + + location / { + absolute_redirect off; + return 301 /studio; + } +} \ No newline at end of file diff --git a/package.json b/package.json index 918029efb..cb3b5b87a 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "cron-parser": "^4.9.0", "dayjs": "^1.11.13", "deep-equal": "^2.2.3", + "dotenv": "^16.4.7", "echarts": "^5.6.0", "envfile": "^7.1.0", "ignore": "^6.0.2", @@ -47,6 +48,7 @@ }, "devDependencies": { "@eslint/compat": "^1.2.7", + "@eslint/js": "^9.23.0", "@melt-ui/pp": "^0.3.2", "@melt-ui/svelte": "^0.86.5", "@playwright/test": "^1.51.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aec88b29b..f0f349ed7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: deep-equal: specifier: ^2.2.3 version: 2.2.3 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 echarts: specifier: ^5.6.0 version: 5.6.0 @@ -84,6 +87,9 @@ importers: '@eslint/compat': specifier: ^1.2.7 version: 1.2.7(eslint@9.23.0) + '@eslint/js': + specifier: ^9.23.0 + version: 9.23.0 '@melt-ui/pp': specifier: ^0.3.2 version: 0.3.2(@melt-ui/svelte@0.86.5(svelte@5.25.3))(svelte@5.25.3) diff --git a/src/app.html b/src/app.html index 18a92b1fa..675d85d59 100644 --- a/src/app.html +++ b/src/app.html @@ -5,9 +5,9 @@ - - - + + + %sveltekit.head% diff --git a/src/hooks.server.ts b/src/hooks.server.ts index e54c183db..8c17e3e98 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -2,6 +2,7 @@ import { sequence } from '@sveltejs/kit/hooks'; import { handleErrorWithSentry, sentryHandle } from '@sentry/sveltekit'; import * as Sentry from '@sentry/sveltekit'; import { isCloud, isProd } from '$lib/system'; +import type { Handle } from '@sveltejs/kit'; Sentry.init({ enabled: isCloud && isProd, @@ -9,6 +10,26 @@ Sentry.init({ tracesSampleRate: 1.0 }); -export const handle = sequence(sentryHandle()); +const projectProfile = process.env.PUBLIC_PROJECT_PROFILE || 'console'; + +const dynamicHtmlTransform: Handle = async ({ event, resolve }) => { + let response = await resolve(event); + + if (response.headers.get('content-type')?.includes('text/html')) { + let html = await response.text(); + + // Replace '/console/' dynamically with the project profile + html = html.replace(/\/{project_profile}\//g, `/${projectProfile}/`); + + response = new Response(html, { + status: response.status, + headers: response.headers + }); + } + + return response; +}; + +export const handle = sequence(sentryHandle(), dynamicHtmlTransform); export const handleError = handleErrorWithSentry(); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 3a1dad550..1934a9047 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -149,14 +149,14 @@ {#each preloadFonts as font} {/each} - + {#if isCloud} {#each preloadFontsCloud as font} {/each} - + {/if} diff --git a/svelte.config.js b/svelte.config.js index 2939a3e1b..0c6a935ef 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,6 +1,9 @@ import adapter from '@sveltejs/adapter-static'; import { sveltePreprocess } from 'svelte-preprocess'; import { preprocessMeltUI, sequence } from '@melt-ui/pp'; +import 'dotenv/config'; + +const projectProfile = process.env.PUBLIC_PROJECT_PROFILE || 'console'; /** @type {import('@sveltejs/kit').Config} */ const config = { @@ -26,7 +29,7 @@ const config = { precompress: true }), paths: { - base: '/console' + base: `/${projectProfile}` } }, vitePlugin: { diff --git a/vite.config.ts b/vite.config.ts index d0a9f9bf0..47086a375 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,7 +12,7 @@ export default defineConfig({ project: 'console' } }), - sveltekit() + sveltekit(), ], optimizeDeps: { include: ['echarts', 'prismjs'] From ed7ee6430a4a050b997276d2b9e4ec8f99dcd6cb Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 12:45:36 +0200 Subject: [PATCH 02/10] Redirect to org on studio --- src/lib/system.ts | 10 +++++++++- .../(console)/organization-[organization]/+page.ts | 3 ++- .../organization-[organization]/billing/+page.ts | 3 ++- .../domain-[domain]/settings/changeOrganization.svelte | 3 ++- src/routes/(studio)/org-[organization]/+page.svelte | 1 + src/routes/+page.ts | 9 +++++++-- 6 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 src/routes/(studio)/org-[organization]/+page.svelte diff --git a/src/lib/system.ts b/src/lib/system.ts index 15f745577..8cd3a70f3 100644 --- a/src/lib/system.ts +++ b/src/lib/system.ts @@ -6,11 +6,17 @@ export const enum Mode { SELF_HOSTED = 'self-hosted' } +export const enum Profile { + CONSOLE = 'console', + STUDIO = 'studio' +} + export const VARS = { CONSOLE_MODE: (env.PUBLIC_CONSOLE_MODE as Mode) ?? undefined, APPWRITE_ENDPOINT: env.PUBLIC_APPWRITE_ENDPOINT ?? undefined, GROWTH_ENDPOINT: env.PUBLIC_GROWTH_ENDPOINT ?? undefined, - PUBLIC_STRIPE_KEY: env.PUBLIC_STRIPE_KEY ?? undefined + PUBLIC_STRIPE_KEY: env.PUBLIC_STRIPE_KEY ?? undefined, + PROJECT_PROFILE: (env.PUBLIC_PROJECT_PROFILE as Profile) ?? undefined }; export const ENV = { @@ -21,7 +27,9 @@ export const ENV = { }; export const MODE = VARS.CONSOLE_MODE === Mode.CLOUD ? Mode.CLOUD : Mode.SELF_HOSTED; +export const PROFILE = VARS.PROJECT_PROFILE === Profile.CONSOLE ? Profile.CONSOLE : Profile.STUDIO; export const isCloud = MODE === Mode.CLOUD; +export const isStudio = PROFILE === Profile.STUDIO; export const isSelfHosted = MODE !== Mode.CLOUD; export const isDev = ENV.DEV; export const isProd = ENV.PROD; diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index 0282852c2..de073e38c 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -4,6 +4,7 @@ import { getLimit, getPage, pageToOffset } from '$lib/helpers/load'; import { CARD_LIMIT, Dependencies } from '$lib/constants'; import type { PageLoad } from './$types'; import { redirect } from '@sveltejs/kit'; +import { base } from '$app/paths'; export const load: PageLoad = async ({ params, url, route, depends, parent }) => { const { scopes } = await parent(); @@ -12,7 +13,7 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => const limit = getLimit(url, route, CARD_LIMIT); const offset = pageToOffset(page, limit); if (!scopes.includes('projects.read') && scopes.includes('billing.read')) { - return redirect(301, `/console/organization-${params.organization}/billing`); + return redirect(301, `${base}/organization-${params.organization}/billing`); } return { diff --git a/src/routes/(console)/organization-[organization]/billing/+page.ts b/src/routes/(console)/organization-[organization]/billing/+page.ts index 36247292e..2c3c8cef3 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.ts +++ b/src/routes/(console)/organization-[organization]/billing/+page.ts @@ -5,12 +5,13 @@ import { sdk } from '$lib/stores/sdk'; import { redirect } from '@sveltejs/kit'; import type { PageLoad } from './$types'; import { Query } from '@appwrite.io/console'; +import { base } from '$app/paths'; export const load: PageLoad = async ({ parent, depends }) => { const { organization, scopes } = await parent(); if (!scopes.includes('billing.read')) { - return redirect(301, `/console/organization-${organization.$id}`); + return redirect(301, `${base}/organization-${organization.$id}`); } depends(Dependencies.PAYMENT_METHODS); depends(Dependencies.ORGANIZATION); diff --git a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/settings/changeOrganization.svelte b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/settings/changeOrganization.svelte index e505a962f..cb286576d 100644 --- a/src/routes/(console)/organization-[organization]/domains/domain-[domain]/settings/changeOrganization.svelte +++ b/src/routes/(console)/organization-[organization]/domains/domain-[domain]/settings/changeOrganization.svelte @@ -8,6 +8,7 @@ import { addNotification } from '$lib/stores/notifications'; import type { OrganizationList } from '$lib/stores/organization'; import { sdk } from '$lib/stores/sdk'; + import { base } from '$app/paths'; export let domain: Domain; export let organizations: OrganizationList; @@ -20,7 +21,7 @@ type: 'success', message: 'Domain moved successfully' }); - await goto(`/console/organization-${selectedOrg}/domains/`); + await goto(`${base}/organization-${selectedOrg}/domains/`); await invalidate(Dependencies.ORGANIZATION); await invalidate(Dependencies.DOMAINS); } catch (e) { diff --git a/src/routes/(studio)/org-[organization]/+page.svelte b/src/routes/(studio)/org-[organization]/+page.svelte new file mode 100644 index 000000000..f35e3e4e7 --- /dev/null +++ b/src/routes/(studio)/org-[organization]/+page.svelte @@ -0,0 +1 @@ +Hey studio! diff --git a/src/routes/+page.ts b/src/routes/+page.ts index 625a46dec..b7e139a94 100644 --- a/src/routes/+page.ts +++ b/src/routes/+page.ts @@ -2,7 +2,7 @@ import { redirect } from '@sveltejs/kit'; import { base } from '$app/paths'; import type { PageLoad } from './$types'; import { sdk } from '$lib/stores/sdk'; -import { VARS } from '$lib/system'; +import { isStudio, VARS } from '$lib/system'; const handleGithubEducationMembership = async (name: string, email: string) => { const result = await sdk.forConsole.billing.setMembership('github-student-developer'); @@ -39,7 +39,12 @@ export const load: PageLoad = async ({ parent, url }) => { if (!teamId) { redirect(303, `${base}/account/organizations${url.search}`); } else { - redirect(303, `${base}/organization-${teamId}${url.search}`); + redirect( + 303, + isStudio + ? `${base}/org-${teamId}${url.search}` + : `${base}/organization-${teamId}${url.search}` + ); } } else { redirect(303, `${base}/onboarding/create-project${url.search}`); From 0f8d35aaca14b7e366baddf535f504428722933b Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 14:12:28 +0200 Subject: [PATCH 03/10] Menu setuping --- .../studio/sidebarOrganization.svelte | 37 ++++++++++ src/routes/(studio)/+layout.svelte | 74 +++++++++++++++++++ src/routes/(studio)/+layout.ts | 70 ++++++++++++++++++ .../(studio)/org-[organization]/+page.svelte | 6 +- 4 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/lib/components/studio/sidebarOrganization.svelte create mode 100644 src/routes/(studio)/+layout.svelte create mode 100644 src/routes/(studio)/+layout.ts diff --git a/src/lib/components/studio/sidebarOrganization.svelte b/src/lib/components/studio/sidebarOrganization.svelte new file mode 100644 index 000000000..84e7b405a --- /dev/null +++ b/src/lib/components/studio/sidebarOrganization.svelte @@ -0,0 +1,37 @@ + + + + + diff --git a/src/routes/(studio)/+layout.svelte b/src/routes/(studio)/+layout.svelte new file mode 100644 index 000000000..a205adf30 --- /dev/null +++ b/src/routes/(studio)/+layout.svelte @@ -0,0 +1,74 @@ + + +
+ +
+ + + + +
+
+ +
+
+ + diff --git a/src/routes/(studio)/+layout.ts b/src/routes/(studio)/+layout.ts new file mode 100644 index 000000000..d51edd31e --- /dev/null +++ b/src/routes/(studio)/+layout.ts @@ -0,0 +1,70 @@ +import { Dependencies } from '$lib/constants'; +import type { Plan } from '$lib/sdk/billing'; +import type { Tier } from '$lib/stores/billing'; +import { sdk } from '$lib/stores/sdk'; +import { isCloud } from '$lib/system'; +import type { LayoutLoad } from './$types'; +import { Query } from '@appwrite.io/console'; + +export const load: LayoutLoad = async ({ params, fetch, depends, parent }) => { + await parent(); + depends(Dependencies.RUNTIMES); + depends(Dependencies.CONSOLE_VARIABLES); + depends(Dependencies.ORGANIZATION); + + const prefs = await sdk.forConsole.account.getPrefs(); + + const { endpoint, project } = sdk.forConsole.client.config; + const versionPromise = fetch(`${endpoint}/health/version`, { + headers: { + 'X-Appwrite-Project': project + } + }).then((response) => response.json() as { version?: string }); + + const variablesPromise = sdk.forConsole.console.variables(); + + const [data, variables] = await Promise.all([versionPromise, variablesPromise]); + + let plansInfo = new Map(); + if (isCloud) { + const plansArray = await sdk.forConsole.billing.getPlansInfo(); + plansInfo = plansArray.plans.reduce((map, plan) => { + map.set(plan.$id as Tier, plan); + return map; + }, new Map()); + } + + const organizations = !isCloud + ? await sdk.forConsole.teams.list() + : await sdk.forConsole.billing.listOrganization(); + + let projects = []; + let currentOrgId = params.organization ? params.organization : prefs.organization; + + if (!currentOrgId && organizations.teams.length > 0) { + currentOrgId = organizations.teams[0].$id; + } + if (currentOrgId) { + const orgProjects = await sdk.forConsole.projects.list([ + Query.equal('teamId', currentOrgId), + Query.limit(100), + Query.orderDesc('$updatedAt') + ]); + projects = orgProjects.projects.length > 0 ? orgProjects.projects : []; + } + + const selectedOrganizationId = + params && params.organization ? params.organization : prefs.organization; + + return { + consoleVariables: variables, + version: data?.version ?? null, + plansInfo, + roles: [], + scopes: [], + projects: projects, + currentProjectId: params.project ?? '', + organizations: organizations, + currentOrganization: organizations.teams.find((org) => org.$id === selectedOrganizationId) + }; +}; diff --git a/src/routes/(studio)/org-[organization]/+page.svelte b/src/routes/(studio)/org-[organization]/+page.svelte index f35e3e4e7..f55e2f435 100644 --- a/src/routes/(studio)/org-[organization]/+page.svelte +++ b/src/routes/(studio)/org-[organization]/+page.svelte @@ -1 +1,5 @@ -Hey studio! + + +dus From 4fde400c87ae9ce5c5fc8ca8fbdb6bae99f096ca Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 15:40:54 +0200 Subject: [PATCH 04/10] Org page setup --- .../(studio)/org-[organization]/+page.svelte | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/routes/(studio)/org-[organization]/+page.svelte b/src/routes/(studio)/org-[organization]/+page.svelte index f55e2f435..b97b46e7c 100644 --- a/src/routes/(studio)/org-[organization]/+page.svelte +++ b/src/routes/(studio)/org-[organization]/+page.svelte @@ -1,5 +1,30 @@ -dus + + + + Projects + Create project + + + + + + {#each data.projects as project} + + {/each} + + + From 312df91601b08411625350626a93916f14f536d1 Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 15:50:10 +0200 Subject: [PATCH 05/10] Override theme for studio --- src/routes/+layout.svelte | 11 +++++++++-- src/themes/index.ts | 6 ++++++ src/themes/light-studio.json | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 src/themes/light-studio.json diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 1934a9047..950455120 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -14,16 +14,23 @@ import { user } from '$lib/stores/user'; import { loading } from '$routes/store'; import { Root } from '@appwrite.io/pink-svelte'; - import { ThemeDark, ThemeLight, ThemeDarkCloud, ThemeLightCloud } from '../themes'; + import { + ThemeDark, + ThemeLight, + ThemeDarkCloud, + ThemeLightCloud, + ThemeLightStudio + } from '../themes'; import { isSmallViewport, updateViewport } from '$lib/stores/viewport'; import { feedback } from '$lib/stores/feedback'; + import { isStudio } from '$lib/system.js'; function resolveTheme(theme: AppStore['themeInUse']) { switch (theme) { case 'dark': return isCloud ? ThemeDarkCloud : ThemeDark; case 'light': - return isCloud ? ThemeLightCloud : ThemeLight; + return isStudio ? ThemeLightStudio : isCloud ? ThemeLightCloud : ThemeLight; } } diff --git a/src/themes/index.ts b/src/themes/index.ts index 2b2344244..bff6f28ef 100644 --- a/src/themes/index.ts +++ b/src/themes/index.ts @@ -3,3 +3,9 @@ export { default as ThemeLight } from './light.json'; export { default as ThemeDarkCloud } from './dark-cloud.json'; export { default as ThemeLightCloud } from './light-cloud.json'; + +import { default as StudioLightOverride } from './light-studio.json'; +import { default as ThemeLightBase } from './light.json'; + +export const ThemeLightStudio = { ...ThemeLightBase, ...StudioLightOverride }; +console.log('ThemeLightStudio', ThemeLightStudio); diff --git a/src/themes/light-studio.json b/src/themes/light-studio.json new file mode 100644 index 000000000..b25007dec --- /dev/null +++ b/src/themes/light-studio.json @@ -0,0 +1,4 @@ +{ + "bgcolor-accent": "var(--neutral-1000)", + "bgcolor-accent-secondary": "var(--neutral-900)" +} \ No newline at end of file From 412101458718a8fa03af3c52da55ad1a5ab1f56c Mon Sep 17 00:00:00 2001 From: ernstmul Date: Tue, 1 Apr 2025 16:31:05 +0200 Subject: [PATCH 06/10] Fix breadcrumb, add project page --- src/lib/components/breadcrumbs.svelte | 6 ++-- .../components/studio/sidebarProject.svelte | 35 +++++++++++++++++++ src/routes/(studio)/+layout.svelte | 19 +++++++--- .../(studio)/proj-[project]/+page.svelte | 1 + src/themes/index.ts | 1 - 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 src/lib/components/studio/sidebarProject.svelte create mode 100644 src/routes/(studio)/proj-[project]/+page.svelte diff --git a/src/lib/components/breadcrumbs.svelte b/src/lib/components/breadcrumbs.svelte index 4acd8a6a4..ffa48e0b6 100644 --- a/src/lib/components/breadcrumbs.svelte +++ b/src/lib/components/breadcrumbs.svelte @@ -9,7 +9,7 @@ } from '@appwrite.io/pink-icons-svelte'; import { BottomSheet } from '$lib/components'; import { isSmallViewport } from '$lib/stores/viewport'; - import { isCloud } from '$lib/system'; + import { isCloud, isStudio } from '$lib/system'; import { goto } from '$app/navigation'; import { base } from '$app/paths'; import { newOrgModal } from '$lib/stores/organization'; @@ -185,7 +185,9 @@
{#if !$isSmallViewport} - / + {#if !isStudio} + / + {/if}
diff --git a/src/lib/components/studio/sidebarOrganization.svelte b/src/lib/components/studio/sidebarOrganization.svelte index 84e7b405a..0af4c1ef8 100644 --- a/src/lib/components/studio/sidebarOrganization.svelte +++ b/src/lib/components/studio/sidebarOrganization.svelte @@ -11,15 +11,15 @@ {organization.name} - Projects - Members - Usage - Billing - Settings diff --git a/src/lib/layout/container.svelte b/src/lib/layout/container.svelte index abe25a4a9..a104f9f43 100644 --- a/src/lib/layout/container.svelte +++ b/src/lib/layout/container.svelte @@ -1,5 +1,6 @@ -
-
- - - +{#if isStudio} + +{:else} +
+
+ + + +
-
+{/if} diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index e8f555fc0..c2dbb2932 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -3,6 +3,7 @@ import { BillingPlan, INTERVAL } from '$lib/constants'; import Footer from '$lib/layout/footer.svelte'; import Shell from '$lib/layout/shell.svelte'; + import ShellStudio from '$lib/layout/shellStudio.svelte'; import { app } from '$lib/stores/app'; import { newOrgModal, organization, type Organization } from '$lib/stores/organization'; import { database, checkForDatabaseBackupPolicies } from '$lib/stores/database'; @@ -32,7 +33,7 @@ import { openMigrationWizard } from './(migration-wizard)'; import { project } from './project-[project]/store'; import { feedback } from '$lib/stores/feedback'; - import { hasStripePublicKey, isCloud, VARS } from '$lib/system'; + import { hasStripePublicKey, isCloud, isStudio, VARS } from '$lib/system'; import { stripe } from '$lib/stores/stripe'; import MobileSupportModal from './wizard/support/mobileSupportModal.svelte'; import { showSupportModal } from './wizard/support/store'; @@ -329,21 +330,24 @@ - - - -