flow-lib-creomnia 1.0.19 → 1.0.20-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,3 @@
1
- import React, { Ref } from "react";
2
1
  import { PointType } from "../../../common/types";
3
2
  import { NodeType } from "../../../node/types";
4
3
  import { ConnectionCurveEnum } from "../../enums";
@@ -9,8 +8,7 @@ interface IProps {
9
8
  childNodeId: string;
10
9
  node: NodeType;
11
10
  curveType?: ConnectionCurveEnum;
12
- onClick?: (event: React.MouseEvent<SVGSVGElement>) => void;
13
- innerRef: Ref<any>;
11
+ onOpen?: (anchorRect: DOMRect) => void;
14
12
  }
15
- export declare const AddButton: ({ endPoint, startPoint, node, curveType, parentId, childNodeId, onClick, innerRef }: IProps) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const AddButton: ({ endPoint, startPoint, node, curveType, parentId, childNodeId, onOpen, }: IProps) => import("react/jsx-runtime").JSX.Element;
16
14
  export {};
@@ -10,7 +10,7 @@ const ConnectionWithButton_1 = require("../ConnectionWithButton");
10
10
  const enums_1 = require("../../enums");
11
11
  const colors_1 = require("../../../../config/colors");
12
12
  const material_1 = require("@mui/material");
13
- const AddButton = ({ endPoint, startPoint, node, curveType, parentId, childNodeId, onClick, innerRef }) => {
13
+ const AddButton = ({ endPoint, startPoint, node, curveType, parentId, childNodeId, onOpen, }) => {
14
14
  const theme = (0, material_1.useTheme)();
15
15
  const background = theme.palette?.background?.default || colors_1.Colors.DIRTY_WHITE;
16
16
  const positionIntoEmptyChoiceNode = !curveType ? 0 : curveType === enums_1.ConnectionCurveEnum.RIGHT ? 2 : 1;
@@ -28,18 +28,37 @@ const AddButton = ({ endPoint, startPoint, node, curveType, parentId, childNodeI
28
28
  });
29
29
  const widthDiff = (config_1.Config.ADD_BUTTON_WIDTH - config_1.Config.CONNECTION_WIDTH) / 2;
30
30
  const xPosition = top ? startPoint.x - widthDiff + width : startPoint.x - widthDiff;
31
- const yPosition = y + ConnectionWithButton_1.nodeHeightByType[node.type] / 2 + config_1.Config.ADD_BUTTON_SHIFT;
31
+ const yPosition = y + (ConnectionWithButton_1.nodeHeightByType[node.type] ?? config_1.Config.NODE_HEIGHT) / 2 + config_1.Config.ADD_BUTTON_SHIFT;
32
32
  const PlusButton = (0, styled_1.createAddButton)({
33
33
  background,
34
+ });
35
+ const PlusButtonWrapper = (0, styled_1.createAddButtonWrapper)({
34
36
  x: xPosition,
35
37
  y: yPosition,
36
38
  });
37
39
  const Placeholder = (0, styled_1.createPlaceholder)(isOver, canDrop);
38
40
  const xDropZone = xPosition - (config_1.Config.NODE_WIDTH / 2 - 5);
39
41
  const yDropZone = yPosition - (config_1.Config.NODE_HEIGHT / 2 - config_1.Config.ADD_BUTTON_WIDTH / 2);
42
+ // The add button lives inside the zoom/pan surface. Without
43
+ // stopping the initial press event, the canvas can start a pan
44
+ // gesture first, and the browser may never emit the follow-up
45
+ // click that opens the nodes menu. This shows up most clearly in
46
+ // the tool-flow modal, where the nested sandbox is rendered inside
47
+ // a Dialog on top of another live canvas.
48
+ const stopCanvasGesture = (event) => {
49
+ event.stopPropagation();
50
+ };
51
+ const handlePressStart = (event) => {
52
+ // Keep the canvas from treating the press as pan/scroll start,
53
+ // then open the menu immediately instead of waiting for a full
54
+ // click sequence that may never fire once a gesture begins.
55
+ event.preventDefault();
56
+ stopCanvasGesture(event);
57
+ onOpen?.(event.currentTarget.getBoundingClientRect());
58
+ };
40
59
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Placeholder, { ref: drop, sx: {
41
60
  top: yDropZone,
42
61
  left: xDropZone,
43
- } }), (0, jsx_runtime_1.jsx)(PlusButton, { onClick: onClick, ref: innerRef })] }));
62
+ } }), (0, jsx_runtime_1.jsx)(PlusButtonWrapper, { "data-flow-interactive": 'true', onMouseDown: handlePressStart, onPointerDown: handlePressStart, onTouchStart: handlePressStart, onClick: stopCanvasGesture, children: (0, jsx_runtime_1.jsx)(PlusButton, {}) })] }));
44
63
  };
45
64
  exports.AddButton = AddButton;
@@ -4,7 +4,8 @@ type AddButtonPropsType = {
4
4
  x: number;
5
5
  y: number;
6
6
  };
7
- export declare const createAddButton: ({ background, x, y, }: AddButtonPropsType) => import("@emotion/styled").StyledComponent<{
7
+ export declare const createAddButtonWrapper: ({ x, y, }: Omit<AddButtonPropsType, 'background'>) => import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/system").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
8
+ export declare const createAddButton: ({ background, }: Omit<AddButtonPropsType, 'x' | 'y'>) => import("@emotion/styled").StyledComponent<{
8
9
  children?: import("react").ReactNode;
9
10
  classes?: Partial<import("@mui/material").SvgIconClasses> | undefined;
10
11
  color?: import("@mui/types").OverridableStringUnion<"error" | "inherit" | "action" | "disabled" | "success" | "info" | "warning" | "primary" | "secondary", import("@mui/material").SvgIconPropsColorOverrides> | undefined;
@@ -3,24 +3,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createPlaceholder = exports.createAddButton = void 0;
6
+ exports.createPlaceholder = exports.createAddButton = exports.createAddButtonWrapper = void 0;
7
7
  const system_1 = require("@mui/system");
8
8
  const Add_1 = __importDefault(require("@mui/icons-material/Add"));
9
9
  const config_1 = require("../../../../config");
10
10
  const colors_1 = require("../../../../config/colors");
11
11
  const material_1 = require("@mui/material");
12
- const createAddButton = ({ background = colors_1.Colors.WHITE, x, y, }) => (0, system_1.styled)(Add_1.default) `
13
- height: ${config_1.Config.ADD_BUTTON_WIDTH}px;
14
- width: ${config_1.Config.ADD_BUTTON_WIDTH}px;
12
+ const createAddButtonWrapper = ({ x, y, }) => (0, system_1.styled)('div') `
15
13
  position: absolute;
16
14
  top: ${y}px;
17
15
  left: ${x}px;
16
+ width: ${config_1.Config.ADD_BUTTON_WIDTH}px;
17
+ height: ${config_1.Config.ADD_BUTTON_WIDTH}px;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ cursor: pointer;
22
+ z-index: 1000;
23
+ `;
24
+ exports.createAddButtonWrapper = createAddButtonWrapper;
25
+ const createAddButton = ({ background = colors_1.Colors.WHITE, }) => (0, system_1.styled)(Add_1.default) `
26
+ height: ${config_1.Config.ADD_BUTTON_WIDTH}px;
27
+ width: ${config_1.Config.ADD_BUTTON_WIDTH}px;
18
28
  font-size: ${config_1.Config.ADD_BUTTON_WIDTH}px;
19
29
  background: ${background};
20
30
  color: ${colors_1.Colors.NAVY_BLUE};
21
31
  border-radius: 50%;
22
- cursor: pointer;
23
- z-index: 1000;
24
32
  :hover {
25
33
  background: ${colors_1.Colors.BLUE};
26
34
  color: ${colors_1.Colors.WHITE};
@@ -7,6 +7,7 @@ export declare const nodeHeightByType: {
7
7
  choiceNode: number;
8
8
  hubNode: number;
9
9
  parallelNode: number;
10
+ telephony: number;
10
11
  };
11
12
  declare const _default: React.NamedExoticComponent<ConnectionPropsType>;
12
13
  export default _default;
@@ -22,11 +22,10 @@ exports.nodeHeightByType = {
22
22
  [enums_1.NodeTypeEnum.ChoiceNode]: 0,
23
23
  [enums_1.NodeTypeEnum.HubNode]: config_1.Config.HUB_NODE_HEIGHT,
24
24
  [enums_1.NodeTypeEnum.ParallelNode]: 0,
25
+ [enums_1.NodeTypeEnum.Telephony]: config_1.Config.NODE_HEIGHT,
25
26
  };
26
27
  const ConnectionWithButton = ({ parentId, menuTabs, startPoint, endPoint, addNewNodeCallback, node, connectionIndex, curveType, isProcessed, childNodeId, emptyMenuItemsComponent, searchPlaceholder }) => {
27
- const popperRef = (0, react_1.useRef)();
28
- const [anchorEl, setAnchorEl] = (0, react_1.useState)(false);
29
- const [styles, setStyles] = (0, react_1.useState)({});
28
+ const [anchorRect, setAnchorRect] = (0, react_1.useState)(null);
30
29
  const ConnectionLine = (0, react_1.useMemo)(() => {
31
30
  const { width, height, x, y, top, bottom, left, right } = connectionParametersServices_1.connectionParametersServices.calculateConnectionParameters({
32
31
  endPoint,
@@ -48,19 +47,18 @@ const ConnectionWithButton = ({ parentId, menuTabs, startPoint, endPoint, addNew
48
47
  });
49
48
  }, [curveType, endPoint, node, startPoint]);
50
49
  const handleClose = () => {
51
- setAnchorEl(false);
50
+ setAnchorRect(null);
52
51
  };
53
- const handleClick = (event) => {
54
- const rect = popperRef?.current?.getBoundingClientRect();
55
- const left = rect?.left || 0;
56
- const top = rect?.top || 0;
57
- const style = {
58
- transform: `translate(${left - 400}px, ${top - 228}px)`,
59
- overflow: 'visible',
60
- };
61
- setStyles(style);
62
- setAnchorEl(true);
52
+ const handleOpen = (nextAnchorRect) => {
53
+ setAnchorRect(nextAnchorRect);
63
54
  };
55
+ const anchorEl = (0, react_1.useMemo)(() => {
56
+ if (!anchorRect)
57
+ return null;
58
+ return {
59
+ getBoundingClientRect: () => anchorRect,
60
+ };
61
+ }, [anchorRect]);
64
62
  const isOpen = Boolean(anchorEl);
65
63
  const props = (0, web_1.useSpring)({
66
64
  borderColor: isProcessed ? colors_1.Colors.GREEN : colors_1.Colors.NAVY_BLUE,
@@ -76,9 +74,11 @@ const ConnectionWithButton = ({ parentId, menuTabs, startPoint, endPoint, addNew
76
74
  curveType,
77
75
  parentId,
78
76
  childNodeId,
79
- onClick: handleClick,
80
- innerRef: popperRef
77
+ onOpen: handleOpen,
81
78
  };
82
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(AddButton_1.AddButton, { ...buttonProps }), (0, jsx_runtime_1.jsx)(AnimatedConnectionLine, { style: props }), (0, jsx_runtime_1.jsx)(material_1.ClickAwayListener, { onClickAway: () => isOpen && handleClose(), mouseEvent: "onMouseDown", touchEvent: "onTouchStart", children: (0, jsx_runtime_1.jsx)(styled_1.StyledPopper, { placement: 'left', open: isOpen, sx: styles, modifiers: [{ name: 'arrow', enabled: true }], children: (0, jsx_runtime_1.jsx)(NodesMenu_1.default, { addNewNodeCallback: addNewNodeCallback, data: { parentId, connectionIndex }, menuTabs: menuTabs, onCloseMenu: handleClose, emptyMenuItemsComponent: emptyMenuItemsComponent, searchPlaceholder: searchPlaceholder }) }) })] }));
79
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(AddButton_1.AddButton, { ...buttonProps }), (0, jsx_runtime_1.jsx)(AnimatedConnectionLine, { style: props }), (0, jsx_runtime_1.jsx)(material_1.ClickAwayListener, { onClickAway: () => isOpen && handleClose(), mouseEvent: "onMouseDown", touchEvent: "onTouchStart", children: (0, jsx_runtime_1.jsx)(styled_1.StyledPopper, { anchorEl: anchorEl, placement: 'left', open: isOpen, modifiers: [
80
+ { name: 'arrow', enabled: true },
81
+ { name: 'offset', options: { offset: [0, 0] } },
82
+ ], children: (0, jsx_runtime_1.jsx)(NodesMenu_1.default, { addNewNodeCallback: addNewNodeCallback, data: { parentId, connectionIndex }, menuTabs: menuTabs, onCloseMenu: handleClose, emptyMenuItemsComponent: emptyMenuItemsComponent, searchPlaceholder: searchPlaceholder }) }) })] }));
83
83
  };
84
84
  exports.default = (0, react_1.memo)(ConnectionWithButton);
@@ -49,7 +49,7 @@ const createAddButton = ({ background = colors_1.Colors.WHITE, x, y, }) => (0, s
49
49
  `;
50
50
  exports.createAddButton = createAddButton;
51
51
  exports.StyledPopper = (0, system_1.styled)(material_1.Popper) `
52
- z-index: 1000;
52
+ z-index: 1400;
53
53
  overflow: hidden;
54
54
  border-radius: 16px;
55
55
  `;
@@ -11,6 +11,10 @@ const Space = ({ children }) => {
11
11
  const [scrollLeft, setScrollLeft] = (0, react_1.useState)(0);
12
12
  const [scrollTop, setScrollTop] = (0, react_1.useState)(0);
13
13
  const handleMouseDown = (event) => {
14
+ const target = event.target;
15
+ if (target?.closest('[data-flow-interactive="true"]')) {
16
+ return;
17
+ }
14
18
  setIsDragging(true);
15
19
  setStartX(event.pageX - spaceRef.current.offsetLeft);
16
20
  setStartY(event.pageY - spaceRef.current.offsetTop);
@@ -4,7 +4,8 @@ export declare enum NodeTypeEnum {
4
4
  EndNode = "endNode",
5
5
  HubNode = "hubNode",
6
6
  ChoiceNode = "choiceNode",
7
- ParallelNode = "parallelNode"
7
+ ParallelNode = "parallelNode",
8
+ Telephony = "telephony"
8
9
  }
9
10
  export declare enum NodeMenuItemType {
10
11
  EXTENSION = "extension",
@@ -9,6 +9,7 @@ var NodeTypeEnum;
9
9
  NodeTypeEnum["HubNode"] = "hubNode";
10
10
  NodeTypeEnum["ChoiceNode"] = "choiceNode";
11
11
  NodeTypeEnum["ParallelNode"] = "parallelNode";
12
+ NodeTypeEnum["Telephony"] = "telephony";
12
13
  })(NodeTypeEnum || (exports.NodeTypeEnum = NodeTypeEnum = {}));
13
14
  var NodeMenuItemType;
14
15
  (function (NodeMenuItemType) {
@@ -17,6 +17,9 @@ exports.nodeModule = {
17
17
  endNode: EndNode_1.default,
18
18
  hubNode: HubNode_1.default,
19
19
  choiceNode: ChoiseNode_1.default,
20
- parallelNode: ParallelNode_1.default
20
+ parallelNode: ParallelNode_1.default,
21
+ // Telephony is a backend special node; it renders as a plain
22
+ // extension node on the canvas (same component as BaseNode).
23
+ telephony: BaseNode_1.default,
21
24
  },
22
25
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-lib-creomnia",
3
- "version": "1.0.19",
3
+ "version": "1.0.20-dev.1",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",