diff --git a/app/controllers/ops_controller/ops_rbac.rb b/app/controllers/ops_controller/ops_rbac.rb index e0f0abefcef..b338b559b65 100644 --- a/app/controllers/ops_controller/ops_rbac.rb +++ b/app/controllers/ops_controller/ops_rbac.rb @@ -131,14 +131,12 @@ def rbac_role_edit_get @_params[:id] = obj[0] end @hide_bottom_bar = true - require 'byebug' - byebug role = MiqUserRole.find_by(id: params[:id]) render :json => { :name => role.name, :vm_restriction => role[:settings] && role[:settings][:restrictions][:vms], :service_template_restriction => role[:settings] && role[:settings][:restrictions][:service_templates], - :featuresWithId => role.miq_product_features, + :miqProductFeatures => role.miq_product_features, } end @@ -1370,11 +1368,8 @@ def rbac_role_get_form_vars @edit[:new][:vm_restriction] = params[:vm_restriction].to_sym if params[:vm_restriction] @edit[:new][:service_template_restriction] = params[:service_template_restriction].to_sym if params[:service_template_restriction] @edit[:new][:features] = params[:features] if params[:features] - @edit[:new][:features_with_id] = params[:featuresWithId] if params[:featuresWithId] @edit[:new][:features].uniq! @edit[:new][:features].sort! - @edit[:new][:features_with_id].uniq! - @edit[:new][:features_with_id].sort! end # Walk the features tree, removing features up to the top @@ -1412,7 +1407,6 @@ def rbac_role_set_record_vars(role) role.settings[:restrictions][:service_templates] = @edit[:new][:service_template_restriction] end role.settings = nil if role.settings[:restrictions].blank? - role[:features_with_id] = @edit[:new][:features_with_id] end def populate_role_features(role) diff --git a/app/helpers/ops_helper/role_rbac_details_helper.rb b/app/helpers/ops_helper/role_rbac_details_helper.rb index dc1fc79379e..7cba57e41fc 100644 --- a/app/helpers/ops_helper/role_rbac_details_helper.rb +++ b/app/helpers/ops_helper/role_rbac_details_helper.rb @@ -9,8 +9,6 @@ def role_rbac_details(role, rbac_menu_tree) end def rbac_role_info_view(role, rbac_menu_tree) - require 'byebug' - byebug rows = [ row_data(_('ID'), role.id), row_data(_('Name'), role.name), @@ -25,8 +23,6 @@ def rbac_role_info_view(role, rbac_menu_tree) end def rbac_role_product_features(role, rbac_menu_tree) - require 'byebug' - byebug cells = row_data(_("Product Features (Read Only)"), {:input => 'component', :component => 'TREE_VIEW_REDUX', :props => rbac_menu_tree.locals_for_render, :name => rbac_menu_tree.name}) cells[:cells][:value][:props] end diff --git a/app/javascript/components/rbac-role-form/index.jsx b/app/javascript/components/rbac-role-form/index.jsx index 5a48fdab2d6..bfaed52dc90 100644 --- a/app/javascript/components/rbac-role-form/index.jsx +++ b/app/javascript/components/rbac-role-form/index.jsx @@ -12,20 +12,37 @@ import miqRedirectBack from '../../helpers/miq-redirect-back'; let idCounter = 0; let modified = false; -const features = []; +let features = new Set(); const RbacRoleForm = (props) => { const { - selectOptions, url, getURL, customProps, role, + selectOptions, url, getURL, customProps, role, existingProductFeatures, } = props; const generateId = () => idCounter++; + // necessary for older roles that do only have top level nodes as features + const checkChildren = (productFeature, child) => { + if (!child.children) { + features.add(child.value); + } else { + for (let nextChild of child.children) { + checkChildren(productFeature, nextChild); + } + } + }; + + // find checked boxes for all role features const findCheck = (productFeature, node) => { const result = node.value.split('__')[1].split('#')[0]; + if (result === productFeature) { - features.push(node.value); + features.add(node.value); + if (node.children) { + for (let child of node.children) { + checkChildren(productFeature, child); + } + } } - if (node.children) { for (let child of node.children) { findCheck(productFeature, child); @@ -41,9 +58,6 @@ const RbacRoleForm = (props) => { label: node.text, }; - if (node.key === 'infra_topology') { - console.log('infra_topology'); - } let icon; switch (node.icon) { case 'fa fa-search': @@ -87,13 +101,13 @@ const RbacRoleForm = (props) => { const customValidation = (values) => { const errors = {}; if (values.tree_dropdown === undefined) { - values.tree_dropdown = formData.initialValues.featuresWithId || []; + values.tree_dropdown = formData.initialValues.miqProductFeatures || []; } if (values) { if (values.name === formData.initialValues.name && values.vm_restriction === formData.initialValues.vm_restriction && values.service_template_restriction === formData.initialValues.service_template_restriction - && JSON.stringify(values.tree_dropdown) === JSON.stringify(formData.initialValues.featuresWithId)) { + && JSON.stringify(values.tree_dropdown) === JSON.stringify(formData.initialValues.miqProductFeatures)) { modified = false; } else { modified = true; @@ -121,42 +135,35 @@ const RbacRoleForm = (props) => { if (roleValues) { const bsTree = JSON.parse(customProps.bs_tree); const nodes = bsTree.map(transformTree); - const uniqueBoxes = []; - const identifiers = []; - roleValues.featuresWithId.forEach((feature) => { - identifiers.push(feature.identifier); - }); - console.log("roleValues: ", identifiers); - roleValues.featuresWithId.forEach((productFeature) => { - uniqueBoxes.push(findCheck(productFeature.identifier, nodes[0])); + roleValues.miqProductFeatures.forEach((productFeature) => { + findCheck(productFeature.identifier, nodes[0]); }); - console.log("features: ", features); setFormData({ ...formData, isLoading: false, initialValues: roleValues, nodes, checked: features, }); } }); } else { - let uniqueBoxes = []; - if (role.features_with_id) { - uniqueBoxes = role.features_with_id.map((str) => { - const parts = str.split('__'); - parts[0] = 'new'; - return parts.join('__'); - }); - } const initialValues = { name: role.name !== null ? `Copy of ${role.name}` : '', vm_restriction: role && role.settings && role.settings.restrictions && role.settings.restrictions.vms, service_template_restriction: role && role.settings && role.settings.restrictions && role.settings.restrictions.service_templates, - tree_dropdown: role.name !== null ? role && role.features_with_id : [], }; const bsTree = JSON.parse(customProps.bs_tree); const nodes = bsTree.map(transformTree); - console.log(nodes); + if (role.name) { + idCounter = 0; + const bsTree = JSON.parse(customProps.bs_tree); + const nodes = bsTree.map(transformTree); + existingProductFeatures.forEach((productFeature) => { + findCheck(productFeature.identifier, nodes[0]); + }); + } + initialValues.tree_dropdown = features; + console.log("initial Values: ", initialValues); if (initialValues) { setFormData({ - ...formData, isLoading: false, initialValues, nodes, checked: uniqueBoxes, + ...formData, isLoading: false, initialValues, nodes, checked: features, }); } } @@ -167,10 +174,10 @@ const RbacRoleForm = (props) => { if (!values.tree_dropdown) { values.tree_dropdown = formData.checked; } - - const treeDropdown = values.tree_dropdown; - const treeValues = treeDropdown.map((string) => string.split('#')[0]); + const checkedBoxes = Array.from(values.tree_dropdown); + const treeValues = checkedBoxes.map((feature) => feature.split('#')[0]); const splitValues = treeValues.map((string) => string.split('__')[1]); + const productFeatures = splitValues; values.tree_dropdown = splitValues; if (values.vm_restriction === '-1') { @@ -186,8 +193,7 @@ const RbacRoleForm = (props) => { name: values.name, vm_restriction: values.vm_restriction, service_template_restriction: values.service_template_restriction, - features: values.tree_dropdown, - featuresWithId: treeDropdown, + features: productFeatures, }; setFormData({ @@ -207,18 +213,19 @@ const RbacRoleForm = (props) => { }; const onReset = () => { + features = new Set(); + idCounter = 0; http.get(`${getURL}/${role.id}`).then((roleValues) => { if (roleValues) { - let uniqueBoxes = []; - if (roleValues.featuresWithId) { - uniqueBoxes = roleValues.featuresWithId.map((str) => { - const parts = str.split('__'); - parts[0] = role.id; - return parts.join('__'); + if (roleValues.miqProductFeatures) { + const bsTree = JSON.parse(customProps.bs_tree); + const nodes = bsTree.map(transformTree); + roleValues.miqProductFeatures.forEach((productFeature) => { + findCheck(productFeature.identifier, nodes[0]); }); } setFormData({ - ...formData, isLoading: false, initialValues: roleValues, checked: uniqueBoxes, + ...formData, isLoading: false, initialValues: roleValues, checked: features, }); } }); @@ -321,14 +328,15 @@ RbacRoleForm.propTypes = { vms: PropTypes.string.isRequired, }), }), - features_with_id: PropTypes.arrayOf(PropTypes.string), }), + existingProductFeatures: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; RbacRoleForm.defaultProps = { url: '', getURL: '', role: undefined, + existingProductFeatures: undefined, }; FormTemplate.propTypes = { diff --git a/app/javascript/components/tree-view/checkbox_tree.jsx b/app/javascript/components/tree-view/checkbox_tree.jsx index be25ccceb28..f301138915e 100644 --- a/app/javascript/components/tree-view/checkbox_tree.jsx +++ b/app/javascript/components/tree-view/checkbox_tree.jsx @@ -51,7 +51,7 @@ const CheckboxTreeComponent = (props) => { CheckboxTreeComponent.propTypes = { label: PropTypes.string.isRequired, nodes: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), - checked: PropTypes.arrayOf(PropTypes.string), + checked: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; CheckboxTreeComponent.defaultProps = { diff --git a/app/javascript/spec/rbac-role-form/__snapshots__/rbac-role-form.spec.js.snap b/app/javascript/spec/rbac-role-form/__snapshots__/rbac-role-form.spec.js.snap index a67336e6deb..09d3f951d1f 100644 --- a/app/javascript/spec/rbac-role-form/__snapshots__/rbac-role-form.spec.js.snap +++ b/app/javascript/spec/rbac-role-form/__snapshots__/rbac-role-form.spec.js.snap @@ -3,7 +3,7 @@ exports[`Rbac Role Form Component render add rbac role form 1`] = `