Skip to content

Commit 14179e0

Browse files
committed
Rework Task Action Buttons into Action Framework
1 parent 6dd91ce commit 14179e0

File tree

6 files changed

+207
-283
lines changed

6 files changed

+207
-283
lines changed

src/components/shared/Buttons/TooltipButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
TooltipTrigger,
99
} from "@/components/ui/tooltip";
1010

11-
export interface TooltipButtonProps extends ButtonProps {
11+
interface TooltipButtonProps extends ButtonProps {
1212
tooltip: React.ReactNode;
1313
tooltipSide?: "top" | "right" | "bottom" | "left";
1414
tooltipAlign?: "start" | "center" | "end";

src/components/shared/Dialogs/ComponentDetailsDialog.tsx

Lines changed: 31 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import { useHydrateComponentReference } from "@/hooks/useHydrateComponentReferen
1717
import type { ComponentReference } from "@/utils/componentSpec";
1818

1919
import InfoIconButton from "../Buttons/InfoIconButton";
20-
import TooltipButton from "../Buttons/TooltipButton";
21-
import { ComponentEditorDialog } from "../ComponentEditor/ComponentEditorDialog";
2220
import { ComponentFavoriteToggle } from "../FavoriteComponentToggle";
2321
import { InfoBox } from "../InfoBox";
2422
import { PublishComponent } from "../ManageComponent/PublishComponent";
@@ -32,7 +30,6 @@ interface ComponentDetailsProps {
3230
component: ComponentReference;
3331
displayName: string;
3432
trigger?: ReactNode;
35-
actions?: ReactNode[];
3633
onClose?: () => void;
3734
onDelete?: () => void;
3835
}
@@ -64,12 +61,7 @@ const ComponentDetailsDialogContentSkeleton = () => {
6461
};
6562

6663
const ComponentDetailsDialogContent = withSuspenseWrapper(
67-
({
68-
component,
69-
displayName,
70-
actions = [],
71-
onDelete,
72-
}: ComponentDetailsProps) => {
64+
({ component, displayName, onDelete }: ComponentDetailsProps) => {
7365
const remoteComponentLibrarySearchEnabled = useBetaFlagValue(
7466
"remote-component-library-search",
7567
);
@@ -138,7 +130,6 @@ const ComponentDetailsDialogContent = withSuspenseWrapper(
138130
componentRef={componentRef}
139131
componentDigest={componentDigest}
140132
url={url}
141-
actions={actions}
142133
onDelete={onDelete}
143134
/>
144135
</TabsContent>
@@ -175,18 +166,12 @@ const ComponentDetails = ({
175166
component,
176167
displayName,
177168
trigger,
178-
actions = [],
179169
onClose,
180170
onDelete,
181171
}: ComponentDetailsProps) => {
182-
const hasEnabledInAppEditor = useBetaFlagValue("in-app-component-editor");
183-
184-
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
185172
const [open, setOpen] = useState(false);
186173
const dialogTriggerButton = trigger || <InfoIconButton />;
187174

188-
const componentText = component.text;
189-
190175
const dialogContextValue = useMemo(
191176
() => ({
192177
name: "ComponentDetails",
@@ -197,79 +182,45 @@ const ComponentDetails = ({
197182
[],
198183
);
199184

200-
const handleCloseEditDialog = useCallback(() => {
201-
setIsEditDialogOpen(false);
202-
}, []);
203-
204185
const onOpenChange = useCallback((open: boolean) => {
205186
setOpen(open);
206187
if (!open) {
207188
onClose?.();
208189
}
209190
}, []);
210191

211-
const handleEditComponent = useCallback(() => {
212-
setIsEditDialogOpen(true);
213-
}, []);
214-
215-
const actionsWithEdit = useMemo(() => {
216-
if (!hasEnabledInAppEditor) return actions;
217-
218-
const EditButton = (
219-
<TooltipButton
220-
variant="secondary"
221-
onClick={handleEditComponent}
222-
tooltip="Edit Component Definition"
223-
key={`${displayName}-edit-button`}
224-
>
225-
<Icon name="FilePenLine" />
226-
</TooltipButton>
227-
);
228-
229-
return [...actions, EditButton];
230-
}, [actions, hasEnabledInAppEditor, handleEditComponent]);
231-
232192
return (
233-
<>
234-
<Dialog modal open={open} onOpenChange={onOpenChange}>
235-
<DialogTrigger asChild>{dialogTriggerButton}</DialogTrigger>
193+
<Dialog modal open={open} onOpenChange={onOpenChange}>
194+
<DialogTrigger asChild>{dialogTriggerButton}</DialogTrigger>
236195

237-
<DialogDescription
238-
className="hidden"
239-
aria-label={`${displayName} component details`}
240-
>
241-
{`${displayName} component details`}
242-
</DialogDescription>
243-
<DialogContent
244-
className="max-w-2xl min-w-2xl overflow-hidden"
245-
aria-label={`${displayName} component details`}
246-
>
247-
<DialogHeader>
248-
<DialogTitle className="flex items-center gap-2 mr-5">
249-
<span>{displayName}</span>
250-
<ComponentFavoriteToggle component={component} />
251-
</DialogTitle>
252-
</DialogHeader>
253-
254-
<DialogContext.Provider value={dialogContextValue}>
255-
<ComponentDetailsDialogContent
256-
component={component}
257-
displayName={displayName}
258-
trigger={dialogTriggerButton}
259-
actions={actionsWithEdit}
260-
onClose={onClose}
261-
onDelete={onDelete}
262-
/>
263-
</DialogContext.Provider>
264-
</DialogContent>
265-
</Dialog>
266-
{isEditDialogOpen && (
267-
<ComponentEditorDialog
268-
text={componentText}
269-
onClose={handleCloseEditDialog}
270-
/>
271-
)}
272-
</>
196+
<DialogDescription
197+
className="hidden"
198+
aria-label={`${displayName} component details`}
199+
>
200+
{`${displayName} component details`}
201+
</DialogDescription>
202+
<DialogContent
203+
className="max-w-2xl min-w-2xl overflow-hidden"
204+
aria-label={`${displayName} component details`}
205+
>
206+
<DialogHeader>
207+
<DialogTitle className="flex items-center gap-2 mr-5">
208+
<span>{displayName}</span>
209+
<ComponentFavoriteToggle component={component} />
210+
</DialogTitle>
211+
</DialogHeader>
212+
213+
<DialogContext.Provider value={dialogContextValue}>
214+
<ComponentDetailsDialogContent
215+
component={component}
216+
displayName={displayName}
217+
trigger={dialogTriggerButton}
218+
onClose={onClose}
219+
onDelete={onDelete}
220+
/>
221+
</DialogContext.Provider>
222+
</DialogContent>
223+
</Dialog>
273224
);
274225
};
275226

src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskNodeCard/TaskNodeCard.tsx

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useNavigate } from "@tanstack/react-router";
22
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
33

4-
import type { TooltipButtonProps } from "@/components/shared/Buttons/TooltipButton";
5-
import { ComponentEditorDialog } from "@/components/shared/ComponentEditor/ComponentEditorDialog";
4+
import { CodeViewer } from "@/components/shared/CodeViewer";
5+
import type { Action } from "@/components/shared/ContextPanel/Blocks/ActionBlock";
66
import { PublishedComponentBadge } from "@/components/shared/ManageComponent/PublishedComponentBadge";
77
import { trimDigest } from "@/components/shared/ManageComponent/utils/digest";
88
import { useBetaFlagValue } from "@/components/shared/Settings/useBetaFlags";
@@ -38,7 +38,6 @@ const TaskNodeCard = () => {
3838
"remote-component-library-search",
3939
);
4040
const isSubgraphNavigationEnabled = useBetaFlagValue("subgraph-navigation");
41-
const isInAppEditorEnabled = useBetaFlagValue("in-app-component-editor");
4241
const { registerNode } = useNodesOverlay();
4342
const taskNode = useTaskNode();
4443
const {
@@ -55,7 +54,7 @@ const TaskNodeCard = () => {
5554
const nodeRef = useRef<HTMLDivElement | null>(null);
5655
const contentRef = useRef<HTMLDivElement>(null);
5756

58-
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
57+
const [isYamlFullscreen, setIsYamlFullscreen] = useState(false);
5958
const [updateOverlayDialogOpen, setUpdateOverlayDialogOpen] = useState<
6059
UpdateOverlayMessage["data"] | undefined
6160
>();
@@ -128,69 +127,63 @@ const TaskNodeCard = () => {
128127
}
129128
}, []);
130129

131-
const handleEditComponent = useCallback(() => {
132-
setIsEditDialogOpen(true);
133-
}, []);
134-
135-
const handleCloseEditDialog = useCallback(() => {
136-
setIsEditDialogOpen(false);
137-
}, []);
138-
139-
const { onDuplicate, onUpgrade } = callbacks;
140-
141-
const taskConfigMarkup = useMemo(() => {
142-
const actions: Array<TooltipButtonProps> = [];
143-
144-
if (!readOnly) {
145-
actions.push({
146-
children: <Icon name="Copy" size="sm" />,
147-
variant: "outline",
148-
tooltip: "Duplicate Task",
149-
onClick: onDuplicate,
150-
});
151-
}
130+
const handleDuplicateTask = useCallback(() => {
131+
callbacks.onDuplicate?.();
132+
}, [callbacks]);
152133

153-
if (!readOnly && !isCustomComponent) {
154-
actions.push({
155-
children: <Icon name="CircleFadingArrowUp" size="sm" />,
156-
variant: "outline",
157-
tooltip: "Update Task from Source URL",
158-
onClick: onUpgrade,
159-
});
160-
}
161-
162-
if (isSubgraphNode && taskId && isSubgraphNavigationEnabled) {
163-
actions.push({
164-
children: <Icon name="Workflow" size="sm" />,
165-
variant: "outline",
166-
tooltip: `Enter Subgraph: ${subgraphDescription}`,
167-
onClick: () => navigateToSubgraph(taskId),
168-
});
169-
}
134+
const handleUpgradeTask = useCallback(() => {
135+
callbacks.onUpgrade?.();
136+
}, [callbacks]);
170137

171-
if (isInAppEditorEnabled) {
172-
actions.push({
173-
children: <Icon name="FilePenLine" size="sm" />,
174-
variant: "outline",
175-
tooltip: "Edit Component Definition",
176-
onClick: handleEditComponent,
177-
});
138+
const handleEnterSubgraph = useCallback(() => {
139+
if (taskId) {
140+
navigateToSubgraph(taskId);
178141
}
142+
}, [navigateToSubgraph, taskId]);
179143

180-
return <TaskOverview taskNode={taskNode} key={nodeId} actions={actions} />;
144+
const taskConfigMarkup = useMemo(() => {
145+
const customActions: Action[] = [
146+
{
147+
label: "Duplicate Task",
148+
icon: "Copy",
149+
hidden: readOnly,
150+
onClick: handleDuplicateTask,
151+
},
152+
{
153+
label: "Update Task from Source URL",
154+
icon: "CircleFadingArrowUp",
155+
hidden: readOnly || isCustomComponent,
156+
onClick: handleUpgradeTask,
157+
},
158+
{
159+
label: `Enter Subgraph: ${subgraphDescription}`,
160+
icon: "Workflow",
161+
hidden: !isSubgraphNode || !isSubgraphNavigationEnabled,
162+
onClick: handleEnterSubgraph,
163+
},
164+
{
165+
label: "View YAML",
166+
icon: "FileCodeCorner",
167+
onClick: () => setIsYamlFullscreen(true),
168+
},
169+
];
170+
171+
return (
172+
<TaskOverview
173+
key={nodeId}
174+
taskNode={taskNode}
175+
customActions={customActions}
176+
/>
177+
);
181178
}, [
182179
taskNode,
183180
nodeId,
184181
readOnly,
185-
isInAppEditorEnabled,
186182
isCustomComponent,
187183
isSubgraphNode,
188184
taskId,
189185
subgraphDescription,
190186
navigateToSubgraph,
191-
handleEditComponent,
192-
onDuplicate,
193-
onUpgrade,
194187
isSubgraphNavigationEnabled,
195188
]);
196189

@@ -272,6 +265,8 @@ const TaskNodeCard = () => {
272265
</QuickTooltip>
273266
);
274267

268+
const componentText = taskSpec.componentRef?.text;
269+
275270
return (
276271
<>
277272
<Card
@@ -361,10 +356,13 @@ const TaskNodeCard = () => {
361356
) : null}
362357
</CardContent>
363358
</Card>
364-
{isEditDialogOpen && (
365-
<ComponentEditorDialog
366-
text={taskSpec.componentRef?.text}
367-
onClose={handleCloseEditDialog}
359+
{isYamlFullscreen && componentText && (
360+
<CodeViewer
361+
code={componentText}
362+
language="yaml"
363+
filename={name}
364+
isFullscreen={isYamlFullscreen}
365+
onClose={() => setIsYamlFullscreen(false)}
368366
/>
369367
)}
370368
</>

0 commit comments

Comments
 (0)