Skip to content

Commit ec2d7b7

Browse files
committed
cleans up pipelineDetails v2
1 parent 58c6a55 commit ec2d7b7

File tree

4 files changed

+228
-136
lines changed

4 files changed

+228
-136
lines changed

.cursorrules

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@ This is a React + TypeScript application for building and running Machine Learni
5555
- Common spacing/layout patterns → Suggest utility classes or component abstractions
5656
- Similar form field styling → Create form field components
5757

58+
### UI Primitives (Prefer Over Raw HTML)
59+
60+
**Always prefer our UI primitives over raw HTML elements:**
61+
62+
- **Layout**: Use `BlockStack` and `InlineStack` from `@/components/ui/layout` instead of `<div className="flex ...">`
63+
- `BlockStack` = vertical flex (`flex-col`)
64+
- `InlineStack` = horizontal flex (`flex-row`)
65+
- Both support `gap`, `align`, `blockAlign` props
66+
- Use `as` prop for semantic elements: `<BlockStack as="ul">`, `<InlineStack as="li">`
67+
68+
- **Typography**: Use `Text` from `@/components/ui/typography` instead of raw `<h1-h6>`, `<p>`, `<span>`, `<dt>`, `<dd>`
69+
- `<Text as="h3" size="md" weight="semibold">` instead of `<h3 className="text-md font-semibold">`
70+
- `<Text as="dt" weight="semibold">` instead of `<dt className="font-semibold">`
71+
- `<Text as="p" size="sm">` instead of `<p className="text-sm">`
72+
- Supports: `as`, `size`, `weight`, `tone`, `font` props
73+
74+
- **Buttons**: Use `Button` from `@/components/ui/button`
75+
- **Icons**: Use `Icon` from `@/components/ui/icon`
76+
77+
**When raw HTML is acceptable:**
78+
- Semantic elements not supported by primitives (e.g., `<dl>`, `<ul>`, `<ol>`, `<table>`)
79+
- Complex layouts where primitives don't fit
80+
- Performance-critical sections where abstraction overhead matters
81+
5882
### State Management
5983

6084
- Use Tanstack Query for server state
@@ -202,6 +226,7 @@ export const useContext = () => {
202226
- Don't create side effects in render functions
203227
- Don't use barrel exports
204228
- Don't modify componentSpec structure without express permission
229+
- Don't use raw HTML elements when UI primitives exist (use `Text`, `BlockStack`, `InlineStack`, etc.)
205230

206231
## Other rules
207232

src/components/Editor/PipelineDetails.tsx

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { CopyText } from "@/components/shared/CopyText/CopyText";
77
import { Button } from "@/components/ui/button";
88
import { Icon } from "@/components/ui/icon";
99
import { BlockStack, InlineStack } from "@/components/ui/layout";
10+
import { Text } from "@/components/ui/typography";
1011
import useToastNotification from "@/hooks/useToastNotification";
1112
import { useComponentSpec } from "@/providers/ComponentSpecProvider";
1213
import { useContextPanel } from "@/providers/ContextPanelProvider";
@@ -145,85 +146,108 @@ const PipelineDetails = () => {
145146
/>
146147
</InlineStack>
147148

148-
{/* General Metadata */}
149-
<div className="flex flex-col gap-2 text-xs text-secondary-foreground mb-2">
150-
<div className="flex flex-wrap gap-6">
151-
{fileMeta.createdBy && (
152-
<div>
153-
<span className="font-semibold">Created by:</span>{" "}
154-
{fileMeta.createdBy}
155-
</div>
156-
)}
157-
</div>
158-
<div className="flex flex-wrap gap-x-6">
159-
{fileMeta.creationTime && (
160-
<div>
161-
<span className="font-semibold">Created at:</span>{" "}
162-
{new Date(fileMeta.creationTime).toLocaleString()}
163-
</div>
164-
)}
165-
{fileMeta.modificationTime && (
166-
<div>
167-
<span className="font-semibold">Last updated:</span>{" "}
168-
{new Date(fileMeta.modificationTime).toLocaleString()}
169-
</div>
170-
)}
171-
</div>
172-
</div>
149+
{(fileMeta.createdBy ||
150+
fileMeta.creationTime ||
151+
fileMeta.modificationTime) && (
152+
<BlockStack>
153+
<Text as="h3" size="md" weight="semibold" className="mb-1">
154+
Pipeline Info
155+
</Text>
156+
<dl className="flex flex-col gap-1 text-xs text-secondary-foreground">
157+
{fileMeta.createdBy && (
158+
<InlineStack as="div" gap="1" blockAlign="center">
159+
<Text as="dt" weight="semibold">
160+
Created by:
161+
</Text>
162+
<dd>{fileMeta.createdBy}</dd>
163+
</InlineStack>
164+
)}
165+
{fileMeta.creationTime && (
166+
<InlineStack as="div" gap="1" blockAlign="center">
167+
<Text as="dt" weight="semibold">
168+
Created at:
169+
</Text>
170+
<dd>{new Date(fileMeta.creationTime).toLocaleString()}</dd>
171+
</InlineStack>
172+
)}
173+
{fileMeta.modificationTime && (
174+
<InlineStack as="div" gap="1" blockAlign="center">
175+
<Text as="dt" weight="semibold">
176+
Last updated:
177+
</Text>
178+
<dd>{new Date(fileMeta.modificationTime).toLocaleString()}</dd>
179+
</InlineStack>
180+
)}
181+
</dl>
182+
</BlockStack>
183+
)}
173184

174-
{/* Description */}
175185
{componentSpec.description && (
176-
<div>
177-
<h3 className="text-md font-medium mb-1">Description</h3>
178-
<div className="text-sm whitespace-pre-line">
186+
<BlockStack>
187+
<Text as="h3" size="md" weight="semibold" className="mb-1">
188+
Description
189+
</Text>
190+
<Text as="p" size="sm" className="whitespace-pre-line">
179191
{componentSpec.description}
180-
</div>
181-
</div>
192+
</Text>
193+
</BlockStack>
182194
)}
183195

184196
{/* Component Digest */}
185197
{digest && (
186-
<div className="mb-2">
187-
<h3 className="text-md font-medium mb-1">Digest</h3>
198+
<BlockStack>
199+
<Text as="h3" size="md" weight="semibold" className="mb-1">
200+
Digest
201+
</Text>
188202
<Button
189203
className="bg-gray-100 border border-gray-300 rounded p-2 h-fit text-xs w-full text-left hover:bg-gray-200 active:bg-gray-300 transition cursor-pointer"
190204
onClick={handleDigestCopy}
191205
variant="ghost"
192206
>
193-
<span className="font-mono break-all w-full text-wrap">
207+
<Text as="span" font="mono" className="break-all w-full text-wrap">
194208
{digest}
195-
</span>
209+
</Text>
196210
</Button>
197-
</div>
211+
</BlockStack>
198212
)}
199213

200214
{/* Annotations */}
201215
{Object.keys(annotations).length > 0 && (
202-
<div>
203-
<h3 className="text-md font-medium mb-1">Annotations</h3>
216+
<BlockStack>
217+
<Text as="h3" size="md" weight="semibold" className="mb-1">
218+
Annotations
219+
</Text>
204220
<ul className="text-xs text-secondary-foreground">
205221
{Object.entries(annotations).map(([key, value]) => (
206222
<li key={key}>
207-
<span className="font-semibold">{key}:</span>{" "}
208-
<span className="break-all">{String(value)}</span>
223+
<Text as="span" weight="semibold">
224+
{key}:
225+
</Text>{" "}
226+
<Text as="span" className="break-all">
227+
{String(value)}
228+
</Text>
209229
</li>
210230
))}
211231
</ul>
212-
</div>
232+
</BlockStack>
213233
)}
214234

215235
{/* Artifacts (Inputs & Outputs) */}
216-
<div>
217-
<h3 className="text-md font-medium mb-1">Artifacts</h3>
218-
<div className="flex gap-4 flex-col">
219-
<div className="flex-1">
220-
<h4 className="text-sm font-semibold mb-1">Inputs</h4>
236+
<BlockStack>
237+
<Text as="h3" size="md" weight="semibold" className="mb-1">
238+
Artifacts
239+
</Text>
240+
<BlockStack gap="4">
241+
<BlockStack>
242+
<Text as="h4" size="sm" weight="semibold" className="mb-1">
243+
Inputs
244+
</Text>
221245
{componentSpec.inputs && componentSpec.inputs.length > 0 ? (
222246
<div className="flex flex-col">
223247
{componentSpec.inputs.map((input) => {
224248
return (
225249
<div
226-
className="flex flex-row justify-between even:bg-white odd:bg-gray-100 gap-1 px-2 py-0 rounded-xs items-center"
250+
className="flex flex-row justify-between even:bg-white odd:bg-gray-100 gap-1 px-2 py-1 rounded-xs items-center"
227251
key={input.name}
228252
>
229253
<div className="text-xs flex-1 truncate max-w-[200px]">
@@ -267,14 +291,16 @@ const PipelineDetails = () => {
267291
) : (
268292
<div className="text-xs text-muted-foreground">No inputs</div>
269293
)}
270-
</div>
271-
<div className="flex-1">
272-
<h4 className="text-sm font-semibold mb-1">Outputs</h4>
294+
</BlockStack>
295+
<BlockStack>
296+
<Text as="h4" size="sm" weight="semibold" className="mb-1">
297+
Outputs
298+
</Text>
273299
{componentSpec.outputs && componentSpec.outputs.length > 0 ? (
274300
<div className="flex flex-col">
275301
{componentSpec.outputs.map((output) => (
276302
<div
277-
className="flex flex-row justify-between even:bg-white odd:bg-gray-100 gap-1 px-2 py-0 rounded-xs items-center"
303+
className="flex flex-row justify-between even:bg-white odd:bg-gray-100 gap-1 px-2 py-1 rounded-xs items-center"
278304
key={output.name}
279305
>
280306
<div className="text-xs flex-1 truncate max-w-[200px]">
@@ -309,20 +335,22 @@ const PipelineDetails = () => {
309335
) : (
310336
<div className="text-xs text-muted-foreground">No outputs</div>
311337
)}
312-
</div>
313-
</div>
314-
</div>
338+
</BlockStack>
339+
</BlockStack>
340+
</BlockStack>
315341

316342
{/* Validations */}
317-
<div className="mt-2">
318-
<h3 className="text-md font-medium mb-1">Validations</h3>
343+
<BlockStack>
344+
<Text as="h3" size="md" weight="semibold" className="mb-1">
345+
Validations
346+
</Text>
319347
<PipelineValidationList
320348
isComponentTreeValid={isComponentTreeValid}
321349
groupedIssues={groupedIssues}
322350
totalIssueCount={globalValidationIssues.length}
323351
onIssueSelect={handleIssueClick}
324352
/>
325-
</div>
353+
</BlockStack>
326354
</BlockStack>
327355
);
328356
};

0 commit comments

Comments
 (0)