Skip to content

Commit 3c509e0

Browse files
authored
Cleanup RunDetails (#1508)
## Description <!-- Please provide a brief description of the changes made in this pull request. Include any relevant context or reasoning for the changes. --> RunDetails recently got a good cleanup, so this PR focusses mostly on bringing it over to the ContextPanel Block system for improved visual consistency. Functionality of the ArtifactsList is already moved to PipelineIO, so this last implementation of it has been removed along with the component itself. PipelineIO has now been moved to a more generic `Execution` folder, where, in future, we can put more execution-related UI components. ## Related Issue and Pull requests <!-- Link to any related issues using the format #<issue-number> --> Closes Shopify/oasis-frontend#401 ## Type of Change <!-- Please delete options that are not relevant --> - [x] Cleanup/Refactor ## Checklist <!-- Please ensure the following are completed before submitting the PR --> - [ ] I have tested this does not break current pipelines / runs functionality - [ ] I have tested the changes on staging ## Screenshots (if applicable) <!-- Include any screenshots that might help explain the changes or provide visual context --> Before: ![image.png](https://app.graphite.com/user-attachments/assets/0d535cdd-c57b-4899-80a2-951d98b579ae.png) After: ![image.png](https://app.graphite.com/user-attachments/assets/b6dd0f2e-ecb6-4ac9-9854-9129de217010.png) ## Test Instructions <!-- Detail steps and prerequisites for testing the changes in this PR --> No change to app functionality. UI update only. Confirm that the interface works and shows info as expected. ## Additional Comments <!-- Add any additional context or information that reviewers might need to know regarding this PR -->
1 parent 05f8f61 commit 3c509e0

File tree

5 files changed

+88
-227
lines changed

5 files changed

+88
-227
lines changed

src/components/Editor/Context/PipelineDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useComponentSpec } from "@/providers/ComponentSpecProvider";
1313
import { getComponentFileFromList } from "@/utils/componentStore";
1414
import { USER_PIPELINES_LIST_NAME } from "@/utils/constants";
1515

16-
import PipelineIO from "../../shared/ArtifactsList/PipelineIO";
16+
import PipelineIO from "../../shared/Execution/PipelineIO";
1717
import { PipelineValidationList } from "./PipelineValidationList";
1818
import RenamePipeline from "./RenamePipeline";
1919

src/components/PipelineRun/RunDetails.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import * as executionService from "@/services/executionService";
1717
import type { ComponentSpec } from "@/utils/componentSpec";
1818

1919
import { RunDetails } from "./RunDetails";
20+
import { ContextPanelProvider } from "@/providers/ContextPanelProvider";
21+
import { ReactFlowProvider } from "@xyflow/react";
2022

2123
// Mock the hooks and services
2224
vi.mock("@tanstack/react-router", async (importOriginal) => {
@@ -181,7 +183,9 @@ describe("<RunDetails/>", () => {
181183
<ComponentSpecProvider spec={mockComponentSpec}>
182184
<QueryClientProvider client={queryClient}>
183185
<ExecutionDataProvider pipelineRunId="123">
184-
{children}
186+
<ReactFlowProvider>
187+
<ContextPanelProvider>{children}</ContextPanelProvider>
188+
</ReactFlowProvider>
185189
</ExecutionDataProvider>
186190
</QueryClientProvider>
187191
</ComponentSpecProvider>
Lines changed: 82 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import { Frown } from "lucide-react";
2-
3-
import { ArtifactsList } from "@/components/shared/ArtifactsList/ArtifactsList";
41
import { CopyText } from "@/components/shared/CopyText/CopyText";
52
import { BlockStack, InlineStack } from "@/components/ui/layout";
6-
import { Spinner } from "@/components/ui/spinner";
73
import { Text } from "@/components/ui/typography";
84
import { useCheckComponentSpecFromPath } from "@/hooks/useCheckComponentSpecFromPath";
95
import { useUserDetails } from "@/hooks/useUserDetails";
@@ -17,7 +13,16 @@ import {
1713
isStatusInProgress,
1814
} from "@/services/executionService";
1915

16+
import {
17+
ActionBlock,
18+
type ActionOrReactNode,
19+
} from "../shared/ContextPanel/Blocks/ActionBlock";
20+
import { ContentBlock } from "../shared/ContextPanel/Blocks/ContentBlock";
21+
import { ListBlock } from "../shared/ContextPanel/Blocks/ListBlock";
22+
import { TextBlock } from "../shared/ContextPanel/Blocks/TextBlock";
23+
import PipelineIO from "../shared/Execution/PipelineIO";
2024
import { InfoBox } from "../shared/InfoBox";
25+
import { LoadingScreen } from "../shared/LoadingScreen";
2126
import { StatusBar, StatusText } from "../shared/Status";
2227
import { TaskImplementation } from "../shared/TaskDetails";
2328
import { CancelPipelineRunButton } from "./components/CancelPipelineRunButton";
@@ -52,29 +57,25 @@ export const RunDetails = () => {
5257

5358
if (error || !details || !state || !componentSpec) {
5459
return (
55-
<div className="flex flex-col gap-8 items-center justify-center h-full">
56-
<Frown className="w-12 h-12 text-secondary-foreground" />
57-
<div className="text-secondary-foreground">
58-
Error loading run details.
59-
</div>
60-
</div>
60+
<BlockStack fill>
61+
<InfoBox title="Error" variant="error">
62+
Pipeline Run could not be loaded.
63+
</InfoBox>
64+
</BlockStack>
6165
);
6266
}
6367

6468
if (isLoading) {
65-
return (
66-
<div className="flex items-center justify-center h-full">
67-
<Spinner className="mr-2" />
68-
<p className="text-secondary-foreground">Loading run details...</p>
69-
</div>
70-
);
69+
return <LoadingScreen message="Loading run details..." />;
7170
}
7271

7372
if (!configured) {
7473
return (
75-
<InfoBox title="Backend not configured" variant="warning">
76-
Configure a backend to view execution artifacts.
77-
</InfoBox>
74+
<BlockStack fill>
75+
<InfoBox title="Backend not configured" variant="warning">
76+
Configure a backend to view execution artifacts.
77+
</InfoBox>
78+
</BlockStack>
7879
);
7980
}
8081

@@ -86,133 +87,92 @@ export const RunDetails = () => {
8687

8788
const annotations = componentSpec.metadata?.annotations || {};
8889

90+
const actions: ActionOrReactNode[] = [];
91+
92+
actions.push(
93+
<TaskImplementation
94+
displayName={componentSpec.name ?? "Pipeline"}
95+
componentSpec={componentSpec}
96+
showInlineContent={false}
97+
/>,
98+
);
99+
100+
if (canAccessEditorSpec && componentSpec.name) {
101+
actions.push(
102+
<InspectPipelineButton key="inspect" pipelineName={componentSpec.name} />,
103+
);
104+
}
105+
106+
actions.push(
107+
<ClonePipelineButton
108+
key="clone"
109+
componentSpec={componentSpec}
110+
runId={runId}
111+
/>,
112+
);
113+
114+
if (isInProgress && isRunCreator) {
115+
actions.push(<CancelPipelineRunButton key="cancel" runId={runId} />);
116+
}
117+
118+
if (isComplete) {
119+
actions.push(
120+
<RerunPipelineButton key="rerun" componentSpec={componentSpec} />,
121+
);
122+
}
123+
89124
return (
90125
<BlockStack gap="6" className="p-2 h-full">
91126
<CopyText className="text-lg font-semibold">
92127
{componentSpec.name ?? "Unnamed Pipeline"}
93128
</CopyText>
94129

95-
<InlineStack gap="2">
96-
<TaskImplementation
97-
displayName={componentSpec.name ?? "Pipeline"}
98-
componentSpec={componentSpec}
99-
showInlineContent={false}
100-
/>
101-
{canAccessEditorSpec && componentSpec.name && (
102-
<InspectPipelineButton pipelineName={componentSpec.name} />
103-
)}
104-
<ClonePipelineButton componentSpec={componentSpec} runId={runId} />
105-
{isInProgress && isRunCreator && (
106-
<CancelPipelineRunButton runId={runId} />
107-
)}
108-
{isComplete && <RerunPipelineButton componentSpec={componentSpec} />}
109-
</InlineStack>
130+
<ActionBlock actions={actions} />
110131

111132
{metadata && (
112-
<BlockStack>
113-
<Text as="h3" size="md" weight="semibold" className="mb-1">
114-
Run Info
115-
</Text>
116-
<dl className="flex flex-col gap-1 text-xs text-secondary-foreground">
117-
{metadata.id && (
118-
<InlineStack as="div" gap="1" blockAlign="center">
119-
<Text as="dt" weight="semibold" className="shrink-0">
120-
Run Id:
121-
</Text>
122-
<dd>
123-
<CopyText className="font-mono truncate max-w-[180px]">
124-
{metadata.id}
125-
</CopyText>
126-
</dd>
127-
</InlineStack>
128-
)}
129-
{metadata.root_execution_id && (
130-
<InlineStack as="div" gap="1" blockAlign="center">
131-
<Text as="dt" weight="semibold" className="shrink-0">
132-
Execution Id:
133-
</Text>
134-
<dd>
135-
<CopyText className="font-mono truncate max-w-[180px]">
136-
{metadata.root_execution_id}
137-
</CopyText>
138-
</dd>
139-
</InlineStack>
140-
)}
141-
{metadata.created_by && (
142-
<InlineStack as="div" gap="1" blockAlign="center">
143-
<Text as="dt" weight="semibold">
144-
Created by:
145-
</Text>
146-
<dd>{metadata.created_by}</dd>
147-
</InlineStack>
148-
)}
149-
{metadata.created_at && (
150-
<InlineStack as="div" gap="1" blockAlign="center">
151-
<Text as="dt" weight="semibold">
152-
Created at:
153-
</Text>
154-
<dd>{new Date(metadata.created_at).toLocaleString()}</dd>
155-
</InlineStack>
156-
)}
157-
</dl>
158-
</BlockStack>
133+
<ListBlock
134+
title="Run Info"
135+
items={[
136+
{ label: "Run Id", value: metadata.id },
137+
{ label: "Execution Id", value: metadata.root_execution_id },
138+
{ label: "Created by", value: metadata.created_by ?? undefined },
139+
{
140+
label: "Created at",
141+
value: metadata.created_at
142+
? new Date(metadata.created_at).toLocaleString()
143+
: undefined,
144+
},
145+
]}
146+
marker="none"
147+
/>
159148
)}
160149

161150
{componentSpec.description && (
162-
<BlockStack>
163-
<Text as="h3" size="md" weight="semibold" className="mb-1">
164-
Description
165-
</Text>
166-
<Text as="p" size="sm" className="whitespace-pre-line">
167-
{componentSpec.description}
168-
</Text>
169-
</BlockStack>
151+
<TextBlock title="Description" text={componentSpec.description} />
170152
)}
171153

172-
<BlockStack>
173-
<Text as="h3" size="md" weight="semibold" className="mb-1">
174-
Status
175-
</Text>
154+
<ContentBlock title="Status">
176155
<InlineStack gap="2" blockAlign="center" className="mb-1">
177156
<Text size="sm" weight="semibold">
178157
{runStatus}
179158
</Text>
180159
<StatusText statusCounts={statusCounts} />
181160
</InlineStack>
182161
<StatusBar statusCounts={statusCounts} />
183-
</BlockStack>
162+
</ContentBlock>
184163

185164
{Object.keys(annotations).length > 0 && (
186-
<BlockStack>
187-
<Text as="h3" size="md" weight="semibold" className="mb-1">
188-
Annotations
189-
</Text>
190-
<ul className="text-xs text-secondary-foreground">
191-
{Object.entries(annotations).map(([key, value]) => (
192-
<li key={key}>
193-
<Text as="span" weight="semibold">
194-
{key}:
195-
</Text>{" "}
196-
<Text as="span" className="break-all">
197-
{String(value)}
198-
</Text>
199-
</li>
200-
))}
201-
</ul>
202-
</BlockStack>
165+
<ListBlock
166+
title="Annotations"
167+
items={Object.entries(annotations).map(([key, value]) => ({
168+
label: key,
169+
value: String(value),
170+
}))}
171+
marker="none"
172+
/>
203173
)}
204174

205-
<ArtifactsList
206-
inputs={(componentSpec.inputs ?? []).map((input) => ({
207-
name: input.name,
208-
type: typeof input.type === "string" ? input.type : "object",
209-
value: input.value ?? input.default,
210-
}))}
211-
outputs={(componentSpec.outputs ?? []).map((output) => ({
212-
name: output.name,
213-
type: typeof output.type === "string" ? output.type : "object",
214-
}))}
215-
/>
175+
<PipelineIO readOnly />
216176
</BlockStack>
217177
);
218178
};

src/components/shared/ArtifactsList/ArtifactsList.tsx

Lines changed: 0 additions & 103 deletions
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)