Skip to content

refactor(platform): provider drawer — headers outside Card, ghost buttons, collapsible options guide#1732

Open
Israeltheminer wants to merge 2 commits into
mainfrom
refactor/provider-drawer-sections-layout
Open

refactor(platform): provider drawer — headers outside Card, ghost buttons, collapsible options guide#1732
Israeltheminer wants to merge 2 commits into
mainfrom
refactor/provider-drawer-sections-layout

Conversation

@Israeltheminer
Copy link
Copy Markdown
Collaborator

@Israeltheminer Israeltheminer commented May 22, 2026

Summary

Tighten the provider detail drawer layout and the provider-options copy.

  • Layout — section headers (General, API Key, Default Models, Provider Options, Models) live outside each Card so the drawer reads as header + content pairs instead of fully enclosed Card sections. Dropped the bespoke SectionHeader helper.
  • Buttons — inline Edit / Test / Add Model / Fetch from Provider actions are now ghost Buttons for visual consistency with the rest of the surface.
  • InfoRow — tighter padding (px-5 py-3.5px-4 py-2.5) and align="start" so multi-line values wrap cleanly; skeleton rebuilt to mirror the new layout.
  • Provider Options guide — the long help copy is rendered through CollapsibleGuide with markdown: bold headings, bullet lists, fenced ```json blocks. New providers.providerOptions.guideLabel translation added in en/de/fr. CollapsibleGuide now styles <pre> blocks.
  • Row Edit fix — wrapping ProviderEditPanel in ProviderEditPanelLoader that fetches config + hash and supplies ProviderConfigProvider. Without it useProviderConfig throws when invoked from the row-level Edit action.
  • PolishCard radius rounded-xlrounded-lg; tabs list min-w-full justify-around so the underline spans the container; the provider-add-panel Models header matches the drawer styling.

Test plan

  • Settings → Providers → row Edit opens the edit panel populated with the existing config (regression for the row Edit crash)
  • Provider detail drawer — General / API Key / Default Models / Provider Options / Models sections render with header outside Card; ghost buttons line up; multi-line values wrap
  • Provider Options guide expands and renders bold/lists/fenced JSON blocks correctly
  • Loading skeleton matches the new layout
  • Translations in en/de/fr show the new guide label

Summary by CodeRabbit

Release Notes

  • Improvements

    • Enhanced provider settings interface with clearer section layouts and improved visual hierarchy.
    • Provider options now displayed in collapsible, expandable guides for better readability.
    • Refined component spacing and corner radius styling for a more polished appearance.
  • Documentation

    • Updated provider options help text with clearer explanations, examples, and improved multilingual support (English, German, French).

Review Change Stack

…tons, collapsible options guide

- Move section headers (General, API Key, Default Models, Provider Options, Models) outside the Card so each section is a header + content pair instead of an enclosed Card with internal `SectionHeader`. Drops the bespoke `SectionHeader` helper.
- Switch inline Edit/Test/Add Model/Fetch from Provider actions to ghost `Button` for visual consistency.
- Tighten InfoRow padding (px-5 py-3.5 → px-4 py-2.5) and align="start" so multi-line values wrap cleanly; rebuild the skeleton to mirror the new layout.
- Render the long provider-options copy through `CollapsibleGuide` with markdown — bold headings, bullet lists, fenced ```json blocks — and add `providers.providerOptions.guideLabel` in en/de/fr. Update `CollapsibleGuide` to style `<pre>` blocks.
- Fix row-level Edit on the providers table: wrap `ProviderEditPanel` in a `ProviderEditPanelLoader` that fetches config + hash and supplies `ProviderConfigProvider`, otherwise `useProviderConfig` throws.
- Minor: `Card` radius `rounded-xl` → `rounded-lg`; tabs list `min-w-full justify-around` so the underline spans the container; `provider-add-panel` Models header matches drawer styling.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

This PR refactors the provider options documentation system to use collapsible guides with markdown formatting, removes a shared SectionHeader helper from ProviderDetailDrawer in favor of per-section header management, adds localization support with improved help text across English, German, and French, introduces a ProviderEditPanelLoader to provide configuration context during provider editing, and applies minor styling updates to several UI components.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • yannickmonney
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main changes: refactoring the provider drawer with headers moved outside cards, ghost button styling, and a collapsible options guide.
Description check ✅ Passed The description includes a comprehensive summary of all changes, directly addresses the pre-merge checklist, provides detailed test plan items, and explains the rationale for each modification.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/provider-drawer-sections-layout

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
services/platform/app/features/settings/providers/components/provider-options-editor.tsx (1)

9-23: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Keep imports contiguous at the top of the module.

providerOptionsClientSchema currently splits two import groups. Move all imports above declarations to match repository conventions.

Proposed fix
 import { JsonInput } from '`@/app/components/ui/forms/json-input`';
 import { Textarea } from '`@/app/components/ui/forms/textarea`';
+import { Card } from '`@/app/components/ui/layout/card`';
+import { HStack, Stack } from '`@/app/components/ui/layout/layout`';
+import { Sheet } from '`@/app/components/ui/overlays/sheet`';
+import { Text } from '`@/app/components/ui/typography/text`';
+import { toast } from '`@/app/hooks/use-toast`';
+import { useT } from '`@/lib/i18n/client`';
 
 // Permissive client-side schema: server-side `providerJsonSchema.parse` is the
 // authoritative gate (it carries the deny-list). This schema only catches
 // "is JSON, is an object" so we don't ship obviously malformed input.
 const providerOptionsClientSchema = z.record(z.string(), z.unknown());
-import { Card } from '`@/app/components/ui/layout/card`';
-import { HStack, Stack } from '`@/app/components/ui/layout/layout`';
-import { Sheet } from '`@/app/components/ui/overlays/sheet`';
-import { Text } from '`@/app/components/ui/typography/text`';
-import { toast } from '`@/app/hooks/use-toast`';
-import { useT } from '`@/lib/i18n/client`';

As per coding guidelines: "Imports at the top, exports at the bottom, both sorted."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@services/platform/app/features/settings/providers/components/provider-options-editor.tsx`
around lines 9 - 23, The declaration providerOptionsClientSchema is placed
between import statements, breaking the "imports contiguous at top" rule; move
the line declaring providerOptionsClientSchema (and its z.record(...)
definition) so that all import statements (e.g. CollapsibleGuide, ConfirmDialog,
JsonInput, Textarea, Card, HStack, Stack, Sheet, Text, toast, useT) appear first
in the file, then add the providerOptionsClientSchema declaration after the
imports (and before any exports), ensuring imports remain grouped at the top and
declarations follow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/platform/app/components/ui/data-display/collapsible-guide.tsx`:
- Around line 53-60: The custom react-markdown pre renderer is currently
spreading all incoming props and then overwriting className; update the renderer
in collapsible-guide.tsx to destructure className (e.g. ({ children, className,
...props }) => ...) and merge it with the component's default classes using a
classname helper (clsx/cn) so incoming className is preserved, and only spread
the remaining DOM-safe props (e.g. ...props) onto <pre> to avoid leaking non-DOM
props.

In
`@services/platform/app/features/settings/providers/components/provider-detail-drawer.tsx`:
- Around line 168-243: Remove the JSX section-structure comments in the skeleton
render block (the comment nodes like {/* GeneralSection: header outside, Card
with 3 InfoRows */}, {/* ApiKeySection: ... */}, {/* DefaultModelsSection: ...
*/}, {/* ProviderOptionsSection: ... */}, {/* ModelsSection: ... */}) so only
the actual JSX elements (Stack, HStack, Card, Skeleton, Array.from mappings
keyed by i, and cn usages) remain; do not change any component structure, props,
or keys (e.g., the Array.from maps, key={i}, className uses of cn), just delete
those explanatory "what" comments to comply with the comment guideline.
- Around line 199-203: The skeleton header HStack currently uses className "px-5
py-3.5" which causes a layout jump compared to the loaded API key rows that use
"px-4 py-2.5"; update the skeleton HStack (in provider-detail-drawer.tsx) to use
the same padding classes as the API key rows (replace "px-5 py-3.5" with "px-4
py-2.5") so the loading and resolved states share identical spacing (look for
the HStack rendering the API key skeleton and the elements rendering the actual
API key rows to confirm both are updated).

In
`@services/platform/app/features/settings/providers/components/providers-table.tsx`:
- Around line 300-303: The component currently returns null when the
useReadProvider hook yields no ok data (the block checking data?.ok after
calling useReadProvider(orgSlug, providerName, { enabled: !!orgSlug })), which
gives no user feedback; change this to render a loading state while the query is
fetching (e.g., a spinner/skeleton inside the sheet when data is undefined or
isLoading from the hook) and render an error state when the query returns an
error or data.ok is false (show an inline error message and trigger a toast via
your existing toast utility) instead of returning null so users see progress and
failure reasons when they click Edit.

---

Outside diff comments:
In
`@services/platform/app/features/settings/providers/components/provider-options-editor.tsx`:
- Around line 9-23: The declaration providerOptionsClientSchema is placed
between import statements, breaking the "imports contiguous at top" rule; move
the line declaring providerOptionsClientSchema (and its z.record(...)
definition) so that all import statements (e.g. CollapsibleGuide, ConfirmDialog,
JsonInput, Textarea, Card, HStack, Stack, Sheet, Text, toast, useT) appear first
in the file, then add the providerOptionsClientSchema declaration after the
imports (and before any exports), ensuring imports remain grouped at the top and
declarations follow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f1ad83d1-4294-4424-8f8b-c76b1a4844e9

📥 Commits

Reviewing files that changed from the base of the PR and between 3a5f83a and 9665bdb.

📒 Files selected for processing (10)
  • services/platform/app/components/ui/data-display/collapsible-guide.tsx
  • services/platform/app/components/ui/layout/card.tsx
  • services/platform/app/components/ui/navigation/tabs.tsx
  • services/platform/app/features/settings/providers/components/provider-add-panel.tsx
  • services/platform/app/features/settings/providers/components/provider-detail-drawer.tsx
  • services/platform/app/features/settings/providers/components/provider-options-editor.tsx
  • services/platform/app/features/settings/providers/components/providers-table.tsx
  • services/platform/messages/de.json
  • services/platform/messages/en.json
  • services/platform/messages/fr.json

Comment on lines +53 to +60
pre: ({ children, ...rest }) => (
<pre
{...rest}
className="bg-muted/60 border-border my-2 overflow-x-auto rounded-md border p-3 font-mono text-[11px] leading-relaxed"
>
{children}
</pre>
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find react-markdown usage and likely custom component renderers
rg -n "react-markdown" -S .
rg -n "components=\{\{[^\}]*pre\s*:" -S --glob="*.{ts,tsx,js,jsx}" .
rg -n "pre:\s*\(\s*\{[^}]*className" -S --glob="*.{ts,tsx,js,jsx}" .
rg -n "node:\s*_" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components/ui/data-display || true

Repository: tale-project/tale

Length of output: 6166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Limit search scope to likely directories to avoid huge output
rg -n "react-markdown" -S services/platform/app/components --glob="*.{ts,tsx,js,jsx}"
rg -n "components=\{\{[^\}]*pre\s*:" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components
rg -n "pre:\s*\(\s*\{[^}]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components
# Also look for cn(., className) merge patterns in markdown pre/code renderers
rg -n "cn\([^)]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components | head -n 50

Repository: tale-project/tale

Length of output: 178


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "react-markdown" -S services/platform/app/components --glob="*.{ts,tsx,js,jsx}"
rg -n "components=\{\{[^\}]*pre\s*:" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components || true
rg -n "pre:\s*\(\s*\{[^}]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components || true
rg -n "cn\([^)]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components | head -n 50

Repository: tale-project/tale

Length of output: 6360


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "react-markdown" -S services/platform/app/components --glob="*.{ts,tsx,js,jsx}"
rg -n "components=\{\{[^\}]*pre\s*:" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components || true
rg -n "pre:\s*\(\s*\{[^}]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components || true
rg -n "cn\([^)]*className" -S --glob="*.{ts,tsx,js,jsx}" services/platform/app/components | head -n 50

Repository: tale-project/tale

Length of output: 6434


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "react-markdown" -S . --glob="*.{ts,tsx,js,jsx}" | head -n 100

Repository: tale-project/tale

Length of output: 5261


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "react-markdown" -S . --glob="*.{ts,tsx,js,jsx}" | head -n 200

Repository: tale-project/tale

Length of output: 5261


Preserve incoming className (and avoid leaking non-DOM props) in react-markdown pre: the current renderer spreads ...rest onto <pre> and then hard-sets className, overwriting any provided className.

Proposed fix
-            pre: ({ children, ...rest }) => (
+            pre: ({ node: _node, className, children, ...rest }) => (
               <pre
                 {...rest}
-                className="bg-muted/60 border-border my-2 overflow-x-auto rounded-md border p-3 font-mono text-[11px] leading-relaxed"
+                className={cn(
+                  'bg-muted/60 border-border my-2 overflow-x-auto rounded-md border p-3 font-mono text-[11px] leading-relaxed',
+                  className,
+                )}
               >
                 {children}
               </pre>
             ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/platform/app/components/ui/data-display/collapsible-guide.tsx`
around lines 53 - 60, The custom react-markdown pre renderer is currently
spreading all incoming props and then overwriting className; update the renderer
in collapsible-guide.tsx to destructure className (e.g. ({ children, className,
...props }) => ...) and merge it with the component's default classes using a
classname helper (clsx/cn) so incoming className is preserved, and only spread
the remaining DOM-safe props (e.g. ...props) onto <pre> to avoid leaking non-DOM
props.

Comment on lines 168 to 243
{/* GeneralSection: header outside, Card with 3 InfoRows */}
<Stack gap={2}>
<HStack justify="between" align="center">
<Skeleton className="h-5 w-16" />
<Skeleton className="h-5 w-32" />
<Skeleton className="h-4 w-28" />
<Skeleton className="h-8 w-20" />
</HStack>
</Card>
<Card contentClassName="p-5">
<Stack gap={4}>
<HStack justify="between" className="border-b pb-4">
<Skeleton className="h-5 w-28" />
<Skeleton className="h-4 w-20" />
<Card contentClassName="p-0">
{Array.from({ length: 3 }).map((_, i) => (
<HStack
key={i}
gap={4}
align="start"
className={cn('px-4 py-2.5', i < 2 && 'border-b')}
>
<Skeleton className="h-4 w-28 shrink-0" />
<Skeleton className="h-4 w-48" />
</HStack>
))}
</Card>
</Stack>

{/* ApiKeySection: header (title + 2 ghost buttons) outside, Card with badge row */}
<Stack gap={2}>
<HStack justify="between" align="center">
<Skeleton className="h-5 w-16" />
<HStack gap={1} align="center">
<Skeleton className="h-8 w-28" />
<Skeleton className="h-8 w-24" />
</HStack>
<Stack gap={3} className="divide-y">
{Array.from({ length: 3 }).map((_, i) => (
<HStack key={i} gap={4} className="pt-3 first:pt-0">
<Skeleton className="h-4 w-28" />
<Skeleton className="h-4 w-32" />
</HStack>
))}
</HStack>
<Card contentClassName="p-0">
<HStack gap={4} align="center" className="px-5 py-3.5">
<Skeleton className="h-5 w-24 rounded-full" />
<Skeleton className="h-4 w-32" />
</HStack>
</Card>
</Stack>

{/* DefaultModelsSection: header (title + description + Edit) outside, Card with 5 InfoRows */}
<Stack gap={2}>
<HStack justify="between" align="start">
<Stack gap={1} className="min-w-0">
<Skeleton className="h-5 w-32" />
<Skeleton className="h-4 w-64" />
</Stack>
</Stack>
</Card>
<Skeleton className="h-8 w-20" />
</HStack>
<Card contentClassName="p-0">
{Array.from({ length: 5 }).map((_, i) => (
<HStack
key={i}
gap={4}
align="start"
className={cn('px-4 py-2.5', i < 4 && 'border-b')}
>
<Skeleton className="h-4 w-28 shrink-0" />
<Skeleton className="h-4 w-32" />
</HStack>
))}
</Card>
</Stack>

{/* ProviderOptionsSection: header outside, collapsible guide, Card with placeholder */}
<Stack gap={2}>
<HStack justify="between" align="center">
<Skeleton className="h-5 w-48" />
<Skeleton className="h-8 w-20" />
</HStack>
<Skeleton className="h-9 w-full rounded-lg" />
<Card contentClassName="p-5">
<Skeleton className="h-4 w-64" />
</Card>
</Stack>

{/* ModelsSection: header (title + 2 ghost buttons) outside, bordered list */}
<Stack gap={3}>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Remove section-structure JSX comments in the skeleton block.

These comments describe layout “what” rather than intent “why,” and they add noise in a straightforward render tree.

As per coding guidelines: "Comments should explain why, rarely what."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@services/platform/app/features/settings/providers/components/provider-detail-drawer.tsx`
around lines 168 - 243, Remove the JSX section-structure comments in the
skeleton render block (the comment nodes like {/* GeneralSection: header
outside, Card with 3 InfoRows */}, {/* ApiKeySection: ... */}, {/*
DefaultModelsSection: ... */}, {/* ProviderOptionsSection: ... */}, {/*
ModelsSection: ... */}) so only the actual JSX elements (Stack, HStack, Card,
Skeleton, Array.from mappings keyed by i, and cn usages) remain; do not change
any component structure, props, or keys (e.g., the Array.from maps, key={i},
className uses of cn), just delete those explanatory "what" comments to comply
with the comment guideline.

Comment on lines +199 to +203
<HStack gap={4} align="center" className="px-5 py-3.5">
<Skeleton className="h-5 w-24 rounded-full" />
<Skeleton className="h-4 w-32" />
</HStack>
</Card>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align API key skeleton spacing with loaded content spacing.

Line 199 uses px-5 py-3.5, but the loaded API key rows use px-4 py-2.5 (Lines 603 and 612). This introduces a layout jump between loading and resolved states.

Proposed fix
-          <HStack gap={4} align="center" className="px-5 py-3.5">
+          <HStack gap={4} align="center" className="px-4 py-2.5">

Also applies to: 603-613

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@services/platform/app/features/settings/providers/components/provider-detail-drawer.tsx`
around lines 199 - 203, The skeleton header HStack currently uses className
"px-5 py-3.5" which causes a layout jump compared to the loaded API key rows
that use "px-4 py-2.5"; update the skeleton HStack (in
provider-detail-drawer.tsx) to use the same padding classes as the API key rows
(replace "px-5 py-3.5" with "px-4 py-2.5") so the loading and resolved states
share identical spacing (look for the HStack rendering the API key skeleton and
the elements rendering the actual API key rows to confirm both are updated).

Comment on lines +300 to +303
const { data } = useReadProvider(orgSlug, providerName, {
enabled: !!orgSlug,
});
if (!data?.ok) return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider adding loading and error feedback.

Returning null while data loads or on error leaves users without feedback after clicking Edit. A brief loading indicator (e.g., skeleton or spinner in a sheet) and error handling (toast or inline message) would improve reliability perception.

♻️ Suggested improvement
 function ProviderEditPanelLoader({
   orgSlug,
   providerName,
   organizationId,
   onClose,
 }: {
   orgSlug: string;
   providerName: string;
   organizationId: string;
   onClose: () => void;
 }) {
-  const { data } = useReadProvider(orgSlug, providerName, {
+  const { data, isLoading, isError } = useReadProvider(orgSlug, providerName, {
     enabled: !!orgSlug,
   });
-  if (!data?.ok) return null;
+
+  if (isLoading) {
+    // Render a loading sheet/skeleton matching ProviderEditPanel layout
+    return <ProviderEditPanelSkeleton open onClose={onClose} />;
+  }
+
+  if (isError || !data?.ok) {
+    // Close panel and notify user
+    onClose();
+    return null;
+  }
+
   return (

You may also want to trigger a toast in the error branch to inform users why the panel closed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@services/platform/app/features/settings/providers/components/providers-table.tsx`
around lines 300 - 303, The component currently returns null when the
useReadProvider hook yields no ok data (the block checking data?.ok after
calling useReadProvider(orgSlug, providerName, { enabled: !!orgSlug })), which
gives no user feedback; change this to render a loading state while the query is
fetching (e.g., a spinner/skeleton inside the sheet when data is undefined or
isLoading from the hook) and render an error state when the query returns an
error or data.ok is false (show an inline error message and trigger a toast via
your existing toast utility) instead of returning null so users see progress and
failure reasons when they click Edit.

…factor

- CollapsibleGuide: preserve incoming className on the markdown <pre> renderer (merge with cn) and strip the non-DOM `node` prop instead of overwriting className and leaking node onto the DOM element.
- ProviderDetailSkeleton: drop the JSX section-structure comments — they describe what the layout is, not why.
- ProviderDetailSkeleton: align API-key row padding with the loaded state (px-5 py-3.5 → px-4 py-2.5) so loading and resolved states share spacing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant