Skip to content

Commit 564039b

Browse files
committed
Add a Settings section registry with one lazy folder per section
Each proposed section has its own folder with a placeholder, loaded on demand in live mode, so a section's owner never edits shared files. Fixture rendering keeps the static list; the live page's gates come from data computed on the server.
1 parent 0d4758a commit 564039b

23 files changed

Lines changed: 228 additions & 7 deletions

File tree

‎apps/sim/platform/app/(shell)/settings/[[...section]]/page.tsx‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ import { SETTINGS_DESTINATIONS } from '@/platform/app/(shell)/_components/settin
33
import { SettingsScreen } from '@/platform/app/(shell)/settings/_components/settings-screen/settings-screen'
44
import { readScenario } from '@/platform/design-system/navigation'
55
import { loadSettingsData, loadShellData } from '@/platform/fixtures'
6+
import { resolvePlatformMode } from '@/platform/lib/data/mode'
67

78
export default async function Page({
89
searchParams,
910
params,
1011
}: PageProps<'/settings/[[...section]]'>) {
1112
const [query, { section: path }] = await Promise.all([searchParams, params])
13+
if (resolvePlatformMode() === 'live') {
14+
const { LiveSettings } = await import(
15+
'@/platform/app/(shell)/settings/_components/live-settings/live-settings'
16+
)
17+
return <LiveSettings path={path ?? []} query={query} />
18+
}
1219
const section = path?.[0] ?? 'preferences'
1320
const destination = SETTINGS_DESTINATIONS.find((item) => item.key === section)
1421
if ((path && path.length !== 1) || !destination) notFound()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { notFound } from 'next/navigation'
2+
import { resolveLiveSetting } from '@/platform/app/(shell)/_components/settings-navigation/destinations'
3+
import { SETTINGS_SECTIONS } from '@/platform/app/(shell)/settings/_components/section-registry'
4+
import { SettingsScreen } from '@/platform/app/(shell)/settings/_components/settings-screen/settings-screen'
5+
import { readOrganizationSurface } from '@/platform/lib/data/surface'
6+
7+
interface LiveSettingsProps {
8+
path: readonly string[]
9+
query: Record<string, string | string[] | undefined>
10+
}
11+
12+
/** A live Settings section. The shell layout has already answered any surface failure. */
13+
export async function LiveSettings({ path, query }: LiveSettingsProps) {
14+
const surface = await readOrganizationSurface()
15+
if (surface.status !== 'ok') return null
16+
const { organization } = surface
17+
const [key = 'preferences', ...subpath] = path
18+
const setting = resolveLiveSetting(key, organization)
19+
if (!setting) notFound()
20+
const entry = SETTINGS_SECTIONS[setting.key]
21+
if (subpath.length && !entry.subpaths?.includes(subpath.join('/'))) notFound()
22+
const { default: Section } = await entry.load()
23+
return (
24+
<SettingsScreen section={setting.key} title={setting.title} data={null}>
25+
<Section organization={organization} subpath={subpath} query={query} />
26+
</SettingsScreen>
27+
)
28+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import type { ComponentType } from 'react'
2+
import type { LiveSettingsKey } from '@/platform/app/(shell)/_components/settings-navigation/destinations'
3+
import type { PlatformOrganization } from '@/platform/lib/data/organization-model'
4+
5+
/** What a section receives. Its gate has already passed; its own API calls enforce the same rule. */
6+
export interface SettingsSectionProps {
7+
organization: PlatformOrganization
8+
/** Segments after the section's key, limited to its declared `subpaths`. */
9+
subpath: readonly string[]
10+
query: Record<string, string | string[] | undefined>
11+
}
12+
13+
interface SettingsSectionEntry {
14+
load: () => Promise<{ default: ComponentType<SettingsSectionProps> }>
15+
subpaths?: readonly string[]
16+
}
17+
18+
/**
19+
* One lazily loaded folder per live section, so a section's owner edits only that folder. The
20+
* `Record` makes a section missing from either side of this map and its navigation entry a
21+
* compile error. Navigation and gates live in `settings-navigation/destinations.ts`.
22+
*/
23+
export const SETTINGS_SECTIONS: Record<LiveSettingsKey, SettingsSectionEntry> = {
24+
preferences: {
25+
load: () =>
26+
import(
27+
'@/platform/app/(shell)/settings/_components/sections/preferences/preferences-section'
28+
),
29+
},
30+
notifications: {
31+
load: () =>
32+
import(
33+
'@/platform/app/(shell)/settings/_components/sections/notifications/notifications-section'
34+
),
35+
},
36+
'keyboard-shortcuts': {
37+
load: () =>
38+
import(
39+
'@/platform/app/(shell)/settings/_components/sections/keyboard-shortcuts/keyboard-shortcuts-section'
40+
),
41+
},
42+
privacy: {
43+
load: () =>
44+
import('@/platform/app/(shell)/settings/_components/sections/privacy/privacy-section'),
45+
},
46+
account: {
47+
load: () =>
48+
import('@/platform/app/(shell)/settings/_components/sections/account/account-section'),
49+
},
50+
'knowledge-graphs': {
51+
load: () =>
52+
import(
53+
'@/platform/app/(shell)/settings/_components/sections/knowledge-graphs/knowledge-graphs-section'
54+
),
55+
},
56+
'recently-deleted': {
57+
load: () =>
58+
import(
59+
'@/platform/app/(shell)/settings/_components/sections/recently-deleted/recently-deleted-section'
60+
),
61+
},
62+
members: {
63+
load: () =>
64+
import('@/platform/app/(shell)/settings/_components/sections/members/members-section'),
65+
},
66+
billing: {
67+
load: () =>
68+
import('@/platform/app/(shell)/settings/_components/sections/billing/billing-section'),
69+
},
70+
usage: {
71+
load: () => import('@/platform/app/(shell)/settings/_components/sections/usage/usage-section'),
72+
subpaths: ['events'],
73+
},
74+
whitelabeling: {
75+
load: () =>
76+
import(
77+
'@/platform/app/(shell)/settings/_components/sections/whitelabeling/whitelabeling-section'
78+
),
79+
},
80+
requests: {
81+
load: () =>
82+
import('@/platform/app/(shell)/settings/_components/sections/requests/requests-section'),
83+
},
84+
links: {
85+
load: () => import('@/platform/app/(shell)/settings/_components/sections/links/links-section'),
86+
},
87+
'audit-logs': {
88+
load: () =>
89+
import('@/platform/app/(shell)/settings/_components/sections/audit-logs/audit-logs-section'),
90+
},
91+
'access-control': {
92+
load: () =>
93+
import(
94+
'@/platform/app/(shell)/settings/_components/sections/access-control/access-control-section'
95+
),
96+
},
97+
sso: {
98+
load: () => import('@/platform/app/(shell)/settings/_components/sections/sso/sso-section'),
99+
},
100+
security: {
101+
load: () =>
102+
import('@/platform/app/(shell)/settings/_components/sections/security/security-section'),
103+
},
104+
'data-retention': {
105+
load: () =>
106+
import(
107+
'@/platform/app/(shell)/settings/_components/sections/data-retention/data-retention-section'
108+
),
109+
},
110+
'data-drains': {
111+
load: () =>
112+
import(
113+
'@/platform/app/(shell)/settings/_components/sections/data-drains/data-drains-section'
114+
),
115+
},
116+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function AccessControlSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function AccountSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function AuditLogsSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function BillingSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function DataDrainsSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function DataRetentionSection() {
2+
return null
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function KeyboardShortcutsSection() {
2+
return null
3+
}

0 commit comments

Comments
 (0)