Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import { CredentialsSkeleton } from '@/app/workspace/[workspaceId]/settings/comp
import { CustomToolsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/custom-tools/custom-tool-skeleton'
import { GeneralSkeleton } from '@/app/workspace/[workspaceId]/settings/components/general/general-skeleton'
import { InboxSkeleton } from '@/app/workspace/[workspaceId]/settings/components/inbox/inbox-skeleton'
import { IntegrationsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton'
import { McpSkeleton } from '@/app/workspace/[workspaceId]/settings/components/mcp/mcp-skeleton'
import { SkillsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/skills/skill-skeleton'
import { RecentlyDeletedSkeleton } from '@/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted-skeleton'
import { WorkflowMcpServersSkeleton } from '@/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers-skeleton'
import type { SettingsSection } from '@/app/workspace/[workspaceId]/settings/navigation'
import {
Expand Down Expand Up @@ -52,7 +54,7 @@ const Integrations = dynamic(
import('@/app/workspace/[workspaceId]/settings/components/integrations/integrations').then(
(m) => m.Integrations
),
{ loading: () => <CredentialsSkeleton /> }
{ loading: () => <IntegrationsSkeleton /> }
)
const Credentials = dynamic(
() =>
Expand Down Expand Up @@ -145,7 +147,7 @@ const RecentlyDeleted = dynamic(
import(
'@/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted'
).then((m) => m.RecentlyDeleted),
{ loading: () => <SettingsSectionSkeleton /> }
{ loading: () => <RecentlyDeletedSkeleton /> }
)
const AccessControl = dynamic(
() => import('@/ee/access-control/components/access-control').then((m) => m.AccessControl),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,79 @@
import { Skeleton } from '@/components/emcn'

/**
* Skeleton component for admin settings loading state.
* Matches the exact layout structure of the Admin component.
*/
export function AdminSkeleton() {
return (
<div className='flex h-full flex-col gap-6'>
{/* Super admin mode toggle */}
<div className='flex items-center justify-between'>
<Skeleton className='h-[14px] w-[120px]' />
<Skeleton className='h-[20px] w-[36px] rounded-full' />
</div>

<div className='h-px bg-[var(--border-secondary)]' />

{/* Workflow import section */}
<div className='flex flex-col gap-2'>
<Skeleton className='h-[14px] w-[340px]' />
<div className='flex gap-2'>
<Skeleton className='h-9 flex-1 rounded-md' />
<Skeleton className='h-9 w-[80px] rounded-md' />
</div>
</div>
<div className='flex flex-col gap-2'>

<div className='h-px bg-[var(--border-secondary)]' />

{/* User management section */}
<div className='flex flex-col gap-3'>
<Skeleton className='h-[14px] w-[120px]' />
<Skeleton className='h-[200px] w-full rounded-lg' />

{/* Search input + button */}
<div className='flex gap-2'>
<Skeleton className='h-9 flex-1 rounded-md' />
<Skeleton className='h-9 w-[80px] rounded-md' />
</div>

{/* Table */}
<div className='flex flex-col gap-0.5'>
{/* Column headers */}
<div className='flex items-center gap-3 border-[var(--border-secondary)] border-b px-3 py-2'>
<Skeleton className='h-[12px] w-[200px]' />
<Skeleton className='h-[12px] flex-1' />
<Skeleton className='h-[12px] w-[80px]' />
<Skeleton className='h-[12px] w-[80px]' />
<Skeleton className='h-[12px] w-[250px]' />
</div>

{/* Table rows */}
{Array.from({ length: 5 }).map((_, i) => (
<div
key={i}
className='flex items-center gap-3 border-[var(--border-secondary)] border-b px-3 py-2 last:border-b-0'
>
<Skeleton className='h-[14px] w-[200px]' />
<Skeleton className='h-[14px] flex-1' />
<Skeleton className='h-[20px] w-[50px] rounded-full' />
<Skeleton className='h-[20px] w-[50px] rounded-full' />
<div className='flex w-[250px] justify-end gap-1'>
<Skeleton className='h-[28px] w-[80px] rounded-md' />
<Skeleton className='h-[28px] w-[64px] rounded-md' />
<Skeleton className='h-[28px] w-[40px] rounded-md' />
</div>
</div>
))}
</div>

{/* Pagination */}
<div className='flex items-center justify-between'>
<Skeleton className='h-[14px] w-[160px]' />
<div className='flex gap-1'>
<Skeleton className='h-[28px] w-[64px] rounded-md' />
<Skeleton className='h-[28px] w-[48px] rounded-md' />
</div>
</div>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,37 @@ export function ApiKeySkeleton() {
export function ApiKeysSkeleton() {
return (
<div className='flex h-full flex-col gap-4.5'>
{/* Search bar and Create button */}
<div className='flex items-center gap-2'>
<Skeleton className='h-[30px] flex-1 rounded-lg' />
<Skeleton className='h-[30px] w-[80px] rounded-md' />
<Skeleton className='h-[38px] flex-1 rounded-lg' />
<Skeleton className='h-[38px] w-[90px] rounded-md' />
</div>
<div className='flex flex-col gap-2'>
<ApiKeySkeleton />
<ApiKeySkeleton />

{/* Scrollable content area */}
<div className='min-h-0 flex-1 overflow-y-auto'>
<div className='flex flex-col gap-4.5'>
{/* Workspace section */}
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[80px]' />
<Skeleton className='h-5 w-[180px]' />
</div>

{/* Personal section */}
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[60px]' />
<ApiKeySkeleton />
<ApiKeySkeleton />
</div>
</div>
</div>

{/* Bottom toggle section */}
<div className='mt-6 flex items-center justify-between'>
<div className='flex items-center gap-2'>
<Skeleton className='h-5 w-[170px]' />
<Skeleton className='h-3 w-3 rounded-full' />
</div>
<Skeleton className='h-5 w-9 rounded-full' />
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@ export function ApiKeys() {
<div ref={scrollContainerRef} className='min-h-0 flex-1 overflow-y-auto'>
{isLoading ? (
<div className='flex flex-col gap-4.5'>
{/* Workspace section header */}
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[70px]' />
<div className='text-[var(--text-muted)] text-sm'>
<Skeleton className='h-5 w-[140px]' />
</div>
<Skeleton className='h-5 w-[80px]' />
<Skeleton className='h-5 w-[180px]' />
</div>
{/* Personal section header + keys */}
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[55px]' />
<Skeleton className='h-5 w-[60px]' />
<ApiKeySkeleton />
<ApiKeySkeleton />
</div>
Expand Down Expand Up @@ -310,6 +310,15 @@ export function ApiKeys() {
</div>

{/* Allow Personal API Keys Toggle - Fixed at bottom */}
{isLoading && canManageWorkspaceKeys && (
<div className='mt-6 flex items-center justify-between'>
<div className='flex items-center gap-2'>
<Skeleton className='h-5 w-[170px]' />
<Skeleton className='h-3 w-3 rounded-full' />
</div>
<Skeleton className='h-5 w-9 rounded-full' />
</div>
)}
{!isLoading && canManageWorkspaceKeys && (
<Tooltip.Provider delayDuration={150}>
<div className='mt-6 flex items-center justify-between'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ export function BYOKKeySkeleton() {
<div className='flex items-center gap-3'>
<Skeleton className='h-9 w-9 flex-shrink-0 rounded-md' />
<div className='flex min-w-0 flex-col justify-center gap-[1px]'>
<Skeleton className='h-[14px] w-[100px]' />
<Skeleton className='h-[13px] w-[200px]' />
<Skeleton className='h-[16px] w-[100px]' />
<Skeleton className='h-[14px] w-[200px]' />
</div>
</div>
<Skeleton className='h-[32px] w-[72px] rounded-md' />
<div className='flex flex-shrink-0 items-center gap-2'>
<Skeleton className='h-[32px] w-[72px] rounded-md' />
<Skeleton className='h-[32px] w-[64px] rounded-md' />
</div>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,75 @@
import { Skeleton } from '@/components/emcn'

const GRID_COLS = 'grid grid-cols-[minmax(0,1fr)_8px_minmax(0,1fr)_auto] items-center'
const GRID_COLS = 'grid grid-cols-[minmax(0,1fr)_8px_minmax(0,1fr)_auto_auto] items-center'
const COL_SPAN_ALL = 'col-span-5'

/**
* Skeleton component for a single secret row in the grid layout.
* Skeleton for a single integration credential row.
*/
export function CredentialSkeleton() {
return (
<div className={GRID_COLS}>
<div className='flex items-center justify-between gap-3'>
<div className='flex min-w-0 items-center gap-2.5'>
<Skeleton className='h-8 w-8 flex-shrink-0 rounded-md' />
<div className='flex min-w-0 flex-col justify-center gap-[1px]'>
<Skeleton className='h-4 w-[120px] rounded' />
<Skeleton className='h-3.5 w-[160px] rounded' />
</div>
</div>
<div className='flex flex-shrink-0 items-center gap-1'>
<Skeleton className='h-9 w-[60px] rounded-md' />
<Skeleton className='h-9 w-[88px] rounded-md' />
</div>
</div>
)
}

/**
* Skeleton for a single secret row matching the credentials grid layout.
*/
function CredentialRowSkeleton() {
return (
<div className='contents'>
<Skeleton className='h-9 rounded-md' />
<div />
<Skeleton className='h-9 rounded-md' />
<div className='ml-2 flex items-center gap-0'>
<Skeleton className='h-9 w-9 rounded-md' />
<Skeleton className='h-9 w-9 rounded-md' />
</div>
<Skeleton className='ml-2 h-9 w-[60px] rounded-md' />
<Skeleton className='h-9 w-9 rounded-md' />
</div>
)
}

/**
* Skeleton for the Secrets section shown during dynamic import loading.
* Skeleton for the Credentials (Secrets) page shown during dynamic import loading.
*/
export function CredentialsSkeleton() {
return (
<div className='flex h-full flex-col gap-4'>
{/* Search bar + Save button */}
<div className='flex items-center gap-2'>
<Skeleton className='h-[30px] flex-1 rounded-lg' />
<Skeleton className='h-[30px] w-[56px] rounded-md' />
<Skeleton className='h-[30px] w-[50px] rounded-md' />
</div>
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[70px]' />
<div className='text-[var(--text-muted)] text-small'>
<Skeleton className='h-5 w-[160px]' />

{/* Scrollable content area */}
<div className='min-h-0 flex-1 overflow-y-auto'>
<div className='flex flex-col gap-4'>
<div className={`${GRID_COLS} gap-y-2`}>
{/* Workspace section header */}
<Skeleton className={`${COL_SPAN_ALL} h-5 w-[70px]`} />
<CredentialRowSkeleton />
<CredentialRowSkeleton />

{/* Spacer matching the real component */}
<div className={`${COL_SPAN_ALL} h-[8px]`} />

{/* Personal section header */}
<Skeleton className={`${COL_SPAN_ALL} h-5 w-[55px]`} />
<CredentialRowSkeleton />
<CredentialRowSkeleton />
</div>
</div>
</div>
<div className='flex flex-col gap-2'>
<Skeleton className='h-5 w-[55px]' />
<CredentialSkeleton />
<CredentialSkeleton />
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export function CustomToolSkeleton() {
return (
<div className='flex items-center justify-between gap-3'>
<div className='flex min-w-0 flex-col justify-center gap-[1px]'>
<Skeleton className='h-[14px] w-[100px]' />
<Skeleton className='h-[13px] w-[200px]' />
<Skeleton className='h-4 w-[100px]' />
<Skeleton className='h-3.5 w-[200px]' />
</div>
<div className='flex flex-shrink-0 items-center gap-2'>
<Skeleton className='h-[30px] w-[40px] rounded-sm' />
<Skeleton className='h-[30px] w-[52px] rounded-sm' />
<Skeleton className='h-[30px] w-[54px] rounded-sm' />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ export function GeneralSkeleton() {
<Skeleton className='h-9 w-9 rounded-full' />
<div className='flex flex-1 flex-col justify-center gap-[1px]'>
<div className='flex items-center gap-2'>
<Skeleton className='h-5 w-24' />
<Skeleton className='h-4 w-24' />
<Skeleton className='h-[10.5px] w-[10.5px]' />
</div>
<Skeleton className='h-5 w-40' />
<Skeleton className='h-3.5 w-40' />
</div>
</div>

Expand Down
Loading
Loading