Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useNavigate } from "@tanstack/react-router";
import { CircleFadingArrowUp, CopyIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

import type { TooltipButtonProps } from "@/components/shared/Buttons/TooltipButton";
Expand Down Expand Up @@ -126,38 +125,26 @@ const TaskNodeCard = () => {
const actions: Array<TooltipButtonProps> = [];

if (!readOnly) {
actions.push(
{
children: (
<div className="flex items-center gap-2">
<CopyIcon />
</div>
),
variant: "outline",
tooltip: "Duplicate Task",
onClick: callbacks.onDuplicate,
},
{
children: (
<div className="flex items-center gap-2">
<CircleFadingArrowUp />
</div>
),
variant: "outline",
className: cn(isCustomComponent && "hidden"),
tooltip: "Update Task from Source URL",
onClick: callbacks.onUpgrade,
},
);
actions.push({
children: <Icon name="Copy" size="sm" />,
variant: "outline",
tooltip: "Duplicate Task",
onClick: callbacks.onDuplicate,
});
}

if (!readOnly && !isCustomComponent) {
actions.push({
children: <Icon name="CircleFadingArrowUp" size="sm" />,
variant: "outline",
tooltip: "Update Task from Source URL",
onClick: callbacks.onUpgrade,
});
}

if (isSubgraphNode && taskId && isSubgraphNavigationEnabled) {
actions.push({
children: (
<div className="flex items-center gap-2">
<Icon name="Workflow" size="sm" />
</div>
),
children: <Icon name="Workflow" size="sm" />,
variant: "outline",
tooltip: `Enter Subgraph: ${subgraphDescription}`,
onClick: () => navigateToSubgraph(taskId),
Expand All @@ -166,11 +153,7 @@ const TaskNodeCard = () => {

if (isInAppEditorEnabled) {
actions.push({
children: (
<div className="flex items-center gap-2">
<Icon name="FilePenLine" size="sm" />
</div>
),
children: <Icon name="FilePenLine" size="sm" />,
variant: "outline",
tooltip: "Edit Component Definition",
onClick: handleEditComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ const TaskOverview = ({ taskNode, actions }: TaskOverviewProps) => {
url={taskSpec.componentRef.url}
onDelete={callbacks.onDelete}
status={status}
hasDeletionConfirmation={false}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

readOnly={readOnly}
actions={detailActions}
/>
Expand Down
101 changes: 101 additions & 0 deletions src/components/shared/TaskDetails/Actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { type ReactNode } from "react";
import { FaPython } from "react-icons/fa";

import useToastNotification from "@/hooks/useToastNotification";
import type { ComponentSpec } from "@/utils/componentSpec";
import { downloadYamlFromComponentText } from "@/utils/URL";
import copyToYaml from "@/utils/yaml";

import {
ActionBlock,
type ActionOrReactNode,
} from "../ContextPanel/Blocks/ActionBlock";

interface TaskActionsProps {
displayName: string;
componentSpec: ComponentSpec;
actions?: ReactNode[];
onDelete?: () => void;
readOnly?: boolean;
className?: string;
}

const TaskActions = ({
displayName,
componentSpec,
actions = [],
onDelete,
readOnly = false,
className,
}: TaskActionsProps) => {
const notify = useToastNotification();

const pythonOriginalCode =
componentSpec?.metadata?.annotations?.original_python_code;

const stringToPythonCodeDownload = () => {
if (!pythonOriginalCode) return;

const blob = new Blob([pythonOriginalCode], { type: "text/x-python" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `${componentSpec?.name || displayName}.py`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};

const handleDownloadYaml = () => {
downloadYamlFromComponentText(componentSpec, displayName);
};

const handleCopyYaml = () => {
copyToYaml(
componentSpec,
(message) => notify(message, "success"),
(message) => notify(message, "error"),
);
};

const handleDelete = () => {
try {
onDelete?.();
} catch (error) {
console.error("Error deleting component:", error);
notify(`Error deleting component`, "error");
}
};

const orderedActions: ActionOrReactNode[] = [
{
label: "Download YAML",
icon: "Download",
onClick: handleDownloadYaml,
},
{
label: "Download Python Code",
content: <FaPython />,
hidden: !pythonOriginalCode,
onClick: stringToPythonCodeDownload,
},
{
label: "Copy YAML",
icon: "Clipboard",
onClick: handleCopyYaml,
},
...actions,
{
label: "Delete Component",
icon: "Trash",
destructive: true,
hidden: !onDelete || readOnly,
onClick: handleDelete,
},
];

return <ActionBlock actions={orderedActions} className={className} />;
};

export default TaskActions;
Loading