From eb0a8ad083f50c92df496c213798ff4e0e6e1011 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Wed, 9 Oct 2024 15:09:51 -0400 Subject: [PATCH] Convert clusters and datastores collection from ruby to react --- app/controllers/ops_controller.rb | 7 + .../ops_controller/settings/cap_and_u.rb | 129 +++++-- .../settings-cu-collection/index.jsx | 360 ++++++++++++++++++ .../settings-cu-collection-tab.schema.js | 180 +++++++++ .../components/tree-view/checkbox_tree.jsx | 62 +++ .../forms/mappers/componentMapper.jsx | 2 + .../packs/component-definitions-common.js | 2 + .../__snapshots__/action-form.spec.js.snap | 2 + ...d-remove-security-groups-form.spec.js.snap | 2 + .../ansible-credentials-form.spec.js.snap | 4 + .../ansible-edit-catalog-form.spec.js.snap | 9 + .../c-and-u-collections-form.spec.js.snap | 2 + .../cloud-database-form.spec.js.snap | 2 + ...d-object-store-container-form.spec.js.snap | 6 + .../cloud-volume-actions-form.spec.js.snap | 12 + ...tach-detach-cloud-volume-form.spec.js.snap | 12 + .../__snapshots__/cu-collection.spec.js.snap | 210 ++++++++++ .../spec/cu-collection/cu-collection.spec.js | 35 ++ .../__snapshots__/datastore-form.spec.js.snap | 4 + .../diagnostics-collect-log-form.spec.js.snap | 6 + ...ed-terraform-credentials-form.spec.js.snap | 4 + .../__snapshots__/evacuate-form.spec.js.snap | 6 + .../generic-objects-form.spec.js.snap | 9 + .../host-aggregate-form.spec.js.snap | 2 + .../__snapshots__/host-edit-form.spec.js.snap | 6 + .../host-initiator-group.spec.js.snap | 2 + .../live-migrate-form.spec.js.snap | 6 + .../physical-storage-form.spec.js.snap | 4 + ...e-customization-template-form.spec.js.snap | 6 + .../pxe-image-type-form.spec.js.snap | 4 + .../pxe-iso-datastore-form.spec.js.snap | 2 + .../pxe-iso-image-form.spec.js.snap | 2 + .../reconfigure-vm-form.spec.js.snap | 30 ++ .../__snapshots__/schedule-form.spec.js.snap | 6 + .../service-request-default-form.spec.js.snap | 2 + .../settings-category-form.spec.js.snap | 2 + .../settings-time-profile-form.spec.js.snap | 2 + .../vm-floating-ips-form.spec.js.snap | 8 + .../__snapshots__/vm-resize-form.spec.js.snap | 2 + ...kflow-credential-mapping-form.spec.js.snap | 3 + .../workflow-credentials-form.spec.js.snap | 4 + .../__snapshots__/zone-form.spec.js.snap | 2 + app/stylesheet/application-webpack.scss | 1 + app/stylesheet/settings-cu-collection.scss | 40 ++ .../ops/_settings_cu_collection_tab.html.haml | 76 +--- config/routes.rb | 1 - .../SettingsCUCollection.cy.js | 58 +++ package.json | 1 + ...ttings_cu_collection_tab.html.haml_spec.rb | 45 --- yarn.lock | 17 +- 50 files changed, 1254 insertions(+), 147 deletions(-) create mode 100644 app/javascript/components/settings-cu-collection/index.jsx create mode 100644 app/javascript/components/settings-cu-collection/settings-cu-collection-tab.schema.js create mode 100644 app/javascript/components/tree-view/checkbox_tree.jsx create mode 100644 app/javascript/spec/cu-collection/__snapshots__/cu-collection.spec.js.snap create mode 100644 app/javascript/spec/cu-collection/cu-collection.spec.js create mode 100644 app/stylesheet/settings-cu-collection.scss create mode 100644 cypress/e2e/ui/Settings/Application-Settings/SettingsCUCollection.cy.js delete mode 100644 spec/views/ops/_settings_cu_collection_tab.html.haml_spec.rb diff --git a/app/controllers/ops_controller.rb b/app/controllers/ops_controller.rb index 7c07a6ea681..3c8b0066eb1 100644 --- a/app/controllers/ops_controller.rb +++ b/app/controllers/ops_controller.rb @@ -596,6 +596,10 @@ def replace_right_cell(options = {}) presenter = ExplorerPresenter.new(:active_tree => x_active_tree) + if params["tab_id"] == "settings_cu_collection" + @hide_bottom_bar = true + end + replace_explorer_trees(replace_trees, presenter) rebuild_toolbars(presenter) handle_bottom_cell(nodetype, presenter, locals) @@ -806,6 +810,9 @@ def handle_bottom_cell(nodetype, presenter, locals) if ["settings_workers", "diagnostics_cu_repair"].include?(@sb[:active_tab]) presenter.hide(:form_buttons_div) end + if @hide_bottom_bar + presenter.hide(:form_buttons_div) + end end def replace_explorer_trees(replace_trees, presenter) diff --git a/app/controllers/ops_controller/settings/cap_and_u.rb b/app/controllers/ops_controller/settings/cap_and_u.rb index 0663efb6094..8af528f2395 100644 --- a/app/controllers/ops_controller/settings/cap_and_u.rb +++ b/app/controllers/ops_controller/settings/cap_and_u.rb @@ -6,6 +6,8 @@ def cu_collection_update return unless load_edit("cu_edit__collection", "replace_cell__explorer") + cu_collection_get_form_vars + if params[:button] == "save" # C & U collection settings if @edit[:new][:all_clusters] != @edit[:current][:all_clusters] @@ -39,11 +41,6 @@ def cu_collection_update add_flash(_("Capacity and Utilization Collection settings saved")) get_node_info(x_node) replace_right_cell(:nodetype => @nodetype) - elsif params[:button] == "reset" - @changed = false - add_flash(_("All changes have been reset"), :warning) - get_node_info(x_node) - replace_right_cell(:nodetype => @nodetype) end end @@ -58,22 +55,82 @@ def set_perf_collection_for_clusters end end - def cu_collection_field_changed - assert_privileges("region_edit") + def cu_collection_fetch + @edit = {} + @edit[:new] = {} + @edit[:current] = {} + @edit[:key] = "cu_edit__collection" + @edit[:current][:all_clusters] = Metric::Targets.perf_capture_always[:host_and_cluster] + @edit[:current][:all_storages] = Metric::Targets.perf_capture_always[:storage] + @edit[:current][:clusters] = [] + @cl_hash = EmsCluster.get_perf_collection_object_list + @cl_hash.each_with_index do |h, j| + _cid, cl_hash = h + c = cl_hash[:cl_rec] + enabled = cl_hash[:ho_enabled] + enabled_host_ids = enabled.collect(&:id) + hosts = (cl_hash[:ho_enabled] + cl_hash[:ho_disabled]).sort_by { |ho| ho.name.downcase } + cl_enabled = enabled_host_ids.length == hosts.length + en_flg = cl_enabled && !enabled.empty? + @edit[:current][:clusters].push(:id => c.id, :capture => en_flg) + @edit[:current][c.id] = [] + hosts.each do |host| + host_capture = enabled_host_ids.include?(host.id.to_i) + @edit[:current][c.id].push(:id => host.id, :capture => host_capture) + end + flg = true + count = 0 + @edit[:current][c.id].each do |host| + unless host[:capture] + count += 1 # checking if all hosts are unchecked then cluster capture will be false else undefined + flg = count == @edit[:current][c.id].length ? false : "undefined" + end + @edit[:current][:clusters][j][:capture] = flg + end + end + @edit[:current][:clusters].sort_by! { |c| c[:name] } - return unless load_edit("cu_edit__collection", "replace_cell__explorer") + # ##################### Adding Non-Clustered hosts node + @edit[:current][:non_cl_hosts] ||= [] + ExtManagementSystem.in_my_region.each do |e| + all = e.non_clustered_hosts + all.each do |h| + @edit[:current][:non_cl_hosts] << {:id => h.id, :capture => h.perf_capture_enabled?} + end + end + if @edit[:current][:clusters].present? + @cluster_tree = TreeBuilderClusters.new(:cluster_tree, @sb, true, :root => @cl_hash) + end + @edit[:current][:storages] = {} + Storage.in_my_region.includes(:taggings, :tags, :hosts).select(:id, :name, :location).sort_by { |s| s.name.downcase }.each do |s| + @edit[:current][:storages][s.id] = {:id => s.id, :capture => s.perf_capture_enabled?} + end + if @edit[:current][:storages].present? + @datastore_tree = TreeBuilderDatastores.new(:datastore_tree, @sb, true, :root => @edit[:current][:storages]) + end + @edit[:new] = copy_hash(@edit[:current]) - cu_collection_get_form_vars - @changed = (@edit[:new] != @edit[:current]) # UI edit form, C&U collection form - # C&U tab - # need to create an array of items, if their or their children's capture has been changed then make the changed one blue. - render :update do |page| - page << javascript_prologue - page.replace_html(@refresh_div, :partial => @refresh_partial) if @refresh_div - page << "$('#clusters_div').#{params[:all_clusters] == 'true' ? "hide" : "show"}()" if params[:all_clusters] - page << "$('#storages_div').#{params[:all_storages] == 'true' ? "hide" : "show"}()" if params[:all_storages] - page << javascript_for_miq_button_visibility(@changed) + clusters = [] + @edit[:current].each do |key, value| + if key.is_a?(Numeric) + clusters << value + end end + hosts = [] + clusters.each do |cluster| + if !cluster.empty? + cluster.each do |host| + hosts << host + end + else + hosts << cluster + end + end + + render :json => { + :hosts => hosts, + :datastores => @edit[:current][:storages].values + } end private @@ -136,38 +193,40 @@ def cu_build_edit_screen end def cu_collection_get_form_vars - @edit[:new][:all_clusters] = params[:all_clusters] == 'true' if params[:all_clusters] - @edit[:new][:all_storages] = params[:all_storages] == 'true' if params[:all_storages] + @edit[:new][:all_clusters] = params[:all_clusters] + @edit[:new][:all_storages] = params[:all_datastores] - if params[:id] - model, id, _ = TreeBuilder.extract_node_model_and_id(params[:id]) - - if model == 'Storage' - @edit[:new][:storages][id.to_i][:capture] = params[:check] == "1" - else - cluster_tree_settings(model, id) - end + params[:clusters_checked].each do |cluster| + model, id, _ = TreeBuilder.extract_node_model_and_id(cluster[:id]) + cluster_tree_settings(model, id, cluster) + end + params[:datastores_checked].each do |storage| + model, id, _ = TreeBuilder.extract_node_model_and_id(storage[:id]) + @edit[:new][:storages][id.to_i][:capture] = storage[:capture] + end + params[:hosts_checked].each do |host| + model, id, _ = TreeBuilder.extract_node_model_and_id(host[:id]) + cluster_tree_settings(model, id, host) end end - def cluster_tree_settings(model, id) + def cluster_tree_settings(model, id, cluster_or_host) if id == "NonCluster" # Clicked on all non-clustered hosts - @edit[:new][:non_cl_hosts].each { |c| c[:capture] = params[:check] == "1" } + @edit[:new][:non_cl_hosts].each { |c| c[:capture] = cluster_or_host[:capture] } elsif model == "EmsCluster" # Clicked on a cluster - @edit[:new][id.to_i].each { |h| h[:capture] = params[:check] == "1" } + @edit[:new][id.to_i].each { |h| h[:capture] = cluster_or_host[:capture] } elsif model == "Host" # Clicked on a host nc_host = @edit[:new][:non_cl_hosts].find { |x| x[:id] == id.to_i } # The host is among the non-clustered ones - return nc_host[:capture] = params[:check] == "1" if nc_host - + return nc_host[:capture] = cluster_or_host[:capture] if nc_host # The host is under a cluster, find it and change it @edit[:new][:clusters].find do |cl| @edit[:new][cl[:id]].find do |h| found = h[:id] == id.to_i - h[:capture] = params[:check] == "1" if found + h[:capture] = cluster_or_host[:capture] if found found end end end end -end +end \ No newline at end of file diff --git a/app/javascript/components/settings-cu-collection/index.jsx b/app/javascript/components/settings-cu-collection/index.jsx new file mode 100644 index 00000000000..bd8052cca96 --- /dev/null +++ b/app/javascript/components/settings-cu-collection/index.jsx @@ -0,0 +1,360 @@ +/* eslint-disable no-restricted-syntax */ +import React, { useState, useEffect } from 'react'; +import { FormSpy } from '@data-driven-forms/react-form-renderer'; +import MiqFormRenderer, { useFormApi } from '@@ddf'; +import { + Db2Database20, BareMetalServer20, +} from '@carbon/icons-react'; +import PropTypes from 'prop-types'; +import { Button } from 'carbon-components-react'; +import createSchema from './settings-cu-collection-tab.schema'; + +let idCounter = 0; +let modified = false; + +const SettingsCUCollectionTab = ({ + url, fetchURL, clusterTree, datastoreTree, allClusters, allDatastores, +}) => { + const [data, setData] = useState({ + isLoading: false, + tempData: undefined, + clustersNodes: [], + datastoresNodes: [], + hostsCheckedWithId: [], + datastoresCheckedWithId: [], + callNumber: 0, + }); + + const customValidation = (values) => { + if (values.tree_dropdown === undefined) { + values.tree_dropdown = data.checked || []; + } + if (values) { + if (JSON.stringify(values.clusters_tree) === JSON.stringify(data.hostsCheckedWithId) + && JSON.stringify(values.datastores_tree) === JSON.stringify(data.datastoresCheckedWithId) + && values.all_clusters === allClusters + && values.all_datastores === allDatastores) { + modified = false; + } else { + modified = true; + } + } + }; + + const generateId = () => idCounter++; + + const parseLabel = (text) => { + const parts = text.match(/(.*?)<\/strong>(.*)/); + + if (parts) { + return ( + + {parts[1]} + {parts[2]} + + ); + } + return {text}; + }; + + const transformTree = (node, isDatastore, depth) => { + const currentId = generateId(); + + const nodeObject = { + value: `${node.key}#${currentId}`, + label: + {parseLabel(node.text)} + , + showCheckbox: !isDatastore || node.nodes !== undefined || depth === 0, + disabled: !isDatastore && !node.nodes && depth === 0, + }; + + let icon; + switch (node.icon) { + case 'fa fa-database': + icon = ; + break; + + case 'pficon pficon-cluster': + icon = ; + break; + default: + break; + } + + if (node.image) { + icon = node; + } + if (icon) { + nodeObject.icon = { icon }; + } + + if (node.nodes) { + nodeObject.children = node.nodes.map((node) => transformTree(node, isDatastore, depth + 1)); + } + return nodeObject; + }; + + const getNodeValues = () => { + let clustersNodes = []; + let datastoresNodes = []; + idCounter = 0; + if (clusterTree) { + const clustersBsTree = JSON.parse(clusterTree.bs_tree); + clustersNodes = clustersBsTree.map((node) => transformTree(node, false, 0)); + } + if (datastoreTree) { + const datastoresBsTree = JSON.parse(datastoreTree.bs_tree); + datastoresNodes = datastoresBsTree.map((node) => transformTree(node, true, 0)); + } + + http.get(fetchURL).then((result) => { + const { hosts, datastores } = result; + const hostsChecked = []; + const hostsCheckedWithId = []; + const datastoresChecked = []; + const datastoresCheckedWithId = []; + for (const host of hosts) { + if (host.capture === true) { + hostsChecked.push(`h-${host.id}`); + } + } + for (const datastore of datastores) { + if (datastore.capture === true) { + datastoresChecked.push(`ds-${datastore.id}`); + } + } + + for (const node of clustersNodes) { + if (node.children) { + for (const host of node.children) { + if (hostsChecked.includes(host.value.split('#')[0])) { + hostsCheckedWithId.push(host.value); + } + } + } + } + + for (const node of datastoresNodes) { + if (node.children) { + const dsValue = node.value.split('#')[0]; + const dsId = dsValue.split('-')[1]; + const foundObject = datastores.find((item) => item.id === Number(dsId)); + if (datastoresChecked.includes(dsValue) && foundObject.capture === true) { + for (const host of node.children) { + datastoresCheckedWithId.push(host.value); + } + } + } else if (datastoresChecked.includes(node.value.split('#')[0])) { + datastoresCheckedWithId.push(node.value); + } + } + + setData({ + ...data, + clustersNodes, + datastoresNodes, + hostsCheckedWithId, + datastoresCheckedWithId, + callNumber: data.callNumber + 1, + }); + }); + }; + + useEffect(() => { + if (data.isLoading) { + http.post(url, data.tempData) + .then(() => { + setData({ + ...data, + isLoading: false, + }); + window.location.reload(); + }) + .catch((error) => console.log('error: ', error)); + } + }, [data.isLoading]); + + useEffect(() => { + getNodeValues(); + }, []); + + const handleSubmit = (values) => { + if (!values.tree_dropdown) { + values.tree_dropdown = data.checked; + } + + const params = { + all_clusters: values.all_clusters, + all_datastores: values.all_datastores, + button: 'save', + clusters_checked: [], + datastores_checked: [], + hosts_checked: [], + }; + + let clustersSplitValues = []; + let datastoresSplitValues = []; + + if (!values.all_clusters) { + const clustersTreeDropdown = values.clusters_tree; + clustersSplitValues = clustersTreeDropdown.map((string) => string.split('#')[0]); + } + + if (!values.all_datastores) { + const datastoresTreeDropdown = values.datastores_tree; + datastoresSplitValues = datastoresTreeDropdown.map((string) => string.split('#')[0]); + } + + for (const node of clusterTree.tree_nodes) { + const curr = []; + if (node.nodes) { + for (const hostNode of node.nodes) { + if (clustersSplitValues.includes(hostNode.key)) { + curr.push(hostNode.key); + params.hosts_checked.push({ id: hostNode.key, capture: true }); + } + if (hostNode === node.nodes[node.nodes.length - 1]) { + if (curr.length === node.nodes.length) { + params.clusters_checked.push({ id: node.key, capture: true }); + for (const val of curr) { + const index = params.hosts_checked.findIndex((host) => host.id === val); + if (index > -1) { + params.hosts_checked.splice(index, 1); + } + } + } else { + params.clusters_checked.push({ id: node.key, capture: false }); + } + } + } + } else if (clustersSplitValues.includes(node.key)) { + params.clusters_checked.push({ id: node.key, capture: true }); + } else { + params.clusters_checked.push({ id: node.key, capture: false }); + } + } + + for (const node of data.datastoresNodes) { + const curr = []; + if (node.children) { + for (const hostNode of node.children) { + if (values.datastores_tree && values.datastores_tree.includes(hostNode.value)) { + curr.push(hostNode.value); + } + if (hostNode === node.children[node.children.length - 1]) { + if (curr.length === node.children.length) { + params.datastores_checked.push({ id: node.value.split('#')[0], capture: true }); + for (const val of curr) { + const index = values.datastores_tree.findIndex((host) => host.id === val); + if (index > -1) { + values.datastores_tree.splice(index, 1); + } + } + } else { + params.datastores_checked.push({ id: node.value.split('#')[0], capture: false }); + } + } + } + } else if (datastoresSplitValues.includes(node.value.split('#')[0])) { + params.datastores_checked.push({ id: node.value.split('#')[0], capture: true }); + } else { + params.datastores_checked.push({ id: node.value.split('#')[0], capture: false }); + } + } + + setData({ + ...data, + isLoading: true, + tempData: params, + }); + }; + + const handleReset = () => { + getNodeValues(); + }; + + return ( + customValidation(values)} + FormTemplate={(props) => } + /> + ); +}; + +const FormTemplate = ({ + formFields, +}) => { + const { + handleSubmit, onReset, getState, + } = useFormApi(); + const { valid } = getState(); + return ( +
+ {formFields} + + {() => ( +
+ + +
+ )} +
+
+ ); +}; + +SettingsCUCollectionTab.propTypes = { + url: PropTypes.string, + fetchURL: PropTypes.string, + clusterTree: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.array]), + datastoreTree: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.array]), + allClusters: PropTypes.bool, + allDatastores: PropTypes.bool, + +}; + +SettingsCUCollectionTab.defaultProps = { + url: '', + fetchURL: '', + clusterTree: undefined, + datastoreTree: undefined, + allClusters: false, + allDatastores: false, +}; + +FormTemplate.propTypes = { + formFields: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.array]), +}; + +FormTemplate.defaultProps = { + formFields: undefined, +}; + +export default SettingsCUCollectionTab; diff --git a/app/javascript/components/settings-cu-collection/settings-cu-collection-tab.schema.js b/app/javascript/components/settings-cu-collection/settings-cu-collection-tab.schema.js new file mode 100644 index 00000000000..ba04afa3172 --- /dev/null +++ b/app/javascript/components/settings-cu-collection/settings-cu-collection-tab.schema.js @@ -0,0 +1,180 @@ +import { componentTypes } from '@@ddf'; + +const createSchema = ( + clustersTree, datastoresTree, clustersNodes, datastoresNodes, hostsChecked, datastoresChecked, allClusters, allDatastores, callNumber, +) => { + const fields = [ + { + component: componentTypes.SUB_FORM, + id: 'parent-div', + name: 'parent_div', + className: 'parent-div', + fields: [ + { + component: componentTypes.SUB_FORM, + id: 'clusters-box', + name: 'clusters_box', + className: 'clusters-box', + fields: [ + { + component: componentTypes.SUB_FORM, + id: 'clusters-selection', + name: 'clusters_section', + className: 'clusters-section', + fields: [ + { + component: componentTypes.SUB_FORM, + id: 'clusters-labels', + name: 'clusters_labels', + className: 'clusters-labels', + fields: [ + { + component: componentTypes.PLAIN_TEXT, + id: 'clusters', + name: 'clusters', + className: 'clusters', + label: __('Clusters'), + style: { fontSize: '16px' }, + }, + { + component: componentTypes.PLAIN_TEXT, + id: 'collect-clusters', + name: 'collect_clusters', + className: 'collect-clusters', + label: __('Collect for All Clusters'), + style: { fontSize: '16px' }, + }, + ], + }, + { + component: componentTypes.SWITCH, + id: 'all-clusters', + name: 'all_clusters', + className: 'toggle', + initialValue: allClusters, + }, + ], + }, + { + component: componentTypes.PLAIN_TEXT, + id: 'collect-note', + name: 'collect_note', + className: 'collect-note', + label: __('Note: Collect for All Clusters must ' + + 'be checked to be able to collect C & U data from ' + + 'Cloud Providers such as Red Hat OpenStack or Amazon EC2'), + style: { fontSize: '16px' }, + }, + { + component: 'checkbox-tree', + id: 'clusters-tree', + name: 'clusters_tree', + key: `${clustersNodes.length}${callNumber}`, + className: 'clusters-tree', + nodes: clustersNodes, + checked: hostsChecked, + condition: { and: [{ when: 'all_clusters', is: false }] }, + label: __('Enable Collection by Cluster'), + }, + + { + component: componentTypes.PLAIN_TEXT, + id: 'vm-data', + name: 'vm_data', + className: 'vm-data', + condition: { and: [{ when: 'all_clusters', is: false }] }, + label: __( + 'VM data will be collected for VMs under selected Hosts only. ' + + 'Data is collected for a Cluster and all of its Hosts when at least one Host is selected.' + ), + }, + ...(clustersTree != null + ? [] + : [{ + component: componentTypes.PLAIN_TEXT, + id: 'available-clusters', + name: 'available_clusters', + className: 'available-clusters', + label: __('Note: No Clusters available.'), + style: { fontSize: '16px' }, + }]), + ], + }, + { + component: componentTypes.SUB_FORM, + id: 'datastores-box', + name: 'datastores_box', + className: 'datastores-box', + fields: [ + { + component: componentTypes.SUB_FORM, + id: 'datastores-section', + name: 'datastores_section', + className: 'datastores-section', + fields: [ + { + component: componentTypes.SUB_FORM, + id: 'datastores-labels', + name: 'datastores_labels', + className: 'datastores-labels', + fields: [ + { + component: componentTypes.PLAIN_TEXT, + id: 'datastores', + name: 'datastores', + className: 'datastores', + label: __('Datastores'), + style: { fontSize: '16px' }, + }, + { + component: componentTypes.PLAIN_TEXT, + id: 'collect-datastores', + name: 'collect_datastores', + className: 'collect-datastores', + label: __('Collect for All Datastores'), + style: { fontSize: '16px' }, + }, + ], + }, + { + component: componentTypes.SWITCH, + id: 'all_datastores', + name: 'all_datastores', + className: 'toggle', + initialValue: allDatastores, + }, + ], + }, + { + component: 'checkbox-tree', + id: 'datastores-tree', + name: 'datastores_tree', + className: 'datastores-tree', + key: `${datastoresNodes.length}${callNumber}`, + nodes: datastoresNodes, + checked: datastoresChecked, + condition: { and: [{ when: 'all_datastores', is: false }] }, + label: __('Enable Collection by Datastore'), + }, + ...(datastoresTree != null + ? [] + : [{ + component: componentTypes.PLAIN_TEXT, + id: 'available-datastores', + name: 'available_datastores', + className: 'available-datastores', + label: __('Note: No Datastores available.'), + style: { fontSize: '16px' }, + }]), + ], + }, + ], + }, + ]; + + return { + fields, + }; +}; + +export default createSchema; diff --git a/app/javascript/components/tree-view/checkbox_tree.jsx b/app/javascript/components/tree-view/checkbox_tree.jsx new file mode 100644 index 00000000000..f301138915e --- /dev/null +++ b/app/javascript/components/tree-view/checkbox_tree.jsx @@ -0,0 +1,62 @@ +import React, { useState, useEffect } from 'react'; +import CheckboxTree from 'react-checkbox-tree'; +import PropTypes from 'prop-types'; +import { useFieldApi } from '@@ddf'; +import 'react-checkbox-tree/lib/react-checkbox-tree.css'; +import { + CheckboxChecked20, Checkbox20, CheckboxCheckedFilled20, ChevronRight20, ChevronDown20, Folder20, FolderOpen20, +} from '@carbon/icons-react'; + +const carbonIcons = { + check: , + uncheck: , + halfCheck: , + expandClose: , + expandOpen: , + parentClose: , + parentOpen: , +}; + +const CheckboxTreeComponent = (props) => { + const { label, nodes, checked } = props; + const { input } = useFieldApi(props); + + const [treeState, setTreeState] = useState({ + checked: checked || [], + expanded: (nodes && nodes[0] && [nodes[0].value]) || [], + tree: nodes, + }); + + useEffect(() => { + input.onChange(treeState.checked); + }, [treeState.checked]); + + return ( +
+

{label}

+ { + setTreeState({ ...treeState, checked }); + }} + onExpand={(expanded) => setTreeState({ ...treeState, expanded })} + /> +
+ ); +}; + +CheckboxTreeComponent.propTypes = { + label: PropTypes.string.isRequired, + nodes: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), + checked: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), +}; + +CheckboxTreeComponent.defaultProps = { + nodes: {}, + checked: [], +}; + +export default CheckboxTreeComponent; diff --git a/app/javascript/forms/mappers/componentMapper.jsx b/app/javascript/forms/mappers/componentMapper.jsx index c2fa1cd0f94..484a1d24a4b 100644 --- a/app/javascript/forms/mappers/componentMapper.jsx +++ b/app/javascript/forms/mappers/componentMapper.jsx @@ -8,6 +8,7 @@ import PasswordField from '../../components/async-credentials/password-field'; import Select from '../../components/select'; import CodeEditor from '../../components/code-editor'; import { TreeViewField, TreeViewSelector } from '../../components/tree-view'; +import CheckboxTreeComponent from '../../components/tree-view/checkbox_tree'; import MultiSelectWithSelectAll from '../../components/multiselect-with-selectall'; import FontIconPicker from '../../components/fonticon-picker'; import FontIconPickerDdf from '../../components/fonticon-picker/font-icon-picker-ddf'; @@ -25,6 +26,7 @@ const mapper = { 'multi-select': MultiSelectWithSelectAll, 'font-icon-picker': FontIconPicker, 'font-icon-picker-ddf': FontIconPickerDdf, // used for react form pages + 'checkbox-tree': CheckboxTreeComponent, }; export default mapper; diff --git a/app/javascript/packs/component-definitions-common.js b/app/javascript/packs/component-definitions-common.js index a196a68e5cd..a347102368d 100644 --- a/app/javascript/packs/component-definitions-common.js +++ b/app/javascript/packs/component-definitions-common.js @@ -135,6 +135,7 @@ import SettingsCompanyCategories from '../components/settings-company-categories import SettingsCompanyTags from '../components/settings-company-tags'; import SettingsCompanyTagsEntryForm from '../components/settings-company-tags-entry-form'; import SettingsDetailsTab from '../components/settings-details-tab'; +import SettingsCUCollectionTab from '../components/settings-cu-collection'; import SettingsLabelTagMapping from '../components/settings-label-tag-mapping'; import SettingsTasksForm from '../components/settings-tasks-form'; import SettingsTimeProfileForm from '../components/settings-time-profile-form'; @@ -317,6 +318,7 @@ ManageIQ.component.addReact('SettingsCompanyCategories', SettingsCompanyCategori ManageIQ.component.addReact('SettingsCompanyTags', SettingsCompanyTags); ManageIQ.component.addReact('SettingsCompanyTagsEntryForm', SettingsCompanyTagsEntryForm); ManageIQ.component.addReact('SettingsDetailsTab', SettingsDetailsTab); +ManageIQ.component.addReact('SettingsCUCollectionTab', SettingsCUCollectionTab); ManageIQ.component.addReact('SettingsLabelTagMapping', SettingsLabelTagMapping); ManageIQ.component.addReact('SettingsTasksForm', SettingsTasksForm); ManageIQ.component.addReact('SettingsTimeProfileForm', SettingsTimeProfileForm); diff --git a/app/javascript/spec/action-form/__snapshots__/action-form.spec.js.snap b/app/javascript/spec/action-form/__snapshots__/action-form.spec.js.snap index 90cbda1e1fb..229f609a43d 100644 --- a/app/javascript/spec/action-form/__snapshots__/action-form.spec.js.snap +++ b/app/javascript/spec/action-form/__snapshots__/action-form.spec.js.snap @@ -816,6 +816,7 @@ exports[`Action Form Component should render adding a new action 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1527,6 +1528,7 @@ exports[`Action Form Component should render adding a new action 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/add-remove-security-groups-form/__snapshots__/add-remove-security-groups-form.spec.js.snap b/app/javascript/spec/add-remove-security-groups-form/__snapshots__/add-remove-security-groups-form.spec.js.snap index 601dcb307b5..e9dc69ed325 100644 --- a/app/javascript/spec/add-remove-security-groups-form/__snapshots__/add-remove-security-groups-form.spec.js.snap +++ b/app/javascript/spec/add-remove-security-groups-form/__snapshots__/add-remove-security-groups-form.spec.js.snap @@ -130,6 +130,7 @@ exports[`Add/remove security groups form component should remove security group componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -193,6 +194,7 @@ exports[`Add/remove security groups form component should remove security group componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/ansible-credentials-form/__snapshots__/ansible-credentials-form.spec.js.snap b/app/javascript/spec/ansible-credentials-form/__snapshots__/ansible-credentials-form.spec.js.snap index 19d4211a2d1..cb1fc79e74a 100644 --- a/app/javascript/spec/ansible-credentials-form/__snapshots__/ansible-credentials-form.spec.js.snap +++ b/app/javascript/spec/ansible-credentials-form/__snapshots__/ansible-credentials-form.spec.js.snap @@ -90,6 +90,7 @@ exports[`Ansible Credential Form Component should render adding a new credential componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -183,6 +184,7 @@ exports[`Ansible Credential Form Component should render adding a new credential componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1573,6 +1575,7 @@ exports[`Ansible Credential Form Component should render editing a credential 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1673,6 +1676,7 @@ exports[`Ansible Credential Form Component should render editing a credential 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/ansible-edit-catalog-form/__snapshots__/ansible-edit-catalog-form.spec.js.snap b/app/javascript/spec/ansible-edit-catalog-form/__snapshots__/ansible-edit-catalog-form.spec.js.snap index f4b3fd2abcd..f9d2e3cef15 100644 --- a/app/javascript/spec/ansible-edit-catalog-form/__snapshots__/ansible-edit-catalog-form.spec.js.snap +++ b/app/javascript/spec/ansible-edit-catalog-form/__snapshots__/ansible-edit-catalog-form.spec.js.snap @@ -1320,6 +1320,7 @@ exports[`Ansible playbook edit catalog Form Component should not render some fie componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -3530,6 +3531,7 @@ exports[`Ansible playbook edit catalog Form Component should not render some fie componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -5747,6 +5749,7 @@ exports[`Ansible playbook edit catalog Form Component should not render some fie componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -59572,6 +59575,7 @@ exports[`Ansible playbook edit catalog Form Component should render correct form componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -61791,6 +61795,7 @@ exports[`Ansible playbook edit catalog Form Component should render correct form componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -64017,6 +64022,7 @@ exports[`Ansible playbook edit catalog Form Component should render correct form componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -120767,6 +120773,7 @@ exports[`Ansible playbook edit catalog Form Component should render retirement p componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -122977,6 +122984,7 @@ exports[`Ansible playbook edit catalog Form Component should render retirement p componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], @@ -125194,6 +125202,7 @@ exports[`Ansible playbook edit catalog Form Component should render retirement p componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "conditional-checkbox": [Function], "copy-from-provisioning": [Function], diff --git a/app/javascript/spec/c-and-u-collections-form/__snapshots__/c-and-u-collections-form.spec.js.snap b/app/javascript/spec/c-and-u-collections-form/__snapshots__/c-and-u-collections-form.spec.js.snap index 60dd95d7d99..df288545b01 100644 --- a/app/javascript/spec/c-and-u-collections-form/__snapshots__/c-and-u-collections-form.spec.js.snap +++ b/app/javascript/spec/c-and-u-collections-form/__snapshots__/c-and-u-collections-form.spec.js.snap @@ -96,6 +96,7 @@ exports[`DiagnosticsCURepairForm Component Should add a record from DiagnosticsC componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -205,6 +206,7 @@ exports[`DiagnosticsCURepairForm Component Should add a record from DiagnosticsC componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/cloud-database-form/__snapshots__/cloud-database-form.spec.js.snap b/app/javascript/spec/cloud-database-form/__snapshots__/cloud-database-form.spec.js.snap index 2cbf9b0cf7d..cf23e11fcd6 100644 --- a/app/javascript/spec/cloud-database-form/__snapshots__/cloud-database-form.spec.js.snap +++ b/app/javascript/spec/cloud-database-form/__snapshots__/cloud-database-form.spec.js.snap @@ -128,6 +128,7 @@ exports[`Cloud Database form component should render "Edit" form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -210,6 +211,7 @@ exports[`Cloud Database form component should render "Edit" form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/cloud-object-store-container-form/__snapshots__/cloud-object-store-container-form.spec.js.snap b/app/javascript/spec/cloud-object-store-container-form/__snapshots__/cloud-object-store-container-form.spec.js.snap index 1c91a0a2e39..d6e21a609eb 100644 --- a/app/javascript/spec/cloud-object-store-container-form/__snapshots__/cloud-object-store-container-form.spec.js.snap +++ b/app/javascript/spec/cloud-object-store-container-form/__snapshots__/cloud-object-store-container-form.spec.js.snap @@ -60,6 +60,7 @@ exports[`Cloud Object Store Container form component should add Amazon cloud obj componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -124,6 +125,7 @@ exports[`Cloud Object Store Container form component should add Amazon cloud obj componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -976,6 +978,7 @@ exports[`Cloud Object Store Container form component should add Openstack cloud componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1040,6 +1043,7 @@ exports[`Cloud Object Store Container form component should add Openstack cloud componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1868,6 +1872,7 @@ exports[`Cloud Object Store Container form component should render add cloud obj componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1932,6 +1937,7 @@ exports[`Cloud Object Store Container form component should render add cloud obj componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/cloud-volume-actions-form/__snapshots__/cloud-volume-actions-form.spec.js.snap b/app/javascript/spec/cloud-volume-actions-form/__snapshots__/cloud-volume-actions-form.spec.js.snap index b3487ae0b58..18a5e33683b 100644 --- a/app/javascript/spec/cloud-volume-actions-form/__snapshots__/cloud-volume-actions-form.spec.js.snap +++ b/app/javascript/spec/cloud-volume-actions-form/__snapshots__/cloud-volume-actions-form.spec.js.snap @@ -92,6 +92,7 @@ exports[`Cloud Volume Backup Create form component should render the cloud volum componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -184,6 +185,7 @@ exports[`Cloud Volume Backup Create form component should render the cloud volum componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1630,6 +1632,7 @@ exports[`Cloud Volume Backup Create form component when adding a new backup of c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1722,6 +1725,7 @@ exports[`Cloud Volume Backup Create form component when adding a new backup of c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3148,6 +3152,7 @@ exports[`Cloud Volume Restore from backup form component should render the cloud componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3220,6 +3225,7 @@ exports[`Cloud Volume Restore from backup form component should render the cloud componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4239,6 +4245,7 @@ exports[`Cloud Volume Restore from backup form component when restoring cloud vo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4311,6 +4318,7 @@ exports[`Cloud Volume Restore from backup form component when restoring cloud vo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5322,6 +5330,7 @@ exports[`Cloud Volume Snapshot Create form component should render the cloud vol componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5386,6 +5395,7 @@ exports[`Cloud Volume Snapshot Create form component should render the cloud vol componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -6171,6 +6181,7 @@ exports[`Cloud Volume Snapshot Create form component when adding a new snapshot componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -6235,6 +6246,7 @@ exports[`Cloud Volume Snapshot Create form component when adding a new snapshot componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/cloud-volume-form/__snapshots__/attach-detach-cloud-volume-form.spec.js.snap b/app/javascript/spec/cloud-volume-form/__snapshots__/attach-detach-cloud-volume-form.spec.js.snap index eb86f377754..925e55508a4 100644 --- a/app/javascript/spec/cloud-volume-form/__snapshots__/attach-detach-cloud-volume-form.spec.js.snap +++ b/app/javascript/spec/cloud-volume-form/__snapshots__/attach-detach-cloud-volume-form.spec.js.snap @@ -123,6 +123,7 @@ exports[`Attach / Detach form component should render Attach Cloud Volume to the componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -216,6 +217,7 @@ exports[`Attach / Detach form component should render Attach Cloud Volume to the componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1384,6 +1386,7 @@ exports[`Attach / Detach form component should render Attach Selected Cloud Volu componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1477,6 +1480,7 @@ exports[`Attach / Detach form component should render Attach Selected Cloud Volu componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2632,6 +2636,7 @@ exports[`Attach / Detach form component should render Detach Cloud Volume from t componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2712,6 +2717,7 @@ exports[`Attach / Detach form component should render Detach Cloud Volume from t componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3673,6 +3679,7 @@ exports[`Attach / Detach form component should render Detach Selected Cloud Volu componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3753,6 +3760,7 @@ exports[`Attach / Detach form component should render Detach Selected Cloud Volu componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4729,6 +4737,7 @@ exports[`Attach / Detach form component should submit Attach API call 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4822,6 +4831,7 @@ exports[`Attach / Detach form component should submit Attach API call 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5977,6 +5987,7 @@ exports[`Attach / Detach form component should submit Detach API call 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -6057,6 +6068,7 @@ exports[`Attach / Detach form component should submit Detach API call 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/cu-collection/__snapshots__/cu-collection.spec.js.snap b/app/javascript/spec/cu-collection/__snapshots__/cu-collection.spec.js.snap new file mode 100644 index 00000000000..c753c4eabcf --- /dev/null +++ b/app/javascript/spec/cu-collection/__snapshots__/cu-collection.spec.js.snap @@ -0,0 +1,210 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`C&U Form Collection Form Render C&U Collection form 1`] = ` + +`; diff --git a/app/javascript/spec/cu-collection/cu-collection.spec.js b/app/javascript/spec/cu-collection/cu-collection.spec.js new file mode 100644 index 00000000000..a169dd5700e --- /dev/null +++ b/app/javascript/spec/cu-collection/cu-collection.spec.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import fetchMock from 'fetch-mock'; +import toJson from 'enzyme-to-json'; +import SettingsCUCollectionTab from '../../components/settings-cu-collection'; + +describe('C&U Form Collection Form', () => { + const CUCollectionMockData = [ + { + href: `/ops/cu_collection_update/90/`, + id: '90', + hosts: [], + datastores: [], + }, + ]; + + afterEach(() => { + fetchMock.reset(); + fetchMock.restore(); + }); + + it('Render C&U Collection form', async() => { + const wrapper = shallow(); + + fetchMock.get(`/cu_collection_update/90`, CUCollectionMockData); + + await new Promise((resolve) => { + setImmediate(() => { + wrapper.update(); + expect(toJson(wrapper)).toMatchSnapshot(); + resolve(); + }); + }); + }); +}); diff --git a/app/javascript/spec/data-store-fore/__snapshots__/datastore-form.spec.js.snap b/app/javascript/spec/data-store-fore/__snapshots__/datastore-form.spec.js.snap index a392aa4bdc0..aa932533c47 100644 --- a/app/javascript/spec/data-store-fore/__snapshots__/datastore-form.spec.js.snap +++ b/app/javascript/spec/data-store-fore/__snapshots__/datastore-form.spec.js.snap @@ -165,6 +165,7 @@ exports[`Datastore form component Datastore domain form component should render componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -261,6 +262,7 @@ exports[`Datastore form component Datastore domain form component should render componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1751,6 +1753,7 @@ exports[`Datastore form component Datastore namespace form component should rend componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1850,6 +1853,7 @@ exports[`Datastore form component Datastore namespace form component should rend componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/diagnostics-collect-log-form/__snapshots__/diagnostics-collect-log-form.spec.js.snap b/app/javascript/spec/diagnostics-collect-log-form/__snapshots__/diagnostics-collect-log-form.spec.js.snap index 747bc061893..71c50334b66 100644 --- a/app/javascript/spec/diagnostics-collect-log-form/__snapshots__/diagnostics-collect-log-form.spec.js.snap +++ b/app/javascript/spec/diagnostics-collect-log-form/__snapshots__/diagnostics-collect-log-form.spec.js.snap @@ -103,6 +103,7 @@ exports[`Diagnostics Collect Log form component should render edit DiagnosticsCo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -195,6 +196,7 @@ exports[`Diagnostics Collect Log form component should render edit DiagnosticsCo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1646,6 +1648,7 @@ exports[`Diagnostics Collect Log form component should render edit DiagnosticsCo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1738,6 +1741,7 @@ exports[`Diagnostics Collect Log form component should render edit DiagnosticsCo componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3194,6 +3198,7 @@ exports[`Diagnostics Collect Log form component should render new DiagnosticsCol componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3291,6 +3296,7 @@ exports[`Diagnostics Collect Log form component should render new DiagnosticsCol componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/embedded-terraform-credentials-form/__snapshots__/embedded-terraform-credentials-form.spec.js.snap b/app/javascript/spec/embedded-terraform-credentials-form/__snapshots__/embedded-terraform-credentials-form.spec.js.snap index 8f329917aef..667a29fe925 100644 --- a/app/javascript/spec/embedded-terraform-credentials-form/__snapshots__/embedded-terraform-credentials-form.spec.js.snap +++ b/app/javascript/spec/embedded-terraform-credentials-form/__snapshots__/embedded-terraform-credentials-form.spec.js.snap @@ -91,6 +91,7 @@ exports[`Embedded Terraform Credential Form Component should render adding a new componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -185,6 +186,7 @@ exports[`Embedded Terraform Credential Form Component should render adding a new componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1596,6 +1598,7 @@ exports[`Embedded Terraform Credential Form Component should render editing a cr componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1697,6 +1700,7 @@ exports[`Embedded Terraform Credential Form Component should render editing a cr componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/evacuate-form/__snapshots__/evacuate-form.spec.js.snap b/app/javascript/spec/evacuate-form/__snapshots__/evacuate-form.spec.js.snap index 0dd65d40030..f29f7cfa942 100644 --- a/app/javascript/spec/evacuate-form/__snapshots__/evacuate-form.spec.js.snap +++ b/app/javascript/spec/evacuate-form/__snapshots__/evacuate-form.spec.js.snap @@ -117,6 +117,7 @@ exports[`evacuate form component should render evacuate form when hosts empty 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -228,6 +229,7 @@ exports[`evacuate form component should render evacuate form when hosts empty 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2048,6 +2050,7 @@ exports[`evacuate form component should render evacuate form with host options 1 componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2180,6 +2183,7 @@ exports[`evacuate form component should render evacuate form with host options 1 componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4359,6 +4363,7 @@ exports[`evacuate form component should render evacuate form with multiple insta componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4470,6 +4475,7 @@ exports[`evacuate form component should render evacuate form with multiple insta componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/generic-objects-form/__snapshots__/generic-objects-form.spec.js.snap b/app/javascript/spec/generic-objects-form/__snapshots__/generic-objects-form.spec.js.snap index 66f33b298f7..81f95e3d5a0 100644 --- a/app/javascript/spec/generic-objects-form/__snapshots__/generic-objects-form.spec.js.snap +++ b/app/javascript/spec/generic-objects-form/__snapshots__/generic-objects-form.spec.js.snap @@ -29,6 +29,7 @@ exports[`Generic Object Form Component should render adding a new generic object componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -287,6 +288,7 @@ exports[`Generic Object Form Component should render adding a new generic object componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -548,6 +550,7 @@ exports[`Generic Object Form Component should render adding a new generic object componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4626,6 +4629,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4942,6 +4946,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5261,6 +5266,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -12247,6 +12253,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -12560,6 +12567,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -12876,6 +12884,7 @@ exports[`Generic Object Form Component should render editing a generic object wi componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/host-aggregate-form/__snapshots__/host-aggregate-form.spec.js.snap b/app/javascript/spec/host-aggregate-form/__snapshots__/host-aggregate-form.spec.js.snap index 4d6557f87fa..e190520bd6c 100644 --- a/app/javascript/spec/host-aggregate-form/__snapshots__/host-aggregate-form.spec.js.snap +++ b/app/javascript/spec/host-aggregate-form/__snapshots__/host-aggregate-form.spec.js.snap @@ -86,6 +86,7 @@ exports[`Host aggregate form component should render add host form variant (remv componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -144,6 +145,7 @@ exports[`Host aggregate form component should render add host form variant (remv componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/host-edit-form/__snapshots__/host-edit-form.spec.js.snap b/app/javascript/spec/host-edit-form/__snapshots__/host-edit-form.spec.js.snap index 2fa98ecddcc..9b17ee9357b 100644 --- a/app/javascript/spec/host-edit-form/__snapshots__/host-edit-form.spec.js.snap +++ b/app/javascript/spec/host-edit-form/__snapshots__/host-edit-form.spec.js.snap @@ -30,6 +30,7 @@ exports[`Show Edit Host Form Component should render form for *one* host 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -250,6 +251,7 @@ exports[`Show Edit Host Form Component should render form for *one* host 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -477,6 +479,7 @@ exports[`Show Edit Host Form Component should render form for *one* host 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5515,6 +5518,7 @@ exports[`Show Edit Host Form Component should render form for multiple hosts 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5574,6 +5578,7 @@ exports[`Show Edit Host Form Component should render form for multiple hosts 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5640,6 +5645,7 @@ exports[`Show Edit Host Form Component should render form for multiple hosts 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/host-initiator-group-form/__snapshots__/host-initiator-group.spec.js.snap b/app/javascript/spec/host-initiator-group-form/__snapshots__/host-initiator-group.spec.js.snap index e1e208cb81e..dfc392fcd1e 100644 --- a/app/javascript/spec/host-initiator-group-form/__snapshots__/host-initiator-group.spec.js.snap +++ b/app/javascript/spec/host-initiator-group-form/__snapshots__/host-initiator-group.spec.js.snap @@ -99,6 +99,7 @@ exports[`Host Initiator Group Form Loads data and renders 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -200,6 +201,7 @@ exports[`Host Initiator Group Form Loads data and renders 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/live-migrate-form/__snapshots__/live-migrate-form.spec.js.snap b/app/javascript/spec/live-migrate-form/__snapshots__/live-migrate-form.spec.js.snap index 0423aae64a9..db478bd5224 100644 --- a/app/javascript/spec/live-migrate-form/__snapshots__/live-migrate-form.spec.js.snap +++ b/app/javascript/spec/live-migrate-form/__snapshots__/live-migrate-form.spec.js.snap @@ -109,6 +109,7 @@ exports[`Live Migrate form component should render live migrate form when hosts componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -218,6 +219,7 @@ exports[`Live Migrate form component should render live migrate form when hosts componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1984,6 +1986,7 @@ exports[`Live Migrate form component should render live migrate form with host o componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2114,6 +2117,7 @@ exports[`Live Migrate form component should render live migrate form with host o componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4239,6 +4243,7 @@ exports[`Live Migrate form component should render live migrate form with multip componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4348,6 +4353,7 @@ exports[`Live Migrate form component should render live migrate form with multip componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/physical-storage-form/__snapshots__/physical-storage-form.spec.js.snap b/app/javascript/spec/physical-storage-form/__snapshots__/physical-storage-form.spec.js.snap index 757082d3893..86931be6db9 100644 --- a/app/javascript/spec/physical-storage-form/__snapshots__/physical-storage-form.spec.js.snap +++ b/app/javascript/spec/physical-storage-form/__snapshots__/physical-storage-form.spec.js.snap @@ -20,6 +20,7 @@ exports[`Physical storage form component should render adding form variant 1`] = componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -293,6 +294,7 @@ exports[`Physical storage form component should render editing form variant 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -541,6 +543,7 @@ exports[`Physical storage form component should render editing form variant 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -792,6 +795,7 @@ exports[`Physical storage form component should render editing form variant 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/pxe-customization-template-form/__snapshots__/pxe-customization-template-form.spec.js.snap b/app/javascript/spec/pxe-customization-template-form/__snapshots__/pxe-customization-template-form.spec.js.snap index 12563657d0e..70006e1b2ec 100644 --- a/app/javascript/spec/pxe-customization-template-form/__snapshots__/pxe-customization-template-form.spec.js.snap +++ b/app/javascript/spec/pxe-customization-template-form/__snapshots__/pxe-customization-template-form.spec.js.snap @@ -129,6 +129,7 @@ exports[`Pxe Customization Template Form Component should render adding a new px componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -255,6 +256,7 @@ exports[`Pxe Customization Template Form Component should render adding a new px componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2755,6 +2757,7 @@ exports[`Pxe Customization Template Form Component should render copying a pxe c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2890,6 +2893,7 @@ exports[`Pxe Customization Template Form Component should render copying a pxe c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5417,6 +5421,7 @@ exports[`Pxe Customization Template Form Component should render editing a pxe c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5552,6 +5557,7 @@ exports[`Pxe Customization Template Form Component should render editing a pxe c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/pxe-image-type-form/__snapshots__/pxe-image-type-form.spec.js.snap b/app/javascript/spec/pxe-image-type-form/__snapshots__/pxe-image-type-form.spec.js.snap index 5c1407c21e5..28ddace4491 100644 --- a/app/javascript/spec/pxe-image-type-form/__snapshots__/pxe-image-type-form.spec.js.snap +++ b/app/javascript/spec/pxe-image-type-form/__snapshots__/pxe-image-type-form.spec.js.snap @@ -84,6 +84,7 @@ exports[`Pxe Image Type Form Component should render adding a new pxe image type componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -171,6 +172,7 @@ exports[`Pxe Image Type Form Component should render adding a new pxe image type componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1582,6 +1584,7 @@ exports[`Pxe Image Type Form Component should render editing a pxe image type 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1675,6 +1678,7 @@ exports[`Pxe Image Type Form Component should render editing a pxe image type 1` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/pxe-iso-datastore-form/__snapshots__/pxe-iso-datastore-form.spec.js.snap b/app/javascript/spec/pxe-iso-datastore-form/__snapshots__/pxe-iso-datastore-form.spec.js.snap index 671eec67db8..9c4439efd3d 100644 --- a/app/javascript/spec/pxe-iso-datastore-form/__snapshots__/pxe-iso-datastore-form.spec.js.snap +++ b/app/javascript/spec/pxe-iso-datastore-form/__snapshots__/pxe-iso-datastore-form.spec.js.snap @@ -89,6 +89,7 @@ exports[`Pxe Iso Datastore Form Component should render adding a new iso datasto componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -169,6 +170,7 @@ exports[`Pxe Iso Datastore Form Component should render adding a new iso datasto componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/pxe-iso-image-form/__snapshots__/pxe-iso-image-form.spec.js.snap b/app/javascript/spec/pxe-iso-image-form/__snapshots__/pxe-iso-image-form.spec.js.snap index 0242d88782a..85c76dd0705 100644 --- a/app/javascript/spec/pxe-iso-image-form/__snapshots__/pxe-iso-image-form.spec.js.snap +++ b/app/javascript/spec/pxe-iso-image-form/__snapshots__/pxe-iso-image-form.spec.js.snap @@ -70,6 +70,7 @@ exports[`Pxe Edit Iso Image Form Component should render editing a iso image 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -141,6 +142,7 @@ exports[`Pxe Edit Iso Image Form Component should render editing a iso image 1`] componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/reconfigure-vm-form/__snapshots__/reconfigure-vm-form.spec.js.snap b/app/javascript/spec/reconfigure-vm-form/__snapshots__/reconfigure-vm-form.spec.js.snap index 4481ced8832..a179f2af8eb 100644 --- a/app/javascript/spec/reconfigure-vm-form/__snapshots__/reconfigure-vm-form.spec.js.snap +++ b/app/javascript/spec/reconfigure-vm-form/__snapshots__/reconfigure-vm-form.spec.js.snap @@ -92,6 +92,7 @@ exports[`Reconfigure VM form component should render form with only fields it ha componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -398,6 +399,7 @@ exports[`Reconfigure VM form component should render form with only fields it ha componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -709,6 +711,7 @@ exports[`Reconfigure VM form component should render form with only fields it ha componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4576,6 +4579,7 @@ exports[`Reconfigure VM form component should render reconfigure form and click componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -4986,6 +4990,7 @@ exports[`Reconfigure VM form component should render reconfigure form and click componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -5401,6 +5406,7 @@ exports[`Reconfigure VM form component should render reconfigure form and click componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -15922,6 +15928,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -16034,6 +16041,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -16151,6 +16159,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show c componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -17391,6 +17400,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -17608,6 +17618,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -17830,6 +17841,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -21186,6 +21198,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -21403,6 +21416,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -21625,6 +21639,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show d componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -24960,6 +24975,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show h componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -25183,6 +25199,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show h componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -25411,6 +25428,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show h componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -30011,6 +30029,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show n componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -30153,6 +30172,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show n componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -30300,6 +30320,7 @@ exports[`Reconfigure VM form component should render reconfigure form and show n componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -32114,6 +32135,7 @@ exports[`Reconfigure VM form component should render reconfigure form with datat componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -32525,6 +32547,7 @@ exports[`Reconfigure VM form component should render reconfigure form with datat componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -32941,6 +32964,7 @@ exports[`Reconfigure VM form component should render reconfigure form with datat componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -43635,6 +43659,7 @@ exports[`Reconfigure VM form component should render reconfigure form without da componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -43858,6 +43883,7 @@ exports[`Reconfigure VM form component should render reconfigure form without da componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -44086,6 +44112,7 @@ exports[`Reconfigure VM form component should render reconfigure form without da componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -48686,6 +48713,7 @@ exports[`Reconfigure VM form component should render reconfigure sub form and cl componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -49095,6 +49123,7 @@ exports[`Reconfigure VM form component should render reconfigure sub form and cl componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -49509,6 +49538,7 @@ exports[`Reconfigure VM form component should render reconfigure sub form and cl componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/schedule-form/__snapshots__/schedule-form.spec.js.snap b/app/javascript/spec/schedule-form/__snapshots__/schedule-form.spec.js.snap index 5f66a742d81..377457eb4c9 100644 --- a/app/javascript/spec/schedule-form/__snapshots__/schedule-form.spec.js.snap +++ b/app/javascript/spec/schedule-form/__snapshots__/schedule-form.spec.js.snap @@ -721,6 +721,7 @@ exports[`Schedule form component should render edit form when filter_type is not componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1361,6 +1362,7 @@ exports[`Schedule form component should render edit form when filter_type is not componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -15534,6 +15536,7 @@ exports[`Schedule form component should render edit form when filter_type is nul componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -16316,6 +16319,7 @@ exports[`Schedule form component should render edit form when filter_type is nul componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -33722,6 +33726,7 @@ exports[`Schedule form component should render schedule add form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -34285,6 +34290,7 @@ exports[`Schedule form component should render schedule add form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/service-request-default-form/__snapshots__/service-request-default-form.spec.js.snap b/app/javascript/spec/service-request-default-form/__snapshots__/service-request-default-form.spec.js.snap index 118f031591c..55b1ba7ed8c 100644 --- a/app/javascript/spec/service-request-default-form/__snapshots__/service-request-default-form.spec.js.snap +++ b/app/javascript/spec/service-request-default-form/__snapshots__/service-request-default-form.spec.js.snap @@ -320,6 +320,7 @@ exports[`Show Service Request Page should render 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -521,6 +522,7 @@ exports[`Show Service Request Page should render 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/settings-category-form/__snapshots__/settings-category-form.spec.js.snap b/app/javascript/spec/settings-category-form/__snapshots__/settings-category-form.spec.js.snap index bc4902129a9..870a074d0b6 100644 --- a/app/javascript/spec/settings-category-form/__snapshots__/settings-category-form.spec.js.snap +++ b/app/javascript/spec/settings-category-form/__snapshots__/settings-category-form.spec.js.snap @@ -131,6 +131,7 @@ exports[`SettingsCategoryForm Component should render a new SettingsCategoryForm componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -263,6 +264,7 @@ exports[`SettingsCategoryForm Component should render a new SettingsCategoryForm componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/settings-time-profile-form/__snapshots__/settings-time-profile-form.spec.js.snap b/app/javascript/spec/settings-time-profile-form/__snapshots__/settings-time-profile-form.spec.js.snap index c232ad39783..2529d9e67aa 100644 --- a/app/javascript/spec/settings-time-profile-form/__snapshots__/settings-time-profile-form.spec.js.snap +++ b/app/javascript/spec/settings-time-profile-form/__snapshots__/settings-time-profile-form.spec.js.snap @@ -491,6 +491,7 @@ exports[`VM common form component should render adding form variant add new time componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -989,6 +990,7 @@ exports[`VM common form component should render adding form variant add new time componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/vm-floating-ips-form/__snapshots__/vm-floating-ips-form.spec.js.snap b/app/javascript/spec/vm-floating-ips-form/__snapshots__/vm-floating-ips-form.spec.js.snap index 9123718af98..9f24222971b 100644 --- a/app/javascript/spec/vm-floating-ips-form/__snapshots__/vm-floating-ips-form.spec.js.snap +++ b/app/javascript/spec/vm-floating-ips-form/__snapshots__/vm-floating-ips-form.spec.js.snap @@ -53,6 +53,7 @@ exports[`Associate / Disassociate form component should render associate form va componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -116,6 +117,7 @@ exports[`Associate / Disassociate form component should render associate form va componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1079,6 +1081,7 @@ exports[`Associate / Disassociate form component should render disassociate form componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1142,6 +1145,7 @@ exports[`Associate / Disassociate form component should render disassociate form componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2132,6 +2136,7 @@ exports[`Associate / Disassociate form component should submit Associate API cal componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -2195,6 +2200,7 @@ exports[`Associate / Disassociate form component should submit Associate API cal componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3038,6 +3044,7 @@ exports[`Associate / Disassociate form component should submit Disassociate API componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -3101,6 +3108,7 @@ exports[`Associate / Disassociate form component should submit Disassociate API componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/vm-resize-form/__snapshots__/vm-resize-form.spec.js.snap b/app/javascript/spec/vm-resize-form/__snapshots__/vm-resize-form.spec.js.snap index a339a5241fd..d46211457e0 100644 --- a/app/javascript/spec/vm-resize-form/__snapshots__/vm-resize-form.spec.js.snap +++ b/app/javascript/spec/vm-resize-form/__snapshots__/vm-resize-form.spec.js.snap @@ -63,6 +63,7 @@ exports[`vm resize form component should render a resize form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -127,6 +128,7 @@ exports[`vm resize form component should render a resize form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/workflow-credential-mapping-form/__snapshots__/workflow-credential-mapping-form.spec.js.snap b/app/javascript/spec/workflow-credential-mapping-form/__snapshots__/workflow-credential-mapping-form.spec.js.snap index b42ce7709a4..383fdef5d0e 100644 --- a/app/javascript/spec/workflow-credential-mapping-form/__snapshots__/workflow-credential-mapping-form.spec.js.snap +++ b/app/javascript/spec/workflow-credential-mapping-form/__snapshots__/workflow-credential-mapping-form.spec.js.snap @@ -55,6 +55,7 @@ exports[`Workflow Credential Form Component should render mapping credentials to componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "credential-mapper": [Function], "date-picker": [Function], @@ -241,6 +242,7 @@ exports[`Workflow Credential Form Component should render mapping credentials to componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "credential-mapper": [Function], "date-picker": [Function], @@ -430,6 +432,7 @@ exports[`Workflow Credential Form Component should render mapping credentials to componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "credential-mapper": [Function], "date-picker": [Function], diff --git a/app/javascript/spec/workflow-credentials-form/__snapshots__/workflow-credentials-form.spec.js.snap b/app/javascript/spec/workflow-credentials-form/__snapshots__/workflow-credentials-form.spec.js.snap index 3df6e3fe898..78c7cdde9a6 100644 --- a/app/javascript/spec/workflow-credentials-form/__snapshots__/workflow-credentials-form.spec.js.snap +++ b/app/javascript/spec/workflow-credentials-form/__snapshots__/workflow-credentials-form.spec.js.snap @@ -91,6 +91,7 @@ exports[`Workflow Credential Form Component should render adding a new credentia componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -185,6 +186,7 @@ exports[`Workflow Credential Form Component should render adding a new credentia componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1596,6 +1598,7 @@ exports[`Workflow Credential Form Component should render editing a credential 1 componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -1697,6 +1700,7 @@ exports[`Workflow Credential Form Component should render editing a credential 1 componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/javascript/spec/zone-form/__snapshots__/zone-form.spec.js.snap b/app/javascript/spec/zone-form/__snapshots__/zone-form.spec.js.snap index 84df0d15886..c9c50fbb65a 100644 --- a/app/javascript/spec/zone-form/__snapshots__/zone-form.spec.js.snap +++ b/app/javascript/spec/zone-form/__snapshots__/zone-form.spec.js.snap @@ -305,6 +305,7 @@ exports[`zone Form Component should render editing a zone form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], @@ -475,6 +476,7 @@ exports[`zone Form Component should render editing a zone form 1`] = ` componentMapper={ Object { "checkbox": [Function], + "checkbox-tree": [Function], "code-editor": [Function], "date-picker": [Function], "dual-list-select": [Function], diff --git a/app/stylesheet/application-webpack.scss b/app/stylesheet/application-webpack.scss index aa61b6787dc..500ca1196ac 100644 --- a/app/stylesheet/application-webpack.scss +++ b/app/stylesheet/application-webpack.scss @@ -24,6 +24,7 @@ @import './quadicon.scss'; @import './search-bar.scss'; @import './settings.scss'; +@import './settings-cu-collection.scss'; @import './responsive_layout.scss'; @import './tags.scss'; @import './tree.scss'; diff --git a/app/stylesheet/settings-cu-collection.scss b/app/stylesheet/settings-cu-collection.scss new file mode 100644 index 00000000000..2d64b239528 --- /dev/null +++ b/app/stylesheet/settings-cu-collection.scss @@ -0,0 +1,40 @@ +.parent-div { + display: flex; + flex-direction: row; + } + .clusters-section, .datastores-section { + display: flex; + flex-direction: row; + margin-bottom: 10%; + } + .clusters, .datastores { + font-size: large; + } + .clusters-box, .datastores-box { + width: 45%; + border: 1px solid; + padding: 2%; + } + .available-clusters, .available-datastores, .collect-note { + font-weight: bold; + } + .clusters-box, .datastores-box { + margin-bottom: 5%; + } + .clusters-box { + margin-right: 10%; + } + .clusters-labels, .datastores-labels { + margin-right: 30%; + } + .bx--btn--primary { + margin-right: 10%; + } + + .bx--btn--primary, .bx--btn--secondary { + width: 20%; + } + + .dropdown-label { + font-size: x-small; + } \ No newline at end of file diff --git a/app/views/ops/_settings_cu_collection_tab.html.haml b/app/views/ops/_settings_cu_collection_tab.html.haml index 2a456c0905c..67ff1e968cf 100644 --- a/app/views/ops/_settings_cu_collection_tab.html.haml +++ b/app/views/ops/_settings_cu_collection_tab.html.haml @@ -1,65 +1,11 @@ -- if @sb[:active_tab] == "settings_cu_collection" - - url = url_for_only_path(:action => 'cu_collection_field_changed') - = form_tag({:action => 'cu_collection_update'}, - :id => "config_form", - :class => "form-horizontal", - :method => :post) do - .row - .col-md-12.col-lg-6 - %fieldset - %h3 - = _("Clusters") - .form-horizontal - .form-group - %label.col-md-4.control-label - = _("Collect for All Clusters") - .col-md-8 - = check_box_tag("all_clusters", true, @edit[:new][:all_clusters], - "data-miq_sparkle_on" => true, "data-miq_sparkle_off" => true, :data => {:on_text => _('Yes'), :off_text => _('No')}) - :javascript - miqInitBootstrapSwitch('all_clusters', "#{url}") - .note - %b= _("Note: Collect for All Clusters must be checked to be able to collect C & U data from Cloud Providers such as Red Hat OpenStack or Amazon EC2") - - if @cluster_tree.present? - #clusters_div{:style => "display:#{@edit[:new][:all_clusters] ? "none" : ""}"} - - if @edit[:new][:clusters].blank? && @edit[:new][:non_cl_hosts].blank? - = _("No Clusters found in the current region.") - - else - %br/ - %b= _("Enable Collection by Cluster") - %br/ - :javascript - miqTreeResetState('#{j_str @cluster_tree.name}'); - = render(:partial => 'shared/tree', :locals => {:tree => @cluster_tree, :name => @cluster_tree.name}) - %br/ - .note= _("VM data will be collected for VMs under selected Hosts only. Data is collected for a Cluster and all of its Hosts when at least one Host is selected.") - - else - %br/ - .note - %b= _("Note: No Clusters available.") - .col-md-12.col-lg-6 - %fieldset - %h3= _("Datastores") - .form-horizontal - .form-group - %label.col-md-4.control-label - = _("Collect for All Datastores") - .col-md-8 - = check_box_tag("all_storages", true, @edit[:new][:all_storages], - "data-miq_sparkle_on" => true, "data-miq_sparkle_off" => true, :data => {:on_text => _('Yes'), :off_text => _('No')}) - :javascript - miqInitBootstrapSwitch('all_storages', "#{url}") - - if @datastore_tree.present? - #storages_div{:style => "display:#{@edit[:new][:all_storages] ? "none" : ""}"} - - if @edit[:new][:storages].blank? - = _("No Datastores found in the current region.") - - else - %br/ - %b= _("Enable Collection by Datastore") - %br/ - :javascript - miqTreeResetState('#{j_str @datastore_tree.name}'); - = render(:partial => 'shared/tree', :locals => {:tree => @datastore_tree, :name => @datastore_tree.name}) - - else - .note - %b= _("Note: No Datastores available.") +- @hide_bottom_bar = true +- url = "/ops/cu_collection_update" +- get_url = "/ops/cu_collection_fetch" += react('SettingsCUCollectionTab', + :url => url, + :fetchURL => get_url, + :clusterTree => @cluster_tree, + :datastoreTree => @datastore_tree, + :allClusters => Metric::Targets.perf_capture_always[:host_and_cluster], + :allDatastores => Metric::Targets.perf_capture_always[:storage], +) \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 2056e137c7d..43f0c97c742 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2432,7 +2432,6 @@ ce_new_cat ce_select change_tab - cu_collection_field_changed cu_collection_update cu_repair cu_repair_field_changed diff --git a/cypress/e2e/ui/Settings/Application-Settings/SettingsCUCollection.cy.js b/cypress/e2e/ui/Settings/Application-Settings/SettingsCUCollection.cy.js new file mode 100644 index 00000000000..82e258720d1 --- /dev/null +++ b/cypress/e2e/ui/Settings/Application-Settings/SettingsCUCollection.cy.js @@ -0,0 +1,58 @@ +/* eslint-disable no-undef */ + +describe('Settings > Application Settings > Settings', () => { + beforeEach(() => { + cy.login(); + cy.intercept('POST', '/ops/accordion_select?id=rbac_accord').as('accordion'); + cy.menu('Settings', 'Application Settings'); + }); + + describe('C&U Collection', () => { + beforeEach(() => { + cy.contains('ManageIQ Region').click(); + cy.contains('C & U Collection').click(); + cy.wait(500); + }); + + it('Reset clusters and datastores', () => { + cy.get('.clusters-box').find('[class="rct-checkbox"]').first().click({ force: true }); + cy.get('.datastores-box').find('[class="rct-checkbox"]').first().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--secondary"]').click({force: true}); + cy.get('.react-checkbox-tree').find('input[type="checkbox"]').first().should('not.be.checked'); + cy.get('.react-checkbox-tree').find('input[type="checkbox"]').first().should('not.be.checked'); + }); + + it('Save clusters and datastores', () => { + cy.get('.clusters-box').find('[class="rct-checkbox"]').first().click({ force: true }); + cy.get('.datastores-box').find('[class="rct-checkbox"]').first().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--primary"]').click({force: true}); + cy.get('.react-checkbox-tree').find('input[type="checkbox"]').first().should('be.checked'); + cy.get('.react-checkbox-tree').find('input[type="checkbox"]').first().should('be.checked'); + }); + + it('Collect all clusters', () => { + cy.get('.bx--toggle__switch').first().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--primary"]').click({force: true}); + cy.get('.bx--toggle-input').first().should('be.checked'); + cy.wait(500); + + // cleanup + cy.get('.bx--toggle__switch').first().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--primary"]').click({force: true}); + cy.get('.bx--toggle-input').first().should('not.be.checked'); + }); + + it('Collect all datastores', () => { + cy.get('.bx--toggle__switch').last().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--primary"]').click({ force: true }); + cy.get('.bx--toggle-input').last().should('be.checked'); + + cy.wait(500); + + // cleanup + cy.get('.bx--toggle__switch').last().click({ force: true }); + cy.get('[class="btnRight bx--btn bx--btn--primary"]').click({force: true}); + cy.get('.bx--toggle-input').last().should('not.be.checked'); + }); + }); +}); diff --git a/package.json b/package.json index 9098f7f9912..8b690893bef 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "proxy-polyfill": "^0.1.7", "react": "~16.13.1", "react-bootstrap": "~0.33.0", + "react-checkbox-tree": "^1.8.0", "react-codemirror2": "^6.0.0", "react-dom": "~16.13.1", "react-markdown": "6.0.0", diff --git a/spec/views/ops/_settings_cu_collection_tab.html.haml_spec.rb b/spec/views/ops/_settings_cu_collection_tab.html.haml_spec.rb deleted file mode 100644 index c44fbcb98e8..00000000000 --- a/spec/views/ops/_settings_cu_collection_tab.html.haml_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -describe "ops/_settings_cu_collection_tab.html.haml" do - let(:cluster) { FactoryBot.create(:ems_cluster) } - let(:ems) { FactoryBot.create(:ext_management_system) } - - let(:host_1) { FactoryBot.create(:host, :ems_cluster => cluster) } - let(:host_2) { FactoryBot.create(:host, :ems_cluster => cluster) } - let(:host_3) { FactoryBot.create(:host, :ext_management_system => ems) } - - let(:datastore) { FactoryBot.create(:storage, :name => 'Name', :hosts => [host_1]) } - - before do - assign(:sb, :active_tab => "settings_cu_collection") - - MiqRegion.seed - allow(host_1).to receive(:perf_capture_enabled?).and_return(true) - allow(host_2).to receive(:perf_capture_enabled?).and_return(false) - allow(host_3).to receive(:perf_capture_enabled?).and_return(true) - - @host = FactoryBot.create(:host, :name => 'Host Name') - datastores = { - datastore.id => { - :name => 'Datastore', - :location => 'Location', - :st_rec => datastore, - :capture => false, - } - } - @datastore_tree = TreeBuilderDatastores.new(:datastore_tree, {}, true, :root => datastores) - @cluster_tree = TreeBuilderClusters.new(:cluster_tree, {}, true, :root => EmsCluster.get_perf_collection_object_list) - end - - it "Displays note if there are no Clusters" do - @cluster_tree = nil - assign(:edit, :new => {:all_clusters => false}) - render :template => "ops/_settings_cu_collection_tab" - expect(response).to have_selector("div.note b", :text => "Note: No Clusters available.") - end - - it "Displays note if there are no Datastores" do - @datastore_tree = nil - assign(:edit, :new => {:all_storages => false}) - render :template => "ops/_settings_cu_collection_tab" - expect(response).to have_selector("div.note b", :text => "Note: No Datastores available.") - end -end diff --git a/yarn.lock b/yarn.lock index 1212afcbc7c..3d31b74af5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11747,6 +11747,7 @@ __metadata: proxy-polyfill: "npm:^0.1.7" react: "npm:~16.13.1" react-bootstrap: "npm:~0.33.0" + react-checkbox-tree: "npm:^1.8.0" react-codemirror2: "npm:^6.0.0" react-dom: "npm:~16.13.1" react-markdown: "npm:6.0.0" @@ -12384,7 +12385,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.7": +"nanoid@npm:^3.0.0, nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" bin: @@ -14583,6 +14584,20 @@ __metadata: languageName: node linkType: hard +"react-checkbox-tree@npm:^1.8.0": + version: 1.8.0 + resolution: "react-checkbox-tree@npm:1.8.0" + dependencies: + classnames: "npm:^2.2.5" + lodash: "npm:^4.17.10" + nanoid: "npm:^3.0.0" + prop-types: "npm:^15.5.8" + peerDependencies: + react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10/700e87c0d6b1c7a15e104d0ef01ac1c15b8eb74905cd2a3b1e087a1c6fa596e4a58894ef553d5f8651782d7012c07eab87f9646f44def3569163a89c1cbb0f71 + languageName: node + linkType: hard + "react-codemirror2@npm:^6.0.0": version: 6.0.1 resolution: "react-codemirror2@npm:6.0.1"