From 3662e52f6284b9a42e821bb80d17206f0480b3a5 Mon Sep 17 00:00:00 2001 From: Alaister Young <10985857+alaister@users.noreply.github.com> Date: Fri, 8 May 2026 15:09:06 +0800 Subject: [PATCH] feat(studio): migrate /database/triggers/* + force cva into own chunk (stage 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds routes/project/$ref/database/triggers.tsx as a sub-shell that inlines the inner part of DatabaseTriggersLayout (PageLayout + the permission gate + nav items). Can't re-use DatabaseTriggersLayout directly because it internally wraps in , which would double-wrap under the database.tsx shell. The Next-side component is left untouched. - Adds 3 leaves: triggers/{index,data,event} as Path-A re-exports. - Forces `class-variance-authority` into its own chunk via Rolldown manualChunks. Without this, adding the triggers shell nudges Rolldown into a chunk layout where TreeView is split out and imports `cva` back from the `ui` chunk while `ui` imports `TreeView` — a bundle- level circular dep that leaves `cva` undefined when TreeView's top-level cva(...) initializer runs at SSR prerender. Source has no cycle; this is purely a chunking artifact. Pinning cva to its own chunk breaks the cycle and is robust against future chunk shifts. --- apps/studio/TANSTACK_MIGRATION.md | 7 +- apps/studio/routeTree.gen.ts | 98 +++++++++++++++++++ .../routes/project/$ref/database/triggers.tsx | 39 ++++++++ .../project/$ref/database/triggers/data.tsx | 11 +++ .../project/$ref/database/triggers/event.tsx | 11 +++ .../project/$ref/database/triggers/index.tsx | 11 +++ apps/studio/vite.config.ts | 17 ++++ 7 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 apps/studio/routes/project/$ref/database/triggers.tsx create mode 100644 apps/studio/routes/project/$ref/database/triggers/data.tsx create mode 100644 apps/studio/routes/project/$ref/database/triggers/event.tsx create mode 100644 apps/studio/routes/project/$ref/database/triggers/index.tsx diff --git a/apps/studio/TANSTACK_MIGRATION.md b/apps/studio/TANSTACK_MIGRATION.md index aaab5f9574f..e19cc8375d8 100644 --- a/apps/studio/TANSTACK_MIGRATION.md +++ b/apps/studio/TANSTACK_MIGRATION.md @@ -50,6 +50,7 @@ These are the layout-only TanStack files. Most hold a single product layout comp - [x] `routes/project/$ref.tsx` — DefaultLayout only. **Delta vs plan:** ProjectLayoutWithAuth omitted from the shell because product layouts (DatabaseLayout, AuthLayout, StorageLayout, …) already render `withAuth(... ProjectLayout ...)` internally — adding it here would double-wrap. The home page (`/project/$ref/index.tsx`) wraps itself in `ProjectLayoutWithAuth` since it has no product layout. - [x] `routes/project/$ref/database.tsx` — DatabaseLayout (reads `databaseLayoutTitle` from leaf `staticData`) +- [x] `routes/project/$ref/database/triggers.tsx` — sub-shell with `PageLayout` + permission gate + nav items, inlined from `DatabaseTriggersLayout`. **Delta vs plan:** the existing `DatabaseTriggersLayout` component wraps `` internally, so re-using it inside the database.tsx shell would double-wrap. Inlined the inner part instead; the Next-side component is left untouched (still used by the `pages/...` files we re-export). - [ ] `routes/project/$ref/auth.tsx` — AuthLayout - [ ] `routes/project/$ref/auth/templates.tsx` — AuthEmailsLayout - [ ] `routes/project/$ref/storage.tsx` — StorageLayout @@ -144,9 +145,9 @@ These are the layout-only TanStack files. Most hold a single product layout comp - [x] A `routes/project/$ref/database/replication/index.tsx` ← `pages/project/[ref]/database/replication/index.tsx` - [x] A `routes/project/$ref/database/replication/$pipelineId.tsx` ← `pages/project/[ref]/database/replication/[pipelineId].tsx` - [x] A `routes/project/$ref/database/replication/replica/$replicaId.tsx` ← `pages/project/[ref]/database/replication/replica/[replicaId].tsx` -- [ ] `routes/project/$ref/database/triggers/index.tsx` ← `pages/project/[ref]/database/triggers/index.tsx` -- [ ] `routes/project/$ref/database/triggers/data.tsx` ← `pages/project/[ref]/database/triggers/data.tsx` -- [ ] `routes/project/$ref/database/triggers/event.tsx` ← `pages/project/[ref]/database/triggers/event.tsx` +- [x] A `routes/project/$ref/database/triggers/index.tsx` ← `pages/project/[ref]/database/triggers/index.tsx` +- [x] A `routes/project/$ref/database/triggers/data.tsx` ← `pages/project/[ref]/database/triggers/data.tsx` (sub-shell at `database/triggers.tsx` provides PageLayout + nav, parent shell provides DatabaseLayout) +- [x] A `routes/project/$ref/database/triggers/event.tsx` ← `pages/project/[ref]/database/triggers/event.tsx` (same as data) - [ ] `routes/project/$ref/database/backups/pitr.tsx` ← `pages/project/[ref]/database/backups/pitr.tsx` - [ ] `routes/project/$ref/database/backups/restore-to-new-project.tsx` ← `pages/project/[ref]/database/backups/restore-to-new-project.tsx` - [ ] `routes/project/$ref/database/backups/scheduled.tsx` ← `pages/project/[ref]/database/backups/scheduled.tsx` diff --git a/apps/studio/routeTree.gen.ts b/apps/studio/routeTree.gen.ts index e5e047f80a7..3bbf28be571 100644 --- a/apps/studio/routeTree.gen.ts +++ b/apps/studio/routeTree.gen.ts @@ -59,6 +59,7 @@ import { Route as ApiPlatformOrganizationsIndexRouteImport } from './routes/api/ import { Route as AppOrgSlugIndexRouteImport } from './routes/_app/org/$slug/index' import { Route as AppAccountTokensIndexRouteImport } from './routes/_app/account/tokens/index' import { Route as ProjectRefDatabaseTypesRouteImport } from './routes/project/$ref/database/types' +import { Route as ProjectRefDatabaseTriggersRouteImport } from './routes/project/$ref/database/triggers' import { Route as ProjectRefDatabaseSettingsRouteImport } from './routes/project/$ref/database/settings' import { Route as ProjectRefDatabaseSchemasRouteImport } from './routes/project/$ref/database/schemas' import { Route as ProjectRefDatabaseRolesRouteImport } from './routes/project/$ref/database/roles' @@ -90,12 +91,15 @@ import { Route as AppOrgSlugBillingRouteImport } from './routes/_app/org/$slug/b import { Route as AppOrgSlugAuditRouteImport } from './routes/_app/org/$slug/audit' import { Route as AppOrgSlugAppsRouteImport } from './routes/_app/org/$slug/apps' import { Route as AppAccountTokensScopedRouteImport } from './routes/_app/account/tokens/scoped' +import { Route as ProjectRefDatabaseTriggersIndexRouteImport } from './routes/project/$ref/database/triggers/index' import { Route as ProjectRefDatabaseTablesIndexRouteImport } from './routes/project/$ref/database/tables/index' import { Route as ProjectRefDatabaseReplicationIndexRouteImport } from './routes/project/$ref/database/replication/index' import { Route as ProjectRefDatabasePublicationsIndexRouteImport } from './routes/project/$ref/database/publications/index' import { Route as ApiPlatformProjectsRefIndexRouteImport } from './routes/api/platform/projects/$ref/index' import { Route as AppOrgSlugWebhooksIndexRouteImport } from './routes/_app/org/$slug/webhooks/index' import { Route as AppOrgSlugPrivateAppsIndexRouteImport } from './routes/_app/org/$slug/private-apps/index' +import { Route as ProjectRefDatabaseTriggersEventRouteImport } from './routes/project/$ref/database/triggers/event' +import { Route as ProjectRefDatabaseTriggersDataRouteImport } from './routes/project/$ref/database/triggers/data' import { Route as ProjectRefDatabaseTablesIdRouteImport } from './routes/project/$ref/database/tables/$id' import { Route as ProjectRefDatabaseReplicationPipelineIdRouteImport } from './routes/project/$ref/database/replication/$pipelineId' import { Route as ProjectRefDatabasePublicationsIdRouteImport } from './routes/project/$ref/database/publications/$id' @@ -416,6 +420,12 @@ const ProjectRefDatabaseTypesRoute = ProjectRefDatabaseTypesRouteImport.update({ path: '/types', getParentRoute: () => ProjectRefDatabaseRoute, } as any) +const ProjectRefDatabaseTriggersRoute = + ProjectRefDatabaseTriggersRouteImport.update({ + id: '/triggers', + path: '/triggers', + getParentRoute: () => ProjectRefDatabaseRoute, + } as any) const ProjectRefDatabaseSettingsRoute = ProjectRefDatabaseSettingsRouteImport.update({ id: '/settings', @@ -580,6 +590,12 @@ const AppAccountTokensScopedRoute = AppAccountTokensScopedRouteImport.update({ path: '/tokens/scoped', getParentRoute: () => AppAccountRoute, } as any) +const ProjectRefDatabaseTriggersIndexRoute = + ProjectRefDatabaseTriggersIndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => ProjectRefDatabaseTriggersRoute, + } as any) const ProjectRefDatabaseTablesIndexRoute = ProjectRefDatabaseTablesIndexRouteImport.update({ id: '/tables/', @@ -615,6 +631,18 @@ const AppOrgSlugPrivateAppsIndexRoute = path: '/$slug/private-apps/', getParentRoute: () => AppOrgRoute, } as any) +const ProjectRefDatabaseTriggersEventRoute = + ProjectRefDatabaseTriggersEventRouteImport.update({ + id: '/event', + path: '/event', + getParentRoute: () => ProjectRefDatabaseTriggersRoute, + } as any) +const ProjectRefDatabaseTriggersDataRoute = + ProjectRefDatabaseTriggersDataRouteImport.update({ + id: '/data', + path: '/data', + getParentRoute: () => ProjectRefDatabaseTriggersRoute, + } as any) const ProjectRefDatabaseTablesIdRoute = ProjectRefDatabaseTablesIdRouteImport.update({ id: '/tables/$id', @@ -1077,6 +1105,7 @@ export interface FileRoutesByFullPath { '/project/$ref/database/roles': typeof ProjectRefDatabaseRolesRoute '/project/$ref/database/schemas': typeof ProjectRefDatabaseSchemasRoute '/project/$ref/database/settings': typeof ProjectRefDatabaseSettingsRoute + '/project/$ref/database/triggers': typeof ProjectRefDatabaseTriggersRouteWithChildren '/project/$ref/database/types': typeof ProjectRefDatabaseTypesRoute '/account/tokens/': typeof AppAccountTokensIndexRoute '/org/$slug/': typeof AppOrgSlugIndexRoute @@ -1112,12 +1141,15 @@ export interface FileRoutesByFullPath { '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute + '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute + '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute '/org/$slug/private-apps/': typeof AppOrgSlugPrivateAppsIndexRoute '/org/$slug/webhooks/': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref/': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/database/publications/': typeof ProjectRefDatabasePublicationsIndexRoute '/project/$ref/database/replication/': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables/': typeof ProjectRefDatabaseTablesIndexRoute + '/project/$ref/database/triggers/': typeof ProjectRefDatabaseTriggersIndexRoute '/api/platform/organizations/$slug/billing/subscription': typeof ApiPlatformOrganizationsSlugBillingSubscriptionRoute '/api/platform/projects/$ref/analytics/log-drains': typeof ApiPlatformProjectsRefAnalyticsLogDrainsRouteWithChildren '/api/platform/projects/$ref/api-keys/temporary': typeof ApiPlatformProjectsRefApiKeysTemporaryRoute @@ -1262,12 +1294,15 @@ export interface FileRoutesByTo { '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute + '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute + '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute '/org/$slug/private-apps': typeof AppOrgSlugPrivateAppsIndexRoute '/org/$slug/webhooks': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/database/publications': typeof ProjectRefDatabasePublicationsIndexRoute '/project/$ref/database/replication': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables': typeof ProjectRefDatabaseTablesIndexRoute + '/project/$ref/database/triggers': typeof ProjectRefDatabaseTriggersIndexRoute '/api/platform/organizations/$slug/billing/subscription': typeof ApiPlatformOrganizationsSlugBillingSubscriptionRoute '/api/platform/projects/$ref/analytics/log-drains': typeof ApiPlatformProjectsRefAnalyticsLogDrainsRouteWithChildren '/api/platform/projects/$ref/api-keys/temporary': typeof ApiPlatformProjectsRefApiKeysTemporaryRoute @@ -1382,6 +1417,7 @@ export interface FileRoutesById { '/project/$ref/database/roles': typeof ProjectRefDatabaseRolesRoute '/project/$ref/database/schemas': typeof ProjectRefDatabaseSchemasRoute '/project/$ref/database/settings': typeof ProjectRefDatabaseSettingsRoute + '/project/$ref/database/triggers': typeof ProjectRefDatabaseTriggersRouteWithChildren '/project/$ref/database/types': typeof ProjectRefDatabaseTypesRoute '/_app/account/tokens/': typeof AppAccountTokensIndexRoute '/_app/org/$slug/': typeof AppOrgSlugIndexRoute @@ -1417,12 +1453,15 @@ export interface FileRoutesById { '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute + '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute + '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute '/_app/org/$slug/private-apps/': typeof AppOrgSlugPrivateAppsIndexRoute '/_app/org/$slug/webhooks/': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref/': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/database/publications/': typeof ProjectRefDatabasePublicationsIndexRoute '/project/$ref/database/replication/': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables/': typeof ProjectRefDatabaseTablesIndexRoute + '/project/$ref/database/triggers/': typeof ProjectRefDatabaseTriggersIndexRoute '/api/platform/organizations/$slug/billing/subscription': typeof ApiPlatformOrganizationsSlugBillingSubscriptionRoute '/api/platform/projects/$ref/analytics/log-drains': typeof ApiPlatformProjectsRefAnalyticsLogDrainsRouteWithChildren '/api/platform/projects/$ref/api-keys/temporary': typeof ApiPlatformProjectsRefApiKeysTemporaryRoute @@ -1536,6 +1575,7 @@ export interface FileRouteTypes { | '/project/$ref/database/roles' | '/project/$ref/database/schemas' | '/project/$ref/database/settings' + | '/project/$ref/database/triggers' | '/project/$ref/database/types' | '/account/tokens/' | '/org/$slug/' @@ -1571,12 +1611,15 @@ export interface FileRouteTypes { | '/project/$ref/database/publications/$id' | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' + | '/project/$ref/database/triggers/data' + | '/project/$ref/database/triggers/event' | '/org/$slug/private-apps/' | '/org/$slug/webhooks/' | '/api/platform/projects/$ref/' | '/project/$ref/database/publications/' | '/project/$ref/database/replication/' | '/project/$ref/database/tables/' + | '/project/$ref/database/triggers/' | '/api/platform/organizations/$slug/billing/subscription' | '/api/platform/projects/$ref/analytics/log-drains' | '/api/platform/projects/$ref/api-keys/temporary' @@ -1721,12 +1764,15 @@ export interface FileRouteTypes { | '/project/$ref/database/publications/$id' | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' + | '/project/$ref/database/triggers/data' + | '/project/$ref/database/triggers/event' | '/org/$slug/private-apps' | '/org/$slug/webhooks' | '/api/platform/projects/$ref' | '/project/$ref/database/publications' | '/project/$ref/database/replication' | '/project/$ref/database/tables' + | '/project/$ref/database/triggers' | '/api/platform/organizations/$slug/billing/subscription' | '/api/platform/projects/$ref/analytics/log-drains' | '/api/platform/projects/$ref/api-keys/temporary' @@ -1840,6 +1886,7 @@ export interface FileRouteTypes { | '/project/$ref/database/roles' | '/project/$ref/database/schemas' | '/project/$ref/database/settings' + | '/project/$ref/database/triggers' | '/project/$ref/database/types' | '/_app/account/tokens/' | '/_app/org/$slug/' @@ -1875,12 +1922,15 @@ export interface FileRouteTypes { | '/project/$ref/database/publications/$id' | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' + | '/project/$ref/database/triggers/data' + | '/project/$ref/database/triggers/event' | '/_app/org/$slug/private-apps/' | '/_app/org/$slug/webhooks/' | '/api/platform/projects/$ref/' | '/project/$ref/database/publications/' | '/project/$ref/database/replication/' | '/project/$ref/database/tables/' + | '/project/$ref/database/triggers/' | '/api/platform/organizations/$slug/billing/subscription' | '/api/platform/projects/$ref/analytics/log-drains' | '/api/platform/projects/$ref/api-keys/temporary' @@ -2374,6 +2424,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabaseTypesRouteImport parentRoute: typeof ProjectRefDatabaseRoute } + '/project/$ref/database/triggers': { + id: '/project/$ref/database/triggers' + path: '/triggers' + fullPath: '/project/$ref/database/triggers' + preLoaderRoute: typeof ProjectRefDatabaseTriggersRouteImport + parentRoute: typeof ProjectRefDatabaseRoute + } '/project/$ref/database/settings': { id: '/project/$ref/database/settings' path: '/settings' @@ -2591,6 +2648,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AppAccountTokensScopedRouteImport parentRoute: typeof AppAccountRoute } + '/project/$ref/database/triggers/': { + id: '/project/$ref/database/triggers/' + path: '/' + fullPath: '/project/$ref/database/triggers/' + preLoaderRoute: typeof ProjectRefDatabaseTriggersIndexRouteImport + parentRoute: typeof ProjectRefDatabaseTriggersRoute + } '/project/$ref/database/tables/': { id: '/project/$ref/database/tables/' path: '/tables' @@ -2633,6 +2697,20 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AppOrgSlugPrivateAppsIndexRouteImport parentRoute: typeof AppOrgRoute } + '/project/$ref/database/triggers/event': { + id: '/project/$ref/database/triggers/event' + path: '/event' + fullPath: '/project/$ref/database/triggers/event' + preLoaderRoute: typeof ProjectRefDatabaseTriggersEventRouteImport + parentRoute: typeof ProjectRefDatabaseTriggersRoute + } + '/project/$ref/database/triggers/data': { + id: '/project/$ref/database/triggers/data' + path: '/data' + fullPath: '/project/$ref/database/triggers/data' + preLoaderRoute: typeof ProjectRefDatabaseTriggersDataRouteImport + parentRoute: typeof ProjectRefDatabaseTriggersRoute + } '/project/$ref/database/tables/$id': { id: '/project/$ref/database/tables/$id' path: '/tables/$id' @@ -3192,6 +3270,24 @@ const AuthRouteChildren: AuthRouteChildren = { const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren) +interface ProjectRefDatabaseTriggersRouteChildren { + ProjectRefDatabaseTriggersDataRoute: typeof ProjectRefDatabaseTriggersDataRoute + ProjectRefDatabaseTriggersEventRoute: typeof ProjectRefDatabaseTriggersEventRoute + ProjectRefDatabaseTriggersIndexRoute: typeof ProjectRefDatabaseTriggersIndexRoute +} + +const ProjectRefDatabaseTriggersRouteChildren: ProjectRefDatabaseTriggersRouteChildren = + { + ProjectRefDatabaseTriggersDataRoute: ProjectRefDatabaseTriggersDataRoute, + ProjectRefDatabaseTriggersEventRoute: ProjectRefDatabaseTriggersEventRoute, + ProjectRefDatabaseTriggersIndexRoute: ProjectRefDatabaseTriggersIndexRoute, + } + +const ProjectRefDatabaseTriggersRouteWithChildren = + ProjectRefDatabaseTriggersRoute._addFileChildren( + ProjectRefDatabaseTriggersRouteChildren, + ) + interface ProjectRefDatabaseRouteChildren { ProjectRefDatabaseColumnPrivilegesRoute: typeof ProjectRefDatabaseColumnPrivilegesRoute ProjectRefDatabaseExtensionsRoute: typeof ProjectRefDatabaseExtensionsRoute @@ -3201,6 +3297,7 @@ interface ProjectRefDatabaseRouteChildren { ProjectRefDatabaseRolesRoute: typeof ProjectRefDatabaseRolesRoute ProjectRefDatabaseSchemasRoute: typeof ProjectRefDatabaseSchemasRoute ProjectRefDatabaseSettingsRoute: typeof ProjectRefDatabaseSettingsRoute + ProjectRefDatabaseTriggersRoute: typeof ProjectRefDatabaseTriggersRouteWithChildren ProjectRefDatabaseTypesRoute: typeof ProjectRefDatabaseTypesRoute ProjectRefDatabasePublicationsIdRoute: typeof ProjectRefDatabasePublicationsIdRoute ProjectRefDatabaseReplicationPipelineIdRoute: typeof ProjectRefDatabaseReplicationPipelineIdRoute @@ -3221,6 +3318,7 @@ const ProjectRefDatabaseRouteChildren: ProjectRefDatabaseRouteChildren = { ProjectRefDatabaseRolesRoute: ProjectRefDatabaseRolesRoute, ProjectRefDatabaseSchemasRoute: ProjectRefDatabaseSchemasRoute, ProjectRefDatabaseSettingsRoute: ProjectRefDatabaseSettingsRoute, + ProjectRefDatabaseTriggersRoute: ProjectRefDatabaseTriggersRouteWithChildren, ProjectRefDatabaseTypesRoute: ProjectRefDatabaseTypesRoute, ProjectRefDatabasePublicationsIdRoute: ProjectRefDatabasePublicationsIdRoute, ProjectRefDatabaseReplicationPipelineIdRoute: diff --git a/apps/studio/routes/project/$ref/database/triggers.tsx b/apps/studio/routes/project/$ref/database/triggers.tsx new file mode 100644 index 00000000000..79e9cb83c94 --- /dev/null +++ b/apps/studio/routes/project/$ref/database/triggers.tsx @@ -0,0 +1,39 @@ +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { createFileRoute, Outlet } from '@tanstack/react-router' + +import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' +import NoPermission from '@/components/ui/NoPermission' +import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' + +export const Route = createFileRoute('/project/$ref/database/triggers')({ + component: TriggersShell, + staticData: { + databaseLayoutTitle: 'Triggers', + }, +}) + +function TriggersShell() { + const { ref } = Route.useParams() + const { can: canReadTriggers, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions( + PermissionAction.TENANT_SQL_ADMIN_READ, + 'triggers' + ) + + if (isPermissionsLoaded && !canReadTriggers) { + return + } + + return ( + + + + ) +} diff --git a/apps/studio/routes/project/$ref/database/triggers/data.tsx b/apps/studio/routes/project/$ref/database/triggers/data.tsx new file mode 100644 index 00000000000..82b1b70175f --- /dev/null +++ b/apps/studio/routes/project/$ref/database/triggers/data.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router' + +import TriggersDataPage from '@/pages/project/[ref]/database/triggers/data' + +export const Route = createFileRoute('/project/$ref/database/triggers/data')({ + component: TriggersDataRoute, +}) + +function TriggersDataRoute() { + return +} diff --git a/apps/studio/routes/project/$ref/database/triggers/event.tsx b/apps/studio/routes/project/$ref/database/triggers/event.tsx new file mode 100644 index 00000000000..f8bbeacdbb7 --- /dev/null +++ b/apps/studio/routes/project/$ref/database/triggers/event.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router' + +import TriggersSchemaPage from '@/pages/project/[ref]/database/triggers/event' + +export const Route = createFileRoute('/project/$ref/database/triggers/event')({ + component: TriggersEventRoute, +}) + +function TriggersEventRoute() { + return +} diff --git a/apps/studio/routes/project/$ref/database/triggers/index.tsx b/apps/studio/routes/project/$ref/database/triggers/index.tsx new file mode 100644 index 00000000000..038e97727ed --- /dev/null +++ b/apps/studio/routes/project/$ref/database/triggers/index.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router' + +import DatabaseTriggersIndexPage from '@/pages/project/[ref]/database/triggers/index' + +export const Route = createFileRoute('/project/$ref/database/triggers/')({ + component: DatabaseTriggersIndexRoute, +}) + +function DatabaseTriggersIndexRoute() { + return +} diff --git a/apps/studio/vite.config.ts b/apps/studio/vite.config.ts index bdeefeabe6a..f67bba50621 100644 --- a/apps/studio/vite.config.ts +++ b/apps/studio/vite.config.ts @@ -118,6 +118,23 @@ export default defineConfig(({ mode }) => { }, ...(basePath && { base: basePath }), define: publicEnvDefines, + // Force `class-variance-authority` into its own chunk. Without this, + // Rolldown splits `TreeView` into a separate chunk that imports `cva` + // from the `ui` chunk while the `ui` chunk imports `TreeView` back — + // a circular dep in the bundle output (not in source) that leaves + // `cva` undefined when TreeView's top-level `cva(...)` initializer + // runs at SSR prerender time. Pinning cva to its own chunk breaks + // the cycle. + build: { + rollupOptions: { + output: { + manualChunks: (id) => + id.includes('node_modules/class-variance-authority/') + ? 'class-variance-authority' + : undefined, + }, + }, + }, css: { // Disable PostCSS auto-discovery. Studio's postcss.config.cjs is kept // for the Next build (`build:next`) and uses `@tailwindcss/postcss`,