Skip to content
Merged
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
Expand Up @@ -4,6 +4,7 @@ import { BlockStack } from "@/components/ui/layout";
import { Separator } from "@/components/ui/separator";
import useToastNotification from "@/hooks/useToastNotification";
import type { AnnotationConfig, Annotations } from "@/types/annotations";
import { HIDDEN_ANNOTATIONS } from "@/utils/annotations";
import type { TaskSpec } from "@/utils/componentSpec";

import { AnnotationsEditor } from "./AnnotationsEditor";
Expand Down Expand Up @@ -61,7 +62,7 @@ export const AnnotationsSection = ({

return Object.entries(annotations).reduce<Annotations>(
(acc, [key, value]) => {
if (!managedAnnotationKeys.has(key)) {
if (!managedAnnotationKeys.has(key) && !HIDDEN_ANNOTATIONS.has(key)) {
acc[key] = value;
}
return acc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,17 @@ const TaskNodeCard = () => {
const executionState = executionData?.state;

const nodeRef = useRef<HTMLDivElement | null>(null);
const contentRef = useRef<HTMLDivElement>(null);

const [updateOverlayDialogOpen, setUpdateOverlayDialogOpen] = useState<
UpdateOverlayMessage["data"] | undefined
>();
const [highlightedState, setHighlighted] = useState(false);

const [scrollHeight, setScrollHeight] = useState(0);
const [condensed, setCondensed] = useState(false);
const [expandedInputs, setExpandedInputs] = useState(false);
const [expandedOutputs, setExpandedOutputs] = useState(false);

const { name, displayName, state, nodeId, taskSpec, taskId } = taskNode;
const { dimensions, selected, highlighted, readOnly } = state;
const { dimensions, selected, highlighted, readOnly, isCollapsed } = state;

const { isConnectedToSelectedEdge } = useEdgeSelectionHighlight(nodeId);

Expand Down Expand Up @@ -160,23 +157,6 @@ const TaskNodeCard = () => {
navigate,
]);

useEffect(() => {
if (nodeRef.current) {
setScrollHeight(nodeRef.current.scrollHeight);
}
}, []);

useEffect(() => {
if (!dimensions.h) {
setCondensed(false);
return;
}

if (contentRef.current && scrollHeight > 0) {
setCondensed(scrollHeight > dimensions.h);
}
}, [scrollHeight, dimensions.h]);

useEffect(() => {
if (selected) {
setContent(taskConfigMarkup);
Expand Down Expand Up @@ -211,7 +191,7 @@ const TaskNodeCard = () => {
return (
<Card
className={cn(
"rounded-2xl border-gray-200 border-2 wrap-break-word p-0 drop-shadow-none gap-2",
"rounded-2xl border-gray-200 border-2 wrap-break-word p-0 drop-shadow-none gap-2 min-h-fit",
selected ? "border-gray-500" : "hover:border-slate-200",
(highlighted || highlightedState) && "border-orange-500!",
isConnectedToSelectedEdge &&
Expand All @@ -220,7 +200,7 @@ const TaskNodeCard = () => {
)}
style={{
width: dimensions.w + "px",
height: condensed || !dimensions.h ? "auto" : dimensions.h + "px",
height: isCollapsed || !dimensions.h ? "auto" : dimensions.h + "px",
transition: "height 0.2s",
}}
ref={nodeRef}
Expand Down Expand Up @@ -279,21 +259,22 @@ const TaskNodeCard = () => {
<div
style={{
maxHeight:
dimensions.h && !(expandedInputs || expandedOutputs)
!isCollapsed &&
dimensions.h &&
!(expandedInputs || expandedOutputs)
? `${dimensions.h}px`
: "100%",
}}
className="min-h-fit"
ref={contentRef}
>
<TaskNodeInputs
condensed={condensed}
collapsed={isCollapsed}
expanded={expandedInputs}
onBackgroundClick={handleInputSectionClick}
/>

<TaskNodeOutputs
condensed={condensed}
collapsed={isCollapsed}
expanded={expandedOutputs}
onBackgroundClick={handleOutputSectionClick}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe("<TaskNodeInputs />", () => {

useMockedUseTaskNode(inputs, taskSpec);

render(<TaskNodeInputs condensed={false} expanded={true} />, {
render(<TaskNodeInputs collapsed={false} expanded={true} />, {
wrapper: TestWrapper,
});

Expand Down Expand Up @@ -108,7 +108,7 @@ describe("<TaskNodeInputs />", () => {
);
});

it("should show hidden invalid arguments warning in condensed mode", () => {
it("should show hidden invalid arguments warning in collapsed mode", () => {
const inputs = [
createMockInput("visibleInput", "String", false),
createMockInput("hiddenInvalidInput1", "String", false),
Expand All @@ -123,7 +123,7 @@ describe("<TaskNodeInputs />", () => {

useMockedUseTaskNode(inputs, taskSpec);

render(<TaskNodeInputs condensed={true} expanded={false} />, {
render(<TaskNodeInputs collapsed={true} expanded={false} />, {
wrapper: TestWrapper,
});

Expand All @@ -147,7 +147,7 @@ describe("<TaskNodeInputs />", () => {

useMockedUseTaskNode(inputs, taskSpec);

render(<TaskNodeInputs condensed={true} expanded={false} />, {
render(<TaskNodeInputs collapsed={true} expanded={false} />, {
wrapper: TestWrapper,
});

Expand All @@ -170,7 +170,7 @@ describe("<TaskNodeInputs />", () => {

useMockedUseTaskNode(inputs, taskSpec);

render(<TaskNodeInputs condensed={true} expanded={false} />, {
render(<TaskNodeInputs collapsed={true} expanded={false} />, {
wrapper: TestWrapper,
});

Expand All @@ -183,7 +183,7 @@ describe("<TaskNodeInputs />", () => {
it("should handle edge case with no inputs", () => {
useMockedUseTaskNode([], createMockTaskSpec());

render(<TaskNodeInputs condensed={false} expanded={true} />, {
render(<TaskNodeInputs collapsed={false} expanded={true} />, {
wrapper: TestWrapper,
});

Expand Down Expand Up @@ -214,7 +214,7 @@ describe("<TaskNodeInputs />", () => {

useMockedUseTaskNode(inputs, taskSpec);

render(<TaskNodeInputs condensed={false} expanded={true} />, {
render(<TaskNodeInputs collapsed={false} expanded={true} />, {
wrapper: TestWrapper,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import { InputHandle } from "./Handles";
import { getDisplayValue } from "./handleUtils";

interface TaskNodeInputsProps {
condensed: boolean;
collapsed: boolean;
expanded: boolean;
onBackgroundClick?: () => void;
}

export function TaskNodeInputs({
condensed,
collapsed,
expanded,
onBackgroundClick,
}: TaskNodeInputsProps) {
Expand Down Expand Up @@ -76,12 +76,12 @@ export function TaskNodeInputs({

const handleBackgroundClick = useCallback(
(e: MouseEvent) => {
if (condensed && onBackgroundClick) {
if (collapsed && onBackgroundClick) {
e.stopPropagation();
onBackgroundClick();
}
},
[condensed, onBackgroundClick],
[collapsed, onBackgroundClick],
);

const handleSelectionChange = useCallback(
Expand Down Expand Up @@ -176,7 +176,7 @@ export function TaskNodeInputs({

const hiddenInputs = inputs.length - connectedInputs.length;
if (hiddenInputs < 1) {
condensed = false;
collapsed = false;
}

const hiddenInvalidArguments = invalidArguments.filter(
Expand All @@ -188,11 +188,11 @@ export function TaskNodeInputs({
<div
className={cn(
"flex flex-col items-center gap-3 p-2 bg-gray-100 border border-gray-200 rounded-lg",
condensed && onBackgroundClick && "hover:bg-gray-200/70 cursor-pointer",
collapsed && onBackgroundClick && "hover:bg-gray-200/70 cursor-pointer",
)}
onClick={handleBackgroundClick}
>
{condensed && !expanded ? (
{collapsed && !expanded ? (
<>
{connectedInputs.map((input, i) => (
<InputHandle
Expand Down Expand Up @@ -231,7 +231,7 @@ export function TaskNodeInputs({
onLabelClick={handleLabelClick}
/>
))}
{condensed && (
{collapsed && (
<span className="text-xs text-gray-400 mt-1">
(Click to collapse)
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { checkArtifactMatchesSearchFilters } from "@/utils/searchUtils";
import { OutputHandle } from "./Handles";

type TaskNodeOutputsProps = {
condensed: boolean;
collapsed: boolean;
expanded: boolean;
onBackgroundClick?: () => void;
};

export function TaskNodeOutputs({
condensed,
collapsed,
expanded,
onBackgroundClick,
}: TaskNodeOutputsProps) {
Expand Down Expand Up @@ -65,12 +65,12 @@ export function TaskNodeOutputs({

const handleBackgroundClick = useCallback(
(e: MouseEvent) => {
if (condensed && onBackgroundClick) {
if (collapsed && onBackgroundClick) {
e.stopPropagation();
onBackgroundClick();
}
},
[condensed, onBackgroundClick],
[collapsed, onBackgroundClick],
);

const handleSelectionChange = useCallback(
Expand Down Expand Up @@ -161,18 +161,18 @@ export function TaskNodeOutputs({

const hiddenOutputs = outputs.length - outputsWithTaskInput.length;
if (hiddenOutputs < 1) {
condensed = false;
collapsed = false;
}

return (
<div
className={cn(
"flex flex-col justify-end items-center gap-3 p-2 bg-gray-100 border border-gray-200 rounded-lg",
condensed && onBackgroundClick && "hover:bg-gray-200/70 cursor-pointer",
collapsed && onBackgroundClick && "hover:bg-gray-200/70 cursor-pointer",
)}
onClick={handleBackgroundClick}
>
{condensed && !expanded ? (
{collapsed && !expanded ? (
outputsWithTaskInput.map((output, i) => (
<OutputHandle
key={output.name}
Expand All @@ -198,7 +198,7 @@ export function TaskNodeOutputs({
onLabelClick={handleLabelClick}
/>
))}
{condensed && (
{collapsed && (
<span className="text-xs text-gray-400 mt-1">
(Click to collapse)
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ const TaskConfiguration = ({ taskNode }: TaskConfigurationProps) => {
onCheckedChange={handleDisableCacheChange}
/>
</InlineStack>
<InlineStack align="space-between" gap="2" className="w-full">
<Paragraph tone="subdued" size="sm">
Collapse node
</Paragraph>
<Switch
checked={taskNode.state.isCollapsed}
onCheckedChange={taskNode.callbacks.setCollapsed}
/>
</InlineStack>
</BlockStack>
);
};
Expand Down
31 changes: 31 additions & 0 deletions src/providers/TaskNodeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import {
type TaskNodeData,
type TaskNodeDimensions,
} from "@/types/taskNode";
import {
EDITOR_COLLAPSED_ANNOTATION,
getAnnotationValue,
removeAnnotation,
setAnnotation,
} from "@/utils/annotations";
import {
type ArgumentType,
type ComponentReference,
Expand Down Expand Up @@ -39,13 +45,15 @@ type TaskNodeState = Readonly<{
connectable: boolean;
status?: string;
isCustomComponent: boolean;
isCollapsed: boolean;
dimensions: TaskNodeDimensions;
}>;

type TaskNodeCallbacks = {
setArguments: (args: Record<string, ArgumentType>) => void;
setAnnotations: (annotations: Annotations) => void;
setCacheStaleness: (cacheStaleness: string | undefined) => void;
setCollapsed: (collapsed: boolean) => void;
onDelete?: () => void;
onDuplicate?: () => void;
onUpgrade?: () => void;
Expand Down Expand Up @@ -139,6 +147,25 @@ export const TaskNodeProvider = ({
[setCacheStaleness, notify],
);

const isCollapsed =
getAnnotationValue(taskSpec?.annotations, EDITOR_COLLAPSED_ANNOTATION) ===
"true";

const handleSetCollapsed = useCallback(
(collapsed: boolean) => {
const updatedAnnotations = collapsed
? setAnnotation(
taskSpec?.annotations,
EDITOR_COLLAPSED_ANNOTATION,
"true",
)
: removeAnnotation(taskSpec?.annotations, EDITOR_COLLAPSED_ANNOTATION);

setAnnotations(updatedAnnotations as Annotations);
},
[taskSpec?.annotations, setAnnotations],
);

const handleDeleteTaskNode = useCallback(() => {
onDelete();
}, [onDelete]);
Expand Down Expand Up @@ -173,6 +200,7 @@ export const TaskNodeProvider = ({
status: data.isGhost ? undefined : status,
disabled: data.isGhost ?? false,
isCustomComponent,
isCollapsed,
dimensions,
}),
[
Expand All @@ -182,6 +210,7 @@ export const TaskNodeProvider = ({
data.isGhost,
status,
isCustomComponent,
isCollapsed,
dimensions,
],
);
Expand All @@ -191,13 +220,15 @@ export const TaskNodeProvider = ({
setArguments: handleSetArguments,
setAnnotations: handleSetAnnotations,
setCacheStaleness: handleSetCacheStaleness,
setCollapsed: handleSetCollapsed,
onDelete: handleDeleteTaskNode,
onDuplicate: handleDuplicateTaskNode,
onUpgrade: handleUpgradeTaskNode,
}),
[
handleSetArguments,
handleSetAnnotations,
handleSetCollapsed,
handleDeleteTaskNode,
handleDuplicateTaskNode,
handleUpgradeTaskNode,
Expand Down
Loading