fix(admin-panel): inline skeleton loaders for table sections (#20014)

## Summary
\`SettingsSkeletonLoader\` wraps its content in \`PageHeader\` +
\`PageBody\`, which is right for **full-page replacement** (user detail,
config variable detail, etc.) but renders as a large empty stub with one
tiny floating bar when placed **inline inside a section that's already
scaffolded**. That's what showed up in Recent Users, Top Workspaces, and
the Chats tab in the admin panel — a jarring white page flash where a
few row placeholders should be.

This PR adds \`SettingsAdminSectionSkeletonLoader\` — a small,
configurable-row-count skeleton that uses the project's standard
\`SkeletonTheme\` pattern (\`theme.background.tertiary\` /
\`theme.background.transparent.lighter\` + \`borderRadius: 4\`, matching
\`PageContentSkeletonLoader\` and \`SettingsAdminTabSkeletonLoader\`)
and renders row-height bars that match \`TableRow\` spacing. Swaps it
into the three inline call sites.

Full-page usages of \`SettingsSkeletonLoader\` are unchanged.

### Changed
- **New**:
\`packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminSectionSkeletonLoader.tsx\`
- **Swapped** (3 inline loading states): \`SettingsAdminGeneral.tsx\`
(Recent Users + Top Workspaces), \`SettingsAdminWorkspaceDetail.tsx\`
(Chats tab)

## Test plan
- [x] typecheck (\`npx nx typecheck twenty-front --skip-nx-cache\`) —
clean
- [x] oxlint — 0 warnings
- [x] prettier — clean
- [ ] Visual: navigate to admin panel, observe Recent Users / Top
Workspaces / Chats tab loading — should see a tight stack of row-height
placeholder bars instead of a big empty page stub

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Félix Malfait
2026-04-23 21:58:33 +02:00
committed by GitHub
parent b1838b3090
commit ec98130def
11 changed files with 53 additions and 101 deletions
@@ -1,9 +1,9 @@
import { canManageFeatureFlagsState } from '@/client-config/states/canManageFeatureFlagsState';
import { useApolloAdminClient } from '@/settings/admin-panel/apollo/hooks/useApolloAdminClient';
import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader';
import { SettingsAdminVersionContainer } from '@/settings/admin-panel/components/SettingsAdminVersionContainer';
import { ADMIN_PANEL_RECENT_USERS } from '@/settings/admin-panel/graphql/queries/adminPanelRecentUsers';
import { ADMIN_PANEL_TOP_WORKSPACES } from '@/settings/admin-panel/graphql/queries/adminPanelTopWorkspaces';
import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader';
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
import { Table } from '@/ui/layout/table/components/Table';
import { TableBody } from '@/ui/layout/table/components/TableBody';
@@ -105,7 +105,7 @@ export const SettingsAdminGeneral = () => {
fullWidth
/>
{isLoadingUsers ? (
<SettingsSkeletonLoader />
<SettingsSectionSkeletonLoader />
) : recentUsers.length === 0 ? (
<StyledEmptyState>
{t`No users found matching your search criteria.`}
@@ -154,7 +154,7 @@ export const SettingsAdminGeneral = () => {
fullWidth
/>
{isLoadingWorkspaces ? (
<SettingsSkeletonLoader />
<SettingsSectionSkeletonLoader />
) : topWorkspaces.length === 0 ? (
<StyledEmptyState>
{t`No workspaces found matching your search criteria.`}
@@ -1,18 +0,0 @@
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const SettingsAdminTabSkeletonLoader = () => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
highlightColor={theme.background.transparent.lighter}
borderRadius={4}
>
<Skeleton height={SKELETON_LOADER_HEIGHT_SIZES.standard.m} width={120} />
</SkeletonTheme>
);
};