diff --git a/client/src/components/Admin/AddonManager.test.tsx b/client/src/components/Admin/AddonManager.test.tsx
index 227ea731e..a602574f2 100644
--- a/client/src/components/Admin/AddonManager.test.tsx
+++ b/client/src/components/Admin/AddonManager.test.tsx
@@ -399,7 +399,18 @@ describe('AddonManager', () => {
// The catalog key now exists, so the tile shows the translation rather than falling
// back to the English description the server sent.
expect(screen.getByText('Reads bookings the built-in parser cannot, using an AI model you choose')).toBeInTheDocument();
- expect(screen.queryByText('Connection')).not.toBeInTheDocument();
+ expect(screen.queryByText('Provider')).not.toBeInTheDocument();
+ });
+
+ it('FE-ADMIN-ADDON-020b: the config lives in the tile shelf, not as a band below the grid', async () => {
+ server.use(addonsRoute([llmAddon({ provider: 'openai' })]));
+ render();
+
+ const label = await screen.findByText('Provider');
+ // Inside the AI Parsing tile's , like the collab toggles sit in theirs.
+ const tile = label.closest('article');
+ expect(tile).not.toBeNull();
+ expect(tile!.textContent).toContain('AI Parsing');
});
it('FE-ADMIN-ADDON-021: the local provider lists installed models and a chip fills the model field', async () => {
@@ -617,7 +628,7 @@ describe('AddonManager', () => {
server.use(addonsRoute([llmAddon({ provider: 'openai' })]), modelsRoute([], urls));
render();
- await screen.findByText('Connection');
+ await screen.findByText('Provider');
expect(screen.queryByText('Installed on the server')).not.toBeInTheDocument();
await user.type(screen.getByPlaceholderText('https://api.openai.com/v1'), 'https://proxy.local/v1');
diff --git a/client/src/components/Admin/AddonManager.tsx b/client/src/components/Admin/AddonManager.tsx
index 038a4d406..41a88fbf5 100644
--- a/client/src/components/Admin/AddonManager.tsx
+++ b/client/src/components/Admin/AddonManager.tsx
@@ -196,6 +196,11 @@ export default function AddonManager({ bagTrackingEnabled, onToggleBagTracking,
)
})
}
+ // The AI-parsing settings hang off their tile like every other sub-feature,
+ // just as a form instead of toggle rows.
+ if (addon.id === 'llm_parsing' && addon.enabled) {
+ return
+ }
return null
}
@@ -215,8 +220,6 @@ export default function AddonManager({ bagTrackingEnabled, onToggleBagTracking,
)
}
- const llmAddon = integrationAddons.find(a => a.id === 'llm_parsing')
-
/* One column per type, side by side, instead of three stacked sections. Stacked, each
section opened its own set of columns and the tall tiles (Collab 261px, Journey
185px) set a section's height while its neighbours ran out early. Side by side the
@@ -253,23 +256,17 @@ export default function AddonManager({ bagTrackingEnabled, onToggleBagTracking,
{addons.length === 0 ? (
) : (
- <>
-
- {/* The AI-parsing form is far too wide for a tile, so it sits as a band under
- the columns — no span, no reflow, and the next service that needs settings
- stacks below it. */}
- {llmAddon?.enabled && }
- >
+