Skip to content

Commit b3b86c8

Browse files
committed
refactor(settings): section the API keys page like secrets
Wrap Workspace, Personal, and the allow-personal-keys toggle in SettingsSection (muted label + divider) instead of bare bold headers, matching the secrets and BYOK pages.
1 parent a79b3f4 commit b3b86c8

1 file changed

Lines changed: 71 additions & 71 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/settings/components/api-keys

apps/sim/app/workspace/[workspaceId]/settings/components/api-keys/api-keys.tsx

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from '@/components/emcn'
1818
import { useSession } from '@/lib/auth/auth-client'
1919
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
20+
import { SettingsSection } from '@/app/workspace/[workspaceId]/settings/components/settings-section/settings-section'
2021
import {
2122
type ApiKey,
2223
useApiKeys,
@@ -146,20 +147,17 @@ export function ApiKeys() {
146147
Click "Create API Key" above to get started
147148
</div>
148149
) : (
149-
<div className='flex flex-col gap-4.5'>
150-
<>
151-
{/* Workspace section */}
152-
{!searchTerm.trim() ? (
153-
<div className='flex flex-col gap-2'>
154-
<div className='font-medium text-[var(--text-secondary)] text-sm'>
155-
Workspace
150+
<div className='flex flex-col gap-6'>
151+
{/* Workspace section */}
152+
{!searchTerm.trim() ? (
153+
<SettingsSection label='Workspace'>
154+
{workspaceKeys.length === 0 ? (
155+
<div className='text-[var(--text-muted)] text-sm'>
156+
No workspace API keys yet
156157
</div>
157-
{workspaceKeys.length === 0 ? (
158-
<div className='text-[var(--text-muted)] text-sm'>
159-
No workspace API keys yet
160-
</div>
161-
) : (
162-
workspaceKeys.map((key) => (
158+
) : (
159+
<div className='flex flex-col gap-2'>
160+
{workspaceKeys.map((key) => (
163161
<div key={key.id} className='flex items-center justify-between gap-3'>
164162
<div className='flex min-w-0 flex-col justify-center gap-[1px]'>
165163
<div className='flex items-center gap-1.5'>
@@ -185,14 +183,13 @@ export function ApiKeys() {
185183
Delete
186184
</Chip>
187185
</div>
188-
))
189-
)}
190-
</div>
191-
) : filteredWorkspaceKeys.length > 0 ? (
192-
<div className='flex flex-col gap-2'>
193-
<div className='font-medium text-[var(--text-secondary)] text-sm'>
194-
Workspace
186+
))}
195187
</div>
188+
)}
189+
</SettingsSection>
190+
) : filteredWorkspaceKeys.length > 0 ? (
191+
<SettingsSection label='Workspace'>
192+
<div className='flex flex-col gap-2'>
196193
{filteredWorkspaceKeys.map(({ key }) => (
197194
<div key={key.id} className='flex items-center justify-between gap-3'>
198195
<div className='flex min-w-0 flex-col justify-center gap-[1px]'>
@@ -221,12 +218,13 @@ export function ApiKeys() {
221218
</div>
222219
))}
223220
</div>
224-
) : null}
221+
</SettingsSection>
222+
) : null}
225223

226-
{/* Personal section */}
227-
{(!searchTerm.trim() || filteredPersonalKeys.length > 0) && (
224+
{/* Personal section */}
225+
{(!searchTerm.trim() || filteredPersonalKeys.length > 0) && (
226+
<SettingsSection label='Personal'>
228227
<div className='flex flex-col gap-2'>
229-
<div className='font-medium text-[var(--text-secondary)] text-sm'>Personal</div>
230228
{filteredPersonalKeys.map(({ key }) => {
231229
const isConflict = conflicts.includes(key.name)
232230
return (
@@ -265,61 +263,63 @@ export function ApiKeys() {
265263
)
266264
})}
267265
</div>
268-
)}
266+
</SettingsSection>
267+
)}
269268

270-
{/* Show message when search has no results across both sections */}
271-
{searchTerm.trim() &&
272-
filteredPersonalKeys.length === 0 &&
273-
filteredWorkspaceKeys.length === 0 &&
274-
(personalKeys.length > 0 || workspaceKeys.length > 0) && (
275-
<div className='py-4 text-center text-[var(--text-muted)] text-sm'>
276-
No API keys found matching "{searchTerm}"
277-
</div>
278-
)}
279-
</>
269+
{/* Show message when search has no results across both sections */}
270+
{searchTerm.trim() &&
271+
filteredPersonalKeys.length === 0 &&
272+
filteredWorkspaceKeys.length === 0 &&
273+
(personalKeys.length > 0 || workspaceKeys.length > 0) && (
274+
<div className='py-4 text-center text-[var(--text-muted)] text-sm'>
275+
No API keys found matching "{searchTerm}"
276+
</div>
277+
)}
280278
</div>
281279
)}
282280

283281
{/* Allow Personal API Keys Toggle */}
284282
{!isLoading && canManageWorkspaceKeys && (
285283
<Tooltip.Provider delayDuration={150}>
286-
<div className='mt-6 flex items-center justify-between'>
287-
<div className='flex items-center gap-2'>
288-
<span className='font-medium text-[var(--text-secondary)] text-sm'>
289-
Allow personal API keys
290-
</span>
291-
<Tooltip.Root>
292-
<Tooltip.Trigger asChild>
293-
<button
294-
type='button'
295-
className='rounded-full p-1 text-[var(--text-muted)] transition hover-hover:text-[var(--text-primary)]'
296-
>
297-
<Info className='size-[12px]' strokeWidth={2} />
298-
</button>
299-
</Tooltip.Trigger>
300-
<Tooltip.Content side='top' className='max-w-xs text-small'>
301-
Allow collaborators to create and use their own keys with billing charged to
302-
them.
303-
</Tooltip.Content>
304-
</Tooltip.Root>
284+
<SettingsSection label='Permissions'>
285+
<div className='flex items-center justify-between'>
286+
<div className='flex items-center gap-2'>
287+
<span className='text-[14px] text-[var(--text-body)]'>
288+
Allow personal API keys
289+
</span>
290+
<Tooltip.Root>
291+
<Tooltip.Trigger asChild>
292+
<button
293+
type='button'
294+
className='rounded-full p-1 text-[var(--text-muted)] transition hover-hover:text-[var(--text-primary)]'
295+
>
296+
<Info className='size-[12px]' strokeWidth={2} />
297+
</button>
298+
</Tooltip.Trigger>
299+
<Tooltip.Content side='top' className='max-w-xs text-small'>
300+
Allow collaborators to create and use their own keys with billing charged to
301+
them.
302+
</Tooltip.Content>
303+
</Tooltip.Root>
304+
</div>
305+
{isLoadingSettings ? null : (
306+
<Switch
307+
checked={allowPersonalApiKeys}
308+
disabled={!canManageWorkspaceKeys || updateSettingsMutation.isPending}
309+
onCheckedChange={async (checked) => {
310+
try {
311+
await updateSettingsMutation.mutateAsync({
312+
workspaceId,
313+
allowPersonalApiKeys: checked,
314+
})
315+
} catch (error) {
316+
logger.error('Error updating workspace settings:', { error })
317+
}
318+
}}
319+
/>
320+
)}
305321
</div>
306-
{isLoadingSettings ? null : (
307-
<Switch
308-
checked={allowPersonalApiKeys}
309-
disabled={!canManageWorkspaceKeys || updateSettingsMutation.isPending}
310-
onCheckedChange={async (checked) => {
311-
try {
312-
await updateSettingsMutation.mutateAsync({
313-
workspaceId,
314-
allowPersonalApiKeys: checked,
315-
})
316-
} catch (error) {
317-
logger.error('Error updating workspace settings:', { error })
318-
}
319-
}}
320-
/>
321-
)}
322-
</div>
322+
</SettingsSection>
323323
</Tooltip.Provider>
324324
)}
325325
</div>

0 commit comments

Comments
 (0)