Skip to content
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- `searchListPredicate` property: Allows to filter the complete list of search options at once.
- Following optional BlueprintJs properties are forwarded now to override default behaviour: `noResults`, `createNewItemRenderer` and `itemRenderer`
- `isValidNewOption` property: Checks if an input string is or can be turned into a valid new option.
- `ActivityControlWidge`
- Support `badge` on activity control menu button.

### Fixed

- `<MultiSelect />`
- border of the BlueprintJS `Tag` elements were fixed
- `extendedTooltip` of a handle in the ReactFlow (v12) component does not show the tooltip.

### Changed

Expand Down
11 changes: 11 additions & 0 deletions src/cmem/ActivityControl/ActivityControlWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export interface ActivityControlWidgetProps extends TestableComponent {
interface IActivityContextMenu extends TestableComponent {
// Tooltip for the context menu
tooltip?: string;
// Optional badge shown on the context menu button.
badge?: string | number;
// The entries of the context menu
menuItems: IActivityMenuAction[];
}
Expand Down Expand Up @@ -228,6 +230,15 @@ export function ActivityControlWidget(props: ActivityControlWidgetProps) {
<ContextMenu
data-test-id={activityContextMenu["data-test-id"]}
togglerText={activityContextMenu.tooltip}
togglerElement={
<IconButton
name={["item-moremenu"]}
text={activityContextMenu.tooltip}
badge={activityContextMenu.badge}
tooltipAsTitle
data-test-id={activityContextMenu["data-test-id"]}
/>
}
>
{activityContextMenu.menuItems.map((menuAction, idx) => {
return (
Expand Down
21 changes: 21 additions & 0 deletions src/cmem/ActivityControl/tests/ActivityControlWidget.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,25 @@ describe("ActivityControlWidget", () => {
fireEvent.click(customButton);
expect(mockAction).toHaveBeenCalledTimes(1);
});

it("renders a badge on the context menu trigger", () => {
const { container } = render(
<ActivityControlWidget
activityContextMenu={{
tooltip: "More options",
badge: 3,
menuItems: [
{
icon: "item-settings",
action: jest.fn(),
tooltip: "Configure",
},
],
"data-testid": "activity-menu",
}}
/>,
);

expect(container.querySelector("button[title='More options']")).toHaveTextContent("3");
});
});
12 changes: 11 additions & 1 deletion src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const nodeExamples = {
content: "Example content.",
minimalShape: "none",
},
position: { x: 400, y: 200 },
position: { x: 400, y: 100 },
},
{
id: "linking-3",
Expand Down Expand Up @@ -141,6 +141,16 @@ const nodeExamples = {
},
position: { x: 50, y: 300 },
},
{
id: "linking-6",
type: "ruleblock",
data: {
label: "Rule block",
content: "Example content.",
minimalShape: "none",
},
position: { x: 400, y: 200 },
},
],
edges: [
{
Expand Down
1 change: 1 addition & 0 deletions src/cmem/react-flow/_handles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
@include handletypestyles("sourcepath");
@include handletypestyles("targetpath");
@include handletypestyles("transformation");
@include handletypestyles("ruleblock");
@include handletypestyles("comparator");
@include handletypestyles("aggregator");
1 change: 1 addition & 0 deletions src/cmem/react-flow/_minimap.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
@include mapnodestyles("sourcepath");
@include mapnodestyles("targetpath");
@include mapnodestyles("transformation");
@include mapnodestyles("ruleblock");
@include mapnodestyles("comparator");
@include mapnodestyles("aggregator");
2 changes: 2 additions & 0 deletions src/cmem/react-flow/configuration/_colors-linking.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
--#{$eccgui}-targetpath-node-bright: #{eccgui-color-var("layout", "petrol", 300)};
--#{$eccgui}-transformation-node: #{eccgui-color-var("layout", "pink", 700)};
--#{$eccgui}-transformation-node-bright: #{eccgui-color-var("layout", "pink", 300)};
--#{$eccgui}-ruleblock-node: #{eccgui-color-var("layout", "vermilion", 700)};
--#{$eccgui}-ruleblock-node-bright: #{eccgui-color-var("layout", "vermilion", 300)};
--#{$eccgui}-comparator-node: #{eccgui-color-var("layout", "teal", 700)};
--#{$eccgui}-comparator-node-bright: #{eccgui-color-var("layout", "teal", 300)};
--#{$eccgui}-aggregator-node: #{eccgui-color-var("layout", "cyan", 700)};
Expand Down
1 change: 1 addition & 0 deletions src/cmem/react-flow/configuration/linking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const nodeTypes: Record<LINKING_NODE_TYPES, React.ComponentType<NodeProps>> = {
sourcepath: NodeDefault,
targetpath: NodeDefault,
transformation: NodeDefault,
ruleblock: NodeDefault,
comparator: NodeDefault,
aggregator: NodeDefault,
stickynote: StickyNoteNode,
Expand Down
1 change: 1 addition & 0 deletions src/cmem/react-flow/configuration/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum LINKING_NODE_TYPES {
sourcepath = "sourcepath",
targetpath = "targetpath",
transformation = "transformation",
ruleblock = "ruleblock",
comparator = "comparator",
aggregator = "aggregator",
stickynote = "stickynote",
Expand Down
1 change: 1 addition & 0 deletions src/cmem/react-flow/nodes/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@
@include nodetypestyles("sourcepath");
@include nodetypestyles("targetpath");
@include nodetypestyles("transformation");
@include nodetypestyles("ruleblock");
@include nodetypestyles("comparator");
@include nodetypestyles("aggregator");
1 change: 1 addition & 0 deletions src/components/Icon/canonicalIconNames.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const canonicalIcons = {
"artefact-report": icons.Report,
"artefact-task": icons.Script,
"artefact-transform": icons.DataRefinery,
"artefact-ruleblock": transform(icons.Fragments, 90),
"artefact-uncategorized": icons.Unknown,
"artefact-workflow": icons.ModelBuilder,

Expand Down
3 changes: 2 additions & 1 deletion src/extensions/react-flow/handles/HandleContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const HandleContent = memo(
{children}
</div>
) : extendedTooltip ? (
<div className={`${eccgui}-graphviz__handle__content`} {...otherDivProps} />
<div className={`${eccgui}-graphviz__handle__content ${eccgui}-graphviz__handle__content--extendedTooltip`} {...otherDivProps} />
) : (
<></>
);
Expand All @@ -33,6 +33,7 @@ export const HandleContent = memo(
autoFocus={false}
enforceFocus={false}
openOnTargetFocus={false}
usePlaceholder={false}
{...tooltipProps}
>
{handleContent}
Expand Down
39 changes: 21 additions & 18 deletions src/extensions/react-flow/handles/HandleDefault.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const HandleDefault = memo(
offset: {
enabled: true,
options: {
offset: [3, 20],
offset: [0, 20],
},
},
},
Expand All @@ -89,21 +89,15 @@ export const HandleDefault = memo(
isOpen: extendedTooltipDisplayed,
};

const handleContentProps = React.useMemo(
() => ({
...data,
tooltipProps: {
...handleContentTooltipProps,
...data?.tooltipProps,
} as TooltipProps,
}),
[intent, category, handleProps.isConnectable],
);
const handleContentProps = {
...data,
tooltipProps: {
...handleContentTooltipProps,
...data?.tooltipProps,
} as TooltipProps,
};

const handleContent = React.useMemo(
() => <HandleContent {...handleContentProps}>{children}</HandleContent>,
[],
);
const handleContent = <HandleContent {...handleContentProps}>{children}</HandleContent>;

let switchTooltipTimerOn: ReturnType<typeof setTimeout>;
let switchToolsTimerOff: ReturnType<typeof setTimeout>;
Expand All @@ -119,15 +113,15 @@ export const HandleDefault = memo(
if (handleProps.onClick) {
handleProps.onClick(e);
}
if (toolsTarget.length > 0 && e.target === handleDefaultRef.current) {
if (toolsTarget.length > 0 && e.currentTarget === handleDefaultRef.current) {
setExtendedTooltipDisplayed(false);
(toolsTarget[0] as HTMLElement).click();
}
},
"data-category": category,
onMouseEnter: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (switchToolsTimerOff) clearTimeout(switchToolsTimerOff);
if (e.target === handleDefaultRef.current) {
if (e.currentTarget === handleDefaultRef.current) {
switchTooltipTimerOn = setTimeout(
() => setExtendedTooltipDisplayed(true),
data?.tooltipProps?.hoverOpenDelay ?? 500,
Expand All @@ -142,7 +136,16 @@ export const HandleDefault = memo(
setExtendedTooltipDisplayed(false);
},
}),
[intent, category, tooltip, handleProps.isConnectable, handleProps.style],
[
intent,
category,
tooltip,
flowVersionCheck,
handleProps.isConnectable,
handleProps.style,
handleProps.onClick,
data?.tooltipProps?.hoverOpenDelay,
],
);

switch (flowVersionCheck) {
Expand Down
9 changes: 8 additions & 1 deletion src/extensions/react-flow/handles/_handles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,14 @@ div.react-flow__handle {
position: absolute;
inset: 0;
overflow: hidden;
cursor: help;
}

.#{$eccgui}-graphviz__handle__content--extendedTooltip {
inset: unset;
top: 50%;
left: 50%;
height: 0;
width: 0;
}

div.react-flow__handle-right {
Expand Down
60 changes: 60 additions & 0 deletions src/extensions/react-flow/handles/tests/HandleDefault.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";
import { OverlaysProvider } from "@blueprintjs/core";
import "@testing-library/jest-dom";

import { HandleDefault } from "../HandleDefault";

jest.mock("react-flow-renderer", () => {
const React = require("react");
return {
Handle: React.forwardRef(
({ children, isConnectable, position, type, ...props }: any, ref: React.Ref<HTMLDivElement>) => (
<div ref={ref} {...props}>
{children}
</div>
),
),
};
});

jest.mock("@xyflow/react", () => {
const React = require("react");
return {
Handle: React.forwardRef(
({ children, isConnectable, position, type, ...props }: any, ref: React.Ref<HTMLDivElement>) => (
<div ref={ref} {...props}>
{children}
</div>
),
),
};
});

jest.mock("../../versionsupport", () => ({
useReactFlowVersion: () => "v9",
}));

describe("HandleDefault", () => {
it("shows the extended tooltip on handle hover", async () => {
render(
<OverlaysProvider>
<HandleDefault
type="target"
isConnectable={true}
data-testid="handle"
data={{
extendedTooltip: "This is another Tooltip",
tooltipProps: {
hoverOpenDelay: 0,
},
}}
/>
</OverlaysProvider>,
);

fireEvent.mouseEnter(screen.getByTestId("handle"));

expect(await screen.findByText("This is another Tooltip")).toBeVisible();
});
});
Loading