diff --git a/app/controllers/application_controller/miq_request_methods.rb b/app/controllers/application_controller/miq_request_methods.rb
index 3bc90454e214..2bf378fe40d6 100644
--- a/app/controllers/application_controller/miq_request_methods.rb
+++ b/app/controllers/application_controller/miq_request_methods.rb
@@ -651,7 +651,7 @@ def prov_req_submit
# Get variables from provisioning form
def prov_get_form_vars
if params[:ids_checked] # User checked/unchecked a tree node
- ids = params[:ids_checked].split(",")
+ ids = params[:ids_checked]
# for some reason if tree is not expanded clicking on radiobuttons this.getAllChecked() sends up extra blanks
@edit.store_path(:new, tag_symbol_for_workflow, ids.select(&:present?).collect(&:to_i))
end
@@ -984,69 +984,35 @@ def workflow_instance_from_vars(req)
end
def build_tags_tree(wf, vm_tags, edit_mode)
- tags = wf.send("allowed_tags")
- @curr_tag = nil
- # Build the default filters tree for the search views
- all_tags = [] # Array to hold all CIs
- kids_checked = false
- tags.each_with_index do |t, i| # Go thru all of the Searches
- if @curr_tag.blank? || @curr_tag != t[:name]
- if @curr_tag != t[:name] && @ci_node
- @ci_node[:expand] = true if kids_checked
- kids_checked = false
- @ci_node[:children] = @ci_kids if @ci_kids.present?
- all_tags.push(@ci_node) if @ci_kids.present?
- end
- @curr_tag = t[:name]
- @ci_node = {} # Build the ci node
- @ci_node[:key] = t[:id].to_s
- @ci_node[:title] = t[:description]
- @ci_node[:title] += " *" if t[:single_value]
- @ci_node[:tooltip] = t[:description]
- @ci_node[:addClass] = "cfme-no-cursor-node" # No cursor pointer
- @ci_node[:icon] = 'pficon pficon-folder-close'
- @ci_node[:hideCheckbox] = @ci_node[:cfmeNoClick] = true
- @ci_node[:addClass] = "cfme-bold-node" # Show node as different
- @ci_kids = []
- end
- if @curr_tag.present? && @curr_tag == t[:name]
- t[:children].each do |c|
- temp = {}
- temp[:key] = c[0].to_s
- # only add cfme_parent_key for single value tags, need to use in JS onclick handler
- temp[:selectable] = false
- temp[:title] = temp[:tooltip] = c[1][:description]
- temp[:addClass] = "cfme-no-cursor-node"
- temp[:icon] = 'fa fa-tag'
- if edit_mode # Don't show checkboxes/radio buttons in non-edit mode
- if vm_tags && vm_tags.include?(c[0].to_i)
- temp[:select] = true
- kids_checked = true
- else
- temp[:select] = false
- end
- if @edit && @edit[:current][tag_symbol_for_workflow] != @edit[:new][tag_symbol_for_workflow]
- # checking to see if id is in current but not in new, change them to blue OR if id is in current but deleted from new
- if (!@edit[:current][tag_symbol_for_workflow].include?(c[0].to_i) && @edit[:new][tag_symbol_for_workflow].include?(c[0].to_i)) ||
- (!@edit[:new][tag_symbol_for_workflow].include?(c[0].to_i) && @edit[:current][tag_symbol_for_workflow].include?(c[0].to_i))
- temp[:addClass] = "cfme-blue-bold-node"
- end
- end
- @ci_kids.push(temp) unless @ci_kids.include?(temp)
- else
- temp[:hideCheckbox] = true
- @ci_kids.push(temp) unless @ci_kids.include?(temp) || !vm_tags.include?(c[0].to_i)
- end
- end
- end
- if i == tags.length - 1 # Adding last node
- @ci_node[:expand] = true if kids_checked
- kids_checked = false
- @ci_node[:children] = @ci_kids if @ci_kids.present?
- all_tags.push(@ci_node) if @ci_kids.present?
+ # for some reason @tags is set in wf, and it is changed by map bellow which causes bugs
+ wf.instance_variable_set(:@tags, nil)
+ tags = wf.allowed_tags
+ tags.each do |cat|
+ cat[:values] = cat[:children].map do |tag|
+ { :id => tag.first, :description => tag.second[:description] }
end
+ cat[:id] = cat[:name]
+ cat[:singleValue] = cat[:single_value]
+ cat.delete(:children)
+ cat.delete(:name)
end
- @all_tags_tree = TreeBuilder.convert_bs_tree(all_tags).to_json # Add ci node array to root of tree
+
+ assignments = Classification.select { |tag| vm_tags.include?(tag.id) }
+ assigned_tags = assignments.map do |tag|
+ {
+ :description => tag.parent.description,
+ :id => tag.parent.id,
+ :values => assignments.select { |assignment| assignment.parent_id == tag.parent_id }.map do |assignment|
+ { :description => assignment.description, :id => assignment.id }
+ end
+ }
+ end.uniq
+
+ @button_urls = {
+ :save_url => '',
+ :cancel_url => ''
+ }
+ @tags = {:tags => tags, :assignedTags => assigned_tags, :affectedItems => []}
end
def build_template_filter
diff --git a/app/javascript/components/taggingWrapper.jsx b/app/javascript/components/taggingWrapper.jsx
index 86f7054f316c..cb613ff4ff1e 100644
--- a/app/javascript/components/taggingWrapper.jsx
+++ b/app/javascript/components/taggingWrapper.jsx
@@ -5,6 +5,26 @@ import { Spinner } from 'patternfly-react';
import { TaggingWithButtonsConnected, TaggingConnected, taggingApp } from '@manageiq/react-ui-components/dist/tagging';
import { http } from '../http_api';
+const params = (type = 'default', state, tag = {}) => ({
+ provision: {
+ id: "new",
+ ids_checked: [state.tagging.appState.assignedTags.map(t => t.values.map(val => val.id)).flat(), tag.tagValue.id].flat(),
+ tree_typ: 'tags'
+ },
+ default: {
+ id: state.tagging.appState.affectedItems[0] || "new",
+ cat: tag.tagCategory.id,
+ val: tag.tagValue.id,
+ check: 1,
+ tree_typ: 'tags'
+ }
+})[type]
+
+const onDelete = (type = 'default', params = [], deleted_element) => ({
+ provision: {...params, ids_checked: params.ids_checked.filter(element => element !== deleted_element)},
+ default: params,
+})[type]
+
class TaggingWrapper extends React.Component {
constructor(props) {
super(props);
@@ -22,7 +42,7 @@ class TaggingWrapper extends React.Component {
render() {
if (!this.props.isLoaded) return ;
const { urls, options } = this.props;
- return (options && options.hideButtons && || || );
}
}
diff --git a/app/javascript/miq-redux/middleware.js b/app/javascript/miq-redux/middleware.js
index ad15b1d1906b..cc13e1f16c85 100644
--- a/app/javascript/miq-redux/middleware.js
+++ b/app/javascript/miq-redux/middleware.js
@@ -5,10 +5,11 @@ import promiseMiddleware from 'redux-promise-middleware';
export const taggingMiddleware = store => next => action => {
const { type, meta, tagCategory, tag } = action;
if (meta && meta.url) {
- const params = {id: store.getState().tagging.appState.affectedItems[0], cat: tag.tagCategory.id, val: tag.tagValue.id, check: 1, tree_typ: 'tags' };
+ let params = meta.params(meta.type, store.getState(), tag);
if (type === 'UI-COMPONENTS_TAGGING_TOGGLE_TAG_VALUE_CHANGE') {
$.post(meta.url, params)
} else if (type === 'UI-COMPONENTS_TAGGING_DELETE_ASSIGNED_TAG') {
+ params = meta.onDelete(meta.type, params, tag.tagValue.id);
$.post(meta.url, {...params, check: 0})
}
}
diff --git a/app/views/miq_request/_prov_field.html.haml b/app/views/miq_request/_prov_field.html.haml
index 41c995f1b061..e11d1b074934 100644
--- a/app/views/miq_request/_prov_field.html.haml
+++ b/app/views/miq_request/_prov_field.html.haml
@@ -298,13 +298,7 @@
- check = @miq_request.id
- else
- check = 'new'
- = render(:partial => "layouts/tree",
- :locals => {:tree_id => "all_tags_treebox",
- :tree_name => "all_tags_tree",
- :bs_tree => @all_tags_tree,
- :oncheck => "miqOnCheckProvTags",
- :check_url => "/miq_request/prov_field_changed/#{check}",
- :checkboxes => true})
+ = react 'TaggingWrapperConnected', { :tags => @tags, :urls => @button_urls, :options => { :type => 'provision', :hideHeaders => true, :hideButtons => true, :url => url_for_only_path(:action => 'prov_field_changed')} }
- unless field_hash[:notes_display] == :hide || field_hash[:notes].blank?
-# Display notes if available
= field_hash[:notes]