Skip to content

Commit ce71035

Browse files
committed
move codes to different components
1 parent d1f82d9 commit ce71035

File tree

7 files changed

+276
-115
lines changed

7 files changed

+276
-115
lines changed

app/javascript/components/AeInlineMethods/index.jsx

Lines changed: 15 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,17 @@
11
/* eslint-disable jsx-a11y/no-static-element-interactions */
22
/* eslint-disable jsx-a11y/click-events-have-key-events */
3-
import React, { useEffect, useState } from 'react';
3+
import React, { useState } from 'react';
44
import PropTypes from 'prop-types';
5-
import {
6-
Modal, Button, ModalBody, Loading,
7-
} from 'carbon-components-react';
8-
import classNames from 'classnames';
9-
import { CaretRight16, CaretDown16, CheckmarkFilled16 } from '@carbon/icons-react';
10-
import { http } from '../../http_api';
11-
import { findNodeByKey, selectableItem, TREE_CONFIG } from './helper';
12-
import './style.scss';
5+
import { Modal, Button, ModalBody } from 'carbon-components-react';
6+
import MiqTree from '../MiqTreeView';
137

148
/** Component to render a tree and to select an embedded method. */
159
const AeInlineMethod = ({ type }) => {
16-
const treeType = TREE_CONFIG[type];
17-
1810
const [data, setData] = useState({
19-
list: undefined,
2011
isModalOpen: false,
21-
isLoading: true,
2212
selectedNode: undefined,
2313
});
2414

25-
/** When isModal is true, a GET request is made to get the initial data. */
26-
useEffect(() => {
27-
if (data.isModalOpen) {
28-
http.get(treeType.url)
29-
.then((response) => {
30-
setData({
31-
...data,
32-
list: response,
33-
isLoading: false,
34-
});
35-
});
36-
}
37-
}, [data.isModalOpen]);
38-
39-
console.log(data);
40-
4115
/** Function to show/hide the modal. */
4216
const showModal = (status) => {
4317
setData({
@@ -46,46 +20,6 @@ const AeInlineMethod = ({ type }) => {
4620
});
4721
};
4822

49-
/** Function to handle the click events of tree node. */
50-
const loadSelectedNode = (node) => {
51-
const foundItem = findNodeByKey(data.list[0].nodes, node.key);
52-
const newUrl = `${treeType.url}?id=${node.key}`;
53-
54-
if (selectableItem(node, treeType.selectKey)) {
55-
setData({
56-
...data,
57-
selectedNode: (data.selectedNode && data.selectedNode.key === node.key) ? undefined : node,
58-
});
59-
} else if (!node.state.expanded) {
60-
if (foundItem.nodes && foundItem.nodes.length > 0) {
61-
// if nodes are already available, just expand the tree.
62-
foundItem.state.expanded = true;
63-
setData({
64-
...data,
65-
list: [...data.list],
66-
});
67-
} else {
68-
// if nodes are not available, request for the data from the url and update the nodes.
69-
http.get(newUrl)
70-
.then((response) => {
71-
foundItem.nodes = response;
72-
foundItem.state.expanded = true;
73-
setData({
74-
...data,
75-
list: [...data.list],
76-
});
77-
});
78-
}
79-
} else {
80-
// Hides the children.
81-
foundItem.state.expanded = false;
82-
setData({
83-
...data,
84-
list: [...data.list],
85-
});
86-
}
87-
};
88-
8923
/** Function to render the Add method button. */
9024
const renderAddButton = () => (
9125
<Button
@@ -99,49 +33,6 @@ const AeInlineMethod = ({ type }) => {
9933
</Button>
10034
);
10135

102-
/** Function to render the down and right caret. */
103-
const renderCaret = (child) => {
104-
if (!child) {
105-
return undefined;
106-
}
107-
if (selectableItem(child, treeType.selectableItem)) {
108-
return undefined;
109-
}
110-
return child.state.expanded ? <CaretDown16 className="tree-caret" /> : <CaretRight16 className="tree-caret" />;
111-
};
112-
113-
const renderIcon = (child) => (<div className="tree-icon"><i className={child.icon} /></div>);
114-
115-
const renderText = (child) => (<div className="tree-text">{child.text}</div>);
116-
117-
const isSelectedNode = (child) => (data.selectedNode && data.selectedNode.key === child.key);
118-
119-
/** Function to render the Tree Node. */
120-
const renderTreeNode = (child) => {
121-
const isSelected = isSelectedNode(child);
122-
return (
123-
<div key={child.key}>
124-
<div className={classNames('tree-row parent-tree', isSelected && 'selected-node')} onClick={() => loadSelectedNode(child)}>
125-
{renderCaret(child)}
126-
{renderIcon(child)}
127-
{renderText(child)}
128-
{isSelected && <CheckmarkFilled16 className="selected-node-check" />}
129-
</div>
130-
{child.state.expanded && child.nodes && child.nodes.length > 0 && (
131-
<div className="tree-row child-tree intend-right" key={child.key}>
132-
{child.nodes.map((child) => renderTreeNode(child))}
133-
</div>
134-
)}
135-
</div>
136-
);
137-
};
138-
139-
/** Function to render the tree contents. */
140-
const renderTree = (list) => (list && list.map((child) => renderTreeNode(child)));
141-
142-
/** Function to render the modal contents. */
143-
const renderModalContent = () => (data.list ? data.list[0].nodes && renderTree(data.list[0].nodes) : undefined);
144-
14536
return (
14637
<div>
14738
{renderAddButton()}
@@ -164,9 +55,18 @@ const AeInlineMethod = ({ type }) => {
16455
>
16556
<ModalBody>
16657
{
167-
data.isLoading
168-
? <Loading active small withOverlay={false} className="loading" />
169-
: renderModalContent()
58+
data.isModalOpen
59+
&& (
60+
<MiqTree
61+
type={type}
62+
onNodeSelect={(item) => {
63+
setData({
64+
...data,
65+
selectedNode: item,
66+
});
67+
}}
68+
/>
69+
)
17070
}
17171
</ModalBody>
17272
</Modal>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* eslint-disable jsx-a11y/no-static-element-interactions */
2+
/* eslint-disable jsx-a11y/click-events-have-key-events */
3+
/* eslint-disable import/no-cycle */
4+
import React from 'react';
5+
import PropTypes from 'prop-types';
6+
import MiqTreeNode from './MiqTreeNode';
7+
8+
/** A component to render the parent node of the tree. */
9+
const MiqTreeChildNode = ({
10+
node, onSelect, selectedNode, selectKey,
11+
}) => (
12+
<div className="tree-row child-tree intend-right" key={node.key}>
13+
{
14+
node.nodes.map((item) => (
15+
<MiqTreeNode
16+
key={item.key}
17+
node={item}
18+
selectedNode={selectedNode}
19+
selectKey={selectKey}
20+
onSelect={(childItem) => onSelect(childItem)}
21+
/>
22+
))
23+
}
24+
</div>
25+
);
26+
27+
export default MiqTreeChildNode;
28+
29+
MiqTreeChildNode.propTypes = {
30+
node: PropTypes.shape({
31+
key: PropTypes.string,
32+
nodes: PropTypes.arrayOf(PropTypes.any),
33+
state: PropTypes.shape({
34+
expanded: PropTypes.bool,
35+
}),
36+
}).isRequired,
37+
selectKey: PropTypes.string.isRequired,
38+
onSelect: PropTypes.func.isRequired,
39+
selectedNode: PropTypes.shape({
40+
key: PropTypes.string,
41+
}),
42+
};
43+
44+
MiqTreeChildNode.defaultProps = {
45+
selectedNode: undefined,
46+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* eslint-disable import/no-cycle */
2+
import React from 'react';
3+
import PropTypes from 'prop-types';
4+
import MiqTreeParentNode from './MiqTreeParentNode';
5+
import MiqTreeChildNode from './MiqTreeChildNode';
6+
7+
/** A Recursive Functional component to render the Tree and its child nodes. */
8+
const MiqTreeNode = ({
9+
node, selectedNode, selectKey, onSelect,
10+
}) => {
11+
const isSelected = (selectedNode && selectedNode.key === node.key) || false;
12+
13+
return (
14+
<div key={node.key}>
15+
<MiqTreeParentNode
16+
node={node}
17+
isSelected={isSelected}
18+
selectKey={selectKey}
19+
onSelect={(parentItem) => onSelect(parentItem)}
20+
/>
21+
{
22+
node.state.expanded && node.nodes && node.nodes.length > 0 && (
23+
<MiqTreeChildNode
24+
node={node}
25+
onSelect={(childItem) => onSelect(childItem)}
26+
selectedNode={selectedNode}
27+
selectKey={selectKey}
28+
/>
29+
)
30+
}
31+
</div>
32+
);
33+
};
34+
35+
export default MiqTreeNode;
36+
37+
MiqTreeNode.propTypes = {
38+
node: PropTypes.shape({
39+
key: PropTypes.string,
40+
nodes: PropTypes.arrayOf(PropTypes.any),
41+
state: PropTypes.shape({
42+
expanded: PropTypes.bool,
43+
}),
44+
}).isRequired,
45+
selectKey: PropTypes.string.isRequired,
46+
onSelect: PropTypes.func.isRequired,
47+
selectedNode: PropTypes.shape({
48+
key: PropTypes.string,
49+
}),
50+
};
51+
52+
MiqTreeNode.defaultProps = {
53+
selectedNode: undefined,
54+
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* eslint-disable jsx-a11y/no-static-element-interactions */
2+
/* eslint-disable jsx-a11y/click-events-have-key-events */
3+
import React from 'react';
4+
import PropTypes from 'prop-types';
5+
import classNames from 'classnames';
6+
import { CaretRight16, CaretDown16, CheckmarkFilled16 } from '@carbon/icons-react';
7+
import { selectableItem } from './helper';
8+
9+
/** A component to render the parent node of the tree. */
10+
const MiqTreeParentNode = ({
11+
node, selectKey, isSelected, onSelect,
12+
}) => {
13+
/** Function to render the down and right caret. */
14+
const renderCaret = (item) => {
15+
if (!item) {
16+
return undefined;
17+
}
18+
if (selectableItem(item, selectKey)) {
19+
return undefined;
20+
}
21+
return item.state.expanded ? <CaretDown16 className="tree-caret" /> : <CaretRight16 className="tree-caret" />;
22+
};
23+
24+
return (
25+
<div className={classNames('tree-row parent-tree', isSelected && 'selected-node')} onClick={() => onSelect(node)}>
26+
{renderCaret(node)}
27+
<div className="tree-icon"><i className={node.icon} /></div>
28+
<div className="tree-text">{node.text}</div>
29+
{isSelected && <CheckmarkFilled16 className="selected-node-check" />}
30+
</div>
31+
);
32+
};
33+
34+
export default MiqTreeParentNode;
35+
36+
MiqTreeParentNode.propTypes = {
37+
node: PropTypes.shape({
38+
icon: PropTypes.string,
39+
text: PropTypes.string,
40+
key: PropTypes.string,
41+
nodes: PropTypes.arrayOf(PropTypes.any),
42+
state: PropTypes.shape({
43+
expanded: PropTypes.bool,
44+
}),
45+
}).isRequired,
46+
selectKey: PropTypes.string.isRequired,
47+
isSelected: PropTypes.bool.isRequired,
48+
onSelect: PropTypes.func.isRequired,
49+
};

0 commit comments

Comments
 (0)