diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb
index 94b406877c4..3808add3528 100644
--- a/app/controllers/catalog_controller.rb
+++ b/app/controllers/catalog_controller.rb
@@ -664,14 +664,6 @@ def ae_tree_select_toggle
session[:edit] = @edit
end
- def ae_tree_load
- assert_new_or_edit_by_service_type
-
- require 'byebug'
- byebug
- session[:edit]
- end
-
# Method to open the workflows dialog box
# params[:field] => :fqname || :retire_fqname || :reconfigure_fqname
# params[:selected] => Holds the value of the *_configuration_script_id
diff --git a/app/javascript/components/automate-entry-points/checkbox.js b/app/javascript/components/automate-entry-points/checkbox.js
new file mode 100644
index 00000000000..399c9294c85
--- /dev/null
+++ b/app/javascript/components/automate-entry-points/checkbox.js
@@ -0,0 +1,31 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+
+const Checkbox = ({ defaultState = false, onChange, children }) => {
+ const [on, setOn] = useState(defaultState);
+ const handleChange = (e) => {
+ setOn(e.target.checked);
+ onChange && onChange(e.target.checked);
+ };
+ return (
+
+ );
+};
+
+Checkbox.propTypes = {
+ defaultState: PropTypes.bool,
+ onChange: PropTypes.func.isRequired,
+ children: PropTypes.arrayOf(PropTypes.any),
+};
+
+Checkbox.defaultProps = {
+ defaultState: false,
+ children: [],
+};
+
+export default Checkbox;
diff --git a/app/javascript/components/automate-entry-points/index.jsx b/app/javascript/components/automate-entry-points/index.jsx
index 5cd75e3fd1f..c65e722a3c2 100644
--- a/app/javascript/components/automate-entry-points/index.jsx
+++ b/app/javascript/components/automate-entry-points/index.jsx
@@ -1,121 +1,338 @@
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { Loading, Modal, ModalBody } from 'carbon-components-react';
-import MiqDataTable from '../miq-data-table';
-import { http } from '../../http_api';
-
-const AutomateEntryPoints = ({
- field, selected, type, setShowModal, setSelectedValue,
-}) => {
- const [data, setData] = useState({
- isLoading: true, list: {}, selectedItemId: selected,
- });
-
- const workflowTypes = {
- provision: __('Provision'),
- reconfigure: __('Reconfigure'),
- retire: __('Retirement'),
+// import React, { useState, useEffect } from 'react';
+// import PropTypes from 'prop-types';
+// import { Loading, Modal, ModalBody } from 'carbon-components-react';
+// import MiqDataTable from '../miq-data-table';
+// import { http } from '../../http_api';
+
+// const AutomateEntryPoints = ({
+// field, selected, type, setShowModal, setSelectedValue,
+// }) => {
+// const [data, setData] = useState({
+// isLoading: true, list: {}, selectedItemId: selected,
+// });
+
+// const workflowTypes = {
+// provision: __('Provision'),
+// reconfigure: __('Reconfigure'),
+// retire: __('Retirement'),
+// };
+
+// useEffect(() => {
+// API.get('/api/automate')
+// .then((_data) => {
+// console.log(data);
+// setData({
+// ...data,
+// isLoading: false,
+// });
+// });
+// }, []);
+
+// /** Function to handle a row's click event. */
+// const onSelect = (selectedItemId) => {
+// setData({
+// ...data,
+// selectedItemId: (data.selectedItemId === selectedItemId) ? undefined : selectedItemId,
+// });
+// const params = `cfp-${encodeURIComponent(selectedItemId)}&tree=automate_catalog_tree&field=${field}`;
+// window.miqJqueryRequest(`/catalog/ae_tree_select/?id=${params}&typ=${type}`);
+// };
+// if (data.isLoading) {
+// return ();
+// }
+// /** Function to handle the modal box close button click event. */
+// const onCloseModal = () => {
+// if (setShowModal) {
+// setShowModal(false);
+// } else {
+// document.getElementById(`${type}-workflows`).innerHTML = '';
+// http.post('/catalog/ae_tree_select_toggle?button=cancel', {}, { headers: {}, skipJsonParsing: true });
+// }
+// };
+// /** Function to handle the modal box apply button click event. */
+// const onApply = () => {
+// const seletedItem = data.list.rows.find((item) => item.id === data.selectedItemId);
+// const name = seletedItem.name.text;
+// if (seletedItem) {
+// if (setShowModal && setSelectedValue) {
+// setShowModal(false);
+// setSelectedValue(seletedItem);
+// } else {
+// const nameField = document.getElementById(field);
+// const selectedField = document.getElementById(`${type}_configuration_script_id`);
+
+// if (nameField && selectedField) {
+// nameField.value = name;
+// selectedField.value = data.selectedItemId;
+// http.post('/catalog/ae_tree_select_toggle?button=submit&automation_type=workflow', {}, { headers: {}, skipJsonParsing: true })
+// .then((_data) => {
+// document.getElementById(`${type}-workflows`).innerHTML = '';
+// });
+// }
+// }
+// }
+// };
+// return (
+//
+//
+// onSelect(selectedRow.id)}
+// showPagination={false}
+// truncateText={false}
+// mode="automated-workflow-entry-points"
+// gridChecks={[data.selectedItemId]}
+// size="md"
+// />
+//
+//
+// );
+// };
+// AutomateEntryPoints.propTypes = {
+// field: PropTypes.string.isRequired,
+// type: PropTypes.string.isRequired,
+// selected: PropTypes.string,
+// setShowModal: PropTypes.func,
+// setSelectedValue: PropTypes.func,
+// };
+
+// AutomateEntryPoints.defaultProps = {
+// selected: '',
+// setShowModal: undefined,
+// setSelectedValue: undefined,
+// };
+
+// export default AutomateEntryPoints;
+
+import React, { useEffect, useState } from 'react';
+import { FolderOpen16, Folder16, Document16 } from '@carbon/icons-react';
+import TreeView, { flattenTree } from 'react-accessible-treeview';
+import './styles.css';
+
+const DirectoryTreeView = () => {
+// const [treeData, setTreeData] = useState([{
+// id: 'root',
+// name: '',
+// children: [
+// {
+// id: 'src_folder',
+// name: 'src',
+// },
+// ],
+// },
+// ]);
+
+ const folder = {
+ id: 'root',
+ name: '',
+ children: [
+ {
+ id: 'src_folder',
+ name: 'src',
+ children: [
+ {
+ id: 'index.js_file',
+ name: 'index.js',
+ metadata: { a: '1', b: '2', c: 'test' },
+ },
+ {
+ id: 'styles.css_file',
+ name: 'styles.css',
+ metadata: { a: '1', b: '2', c: 'test' },
+ }],
+ },
+ {
+ id: 'node_modules_folder',
+ name: 'node_modules',
+ children: [
+ {
+ id: 'react-accessible-treeview-folder',
+ name: 'react-accessible-treeview',
+ children: [{
+ id: 'index.js_file2',
+ name: 'index.js',
+ }],
+ },
+ {
+ id: 'react_folder',
+ name: 'react',
+ children: [{
+ id: 'index.js_file3',
+ name: 'index.js',
+ }],
+ },
+ ],
+ },
+ {
+ id: '.npmignore_file',
+ name: '.npmignore',
+ },
+ {
+ id: 'package.json_file',
+ name: 'package.json',
+ },
+ {
+ id: 'webpack.config.js_file',
+ name: 'webpack.config.js',
+ },
+ ],
};
+ const data = flattenTree(folder);
+ console.log(data);
+
+ const initialData = {
+ id: 'root',
+ name: '',
+ children: [
+ {
+ id: 'root-node',
+ name: '',
+ },
+ ],
+ };
+
+ const [rawTreeData, setRawTreeData] = useState(folder);
+ const [treeData, setTreeData] = useState(flattenTree(initialData));
+ const [expandedIds, setExpandedIds] = useState([]);
+ const [key, setKey] = useState('initial');
+
useEffect(() => {
- http.post(`/catalog/ae_tree_load?typ=${type}`, {}, { headers: {}, skipJsonParsing: true })
- .then((_data) => {
- console.log(data);
- API.get('/api/automate_domains?expand=resources')
- .then((response) => {
- console.log(response);
- // API.get('/api/automate_workspaces?expand=resources').then((response) => {
- // console.log(response);
- // });
- setData({
- ...data,
- isLoading: false,
- });
- });
- });
+ setTreeData(data);
}, []);
- /** Function to handle a row's click event. */
- const onSelect = (selectedItemId) => {
- setData({
- ...data,
- selectedItemId: (data.selectedItemId === selectedItemId) ? undefined : selectedItemId,
- });
- const params = `cfp-${encodeURIComponent(selectedItemId)}&tree=automate_catalog_tree&field=${field}`;
- window.miqJqueryRequest(`/catalog/ae_tree_select/?id=${params}&typ=${type}`);
+ useEffect(() => {
+ console.log(rawTreeData);
+ setTreeData(flattenTree(rawTreeData));
+ }, [rawTreeData]);
+
+ useEffect(() => {
+ console.log(treeData);
+ if (treeData.length > 12) {
+ setExpandedIds(['src_folder']);
+ setKey('new');
+ }
+ }, [treeData]);
+
+ const FolderIcon = ({ isOpen }) =>
+ (isOpen ? (
+
+ ) : (
+
+ ));
+
+ const FileIcon = ({ filename }) => {
+ const extension = filename.slice(filename.lastIndexOf('.') + 1);
+ switch (extension) {
+ case 'js':
+ return ;
+ case 'css':
+ return ;
+ case 'json':
+ return ;
+ case 'npmignore':
+ return ;
+ default:
+ return ;
+ }
};
- if (data.isLoading) {
- return ();
- }
- /** Function to handle the modal box close button click event. */
- const onCloseModal = () => {
- if (setShowModal) {
- setShowModal(false);
- } else {
- document.getElementById(`${type}-workflows`).innerHTML = '';
- http.post('/catalog/ae_tree_select_toggle?button=cancel', {}, { headers: {}, skipJsonParsing: true });
+
+ const onSelect = (value) => {
+ if (value && value.isSelected === true) {
+ console.log(value);
}
};
- /** Function to handle the modal box apply button click event. */
- const onApply = () => {
- const seletedItem = data.list.rows.find((item) => item.id === data.selectedItemId);
- const name = seletedItem.name.text;
- if (seletedItem) {
- if (setShowModal && setSelectedValue) {
- setShowModal(false);
- setSelectedValue(seletedItem);
- } else {
- const nameField = document.getElementById(field);
- const selectedField = document.getElementById(`${type}_configuration_script_id`);
-
- if (nameField && selectedField) {
- nameField.value = name;
- selectedField.value = data.selectedItemId;
- http.post('/catalog/ae_tree_select_toggle?button=submit&automation_type=workflow', {}, { headers: {}, skipJsonParsing: true })
- .then((_data) => {
- document.getElementById(`${type}-workflows`).innerHTML = '';
+
+ const onExpand = (value) => {
+ console.log(value);
+ const tempData = treeData;
+ const newChildren = [];
+
+ if (value && value.element) {
+ const ids = value.element.id.split('_');
+ if (ids.includes('folder')) {
+ tempData.forEach((item) => {
+ if (item.id === value.element.id) {
+ console.log(item.name);
+ API.get('/api/automate_domains?expand=resources').then((apiData) => {
+ console.log(apiData);
+ apiData.resources.forEach((domain) => {
+ newChildren.push({
+ id: domain.id,
+ name: domain.name,
+ children: [],
+ parent: item.id,
+ metadata: {},
+ });
+ });
+ return newChildren;
+ }).then((newChildrenArray) => {
+ const newTreeData = treeData.concat(newChildrenArray[2]);
+ if (treeData.includes(newChildrenArray[0]) === false) {
+ newTreeData[1].children = ['index.js_file', 'styles.css_file', '1177'];
+ if (treeData.length === 12) {
+ setTreeData(newTreeData);
+ // Send all relevant data including new children and the clicked item to a new useffect using a new state variable
+ // From this new use effect we can set the treedata, expandedids and the key state variables
+ }
+ }
});
- }
+ }
+ });
}
}
};
+
return (
-
-
- onSelect(selectedRow.id)}
- showPagination={false}
- truncateText={false}
- mode="automated-workflow-entry-points"
- gridChecks={[data.selectedItemId]}
- size="md"
+
+
+
{
+ getNodeProps();
+ return (
+
+ {isBranch ? (
+
+ ) : (
+
+ )}
+
+ {element.name}
+
+ );
+ }}
/>
-
-
+
+
);
};
-AutomateEntryPoints.propTypes = {
- field: PropTypes.string.isRequired,
- type: PropTypes.string.isRequired,
- selected: PropTypes.string,
- setShowModal: PropTypes.func,
- setSelectedValue: PropTypes.func,
+
+DirectoryTreeView.propTypes = {
};
-AutomateEntryPoints.defaultProps = {
- selected: '',
- setShowModal: undefined,
- setSelectedValue: undefined,
+DirectoryTreeView.defaultProps = {
};
-export default AutomateEntryPoints;
+export default DirectoryTreeView;
diff --git a/app/javascript/components/automate-entry-points/styles.css b/app/javascript/components/automate-entry-points/styles.css
new file mode 100644
index 00000000000..deff728d8de
--- /dev/null
+++ b/app/javascript/components/automate-entry-points/styles.css
@@ -0,0 +1,48 @@
+.directory {
+ background: #242322;
+ font-family: monospace;
+ font-size: 16px;
+ color: white;
+ user-select: none;
+ padding: 20px;
+ border-radius: 0.4em;
+}
+
+.directory .tree,
+.directory .tree-node,
+.directory .tree-node-group {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.directory .tree-branch-wrapper,
+.directory .tree-node__leaf {
+ outline: none;
+ outline: none;
+}
+
+.directory .tree-node {
+ cursor: pointer;
+}
+
+.directory .tree-node:hover {
+ background: rgba(255, 255, 255, 0.1);
+}
+
+.directory .tree .tree-node--focused {
+ background: rgba(255, 255, 255, 0.2);
+}
+
+.directory .tree .tree-node--selected {
+ background: rgba(48, 107, 176);
+}
+
+.directory .tree-node__branch {
+ display: block;
+}
+
+.directory .icon {
+ vertical-align: middle;
+ padding-right: 5px;
+}
\ No newline at end of file
diff --git a/app/javascript/components/visual-settings-form/index.jsx b/app/javascript/components/visual-settings-form/index.jsx
index 39e40c069f8..b2b9bd71386 100644
--- a/app/javascript/components/visual-settings-form/index.jsx
+++ b/app/javascript/components/visual-settings-form/index.jsx
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { Loading } from 'carbon-components-react';
import MiqFormRenderer from '@@ddf';
import createSchema from './visual-settings-form.schema';
+import DirectoryTreeView from '../automate-entry-points';
const VisualSettingsForm = ({ recordId }) => {
const [{ initialValues, timezoneOptions, isLoading }, setState] = useState({ isLoading: true });
@@ -41,12 +42,15 @@ const VisualSettingsForm = ({ recordId }) => {
);
}
return (
-
+
+
+
+
);
};
diff --git a/app/javascript/components/visual-settings-form/visual-settings-form.schema.js b/app/javascript/components/visual-settings-form/visual-settings-form.schema.js
index 26c7c881422..0d9d915e5d0 100644
--- a/app/javascript/components/visual-settings-form/visual-settings-form.schema.js
+++ b/app/javascript/components/visual-settings-form/visual-settings-form.schema.js
@@ -1,5 +1,24 @@
import { componentTypes } from '@@ddf';
+// const loadData = API.get('/api/automate?depth=1&attributes=klass,id,fqname,domain_fqname,name').then((data) => {
+// console.log(data);
+// const tree = [];
+// if (data && data.resources) {
+// data.resources.forEach((domain) => {
+// // console.log(domain);
+// tree.push({
+// key: domain.fqname,
+// icon: 'pficon pficon-folder-close',
+// selectable: false,
+// text: domain.name,
+// tooltip: 'root node',
+// state: {},
+// });
+// });
+// }
+// return tree;
+// });
+
const createSchema = (timezoneOptions) => ({
fields: [
{
diff --git a/config/routes.rb b/config/routes.rb
index c5514d40cf1..2056e137c7d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -310,7 +310,6 @@
ae_tree_select
ae_tree_select_discard
ae_tree_select_toggle
- ae_tree_load
atomic_form_field_changed
atomic_st_edit
automate_button_field_changed
diff --git a/package.json b/package.json
index 0e929545bc3..42dd6f5abb0 100644
--- a/package.json
+++ b/package.json
@@ -86,6 +86,7 @@
"prop-types": "^15.6.0",
"proxy-polyfill": "^0.1.7",
"react": "~16.13.1",
+ "react-accessible-treeview": "^2.10.0",
"react-bootstrap": "~0.33.0",
"react-codemirror2": "^6.0.0",
"react-dom": "~16.13.1",