Skip to content

Commit 5f20da9

Browse files
authored
Connect now uses new ListComponentsRequestSchema to fetch components + UI improvements (#2043)
* feat: replaced hard coded benthos schema json file with new connect query endpoint * feat: new ui and removed enableRpcnTiles flag from pipelines-create * feat: cleanup * feat: remaining bug bash fixes * feat: few more * feat: updated tests * feat: reversed shouldShowField * feat: addressed pr comments and improved yaml generation to rely more on backend schema than opinionated defaults and what fields are actually shown * feat: added error handling for schema parsing * feat: fixed deselecting connect tiles and reselecting them * feat: connect tiles is now prop driven via list component schema endpoint, better progressive loading states, no more silent errors, better conditional rendering of new UI withini legacy entry point * feat: andres comment * feat: improved lint results text wrapping, improved layout
1 parent 8f55ecf commit 5f20da9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3909
-1345
lines changed
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
---
2+
name: frontend-developer
3+
description: "Build user interfaces using Redpanda UI Registry components with React, TypeScript, and Vitest testing. Use when user requests UI components, pages, forms, or mentions 'build UI', 'create component', 'design system', 'frontend', or 'registry'."
4+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, mcp__ide__getDiagnostics
5+
---
6+
7+
# Frontend UI Development
8+
9+
Build UIs using the Redpanda UI Registry design system following this repo's patterns.
10+
11+
## Critical Rules
12+
13+
**ALWAYS:**
14+
15+
- Fetch registry docs FIRST: Invoke `mcp__context7__get-library-docs` with library `/websites/redpanda-ui-registry_netlify_app`
16+
- Use registry components from `src/components/redpanda-ui/`
17+
- Install components via CLI: `yes | bunx @fumadocs/cli add --dir https://redpanda-ui-registry.netlify.app/r <component>`
18+
- Use functional React components with TypeScript
19+
- Run `bun i --yarn` after installing packages
20+
21+
**NEVER:**
22+
23+
- Use deprecated `@redpanda-data/ui` or Chakra UI
24+
- Modify files in registry base directory (check `cli.json`)
25+
- Copy/paste registry source code
26+
- Add margin `className` directly to registry components
27+
- Use inline `style` prop on registry components
28+
- Leave `console.log` or comments in code
29+
30+
## Workflow
31+
32+
### 1. Fetch Registry Documentation
33+
34+
```bash
35+
# REQUIRED FIRST STEP
36+
Invoke: mcp__context7__get-library-docs
37+
Library: /websites/redpanda-ui-registry_netlify_app
38+
```
39+
40+
### 2. Install Components
41+
42+
```bash
43+
# Single component
44+
yes | bunx @fumadocs/cli add --dir https://redpanda-ui-registry.netlify.app/r button
45+
46+
# Multiple components (space-separated)
47+
yes | bunx @fumadocs/cli add --dir https://redpanda-ui-registry.netlify.app/r card dialog form
48+
49+
# Then generate yarn.lock
50+
bun i && bun i --yarn
51+
```
52+
53+
### 3. Write Component
54+
55+
**Structure:**
56+
57+
```typescript
58+
// Functional component with explicit types
59+
interface Props {
60+
title: string;
61+
onSubmit: (data: FormData) => void;
62+
}
63+
64+
export function MyComponent({ title, onSubmit }: Props) {
65+
// Component logic
66+
}
67+
```
68+
69+
**Styling:**
70+
71+
```typescript
72+
// ✅ CORRECT: Use component variants
73+
<Button variant="primary" size="lg">Click</Button>
74+
75+
// ✅ CORRECT: Wrap for spacing
76+
<div className="mt-4">
77+
<Button variant="primary">Click</Button>
78+
</div>
79+
80+
// ❌ WRONG: Direct margin on component
81+
<Button className="mt-4" variant="primary">Click</Button>
82+
```
83+
84+
**TypeScript:**
85+
86+
- Define prop interfaces
87+
- Never use `any` - infer correct types
88+
- Use generics for collections
89+
90+
**Performance:**
91+
92+
- Hoist static content outside component
93+
- Use `useMemo` for expensive computations - but only when there's a noticeable performance impact
94+
- Use `memo` for components receiving props
95+
96+
### 4. Write Tests
97+
98+
**Test types:**
99+
100+
- Unit tests (`.test.ts`): Pure logic, utilities, helpers - Node environment
101+
- Integration tests (`.test.tsx`): React components, UI interactions - JSDOM environment
102+
103+
**Unit test example:**
104+
105+
```typescript
106+
// utils.test.ts
107+
import { formatNumber } from "./utils";
108+
109+
describe("formatNumber", () => {
110+
test("should format numbers with commas", () => {
111+
expect(formatNumber(1000)).toBe("1,000");
112+
});
113+
});
114+
```
115+
116+
**Integration test example:**
117+
118+
```typescript
119+
// component.test.tsx
120+
import { render, screen, fireEvent, waitFor } from 'test-utils';
121+
import { createRouterTransport } from '@connectrpc/connect';
122+
import { createPipeline } from 'protogen/redpanda/api/console/v1alpha1/pipeline-PipelineService_connectquery';
123+
import { MyComponent } from './component';
124+
125+
describe('MyComponent', () => {
126+
test('should trigger gRPC mutation when form is submitted', async () => {
127+
// Mock the gRPC service method
128+
const mockCreatePipeline = vi.fn(() =>
129+
Promise.resolve({ id: '123', name: 'test-pipeline' })
130+
);
131+
132+
// Create a mocked transport
133+
const transport = createRouterTransport(({ rpc }) => {
134+
rpc(createPipeline, mockCreatePipeline);
135+
});
136+
137+
// Render with the mocked transport
138+
render(<MyComponent />, { transport });
139+
140+
// Fill out the form
141+
fireEvent.change(screen.getByLabelText('Pipeline Name'), {
142+
target: { value: 'test-pipeline' }
143+
});
144+
145+
// Submit the form
146+
fireEvent.click(screen.getByRole('button', { name: 'Create' }));
147+
148+
// Verify the mutation was called with correct data
149+
await waitFor(() => {
150+
expect(mockCreatePipeline).toHaveBeenCalledWith({
151+
name: 'test-pipeline'
152+
});
153+
});
154+
});
155+
});
156+
```
157+
158+
**Mocking:**
159+
160+
```typescript
161+
vi.mock("module-name", async (importOriginal) => {
162+
const actual = await importOriginal<typeof import("module-name")>();
163+
return {
164+
...actual,
165+
functionToMock: vi.fn(),
166+
};
167+
});
168+
169+
const mockFunction = vi.mocked(functionToMock);
170+
```
171+
172+
### 5. Validation
173+
174+
```bash
175+
# Run in order
176+
bun run type:check # TypeScript errors
177+
bun run test # All tests
178+
bun run lint # Code quality
179+
bun run build # Production build
180+
bun run start2 --port=3004 # Dev server - check browser
181+
```
182+
183+
**Success criteria:**
184+
185+
- ✓ No TypeScript errors
186+
- ✓ All tests passing
187+
- ✓ No lint errors
188+
- ✓ Build succeeds
189+
- ✓ No runtime errors in browser
190+
191+
## Testing Commands
192+
193+
```bash
194+
bun run test # All tests (unit + integration)
195+
bun run test:unit # Unit tests only (.test.ts)
196+
bun run test:integration # Integration tests only (.test.tsx)
197+
bun run test:watch # Watch mode
198+
bun run test:coverage # Coverage report
199+
```
200+
201+
## Common Patterns
202+
203+
### Registry Component Usage
204+
205+
Check `src/components/redpanda-ui/` for installed components before installing new ones.
206+
207+
Use component variants instead of custom styling:
208+
209+
```typescript
210+
<Button variant="primary" size="lg" />
211+
<Card variant="outline" />
212+
<Dialog size="md" />
213+
```
214+
215+
### Form Patterns
216+
217+
For complex forms, use React Hook Form + Zod:
218+
219+
```typescript
220+
import { useForm } from "react-hook-form";
221+
import { zodResolver } from "@hookform/resolvers/zod";
222+
import { z } from "zod";
223+
224+
const schema = z.object({
225+
name: z.string().min(1),
226+
email: z.string().email(),
227+
});
228+
229+
const form = useForm({
230+
resolver: zodResolver(schema),
231+
defaultValues: { name: "", email: "" },
232+
});
233+
```
234+
235+
For simple forms, use AutoForm:
236+
237+
```typescript
238+
import { AutoForm } from '@autoform/react';
239+
import { ZodProvider } from '@autoform/zod';
240+
241+
<AutoForm
242+
schema={schema}
243+
onSubmit={handleSubmit}
244+
provider={ZodProvider}
245+
/>
246+
```
247+
248+
### Reusable Sub-Components
249+
250+
Create sub-components in the same file when logic repeats:
251+
252+
```typescript
253+
export function FeatureComponent() {
254+
return (
255+
<div>
256+
<FeatureHeader />
257+
<FeatureContent />
258+
</div>
259+
);
260+
}
261+
262+
// Colocated sub-components
263+
function FeatureHeader() { /* ... */ }
264+
function FeatureContent() { /* ... */ }
265+
```
266+
267+
## Testing Best Practices
268+
269+
**File naming:**
270+
271+
- `.test.ts` for utilities and pure functions (unit tests)
272+
- `.test.tsx` for React components (integration tests)
273+
274+
**Mock location:**
275+
276+
- Use pre-configured mocks from `src/test-utils/`
277+
- Mock external dependencies, not internal code
278+
279+
**Render utility:**
280+
281+
- Import from `test-utils/test-utils.tsx` for component tests
282+
- Includes all providers (React Query, Router, Auth0)
283+
284+
**Async testing:**
285+
286+
- Use `waitFor` for async operations
287+
- Test loading and error states
288+
- Verify state updates
289+
290+
## Quick Reference
291+
292+
**Check before installing:**
293+
294+
```bash
295+
# Check if component exists
296+
ls src/components/redpanda-ui/components/
297+
```
298+
299+
**Multi-component install:**
300+
301+
```bash
302+
yes | bunx @fumadocs/cli add --dir https://redpanda-ui-registry.netlify.app/r \
303+
button card dialog form input label select
304+
```
305+
306+
**After package install:**
307+
308+
```bash
309+
bun i && bun i --yarn # ALWAYS run this
310+
```
311+
312+
**Testing shortcuts:**
313+
314+
- Unit test: Pure function? Use `.test.ts`
315+
- Integration test: React component? Use `.test.tsx`
316+
- Mock external: Add to `src/test-utils/`
317+
- Custom render: Use `test-utils/test-utils.tsx`
318+
319+
## Output
320+
321+
After completing work:
322+
323+
1. Confirm all validation steps passed
324+
2. Summarize what was built
325+
3. Note any runtime checks needed in browser
326+
4. Mention test coverage if relevant

0 commit comments

Comments
 (0)