flow-lib-creomnia 1.0.4 → 1.0.5-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.
package/README.md CHANGED
@@ -1,12 +1,117 @@
1
- # Nodes flow
1
+ # creo-flow
2
2
 
3
- ## Components
3
+ [![CI](https://github.com/creomnia/creo-flow/workflows/CI/badge.svg)](https://github.com/creomnia/creo-flow/actions/workflows/ci.yml)
4
4
 
5
- `<NodesFlow />`
5
+ ## Development Workflow
6
6
 
7
- Props:
7
+ ### Branch Strategy
8
8
 
9
- - `nodes` - `NodeType[]`
10
- - `menuTabs` - `MenuTabType[]`
11
- - `addNewNodeCallback` - `AddNewNodeCallbackType`
12
- - `addButtonColor`(optional) - `string`
9
+ This repository uses a three-tier branch strategy with branch protection:
10
+
11
+ ```
12
+ feature branches dev → qa → main
13
+ ```
14
+
15
+ **All protected branches (dev, qa, main) require Pull Requests.**
16
+
17
+ ### Step-by-Step Process
18
+
19
+ #### 1. Create Feature Branch
20
+
21
+ ```bash
22
+ git checkout dev
23
+ git pull origin dev
24
+ git checkout -b feature/your-feature-name
25
+ ```
26
+
27
+ #### 2. Develop and Push
28
+
29
+ ```bash
30
+ # Make your changes
31
+ git add <files>
32
+ git commit -m "feat: your feature description"
33
+ git push origin feature/your-feature-name
34
+ ```
35
+
36
+ #### 3. Create PR to `dev`
37
+
38
+ - Open PR on GitHub: `feature/your-feature-name` → `dev`
39
+ - Title: Use conventional commits (`feat:`, `fix:`, `chore:`, etc.)
40
+ - Get code review and merge
41
+ - Result: Publishes to NPM with `dev` tag
42
+
43
+ #### 4. Promote to `qa`
44
+
45
+ - Open PR on GitHub: `dev` → `qa`
46
+ - Title: `chore: promote dev to qa`
47
+ - Merge PR
48
+ - Result: Publishes to NPM with `qa` tag
49
+
50
+ #### 5. Promote to `main`
51
+
52
+ - Open PR on GitHub: `qa` → `main`
53
+ - Title: **`Release: X.Y.Z`** (e.g., "Release: 1.0.6")
54
+ - Merge PR
55
+ - Result: Publishes production version X.Y.Z to NPM
56
+
57
+ ### Important Rules
58
+
59
+ ❌ **NEVER** create PRs directly to `main` from feature branches
60
+
61
+ ❌ **NEVER** skip the `qa` branch when promoting to `main`
62
+
63
+ ❌ **NEVER** try to push directly to `dev`, `qa`, or `main`
64
+
65
+ ✅ **ALWAYS** follow the PR flow: feature → `dev` → `qa` → `main`
66
+
67
+ ✅ **ALWAYS** use PR title `Release: X.Y.Z` when merging to `main`
68
+
69
+ ### NPM Publishing
70
+
71
+ | From Branch | To Branch | PR Title Format | NPM Result |
72
+ |-------------|-----------|-----------------|------------|
73
+ | `feature/*` | `dev` | `feat:` / `fix:` / `chore:` | Publishes with `dev` tag (e.g., `1.0.5-dev.1`) |
74
+ | `dev` | `qa` | `chore: promote dev to qa` | Publishes with `qa` tag (e.g., `1.0.5-qa.1`) |
75
+ | `qa` | `main` | `Release: X.Y.Z` | Publishes production version `X.Y.Z` |
76
+
77
+ ### Commit Message Convention
78
+
79
+ Use conventional commit style:
80
+ - `feat:` - New feature
81
+ - `fix:` - Bug fix
82
+ - `chore:` - Maintenance tasks
83
+ - `docs:` - Documentation changes
84
+ - `refactor:` - Code refactoring
85
+ - `test:` - Adding tests
86
+
87
+ ### Example Workflow
88
+
89
+ ```bash
90
+ # 1. Create feature branch
91
+ git checkout dev
92
+ git pull origin dev
93
+ git checkout -b feature/add-new-node-type
94
+
95
+ # 2. Develop
96
+ git add src/modules/node/components/NewNode.tsx
97
+ git commit -m "feat: add new node type component"
98
+ git push origin feature/add-new-node-type
99
+
100
+ # 3. Open PR: feature/add-new-node-type → dev
101
+ # Title: "feat: add new node type component"
102
+ # Merge after review
103
+
104
+ # 4. Open PR: dev → qa
105
+ # Title: "chore: promote dev to qa"
106
+ # Merge
107
+
108
+ # 5. Open PR: qa → main
109
+ # Title: "Release: 1.0.6"
110
+ # Merge
111
+ ```
112
+
113
+ ### What to Do If PR is Accidentally Opened to Main
114
+
115
+ 1. **Close the PR** (don't merge it)
116
+ 2. **Change the base branch** to `dev` on GitHub (use "Edit" button)
117
+ 3. Or create a new PR: feature branch → `dev`
@@ -5,6 +5,7 @@ export type MenuItemType = {
5
5
  value: string;
6
6
  icon: JSX.Element;
7
7
  type: NodeMenuItemType;
8
+ disabled?: boolean;
8
9
  };
9
10
  export type MenuTabType = {
10
11
  name: string;
@@ -30,53 +30,59 @@ class ConnectionServices {
30
30
  },
31
31
  };
32
32
  };
33
- buildConnections = ({ nodeDrawers, menuTabs, addNewNodeCallback, processedNodeIds, failedNodeId }) => nodeDrawers.reduce((connectionDrawers, nodeDrawer) => {
34
- const childrenIds = nodeDrawer.nodeData?.childrenIds || [];
35
- const children = nodeDrawers.filter((nodeDrawer) => childrenIds?.includes(nodeDrawer.id));
36
- if (!children.length)
37
- return connectionDrawers;
38
- const isNodeWithDoubleConnections = config_1.Config.NODES_WITH_DOUBLE_CONNECTION.includes(nodeDrawer.type);
39
- if (isNodeWithDoubleConnections) {
40
- const leftChild = nodeDrawers.find((node) => node.nodeData?.id === nodeDrawer.nodeData?.leftChildrenId);
41
- const rightChild = nodeDrawers.find((node) => node.nodeData?.id === nodeDrawer.nodeData?.rightChildrenId);
42
- const newConnectionDrawers = [
43
- this.createDrawerConnection({
44
- failedNodeId,
45
- processedNodeIds,
46
- nodeDrawer,
47
- index: 1,
48
- menuTabs,
49
- child: leftChild,
50
- addNewNodeCallback,
51
- curveType: leftChild?.nodeData?.startSectionNodeId
52
- ? enums_2.ConnectionCurveEnum.LEFT
53
- : undefined,
54
- }),
55
- this.createDrawerConnection({
56
- failedNodeId,
57
- processedNodeIds,
58
- nodeDrawer,
59
- index: 2,
60
- menuTabs,
61
- child: rightChild,
62
- addNewNodeCallback,
63
- curveType: rightChild?.nodeData?.startSectionNodeId
64
- ? enums_2.ConnectionCurveEnum.RIGHT
65
- : undefined,
66
- }),
67
- ];
33
+ buildConnections = ({ nodeDrawers, menuTabs, addNewNodeCallback, processedNodeIds, failedNodeId }) => {
34
+ const drawerById = new Map(nodeDrawers.map((d) => [d.id, d]));
35
+ const drawerByNodeDataId = new Map(nodeDrawers.map((d) => [d.nodeData?.id, d]));
36
+ return nodeDrawers.reduce((connectionDrawers, nodeDrawer) => {
37
+ const childrenIds = nodeDrawer.nodeData?.childrenIds || [];
38
+ const children = childrenIds
39
+ .map((id) => drawerById.get(id))
40
+ .filter((d) => !!d);
41
+ if (!children.length)
42
+ return connectionDrawers;
43
+ const isNodeWithDoubleConnections = config_1.Config.NODES_WITH_DOUBLE_CONNECTION.includes(nodeDrawer.type);
44
+ if (isNodeWithDoubleConnections) {
45
+ const leftChild = drawerByNodeDataId.get(nodeDrawer.nodeData?.leftChildrenId);
46
+ const rightChild = drawerByNodeDataId.get(nodeDrawer.nodeData?.rightChildrenId);
47
+ const newConnectionDrawers = [
48
+ this.createDrawerConnection({
49
+ failedNodeId,
50
+ processedNodeIds,
51
+ nodeDrawer,
52
+ index: 1,
53
+ menuTabs,
54
+ child: leftChild,
55
+ addNewNodeCallback,
56
+ curveType: leftChild?.nodeData?.startSectionNodeId
57
+ ? enums_2.ConnectionCurveEnum.LEFT
58
+ : undefined,
59
+ }),
60
+ this.createDrawerConnection({
61
+ failedNodeId,
62
+ processedNodeIds,
63
+ nodeDrawer,
64
+ index: 2,
65
+ menuTabs,
66
+ child: rightChild,
67
+ addNewNodeCallback,
68
+ curveType: rightChild?.nodeData?.startSectionNodeId
69
+ ? enums_2.ConnectionCurveEnum.RIGHT
70
+ : undefined,
71
+ }),
72
+ ];
73
+ return [...connectionDrawers, ...newConnectionDrawers];
74
+ }
75
+ const newConnectionDrawers = children.map((child, index) => this.createDrawerConnection({
76
+ failedNodeId,
77
+ processedNodeIds,
78
+ nodeDrawer,
79
+ index: index + 1,
80
+ menuTabs,
81
+ child: child,
82
+ addNewNodeCallback,
83
+ }));
68
84
  return [...connectionDrawers, ...newConnectionDrawers];
69
- }
70
- const newConnectionDrawers = children.map((child, index) => this.createDrawerConnection({
71
- failedNodeId,
72
- processedNodeIds,
73
- nodeDrawer,
74
- index: index + 1,
75
- menuTabs,
76
- child: child,
77
- addNewNodeCallback,
78
- }));
79
- return [...connectionDrawers, ...newConnectionDrawers];
80
- }, []);
85
+ }, []);
86
+ };
81
87
  }
82
88
  exports.connectionServices = new ConnectionServices();
@@ -7,6 +7,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  const react_1 = require("react");
8
8
  const styled_1 = require("./styled");
9
9
  const Grid_1 = __importDefault(require("@mui/material/Grid"));
10
+ const material_1 = require("@mui/material");
11
+ const icons_material_1 = require("@mui/icons-material");
10
12
  const NodesMenu = ({ addNewNodeCallback, menuTabs, data, onCloseMenu, emptyMenuItemsComponent, searchPlaceholder, }) => {
11
13
  const [value, setValue] = (0, react_1.useState)(menuTabs?.[0].name);
12
14
  const [searchQuery, setSearchQuery] = (0, react_1.useState)("");
@@ -33,7 +35,7 @@ const NodesMenu = ({ addNewNodeCallback, menuTabs, data, onCloseMenu, emptyMenuI
33
35
  return tab[value].filter((menuItem) => menuItem.name.toLowerCase().includes(searchQuery.toLowerCase()));
34
36
  }, [searchQuery, value]);
35
37
  return ((0, jsx_runtime_1.jsxs)(styled_1.MenuContainer, { children: [(0, jsx_runtime_1.jsxs)(Grid_1.default, { direction: "column", p: "0 0 10px 0", children: [(0, jsx_runtime_1.jsxs)(Grid_1.default, { alignItems: "center", container: true, p: "8px 8px 0 0", children: [(0, jsx_runtime_1.jsx)(Grid_1.default, { flexGrow: 1, item: true, children: (0, jsx_runtime_1.jsx)(styled_1.StyledTabs, { value: value, onChange: handleChange, textColor: "primary", indicatorColor: "primary", children: menuTabs.map((tab) => ((0, jsx_runtime_1.jsx)(styled_1.StyledTab, { value: tab.name, label: tab.name }, tab.name))) }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, children: (0, jsx_runtime_1.jsx)(styled_1.Close, { onClick: onCloseMenu }) })] }), (0, jsx_runtime_1.jsx)(styled_1.StyledTextField, { fullWidth: true, variant: "outlined", size: "small", placeholder: searchPlaceholder ? searchPlaceholder : "", value: searchQuery, onChange: handleSearchChange })] }), (0, jsx_runtime_1.jsx)(styled_1.ContentContainer, { children: filteredItems?.length > 0
36
- ? filteredItems.map((menuItem) => ((0, jsx_runtime_1.jsxs)(styled_1.MenuItem, { onClick: () => onMenuItemClick(menuItem.value, menuItem.type), children: [(0, jsx_runtime_1.jsx)(styled_1.IconWrapper, { children: menuItem.icon }), menuItem.name] }, menuItem.value)))
38
+ ? filteredItems.map((menuItem) => ((0, jsx_runtime_1.jsxs)(styled_1.MenuItem, { style: { opacity: menuItem?.disabled ? 0.5 : 1, cursor: menuItem?.disabled ? 'not-allowed' : 'pointer' }, onClick: () => !menuItem?.disabled && onMenuItemClick(menuItem.value, menuItem.type), children: [(0, jsx_runtime_1.jsx)(styled_1.IconWrapper, { children: menuItem?.disabled ? (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: 'Building process', children: (0, jsx_runtime_1.jsx)(icons_material_1.BuildCircle, {}) }) : menuItem.icon }), menuItem.name] }, menuItem.value)))
37
39
  : emptyMenuItemsComponent && emptyMenuItemsComponent })] }));
38
40
  };
39
41
  exports.default = NodesMenu;
@@ -4,13 +4,16 @@ exports.expandCoefficientServices = void 0;
4
4
  const config_1 = require("../../../config");
5
5
  class ExpandCoefficientServices {
6
6
  calculateNodeExpandCoefficient = (nodes) => {
7
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
7
8
  const calculateNodeExpandCoefficientRecursion = ({ startNode, expandCoefficient, indexOfEncapsulation, }) => {
8
9
  if (!startNode.childrenIds?.length ||
9
10
  (startNode.startSectionNodeId && indexOfEncapsulation <= 0)) {
10
11
  return expandCoefficient;
11
12
  }
12
13
  if (startNode.startSectionNodeId && indexOfEncapsulation > 0) {
13
- const childrenNodes = nodes.filter((node) => startNode.childrenIds?.includes(node.id));
14
+ const childrenNodes = (startNode.childrenIds || [])
15
+ .map((id) => nodeMap.get(id))
16
+ .filter((node) => !!node);
14
17
  const nextExpandCoefficient = calculateNodeExpandCoefficientRecursion({
15
18
  startNode: childrenNodes[0],
16
19
  expandCoefficient: 0,
@@ -18,7 +21,9 @@ class ExpandCoefficientServices {
18
21
  });
19
22
  return Math.max(expandCoefficient, nextExpandCoefficient);
20
23
  }
21
- const childrenNodes = nodes.filter((node) => startNode.childrenIds?.includes(node.id));
24
+ const childrenNodes = (startNode.childrenIds || [])
25
+ .map((id) => nodeMap.get(id))
26
+ .filter((node) => !!node);
22
27
  const childrenNodesExpandCoefficient = childrenNodes.map((node) => {
23
28
  const isExpandable = config_1.Config.NODES_WITH_DOUBLE_CONNECTION.includes(startNode.type);
24
29
  const calculatedExpandCoefficient = isExpandable
@@ -5,6 +5,7 @@ const enums_1 = require("../enums");
5
5
  const pointCalculationServices_1 = require("./pointCalculationServices");
6
6
  class NodeServices extends pointCalculationServices_1.NodeCalculationServices {
7
7
  combineNodes = (currentNodes, nodes) => {
8
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
8
9
  const hubNodes = nodes.reduce((hubNodes, node) => {
9
10
  if (node.startSectionNodeId) {
10
11
  return {
@@ -25,7 +26,7 @@ class NodeServices extends pointCalculationServices_1.NodeCalculationServices {
25
26
  const childrenIds = currentNode.childrenIds || [];
26
27
  const childNodes = childrenIds
27
28
  .map((childId) => {
28
- return nodes.find((node) => node.id === childId) || [];
29
+ return nodeMap.get(childId) || [];
29
30
  })
30
31
  .flat();
31
32
  const blockedChildrenIds = currentNode.blockedChildrenIds || [];
@@ -79,10 +80,11 @@ class NodeServices extends pointCalculationServices_1.NodeCalculationServices {
79
80
  childrenNodes: [],
80
81
  updatedHubNodes: hubNodes,
81
82
  });
83
+ const combinedNodesMap = new Map(combinedNodes.map((n) => [n.id, n]));
82
84
  const drawableNodes = currentNodes.map((node) => {
83
85
  const startSectionNodeId = node.startSectionNodeId;
84
86
  const parent = startSectionNodeId
85
- ? combinedNodes.find((node) => node.id === startSectionNodeId)
87
+ ? combinedNodesMap.get(startSectionNodeId)
86
88
  : combinedNodes.find((parentNode) => parentNode.nodeData?.childrenIds?.includes(node.id));
87
89
  // TODO it works when node has 2 children but should be refactored
88
90
  const isSecondBranch = parent?.nodeData?.rightChildrenId === node.id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-lib-creomnia",
3
- "version": "1.0.4",
3
+ "version": "1.0.5-dev.1",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -10,7 +10,10 @@
10
10
  "clean": "rm -rf ./lib",
11
11
  "copy-files": "cp -R src/assets lib/assets",
12
12
  "build": "npm run clean && tsc && npm run copy-files",
13
- "publish-package": "npm run build && npm publish"
13
+ "publish-package": "npm run build && npm publish",
14
+ "publishPackage": "npm run build && npm publish",
15
+ "publishPackageDev": "npm run build && npm publish --tag dev",
16
+ "publishPackageQa": "npm run build && npm publish --tag qa"
14
17
  },
15
18
  "keywords": [],
16
19
  "author": "",