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
2 changes: 1 addition & 1 deletion src/components/shared/Buttons/TooltipButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";

export interface TooltipButtonProps extends ButtonProps {
interface TooltipButtonProps extends ButtonProps {
tooltip: React.ReactNode;
tooltipSide?: "top" | "right" | "bottom" | "left";
tooltipAlign?: "start" | "center" | "end";
Expand Down
2 changes: 1 addition & 1 deletion src/components/shared/ContextPanel/Blocks/ActionBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type Action = {
);

// Temporary: ReactNode included for backward compatibility with some existing buttons. In the long-term we should strive for only Action types.
export type ActionOrReactNode = Action | ReactNode;
type ActionOrReactNode = Action | ReactNode;

interface ActionBlockProps {
title?: string;
Expand Down
111 changes: 31 additions & 80 deletions src/components/shared/Dialogs/ComponentDetailsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import { useHydrateComponentReference } from "@/hooks/useHydrateComponentReferen
import type { ComponentReference } from "@/utils/componentSpec";

import InfoIconButton from "../Buttons/InfoIconButton";
import TooltipButton from "../Buttons/TooltipButton";
import { ComponentEditorDialog } from "../ComponentEditor/ComponentEditorDialog";
import { ComponentFavoriteToggle } from "../FavoriteComponentToggle";
import { InfoBox } from "../InfoBox";
import { PublishComponent } from "../ManageComponent/PublishComponent";
Expand All @@ -32,7 +30,6 @@ interface ComponentDetailsProps {
component: ComponentReference;
displayName: string;
trigger?: ReactNode;
actions?: ReactNode[];
onClose?: () => void;
onDelete?: () => void;
}
Expand Down Expand Up @@ -64,12 +61,7 @@ const ComponentDetailsDialogContentSkeleton = () => {
};

const ComponentDetailsDialogContent = withSuspenseWrapper(
({
component,
displayName,
actions = [],
onDelete,
}: ComponentDetailsProps) => {
({ component, displayName, onDelete }: ComponentDetailsProps) => {
const remoteComponentLibrarySearchEnabled = useBetaFlagValue(
"remote-component-library-search",
);
Expand Down Expand Up @@ -138,7 +130,6 @@ const ComponentDetailsDialogContent = withSuspenseWrapper(
componentSpec={componentSpec}
componentDigest={componentDigest}
url={url}
actions={actions}
onDelete={onDelete}
/>
</TabsContent>
Expand Down Expand Up @@ -175,18 +166,12 @@ const ComponentDetails = ({
component,
displayName,
trigger,
actions = [],
onClose,
onDelete,
}: ComponentDetailsProps) => {
const hasEnabledInAppEditor = useBetaFlagValue("in-app-component-editor");

const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
const [open, setOpen] = useState(false);
const dialogTriggerButton = trigger || <InfoIconButton />;

const componentText = component.text;

const dialogContextValue = useMemo(
() => ({
name: "ComponentDetails",
Expand All @@ -197,79 +182,45 @@ const ComponentDetails = ({
[],
);

const handleCloseEditDialog = useCallback(() => {
setIsEditDialogOpen(false);
}, []);

const onOpenChange = useCallback((open: boolean) => {
setOpen(open);
if (!open) {
onClose?.();
}
}, []);

const handleEditComponent = useCallback(() => {
setIsEditDialogOpen(true);
}, []);

const actionsWithEdit = useMemo(() => {
if (!hasEnabledInAppEditor) return actions;

const EditButton = (
<TooltipButton
variant="secondary"
onClick={handleEditComponent}
tooltip="Edit Component Definition"
key={`${displayName}-edit-button`}
>
<Icon name="FilePenLine" />
</TooltipButton>
);

return [...actions, EditButton];
}, [actions, hasEnabledInAppEditor, handleEditComponent]);

return (
<>
<Dialog modal open={open} onOpenChange={onOpenChange}>
<DialogTrigger asChild>{dialogTriggerButton}</DialogTrigger>
<Dialog modal open={open} onOpenChange={onOpenChange}>
<DialogTrigger asChild>{dialogTriggerButton}</DialogTrigger>

<DialogDescription
className="hidden"
aria-label={`${displayName} component details`}
>
{`${displayName} component details`}
</DialogDescription>
<DialogContent
className="max-w-2xl min-w-2xl overflow-hidden"
aria-label={`${displayName} component details`}
>
<DialogHeader>
<DialogTitle className="flex items-center gap-2 mr-5">
<span>{displayName}</span>
<ComponentFavoriteToggle component={component} />
</DialogTitle>
</DialogHeader>

<DialogContext.Provider value={dialogContextValue}>
<ComponentDetailsDialogContent
component={component}
displayName={displayName}
trigger={dialogTriggerButton}
actions={actionsWithEdit}
onClose={onClose}
onDelete={onDelete}
/>
</DialogContext.Provider>
</DialogContent>
</Dialog>
{isEditDialogOpen && (
<ComponentEditorDialog
text={componentText}
onClose={handleCloseEditDialog}
/>
)}
</>
<DialogDescription
className="hidden"
aria-label={`${displayName} component details`}
>
{`${displayName} component details`}
</DialogDescription>
<DialogContent
className="max-w-2xl min-w-2xl overflow-hidden"
aria-label={`${displayName} component details`}
>
<DialogHeader>
<DialogTitle className="flex items-center gap-2 mr-5">
<span>{displayName}</span>
<ComponentFavoriteToggle component={component} />
</DialogTitle>
</DialogHeader>

<DialogContext.Provider value={dialogContextValue}>
<ComponentDetailsDialogContent
component={component}
displayName={displayName}
trigger={dialogTriggerButton}
onClose={onClose}
onDelete={onDelete}
/>
</DialogContext.Provider>
</DialogContent>
</Dialog>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useNavigate } from "@tanstack/react-router";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

import type { TooltipButtonProps } from "@/components/shared/Buttons/TooltipButton";
import { ComponentEditorDialog } from "@/components/shared/ComponentEditor/ComponentEditorDialog";
import { CodeViewer } from "@/components/shared/CodeViewer";
import type { Action } from "@/components/shared/ContextPanel/Blocks/ActionBlock";
import { PublishedComponentBadge } from "@/components/shared/ManageComponent/PublishedComponentBadge";
import { trimDigest } from "@/components/shared/ManageComponent/utils/digest";
import { useBetaFlagValue } from "@/components/shared/Settings/useBetaFlags";
Expand Down Expand Up @@ -36,7 +36,6 @@ const TaskNodeCard = () => {
"remote-component-library-search",
);
const isSubgraphNavigationEnabled = useBetaFlagValue("subgraph-navigation");
const isInAppEditorEnabled = useBetaFlagValue("in-app-component-editor");
const { registerNode } = useNodesOverlay();
const taskNode = useTaskNode();
const {
Expand All @@ -52,7 +51,7 @@ const TaskNodeCard = () => {
const nodeRef = useRef<HTMLDivElement | null>(null);
const contentRef = useRef<HTMLDivElement>(null);

const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
const [isYamlFullscreen, setIsYamlFullscreen] = useState(false);
const [updateOverlayDialogOpen, setUpdateOverlayDialogOpen] = useState<
UpdateOverlayMessage["data"] | undefined
>();
Expand Down Expand Up @@ -113,67 +112,65 @@ const TaskNodeCard = () => {
}
}, []);

const handleEditComponent = useCallback(() => {
setIsEditDialogOpen(true);
}, []);

const handleCloseEditDialog = useCallback(() => {
setIsEditDialogOpen(false);
}, []);
const handleDuplicateTask = useCallback(() => {
callbacks.onDuplicate?.();
}, [callbacks]);

const taskConfigMarkup = useMemo(() => {
const actions: Array<TooltipButtonProps> = [];

if (!readOnly) {
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,
});
}
const handleUpgradeTask = useCallback(() => {
callbacks.onUpgrade?.();
}, [callbacks]);

if (isSubgraphNode && taskId && isSubgraphNavigationEnabled) {
actions.push({
children: <Icon name="Workflow" size="sm" />,
variant: "outline",
tooltip: `Enter Subgraph: ${subgraphDescription}`,
onClick: () => navigateToSubgraph(taskId),
});
}

if (isInAppEditorEnabled) {
actions.push({
children: <Icon name="FilePenLine" size="sm" />,
variant: "outline",
tooltip: "Edit Component Definition",
onClick: handleEditComponent,
});
const handleEnterSubgraph = useCallback(() => {
if (taskId) {
navigateToSubgraph(taskId);
}
}, [navigateToSubgraph, taskId]);

return <TaskOverview taskNode={taskNode} key={nodeId} actions={actions} />;
const taskConfigMarkup = useMemo(() => {
const customActions: Action[] = [
{
label: "Duplicate Task",
icon: "Copy",
hidden: readOnly,
onClick: handleDuplicateTask,
},
{
label: "Update Task from Source URL",
icon: "CircleFadingArrowUp",
hidden: readOnly || isCustomComponent,
onClick: handleUpgradeTask,
},
{
label: `Enter Subgraph: ${subgraphDescription}`,
icon: "Workflow",
hidden: !isSubgraphNode || !isSubgraphNavigationEnabled,
onClick: handleEnterSubgraph,
},
{
label: "View YAML",
icon: "FileCodeCorner",
onClick: () => setIsYamlFullscreen(true),
},
];

return (
<TaskOverview
key={nodeId}
taskNode={taskNode}
customActions={customActions}
/>
);
}, [
taskNode,
nodeId,
readOnly,
callbacks.onDuplicate,
callbacks.onUpgrade,
isInAppEditorEnabled,
isCustomComponent,
isSubgraphNode,
taskId,
subgraphDescription,
navigateToSubgraph,
handleEditComponent,
]);

const handleInputSectionClick = useCallback(() => {
Expand Down Expand Up @@ -249,6 +246,8 @@ const TaskNodeCard = () => {
</QuickTooltip>
);

const componentText = taskSpec.componentRef?.text;

return (
<>
<Card
Expand Down Expand Up @@ -334,10 +333,13 @@ const TaskNodeCard = () => {
) : null}
</CardContent>
</Card>
{isEditDialogOpen && (
<ComponentEditorDialog
text={taskSpec.componentRef?.text}
onClose={handleCloseEditDialog}
{isYamlFullscreen && componentText && (
<CodeViewer
code={componentText}
language="yaml"
filename={name}
isFullscreen={isYamlFullscreen}
onClose={() => setIsYamlFullscreen(false)}
/>
)}
</>
Expand Down
Loading