Skip to content

Commit 7a27ece

Browse files
gruttCopilotabelanger5
authored
Fe overhaul details (#1552)
* simple trigger * populated * feat:trigger modal * clear * Update frontend/app/src/next/hooks/use-runs.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * wip activity log * merged logs * wip * wip * search box * fudge sort * wip improved worker sheet * wip * chore: improve error on dispatcher (#1538) * fix: empty billing context (#1553) * fix: empty * precommit * hotfix: priority nil pointer (#1555) * hotfix: priority on schedule workflow (#1556) * hotfix: priority on schedule workflow * fix: build * build * lint * build --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: abelanger5 <belanger@sas.upenn.edu>
1 parent c9fc151 commit 7a27ece

File tree

43 files changed

+1476
-567
lines changed

Some content is hidden

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

43 files changed

+1476
-567
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ assignees: ''
77

88
---
99

10-
**Describe the issue**
10+
**Describe the issue**
1111
Briefly describe what’s going wrong — runtime error, broken link, incorrect example, UI issue, etc.
1212

13-
**Environment**
14-
- SDK: [e.g. TypeScript v1.2.3]
13+
**Environment**
14+
- SDK: [e.g. TypeScript v1.2.3]
1515
- Engine: [Cloud or Self-hosted v1.5.0]
1616

17-
**Expected behavior**
17+
**Expected behavior**
1818
What did you expect to happen instead?
1919

20-
**Code to Reproduce, Logs, or Screenshots**
20+
**Code to Reproduce, Logs, or Screenshots**
2121
Include a minimal code snippet that reproduces the issue, error logs around the event, or screenshots, if applicable.
2222

23-
**Additional context**
23+
**Additional context**
2424
Anything else that might help us understand or reproduce the problem — e.g. specific page URL, logged-in vs logged-out, related docs or workflows.

api-contracts/workflows/workflows.proto

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ message ScheduleWorkflowRequest {
157157
optional string additional_metadata = 8;
158158

159159
// (optional) the priority of the workflow
160-
int32 priority = 9;
161-
160+
optional int32 priority = 9;
162161
}
163162

164163
// ScheduledWorkflow represents a scheduled workflow.

frontend/app/src/components/molecules/nav-bar/nav-bar.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
DropdownMenuTrigger,
1010
} from '@/components/ui/dropdown-menu';
1111

12-
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
12+
import { useLocation, useNavigate } from 'react-router-dom';
1313
import api, { TenantVersion, User } from '@/lib/api';
1414
import { useApiError } from '@/lib/hooks';
1515
import { useMutation } from '@tanstack/react-query';
@@ -203,7 +203,6 @@ export default function MainNav({ user, setHasBanner }: MainNavProps) {
203203
const { tenant } = useTenant();
204204
const { pathname } = useLocation();
205205
const navigate = useNavigate();
206-
const [params] = useSearchParams();
207206

208207
const versionedRoutes = useMemo(
209208
() =>
@@ -244,7 +243,7 @@ export default function MainNav({ user, setHasBanner }: MainNavProps) {
244243
}
245244

246245
return;
247-
}, [navigate, params, pathname, tenantVersion, versionedRoutes]);
246+
}, [navigate, pathname, tenantVersion, versionedRoutes]);
248247

249248
useEffect(() => {
250249
if (!setHasBanner) {

frontend/app/src/components/v1/ui/code-editor.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'monaco-themes/themes/Pastels on Dark.json';
55
import { useTheme } from '@/components/theme-provider';
66

77
interface CodeEditorProps {
8-
code: string;
8+
code?: string;
99
setCode?: (code: string | undefined) => void;
1010
language: string;
1111
className?: string;
@@ -17,7 +17,7 @@ interface CodeEditorProps {
1717
}
1818

1919
export function CodeEditor({
20-
code,
20+
code = '',
2121
setCode,
2222
language,
2323
className,
@@ -46,7 +46,7 @@ export function CodeEditor({
4646
<Editor
4747
beforeMount={setEditorTheme}
4848
language={language}
49-
value={code}
49+
value={code || ''}
5050
onChange={setCode}
5151
width={width || '100%'}
5252
height={height || '400px'}
@@ -74,29 +74,28 @@ export function CodeEditor({
7474
{copy && (
7575
<CopyToClipboard
7676
className="absolute top-2 right-2"
77-
text={code.trim()}
77+
text={code?.trim() || ''}
7878
/>
7979
)}
8080
</div>
8181
);
8282
}
8383

8484
export function DiffCodeEditor({
85-
code,
85+
code = '',
8686
setCode,
8787
language,
8888
className,
8989
height,
9090
width,
9191
copy,
92-
originalValue,
92+
originalValue = '',
9393
wrapLines = true,
9494
}: CodeEditorProps & {
9595
originalValue: string;
9696
}) {
9797
const setEditorTheme = (monaco: Monaco) => {
9898
monaco.editor.defineTheme('pastels-on-dark', getMonacoTheme());
99-
10099
monaco.editor.setTheme('pastels-on-dark');
101100
};
102101

@@ -114,7 +113,7 @@ export function DiffCodeEditor({
114113
height={height || '400px'}
115114
theme="pastels-on-dark"
116115
original={originalValue}
117-
modified={code}
116+
modified={code || ''}
118117
options={{
119118
minimap: { enabled: false },
120119
wordWrap: wrapLines ? 'on' : 'off',
@@ -132,7 +131,7 @@ export function DiffCodeEditor({
132131
{copy && (
133132
<CopyToClipboard
134133
className="absolute top-2 right-2"
135-
text={code.trim()}
134+
text={code?.trim() || ''}
136135
/>
137136
)}
138137
</div>

frontend/app/src/lib/atoms.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type TenantContextPresent = {
4848
tenant: Tenant;
4949
tenantId: string;
5050
setTenant: (tenant: Tenant) => void;
51-
billing: BillingContext;
51+
billing?: BillingContext;
5252
can: Can;
5353
};
5454

@@ -209,14 +209,23 @@ export function useTenant(): TenantContext {
209209
return (billingState.data?.paymentMethods?.length || 0) > 0;
210210
}, [billingState.data?.paymentMethods]);
211211

212-
const billingContext: BillingContext = useMemo(() => {
212+
const billingContext: BillingContext | undefined = useMemo(() => {
213+
if (!cloudMeta?.data.canBill) {
214+
return;
215+
}
216+
213217
return {
214218
state: billingState.data,
215219
setPollBilling,
216220
plan: subscriptionPlan,
217221
hasPaymentMethods,
218222
};
219-
}, [billingState.data, setPollBilling, subscriptionPlan, hasPaymentMethods]);
223+
}, [
224+
cloudMeta?.data.canBill,
225+
billingState.data,
226+
subscriptionPlan,
227+
hasPaymentMethods,
228+
]);
220229

221230
const can = useCallback(
222231
(evalFn: Evaluate) => {

frontend/app/src/next/components/layouts/basic.layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default function BasicLayout({
55
}) {
66
return (
77
<div className="flex-grow h-full w-full">
8-
<div className="mx-auto py-8 px-4 sm:px-6 lg:px-8">{children}</div>
8+
<div className="px-4 py-8">{children}</div>
99
</div>
1010
);
1111
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ReactNode } from 'react';
2+
3+
interface SheetViewLayoutProps {
4+
children: ReactNode;
5+
sheet: ReactNode;
6+
}
7+
8+
export function SheetViewLayout({ children, sheet }: SheetViewLayoutProps) {
9+
return (
10+
<div className="flex h-full w-full flex-row gap-4">
11+
<div className="overflow-y-auto flex-grow p-4 py-8">{children}</div>
12+
{sheet}
13+
</div>
14+
);
15+
}

frontend/app/src/next/components/runs/run-children.tsx

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import { ChevronRight } from 'lucide-react';
1010
import { cn } from '@/next/lib/utils';
1111
import { RunsBadge } from './runs-badge';
1212
import { HiMiniArrowTurnLeftUp } from 'react-icons/hi2';
13+
import { useNavigate } from 'react-router-dom';
14+
import { ROUTES } from '@/next/lib/routes';
15+
1316
const MAX_CHILDREN = 10;
1417
const MAX_DEPTH = 2;
1518

@@ -21,6 +24,7 @@ interface RunRowProps {
2124
isExpanded?: boolean;
2225
toggleChildren?: () => void;
2326
parentRun?: V1WorkflowRun;
27+
onClick?: () => void;
2428
}
2529

2630
function HighlightGroup({ children }: PropsWithChildren) {
@@ -35,11 +39,21 @@ function RunRow({
3539
isExpanded,
3640
toggleChildren,
3741
parentRun,
42+
onClick,
3843
}: RunRowProps) {
3944
return (
40-
<div className="grid grid-cols-[200px,1fr] items-center">
45+
<div
46+
className={cn(
47+
'grid grid-cols-[200px,1fr] items-center',
48+
isTitle && 'cursor-pointer',
49+
)}
50+
onClick={onClick}
51+
>
4152
<div
42-
className="text-sm text-muted-foreground truncate overflow-hidden whitespace-nowrap flex items-center gap-2"
53+
className={cn(
54+
'text-sm text-muted-foreground truncate overflow-hidden whitespace-nowrap flex items-center gap-2',
55+
isTitle && 'cursor-pointer',
56+
)}
4357
style={{
4458
paddingLeft: `${depth * 15}px`,
4559
}}
@@ -49,7 +63,10 @@ function RunRow({
4963
variant="ghost"
5064
size="icon"
5165
className="w-4 h-4"
52-
onClick={toggleChildren}
66+
onClick={(e) => {
67+
e.stopPropagation();
68+
toggleChildren?.();
69+
}}
5370
>
5471
<ChevronRight
5572
className={cn('w-2 h-2', isExpanded ? 'rotate-90' : 'rotate-0')}
@@ -60,7 +77,7 @@ function RunRow({
6077
{run?.numSpawnedChildren}
6178
{isTitle ? (
6279
parentRun ? (
63-
<div className="flex items-center gap-2">
80+
<div className="flex items-center gap-2 cursor-pointer">
6481
<HiMiniArrowTurnLeftUp className="w-4 h-4" />
6582
<RunId wfRun={parentRun} />
6683
</div>
@@ -89,14 +106,18 @@ interface RunRowWithChildrenProps {
89106
depth: number;
90107
expandedIds: Set<string>;
91108
toggleExpanded: (id: string) => void;
109+
onTaskSelect?: (taskId: string) => void;
92110
}
93111

94112
function RunRowWithChildren({
95113
run,
96114
depth,
97115
expandedIds,
98116
toggleExpanded,
117+
onTaskSelect,
99118
}: RunRowWithChildrenProps) {
119+
const navigate = useNavigate();
120+
100121
const { data: childrenData } = useRuns({
101122
refetchInterval: 3000,
102123
filters: {
@@ -116,6 +137,13 @@ function RunRowWithChildren({
116137
hasChildren={hasActualChildren}
117138
isExpanded={isExpanded}
118139
toggleChildren={() => toggleExpanded(run.metadata.id)}
140+
onClick={() => {
141+
if (depth == 0) {
142+
onTaskSelect?.(run.metadata.id);
143+
} else {
144+
navigate(ROUTES.runs.detail(run.metadata.id));
145+
}
146+
}}
119147
/>
120148
{isExpanded && hasActualChildren && (
121149
<RunsProvider>
@@ -124,6 +152,7 @@ function RunRowWithChildren({
124152
depth={depth}
125153
expandedIds={expandedIds}
126154
toggleExpanded={toggleExpanded}
155+
onTaskSelect={onTaskSelect}
127156
/>
128157
</RunsProvider>
129158
)}
@@ -136,13 +165,15 @@ interface ChildrenListProps {
136165
depth: number;
137166
expandedIds: Set<string>;
138167
toggleExpanded: (id: string) => void;
168+
onTaskSelect?: (taskId: string) => void;
139169
}
140170

141171
function ChildrenList({
142172
run,
143173
depth,
144174
expandedIds,
145175
toggleExpanded,
176+
onTaskSelect,
146177
}: ChildrenListProps) {
147178
const { data } = useRuns({
148179
refetchInterval: 3000,
@@ -181,6 +212,7 @@ function ChildrenList({
181212
depth={depth + 1}
182213
expandedIds={expandedIds}
183214
toggleExpanded={toggleExpanded}
215+
onTaskSelect={onTaskSelect}
184216
/>
185217
))}
186218
{numHidden > 0 && (
@@ -198,11 +230,13 @@ function ChildrenList({
198230
interface RunChildrenCardProps {
199231
workflow: V1WorkflowRun;
200232
parentRun?: V1WorkflowRun;
233+
onTaskSelect?: (taskId: string) => void;
201234
}
202235

203236
export function RunChildrenCardRoot({
204237
workflow,
205238
parentRun,
239+
onTaskSelect,
206240
}: RunChildrenCardProps) {
207241
const { data } = useRunDetail(workflow.metadata.id, 1000);
208242
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());
@@ -230,7 +264,12 @@ export function RunChildrenCardRoot({
230264
<RunsProvider>
231265
<div className="flex flex-col gap-0">
232266
<HighlightGroup>
233-
<RunRow isTitle depth={0} parentRun={parentRun} />
267+
<RunRow
268+
isTitle
269+
depth={0}
270+
parentRun={parentRun}
271+
onClick={() => onTaskSelect?.(workflow.metadata.id)}
272+
/>
234273
</HighlightGroup>
235274
{data.tasks.map((task) => (
236275
<RunRowWithChildren
@@ -239,6 +278,7 @@ export function RunChildrenCardRoot({
239278
depth={0}
240279
expandedIds={expandedIds}
241280
toggleExpanded={toggleExpanded}
281+
onTaskSelect={onTaskSelect}
242282
/>
243283
))}
244284
</div>

frontend/app/src/next/components/runs/run-dag/dag-run-visualizer.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ const edgeTypes = {
2727

2828
interface WorkflowRunVisualizerProps {
2929
workflowRunId: string;
30-
selectedTaskRunId?: string;
30+
onTaskSelect?: (taskId: string) => void;
3131
}
3232

3333
const WorkflowRunVisualizer = ({
3434
workflowRunId,
35+
onTaskSelect,
3536
}: WorkflowRunVisualizerProps) => {
3637
const { theme } = useTheme();
3738
const navigate = useNavigate();
@@ -42,9 +43,13 @@ const WorkflowRunVisualizer = ({
4243

4344
const setSelectedTaskRunId = useCallback(
4445
(taskRunId: string) => {
45-
navigate(ROUTES.runs.taskDetail(workflowRunId, taskRunId));
46+
if (onTaskSelect) {
47+
onTaskSelect(taskRunId);
48+
} else {
49+
navigate(ROUTES.runs.taskDetail(workflowRunId, taskRunId));
50+
}
4651
},
47-
[navigate, workflowRunId],
52+
[navigate, workflowRunId, onTaskSelect],
4853
);
4954

5055
const edges: Edge[] = useMemo(

0 commit comments

Comments
 (0)