From 3c5455c2fecb07b60a217f7b8b20edd75284a63b Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 26 Jan 2017 16:51:24 -0500 Subject: [PATCH 01/13] Angular Form with REST API calls for Playbook Service Template type. This is a work in Progress, changes in this PR load an Angular form that consumes REST API to populate/save data in form when user tries to add an 'Ansible Playbook' type Service Template or edit an existing 'Ansible Playbook' type Service Template. https://www.pivotaltracker.com/story/show/138302747 --- .../catalog/catalog_item_form_controller.js | 214 ++++++++++++++++++ .../services/catalog/catalog_item_data.js | 10 + app/controllers/catalog_controller.rb | 120 ++++++++-- app/views/catalog/_st_angular_form.html.haml | 69 ++++++ .../_ansible_form_options_angular.html.haml | 184 +++++++++++++++ .../_multi_tab_ansible_form_options.html.haml | 34 +++ config/routes.rb | 2 + 7 files changed, 610 insertions(+), 23 deletions(-) create mode 100644 app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js create mode 100644 app/assets/javascripts/services/catalog/catalog_item_data.js create mode 100644 app/views/catalog/_st_angular_form.html.haml create mode 100644 app/views/layouts/angular/_ansible_form_options_angular.html.haml create mode 100644 app/views/layouts/angular/_multi_tab_ansible_form_options.html.haml diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js new file mode 100644 index 00000000000..c32a03b0227 --- /dev/null +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -0,0 +1,214 @@ +ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalogItemFormId', 'miqService', 'postService', 'API', 'catalogItemDataFactory', function($scope, catalogItemFormId, miqService, postService, API, catalogItemDataFactory) { + var init = function() { + $scope.catalogItemModel = { + name: '', + description: '', + display: false, + prov_type: '', + catalog_id: '', + provisioning_repository_id: '', + provisioning_playbook_id: '', + provisioning_machine_credential_id: '', + provisioning_netowrk_credential_id: '', + provisioning_cloud_credential_id: '', + provisioning_inventory: 'localhost', + provisioning_dialog_existing: 'existing', + provisioning_dialog_id: '', + provisioning_dialog_name: '', + provisioning_key: '', + provisioning_value: '', + provisioning_variables: {"p_var1": "p_val1", "p_var2": "p_val2"}, + provisioning_editMode: false, + retirement_repository_id: '', + retirement_playbook_id: '', + retirement_machine_credential_id: '', + retirement_network_credential_id: '', + retirement_cloud_credential_id: '', + retirement_inventory: 'localhost', + retirement_dialog_existing: 'existing', + retirement_dialog_id: '', + retirement_dialog_name: '', + retirement_key: '', + retirement_value: '', + retirement_variables: {"r_var1": "r_val1", "r_var2": "r_val2"}, + retirement_editMode: false, + key: '', + key_value: '', + }; + $scope.formId = catalogItemFormId; + $scope.afterGet = false; + $scope.modelCopy = angular.copy( $scope.catalogItemModel ); + $scope.model = "catalogItemModel"; + + ManageIQ.angular.scope = $scope; + + if (catalogItemFormId == 'new') { + $scope.newRecord = true; + $scope.catalogItemModel.name = ''; + $scope.catalogItemModel.description = ''; + $scope.catalogItemModel.catalog_id = ''; + $scope.catalogItemModel.display = false; + $scope.catalogItemModel.provisioning_dialog_id = ''; + $scope.catalogItemModel.retirement_dialog_id = ''; + $scope.catalogItemModel.prov_type = 'generic_ansible_playbook'; + $scope.formOptions(); + $scope.afterGet = true; + $scope.modelCopy = angular.copy( $scope.catalogItemModel ); + } else { + $scope.newRecord = false; + catalogItemDataFactory.getCatalogItemData(catalogItemFormId).then(function (catalogItemData) { + $scope.newRecord = false; + $scope.catalogItemModel.name = catalogItemData.name; + $scope.catalogItemModel.description = catalogItemData.description; + $scope.catalogItemModel.display = catalogItemData.display; + $scope.catalogItemModel.catalog_id = catalogItemData.service_template_catalog_id; + $scope.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id;; + $scope.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id;; + $scope.formOptions(); + $scope.afterGet = true; + $scope.modelCopy = angular.copy($scope.catalogItemModel); + }); + } + }; + + var catalogItemEditButtonClicked = function(buttonName, serializeFields) { + miqService.sparkleOn(); + var url = '/catalog/catalog_item_edit/' + catalogItemFormId + '?button=' + buttonName; + if (serializeFields === undefined) { + miqService.miqAjaxButton(url); + } else { + miqService.miqAjaxButton(url, serializeFields); + } + }; + + $scope.cancelClicked = function() { + catalogItemEditButtonClicked('cancel'); + $scope.angularForm.$setPristine(true); + }; + + $scope.resetClicked = function() { + $scope.catalogItemModel = angular.copy( $scope.modelCopy ); + $scope.angularForm.$setUntouched(true); + $scope.angularForm.$setPristine(true); + miqService.miqFlash("warn", __("All changes have been reset")); + }; + + $scope.saveClicked = function() { + catalogItemEditButtonClicked('save', true); + $scope.angularForm.$setPristine(true); + }; + + $scope.addClicked = function() { + $scope.saveClicked(); + }; + + // list of service catalogs + $scope.formOptions = function() { + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function(data) { + $scope.catalogs = data.resources + $scope._catalog = _.find($scope.catalogs, {id: $scope.catalogItemModel.catalog_id}) + }) + + // list of service dailaogs + API.get("/api/service_dialogs/?expand=resources&attributes=id,label").then(function (data) { + $scope.dialogs = data.resources + $scope._retirement_dialog = _.find($scope.dialogs, {id: $scope.catalogItemModel.retirement_dialog_id}) + $scope._provisioning_dialog = _.find($scope.dialogs, {id: $scope.catalogItemModel.provisioning_dialog_id}) + }) + + // list of repositories + //API.get("/api/configuration_script_sources/?expand=resources&attributes=id,name") + + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + $scope.repositories = data.resources + $scope._retirement_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.retirement_repository_id}) + $scope._provisioning_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.provisioning_repository_id}) + }) + + // list of machine credentials + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + $scope.machine_credentials = data.resources + $scope._retirement_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.retirement_machine_credential_id}) + $scope._provisioning_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.provisioning_machine_credential_id}) + }) + + // list of network credentials + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + $scope.network_credentials = data.resources + $scope._retirement_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.retirement_network_credential_id}) + $scope._provisioning_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.provisioning_network_credential_id}) + }) + + // list of cloud credentials + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + $scope.cloud_credentials = data.resources + $scope._retirement_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.retirement_cloud_credential_id}) + $scope._provisioning_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.provisioning_cloud_credential_id}) + }) + }; + + // get playbooks for selected repository + $scope.repositoryChanged = function(prefix, id) { + //uncomment this line and remove line 153 + //var url = "/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads"; + + var url = "/api/cloud_networks/" + '10000000000005' + "?attributes=cloud_subnets"; + $scope.catalogItemModel[prefix + '_playbook_id'] = ''; + $scope.catalogItemModel[prefix + '_repository_id'] = id; + + API.get(url).then(function(response) { + $scope[prefix + '_playbooks'] = response.cloud_subnets; + }) + }; + + $scope.$watch('_provisioning_repository', function(value) { + if (value) { + $scope.repositoryChanged("provisioning", value.id) + } + }); + + $scope.$watch('_retirement_repository', function(value) { + if (value) { + $scope.repositoryChanged("retirement", value.id) + } + }); + + $scope.$watch('catalogItemModel.display', function(value) { + $scope.catalogItemModel.display = value; + return $scope.catalogItemModel.display; + }) + + $scope.addKeyValue = function(prefix) { + $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel[prefix + "_key"]] = $scope.catalogItemModel[prefix + "_value"] + $scope.catalogItemModel[prefix + "_key"] = ''; + $scope.catalogItemModel[prefix + "_value"] = ''; + } + + $scope.removeKeyValue = function(prefix, key) { + delete $scope.catalogItemModel[prefix + "_variables"][key]; + } + + $scope.editKeyValue = function(prefix, key, key_value, index) { + $scope.catalogItemModel[prefix + "_editMode"] = true; + $scope.catalogItemModel.s_index = index; + $scope.catalogItemModel.key = key; + $scope.catalogItemModel.key_value = key_value; + $scope.catalogItemModel.original_key = key; + $scope.catalogItemModel.original_key_value = key_value; + } + + $scope.cancelKeyValue = function(prefix, key, key_value, index) { + $scope.catalogItemModel[prefix + "_editMode"] = false; + $scope.catalogItemModel.s_index = ''; + $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key] = $scope.catalogItemModel.original_key_value; + } + + $scope.saveKeyValue = function(prefix, key, key_value, index) { + $scope.catalogItemModel[prefix + "_editMode"] = false; + $scope.catalogItemModel.s_index = ''; + delete $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key]; + $scope.catalogItemModel[prefix + "_variables"][key] = key_value; + } + + init(); +}]); diff --git a/app/assets/javascripts/services/catalog/catalog_item_data.js b/app/assets/javascripts/services/catalog/catalog_item_data.js new file mode 100644 index 00000000000..2ca42d7775b --- /dev/null +++ b/app/assets/javascripts/services/catalog/catalog_item_data.js @@ -0,0 +1,10 @@ +ManageIQ.angular.app.service('catalogItemDataFactory', ['API', function(API) { + var urlBase = '/api/service_templates'; + + this.getCatalogItemData = function (st_id) { + if(angular.isDefined(st_id)) { + return API.get(urlBase + '/' + miqUncompressedId(st_id)) + } + }; +}]); + diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 72a972dc55a..333d2a08ea7 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -111,6 +111,7 @@ def atomic_st_edit @edit[:new] ||= {} @edit[:current] ||= {} @edit[:key] = "prov_edit__new" + @edit[:st_prov_types] = catalog_item_types end @edit[:new][:st_prov_type] = @record.prov_type if @record.prov_type.present? # set name and description for ServiceTemplate record @@ -126,6 +127,58 @@ def atomic_st_edit end end + def catalog_item_types + { + "amazon" => "Amazon", + "generic_ansible_playbook" => "Ansible Playbook", + "azure" => "Azure", + "generic" => "Generic", + "generic_orchestration" => "Orchestration", + "generic_ansible_tower" => "AnsibleTower", + "google" => "Google", + "microsoft" => "SCVMM", + "openstack" => "OpenStack", + "redhat" => "RHEV", + "vmware" => "VMware" + } + end + + def catalog_item_edit + assert_privileges("atomic_catalogitem_edit") + case params[:button] + when "cancel" + service_template = ServiceTemplate.find_by_id(params[:id]) + if service_template.try(:id).nil? + add_flash(_("Add of new Catalog Item was cancelled by the user")) + else + add_flash(_("Edit of Catalog Item \"%{name}\" was cancelled by the user") % + {:name => service_template.name}) + end + get_node_info(x_node) + replace_right_cell(:nodetype => x_node) + when "save", "add" + service_template = params[:id] != "new" ? ServiceTemplate.find_by_id(params[:id]) : ServiceTemplate.new + + # This should be changed to something like service_template.changed? and service_template.changes + # when we have a version of Rails that supports detecting changes on serialized + # fields + old_service_template_attributes = service_template.attributes.clone + service_template_set_record_vars(service_template) + + begin + service_template.save! + rescue => bang + add_flash(_("Error when adding a new Catalog Item: %{message}") % {:message => bang.message}, :error) + javascript_flash + else + AuditEvent.success(build_saved_audit_hash(old_service_template_attributes, service_template, params[:button] == "add")) + add_flash(_("Catalog Item \"%{name}\" was saved") % + {:name => service_template.name}) + replace_right_cell(:replace_trees => trees_to_replace([:sandt, :svccat, :stcat])) + end + end + end + def atomic_form_field_changed # need to check req_id in session since we are using common code for prov requests and atomic ST screens id = session[:edit][:req_id] || "new" @@ -136,31 +189,45 @@ def atomic_form_field_changed build_ae_tree(:catalog, :automate_tree) if params[:display] || params[:template_id] || params[:manager_id] if params[:st_prov_type] # build request screen for selected item type @_params[:org_controller] = "service_template" - prov_set_form_vars if need_prov_dialogs?(params[:st_prov_type]) - @record = class_service_template(params[:st_prov_type]).new - set_form_vars - @edit[:new][:st_prov_type] = params[:st_prov_type] if params[:st_prov_type] - @edit[:new][:service_type] = "atomic" - default_entry_point(@edit[:new][:st_prov_type], - @edit[:new][:service_type]) - @edit[:rec_id] = @record.try(:id) - @tabactive = @edit[:new][:current_tab_key] + if ansible_playbook? + @record = ServiceTemplate.new + if false + add_flash(_("Before adding Ansible Service, at least 1 repository, 1 playbook, 1 credential must exist in VMDB"), :error) + javascript_flash + return + end + else + prov_set_form_vars if need_prov_dialogs?(params[:st_prov_type]) + @record = class_service_template(params[:st_prov_type]).new + set_form_vars + @edit[:new][:st_prov_type] = params[:st_prov_type] if params[:st_prov_type] + @edit[:new][:service_type] = "atomic" + default_entry_point(@edit[:new][:st_prov_type], + @edit[:new][:service_type]) + @edit[:rec_id] = @record.try(:id) + @tabactive = @edit[:new][:current_tab_key] + end end render :update do |page| page << javascript_prologue - # for generic/orchestration type tabs do not show up on screen as there is only a single tab when form is initialized - # when display in catalog is checked, replace div so tabs can be redrawn - page.replace("form_div", :partial => "st_form") if params[:st_prov_type] || - (params[:display] && @edit[:new][:st_prov_type].starts_with?("generic")) - page.replace_html("basic_info_div", :partial => "form_basic_info") if params[:display] || params[:template_id] || params[:manager_id] - if params[:display] - page << "miq_tabs_show_hide('#details_tab', '#{(params[:display] == "1")}')" - end - if changed != session[:changed] - page << javascript_for_miq_button_visibility(changed) - session[:changed] = changed + if ansible_playbook? + page.replace("form_div", :partial => "st_angular_form") + page << javascript_hide("form_buttons_div") + else + # for generic/orchestration type tabs do not show up on screen as there is only a single tab when form is initialized + # when display in catalog is checked, replace div so tabs can be redrawn + page.replace("form_div", :partial => "st_form") if params[:st_prov_type] || + (params[:display] && @edit[:new][:st_prov_type].starts_with?("generic")) + page.replace_html("basic_info_div", :partial => "form_basic_info") if params[:display] || params[:template_id] || params[:manager_id] + if params[:display] + page << "miq_tabs_show_hide('#details_tab', '#{(params[:display] == "1")}')" + end + if changed != session[:changed] + page << javascript_for_miq_button_visibility(changed) + session[:changed] = changed + end + page << set_spinner_off end - page << set_spinner_off end end @@ -803,6 +870,12 @@ def ot_show private + def ansible_playbook? + prov_type = params[:st_prov_type] ? params[:st_prov_type] : @record.prov_type + prov_type == "generic_ansible_playbook" + end + helper_method :ansible_playbook? + def features [{:role => "svc_catalog_accord", :role_any => true, @@ -1859,7 +1932,7 @@ def replace_right_cell(options = {}) action_url = x_active_tree == :ot_tree ? "ot_tags_edit" : "st_tags_edit" r[:partial => "layouts/x_tagging", :locals => {:action_url => action_url}] elsif action && ["at_st_new", "st_new"].include?(action) - r[:partial => "st_form"] + r[:partial => ansible_playbook? ? "st_angular_form" : "st_form"] elsif action && ["st_catalog_new", "st_catalog_edit"].include?(action) r[:partial => "stcat_form"] elsif action == "dialog_provision" @@ -1904,7 +1977,8 @@ def replace_right_cell(options = {}) 'st_new', 'st_catalog_new', 'st_catalog_edit'].include?(action) presenter.hide(:toolbar).show(:paging_div) # incase it was hidden for summary screen, and incase there were no records on show_list - presenter.show(:form_buttons_div).hide(:pc_div_1) + presenter.hide(:pc_div_1) + ansible_playbook? ? presenter.hide(:form_buttons_div) : presenter.show(:form_buttons_div) locals = {:record_id => @edit[:rec_id]} case action when 'group_edit' diff --git a/app/views/catalog/_st_angular_form.html.haml b/app/views/catalog/_st_angular_form.html.haml new file mode 100644 index 00000000000..cf2120d6749 --- /dev/null +++ b/app/views/catalog/_st_angular_form.html.haml @@ -0,0 +1,69 @@ +- @angular_form = true + +%form.form-horizontal#form_div{"name" => "angularForm", + "ng-controller" => "catalogItemFormController", + "ng-show" => "afterGet"} + = render :partial => "layouts/flash_msg" + %div + %div + .form-group{"ng-class" => "{'has-error': angularForm.name.$invalid}"} + %label.col-md-2.control-label{"for" => "name"} + = _("Name") + .col-md-8 + %input.form-control{"type" => "text", + "id" => "name", + "name" => "name", + "ng-model" => "catalogItemModel.name", + "maxlength" => "#{MAX_NAME_LEN}", + "miqrequired" => "", + "checkchange" => "", + "auto-focus" => ""} + %span.help-block{"ng-show" => "angularForm.name.$error.miqrequired"} + = _("Required") + .form-group{"ng-class" => "{'has-error': angularForm.description.$invalid}"} + %label.col-md-2.control-label{"for" => "description"} + = _("Description") + .col-md-8 + %input.form-control{"type" => "text", + "id" => "description", + "name" => "description", + "ng-model" => "catalogItemModel.description", + "maxlength" => "#{MAX_DESC_LEN}", + "miqrequired" => "", + "checkchange" => ""} + %span.help-block{"ng-show" => "angularForm.description.$error.miqrequired"} + = _("Required") + .form-group + %label.col-md-2.control-label + = _("Display in Catalog") + .col-md-8 + %input#use_config{"bs-switch" => "", + "type" => "checkbox", + "name" => "display", + "ng-model" => "catalogItemModel.display", + "switch-on-text" => "Yes", + "switch-off-text" => "No", + "checkchange" => ""} + + .form-group{"ng-class" => "{'has-error': catalogItemModel.display}"} + %label.col-md-2.control-label{"for" => "catalog_id"} + = _('Catalog') + .col-md-8 + %select{"ng-model" => "_catalog", + "name" => "catalog_id", + "required" => "catalogItemModel.display" ? true : false, + 'ng-options' => 'catalog as catalog.name for catalog in catalogs', + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + %span.help-block{"ng-show" => "catalogItemModel.display"} + = _("Required") + + = render :partial => "layouts/angular/multi_tab_ansible_form_options", + :locals => {:record => @record, :ng_model => "catalogItemModel"} + = render :partial => "layouts/angular/x_edit_buttons_angular" + +:javascript + ManageIQ.angular.app.value('catalogItemFormId', '#{@record.id || "new"}'); + miq_bootstrap('#form_div'); + diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml new file mode 100644 index 00000000000..65d2957dcba --- /dev/null +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -0,0 +1,184 @@ +- prefix ||= 'provisioning' +.row + .col-md-12.col-lg-6 + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_repository_id.$invalid}"} + %label.col-md-2.control-label{"for" => "#{prefix}_repository_id"} + = _('Repository') + .col-md-8 + %select{"ng-model" => "_#{prefix}_repository", + "name" => "#{prefix}_repository_id", + 'ng-options' => 'repository as repository.name for repository in repositories', + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_playbook_id.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_repository_id != ''"} + %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} + = _('Playbook') + .col-md-8 + %select{"ng-model" => "_#{prefix}_playbook", + "name" => "#{prefix}_playbook_id", + 'ng-options' => "playbook as playbook.name for playbook in #{prefix}_playbooks", + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_machine_credential_id.$invalid}"} + %label.col-md-2.control-label{"for" => "#{prefix}_machine_credential_id"} + = _('Machine Credentials') + .col-md-8 + %select{"ng-model" => "_#{prefix}_machine_credential", + "name" => "#{prefix}_machine_credential_id", + 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in machine_credentials', + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + + .form-group + %label.col-md-2.control-label{"for" => "#{prefix}_network_credential_id"} + = _('Network Credentials') + .col-md-8 + %select{"ng-model" => "_#{prefix}_network_credential", + "name" => "#{prefix}_network_credential_id", + 'ng-options' => 'network_credential as network_credential.name for network_credential in network_credentials', + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + + .form-group + %label.col-md-2.control-label{"for" => "#{prefix}_cloud_credential_id"} + = _('Cloud Credentials') + .col-md-8 + %select{"ng-model" => "_#{prefix}_cloud_credential", + "name" => "#{prefix}_cloud_credential_id", + 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in cloud_credentials', + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_inventory.$invalid}"} + %label.col-md-2.control-label + = _("Inventory") + .col-md-8 + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_inventory", + :name => "#{prefix}_inventory", + :maxlength => 50, + "miqrequired" => "", + "checkchange" => ""} + %span.help-block{"ng-show" => "angularForm.#{prefix}_inventory.$error.miqrequired"} + = _("Required") + .col-md-12.col-lg-6 + .form-group + %label.col-md-2.control-label + = _("Key Value Pairs") + %table.table.table-striped.table-hover.table-condensed.table-bordered + %tbody + %tr + %td + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_key", + :name => "#{prefix}_key", + :maxlength => 50, + "placeholder" => "key", + "required" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value != '')" ? true : false, + "checkchange" => ""} + %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value != '')"} + = _("Required") + %td + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_value", + :name => "#{prefix}_value", + :maxlength => 50, + "placeholder" => "value", + "required" => "(#{ng_model}.#{prefix}_key != '' || #{ng_model}.#{prefix}_value == '')" ? true : false, + "checkchange" => ""} + %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key != '' || #{ng_model}.#{prefix}_value == '')"} + = _("Required") + + %td{:class => "action-cell", :style => "width: 15px"} + %div{:class => "btn-container"} + %button{:class => "btn btn-link", + :type => "button", + "ng-click" => "addKeyValue('#{prefix}')", + "ng-disabled" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value == '')"} + %span{:class => "fa fa-plus tag-add"} + + %tr{"ng-repeat" => "(key, key_value) in #{ng_model}.#{prefix}_variables track by $index", "ng-form" => "rowForm"} + %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} + {{key}} + %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} + %input.form-control{"type" => "text", + "name" => "key", + "ng-model" => "#{ng_model}.key", + "checkchange" => "", + "miqrequired" => ""} + %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} + {{key_value}} + %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} + %input.form-control{"type" => "text", + "name" => "key_value", + "ng-model" => "#{ng_model}.key_value", + "checkchange" => "", + "miqrequired" => ""} + + -#%td{:class => "action-cell", :style => "width: 15px"} + -# %div{:class => "btn-container"} + %td + %div{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index", :class => "pull-right"} + %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "!#{ng_model}.#{prefix}_editMode", "ng-click" => "saveKeyValue('#{prefix}', this.key)"} + =_("Save") + %button{:class => "btn btn-default", :type => "button", "ng-click" => "cancelKeyValue('#{prefix}', this.key)"} + =_("Cancel") + + %div{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)", :class => "btn-container"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "editKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %span{:class => "pficon pficon-edit"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "removeKeyValue('#{prefix}', this.key)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %span{:class => "pficon pficon-delete"} + + .form-group + %label.col-md-2.control-label + = _("Dialog") + {{#{ng_model}.#{prefix}_dialog_existing}} + .col-md-4 + %label.radio + %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} + = _("Use Existing") + %label.radio + %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "create", "ng-checked" => ("#{ng_model}.#{prefix}_dialog_existing == create")} + = _("Create New") + .col-md-4 + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_id.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} + %select{"ng-model" => "_#{prefix}_dialog", + "name" => "#{prefix}_dialog_id", + 'ng-options' => 'dialog as dialog.label for dialog in dialogs', + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_id.$error.miqrequired"} + = _("Required") + + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_name.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_dialog_existing == 'create'"} + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_dialog_name", + :name => "#{prefix}_dialog_name", + :maxlength => 50, + "miqrequired" => "", + "checkchange" => ""} + %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_name.$error.miqrequired"} + = _("Required") diff --git a/app/views/layouts/angular/_multi_tab_ansible_form_options.html.haml b/app/views/layouts/angular/_multi_tab_ansible_form_options.html.haml new file mode 100644 index 00000000000..9d8500bbcf6 --- /dev/null +++ b/app/views/layouts/angular/_multi_tab_ansible_form_options.html.haml @@ -0,0 +1,34 @@ +#options_tabs + %ul.nav.nav-tabs + = miq_tab_header('provisioning') do + %i{"error-on-tab" => "provisioning", :style => "color:#cc0000"} + = _("Provisioning") + = miq_tab_header('retirement') do + %i{"error-on-tab" => "retirement", :style => "color:#cc0000"} + = _("Retirement") + + .tab-content + = miq_tab_content('provisioning', 'default') do + .form-group + .col-md-12 + = render :partial => "layouts/angular/ansible_form_options_angular", + :locals => {:ng_show => true, + :ng_model => "#{ng_model}", + :id => record.id, + :prefix => "provisioning", + :basic_info_needed => true} + .form-group + .col-md-12{"ng-if" => "#{ng_model}" == "emsCommonModel" && "#{ng_model}.emstype == 'rhevm'"} + %span{:style => "color:black"} + = _("Used to gather Capacity & Utilization metrics.") + = miq_tab_content('retirement', 'default') do + .form-group + .col-md-12 + = render :partial => "layouts/angular/ansible_form_options_angular", + :locals => {:ng_show => true, + :ng_model => "#{ng_model}", + :id => record.id, + :prefix => "retirement"} + +:javascript + miq_tabs_init('#options_tabs'); diff --git a/config/routes.rb b/config/routes.rb index 4c8cc78a474..ad57318df13 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -259,6 +259,7 @@ :catalog => { :get => %w( + catalog_item_form_fields download_data explorer ot_edit @@ -274,6 +275,7 @@ atomic_form_field_changed atomic_st_edit automate_button_field_changed + catalog_item_edit explorer get_ae_tree_edit_key group_create From 22d1c0b2cb71d1c95d8dcaf548dc5833b2be2a65 Mon Sep 17 00:00:00 2001 From: lgalis Date: Tue, 7 Feb 2017 02:53:09 -0500 Subject: [PATCH 02/13] Update APIs and add divs for plybook and credentials input forms --- .../catalog/catalog_item_form_controller.js | 46 +++++--- app/views/catalog/_st_form.html.haml | 2 +- .../_ansible_form_options_angular.html.haml | 107 +++++++++--------- 3 files changed, 86 insertions(+), 69 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index c32a03b0227..083d0b1a72e 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -105,7 +105,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog // list of service catalogs $scope.formOptions = function() { API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function(data) { - $scope.catalogs = data.resources + $scope.catalogs = data.resources; $scope._catalog = _.find($scope.catalogs, {id: $scope.catalogItemModel.catalog_id}) }) @@ -117,31 +117,35 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog }) // list of repositories - //API.get("/api/configuration_script_sources/?expand=resources&attributes=id,name") - - API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.repositories = data.resources + API.get("/api/configuration_script_sources/?expand=resources&attributes=id,name").then(function (data) { + $scope.repositories = data.resources; $scope._retirement_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.retirement_repository_id}) $scope._provisioning_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.provisioning_repository_id}) }) // list of machine credentials + // check if the type of credentials can be specified in the API + //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.machine_credentials = data.resources + $scope.machine_credentials = data.resources; $scope._retirement_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.retirement_machine_credential_id}) $scope._provisioning_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.provisioning_machine_credential_id}) }) // list of network credentials - API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.network_credentials = data.resources + // check if the type of credentials can be specified in the API + //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") + API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + $scope.network_credentials = data.resources; $scope._retirement_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.retirement_network_credential_id}) $scope._provisioning_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.provisioning_network_credential_id}) }) // list of cloud credentials + // check if the type of credentials can be specified in the API + //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.cloud_credentials = data.resources + $scope.cloud_credentials = data.resources; $scope._retirement_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.retirement_cloud_credential_id}) $scope._provisioning_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.provisioning_cloud_credential_id}) }) @@ -149,15 +153,12 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog // get playbooks for selected repository $scope.repositoryChanged = function(prefix, id) { - //uncomment this line and remove line 153 - //var url = "/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads"; - var url = "/api/cloud_networks/" + '10000000000005' + "?attributes=cloud_subnets"; + API.get("/api/configuration_script_payload/?expand=resources&attributes=id,name").then(function(data){ + //var url = "/api/cloud_networks/" + '10000000000005' + "?attributes=cloud_subnets"; $scope.catalogItemModel[prefix + '_playbook_id'] = ''; $scope.catalogItemModel[prefix + '_repository_id'] = id; - - API.get(url).then(function(response) { - $scope[prefix + '_playbooks'] = response.cloud_subnets; + $scope[prefix + '_playbooks'] = data.resources; }) }; @@ -184,6 +185,21 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog $scope.catalogItemModel[prefix + "_value"] = ''; } + $scope.provisioning_repository_selected = function() { + return $scope.catalogItemModel.provisioning_repository_id !== ''; + } + + $scope.retirement_repository_selected = function() { + return $scope.catalogItemModel.retirement_repository_id !== ''; + } + + $scope.provisioning_playbook_selected = function() { + return $scope.catalogItemModel.provisioning_playbook_id !== ''; + } + + $scope.retirement_playbook_selected = function() { + return $scope.catalogItemModel.retirement_playbook_id !== ''; + } $scope.removeKeyValue = function(prefix, key) { delete $scope.catalogItemModel[prefix + "_variables"][key]; } diff --git a/app/views/catalog/_st_form.html.haml b/app/views/catalog/_st_form.html.haml index 7cda7c22a80..7f4723b9123 100644 --- a/app/views/catalog/_st_form.html.haml +++ b/app/views/catalog/_st_form.html.haml @@ -8,7 +8,7 @@ .form-group %label.col-md-2.control-label= _('Catalog Item Type') .col-md-8 - - array = Array(ServiceTemplate::CATALOG_ITEM_TYPES.invert).sort_by { |a| a.first.downcase } + - array = Array(@edit[:st_prov_types].invert).sort_by { |a| a.first.downcase } = select_tag('st_prov_type', options_for_select(([["<#{_('Choose')}>",nil]]) + array, nil), "data-miq_sparkle_on" => true, diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index 65d2957dcba..73c3f50b890 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -5,67 +5,68 @@ %label.col-md-2.control-label{"for" => "#{prefix}_repository_id"} = _('Repository') .col-md-8 - %select{"ng-model" => "_#{prefix}_repository", + %select{"ng-model" => "#{ng_model}.#{prefix}_repository_id", "name" => "#{prefix}_repository_id", 'ng-options' => 'repository as repository.name for repository in repositories', "required" => "", :miqrequired => true, - :checkchange => true, + 'ng_change' => "repository_changed()", 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" - .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_playbook_id.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_repository_id != ''"} - %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} - = _('Playbook') - .col-md-8 - %select{"ng-model" => "_#{prefix}_playbook", - "name" => "#{prefix}_playbook_id", - 'ng-options' => "playbook as playbook.name for playbook in #{prefix}_playbooks", - "required" => "", - :miqrequired => true, - :checkchange => true, - 'pf-select' => true} - %option{"value" => ""} - = "<#{_('Choose')}>" - - .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_machine_credential_id.$invalid}"} - %label.col-md-2.control-label{"for" => "#{prefix}_machine_credential_id"} - = _('Machine Credentials') - .col-md-8 - %select{"ng-model" => "_#{prefix}_machine_credential", - "name" => "#{prefix}_machine_credential_id", - 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in machine_credentials', - "required" => "", - :miqrequired => true, - :checkchange => true, - 'pf-select' => true} - %option{"value" => ""} - = "<#{_('Choose')}>" + #playbook_div{"ng-if" => "#{prefix}_repository_selected()"} + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_playbook_id.$invalid}"} + %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} + = _('Playbook') + .col-md-8 + %select{"ng-model" => "#{ng_model}.#{prefix}_playbook", + "name" => "#{prefix}_playbook_id", + 'ng-options' => "playbook as playbook.name for playbook in #{prefix}_playbooks", + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + #credentials_div{"ng-show" => "#{prefix}_playbook_selected()"} + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_machine_credential_id.$invalid}"} + %label.col-md-2.control-label{"for" => "#{prefix}_machine_credential_id"} + = _('Machine Credentials') + .col-md-8 + %select{"ng-model" => "#{ng_model}.#{prefix}_machine_credential", + "name" => "#{prefix}_machine_credential_id", + 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in machine_credentials', + "required" => "", + :miqrequired => true, + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" - .form-group - %label.col-md-2.control-label{"for" => "#{prefix}_network_credential_id"} - = _('Network Credentials') - .col-md-8 - %select{"ng-model" => "_#{prefix}_network_credential", - "name" => "#{prefix}_network_credential_id", - 'ng-options' => 'network_credential as network_credential.name for network_credential in network_credentials', - :checkchange => true, - 'pf-select' => true} - %option{"value" => ""} - = "<#{_('Choose')}>" + .form-group + %label.col-md-2.control-label{"for" => "#{prefix}_network_credential_id"} + = _('Network Credentials') + .col-md-8 + %select{"ng-model" => "#{ng_model}.#{prefix}_network_credential", + "name" => "#{prefix}_network_credential_id", + 'ng-options' => 'network_credential as network_credential.name for network_credential in network_credentials', + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" - .form-group - %label.col-md-2.control-label{"for" => "#{prefix}_cloud_credential_id"} - = _('Cloud Credentials') - .col-md-8 - %select{"ng-model" => "_#{prefix}_cloud_credential", - "name" => "#{prefix}_cloud_credential_id", - 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in cloud_credentials', - :checkchange => true, - 'pf-select' => true} - %option{"value" => ""} - = "<#{_('Choose')}>" + .form-group + %label.col-md-2.control-label{"for" => "#{prefix}_cloud_credential_id"} + = _('Cloud Credentials') + .col-md-8 + %select{"ng-model" => "#{ng_model}.#{prefix}_cloud_credential", + "name" => "#{prefix}_cloud_credential_id", + 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in cloud_credentials', + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_inventory.$invalid}"} %label.col-md-2.control-label @@ -121,7 +122,7 @@ %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} %input.form-control{"type" => "text", "name" => "key", - "ng-model" => "#{ng_model}.key", + "ng-model" => "key", "checkchange" => "", "miqrequired" => ""} %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} @@ -129,7 +130,7 @@ %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} %input.form-control{"type" => "text", "name" => "key_value", - "ng-model" => "#{ng_model}.key_value", + "ng-model" => "key_value", "checkchange" => "", "miqrequired" => ""} From fcc122ac123e754e9339e8faae2fd2537749f5b9 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Wed, 8 Feb 2017 13:08:57 -0500 Subject: [PATCH 03/13] Use ServiceTemplate::CATALOG_ITEM_TYPES to populate CI type drop down https://www.pivotaltracker.com/story/show/138302747 --- app/controllers/catalog_controller.rb | 17 ----------------- app/views/catalog/_st_form.html.haml | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 333d2a08ea7..9c8622a3f27 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -111,7 +111,6 @@ def atomic_st_edit @edit[:new] ||= {} @edit[:current] ||= {} @edit[:key] = "prov_edit__new" - @edit[:st_prov_types] = catalog_item_types end @edit[:new][:st_prov_type] = @record.prov_type if @record.prov_type.present? # set name and description for ServiceTemplate record @@ -127,22 +126,6 @@ def atomic_st_edit end end - def catalog_item_types - { - "amazon" => "Amazon", - "generic_ansible_playbook" => "Ansible Playbook", - "azure" => "Azure", - "generic" => "Generic", - "generic_orchestration" => "Orchestration", - "generic_ansible_tower" => "AnsibleTower", - "google" => "Google", - "microsoft" => "SCVMM", - "openstack" => "OpenStack", - "redhat" => "RHEV", - "vmware" => "VMware" - } - end - def catalog_item_edit assert_privileges("atomic_catalogitem_edit") case params[:button] diff --git a/app/views/catalog/_st_form.html.haml b/app/views/catalog/_st_form.html.haml index 7f4723b9123..7cda7c22a80 100644 --- a/app/views/catalog/_st_form.html.haml +++ b/app/views/catalog/_st_form.html.haml @@ -8,7 +8,7 @@ .form-group %label.col-md-2.control-label= _('Catalog Item Type') .col-md-8 - - array = Array(@edit[:st_prov_types].invert).sort_by { |a| a.first.downcase } + - array = Array(ServiceTemplate::CATALOG_ITEM_TYPES.invert).sort_by { |a| a.first.downcase } = select_tag('st_prov_type', options_for_select(([["<#{_('Choose')}>",nil]]) + array, nil), "data-miq_sparkle_on" => true, From 32d457332f9263a29bd424b0c4026e8c6d319bc3 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Wed, 8 Feb 2017 13:42:52 -0500 Subject: [PATCH 04/13] Fixed failure on existing spec test https://www.pivotaltracker.com/story/show/138302747 --- spec/controllers/catalog_controller_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/controllers/catalog_controller_spec.rb b/spec/controllers/catalog_controller_spec.rb index e561a8ff1d2..b4a16b8a0f4 100644 --- a/spec/controllers/catalog_controller_spec.rb +++ b/spec/controllers/catalog_controller_spec.rb @@ -68,6 +68,7 @@ context "#atomic_form_field_changed" do before :each do controller.instance_variable_set(:@sb, {}) + controller.instance_variable_set(:@record, ServiceTemplate.new(:prov_type => "generic")) edit = { :key => "prov_edit__new", :rec_id => 1, From c4cf12aedd869de36c69a927e178cd5ba9f3e9a4 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 9 Feb 2017 16:36:02 -0500 Subject: [PATCH 05/13] Further changes to handle required fields on form Also fixed adding/editing of key/value pairs fields in the form, changed label from "Key Value Pairs" to "Variables and Default values" https://www.pivotaltracker.com/story/show/138302747 --- .../catalog/catalog_item_form_controller.js | 46 +++--- app/views/catalog/_st_angular_form.html.haml | 2 +- .../_ansible_form_options_angular.html.haml | 145 +++++++++--------- 3 files changed, 98 insertions(+), 95 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 083d0b1a72e..78ba1d25e8c 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -6,6 +6,8 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog display: false, prov_type: '', catalog_id: '', + key: '', + key_value: '', provisioning_repository_id: '', provisioning_playbook_id: '', provisioning_machine_credential_id: '', @@ -31,9 +33,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog retirement_key: '', retirement_value: '', retirement_variables: {"r_var1": "r_val1", "r_var2": "r_val2"}, - retirement_editMode: false, - key: '', - key_value: '', + retirement_editMode: false }; $scope.formId = catalogItemFormId; $scope.afterGet = false; @@ -153,25 +153,25 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog // get playbooks for selected repository $scope.repositoryChanged = function(prefix, id) { - - API.get("/api/configuration_script_payload/?expand=resources&attributes=id,name").then(function(data){ - //var url = "/api/cloud_networks/" + '10000000000005' + "?attributes=cloud_subnets"; - $scope.catalogItemModel[prefix + '_playbook_id'] = ''; - $scope.catalogItemModel[prefix + '_repository_id'] = id; - $scope[prefix + '_playbooks'] = data.resources; + API.get("/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads").then(function(data){ + $scope.catalogItemModel[prefix + '_playbook_id'] = ''; + $scope.catalogItemModel[prefix + '_repository_id'] = id; + $scope[prefix + '_playbooks'] = data.configuration_script_payloads; }) }; $scope.$watch('_provisioning_repository', function(value) { if (value) { $scope.repositoryChanged("provisioning", value.id) - } + } else + $scope.catalogItemModel['provisioning_repository_id'] = '' }); $scope.$watch('_retirement_repository', function(value) { if (value) { $scope.repositoryChanged("retirement", value.id) - } + } else + $scope.catalogItemModel['retirement_repository_id'] = '' }); $scope.$watch('catalogItemModel.display', function(value) { @@ -193,13 +193,6 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog return $scope.catalogItemModel.retirement_repository_id !== ''; } - $scope.provisioning_playbook_selected = function() { - return $scope.catalogItemModel.provisioning_playbook_id !== ''; - } - - $scope.retirement_playbook_selected = function() { - return $scope.catalogItemModel.retirement_playbook_id !== ''; - } $scope.removeKeyValue = function(prefix, key) { delete $scope.catalogItemModel[prefix + "_variables"][key]; } @@ -219,12 +212,23 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key] = $scope.catalogItemModel.original_key_value; } - $scope.saveKeyValue = function(prefix, key, key_value, index) { + $scope.saveKeyValue = function(prefix, index) { $scope.catalogItemModel[prefix + "_editMode"] = false; $scope.catalogItemModel.s_index = ''; - delete $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key]; - $scope.catalogItemModel[prefix + "_variables"][key] = key_value; + // delete key if key name was edited, and a add new key to hash with new name + if ($scope.catalogItemModel.original_key !== $scope.catalogItemModel.key) + delete $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key]; + + $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.key] = $scope.catalogItemModel.key_value; } + $scope.toggleDialogSelection = function(prefix, selected_value) { + $scope.catalogItemModel[prefix + "_dialog_existing"] = selected_value + }; + + $scope.repositoryRequired = function(prefix) { + return prefix == "provisioning"; + }; + init(); }]); diff --git a/app/views/catalog/_st_angular_form.html.haml b/app/views/catalog/_st_angular_form.html.haml index cf2120d6749..b4cb9ddce64 100644 --- a/app/views/catalog/_st_angular_form.html.haml +++ b/app/views/catalog/_st_angular_form.html.haml @@ -51,7 +51,7 @@ .col-md-8 %select{"ng-model" => "_catalog", "name" => "catalog_id", - "required" => "catalogItemModel.display" ? true : false, + "ng-required" => "catalogItemModel.display", 'ng-options' => 'catalog as catalog.name for catalog in catalogs', 'pf-select' => true} %option{"value" => ""} diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index 73c3f50b890..9622d8c1cec 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -5,11 +5,10 @@ %label.col-md-2.control-label{"for" => "#{prefix}_repository_id"} = _('Repository') .col-md-8 - %select{"ng-model" => "#{ng_model}.#{prefix}_repository_id", + %select{"ng-model" => "_#{prefix}_repository", "name" => "#{prefix}_repository_id", 'ng-options' => 'repository as repository.name for repository in repositories', - "required" => "", - :miqrequired => true, + "ng-required" => "repositoryRequired('#{prefix}')", 'ng_change' => "repository_changed()", 'pf-select' => true} %option{"value" => ""} @@ -20,7 +19,7 @@ %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} = _('Playbook') .col-md-8 - %select{"ng-model" => "#{ng_model}.#{prefix}_playbook", + %select{"ng-model" => "_#{prefix}_playbook", "name" => "#{prefix}_playbook_id", 'ng-options' => "playbook as playbook.name for playbook in #{prefix}_playbooks", "required" => "", @@ -29,12 +28,13 @@ 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" - #credentials_div{"ng-show" => "#{prefix}_playbook_selected()"} + + #credentials_div{"ng-show" => "#{prefix}_repository_selected()"} .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_machine_credential_id.$invalid}"} %label.col-md-2.control-label{"for" => "#{prefix}_machine_credential_id"} = _('Machine Credentials') .col-md-8 - %select{"ng-model" => "#{ng_model}.#{prefix}_machine_credential", + %select{"ng-model" => "_#{prefix}_machine_credential", "name" => "#{prefix}_machine_credential_id", 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in machine_credentials', "required" => "", @@ -48,7 +48,7 @@ %label.col-md-2.control-label{"for" => "#{prefix}_network_credential_id"} = _('Network Credentials') .col-md-8 - %select{"ng-model" => "#{ng_model}.#{prefix}_network_credential", + %select{"ng-model" => "_#{prefix}_network_credential", "name" => "#{prefix}_network_credential_id", 'ng-options' => 'network_credential as network_credential.name for network_credential in network_credentials', :checkchange => true, @@ -60,7 +60,7 @@ %label.col-md-2.control-label{"for" => "#{prefix}_cloud_credential_id"} = _('Cloud Credentials') .col-md-8 - %select{"ng-model" => "#{ng_model}.#{prefix}_cloud_credential", + %select{"ng-model" => "_#{prefix}_cloud_credential", "name" => "#{prefix}_cloud_credential_id", 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in cloud_credentials', :checkchange => true, @@ -82,72 +82,70 @@ = _("Required") .col-md-12.col-lg-6 .form-group - %label.col-md-2.control-label - = _("Key Value Pairs") %table.table.table-striped.table-hover.table-condensed.table-bordered %tbody - %tr - %td - %input.form-control{:type => "text", - 'ng-model' => "#{ng_model}.#{prefix}_key", - :name => "#{prefix}_key", - :maxlength => 50, - "placeholder" => "key", - "required" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value != '')" ? true : false, - "checkchange" => ""} - %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value != '')"} - = _("Required") - %td - %input.form-control{:type => "text", - 'ng-model' => "#{ng_model}.#{prefix}_value", - :name => "#{prefix}_value", - :maxlength => 50, - "placeholder" => "value", - "required" => "(#{ng_model}.#{prefix}_key != '' || #{ng_model}.#{prefix}_value == '')" ? true : false, - "checkchange" => ""} - %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key != '' || #{ng_model}.#{prefix}_value == '')"} - = _("Required") + %thead + %tr + %th{:colspan => "3", :align => "left"} + = _("Variables and Default values") + %tr + %td + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_key", + :name => "#{prefix}_key", + "placeholder" => "Variable", + "checkchange" => ""} + %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key === '' && #{ng_model}.#{prefix}_value !== '')"} + = _("Required") + %td + %input.form-control{:type => "text", + 'ng-model' => "#{ng_model}.#{prefix}_value", + :name => "#{prefix}_value", + "placeholder" => "Default value", + "checkchange" => ""} + %span.help-block{"ng-show" => "(#{ng_model}.#{prefix}_key !== '' && #{ng_model}.#{prefix}_value === '')"} + = _("Required") - %td{:class => "action-cell", :style => "width: 15px"} - %div{:class => "btn-container"} - %button{:class => "btn btn-link", - :type => "button", - "ng-click" => "addKeyValue('#{prefix}')", - "ng-disabled" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value == '')"} - %span{:class => "fa fa-plus tag-add"} + %td + %div{:class => "btn-container"} + %button{:class => "btn btn-link", + :type => "button", + "ng-click" => "addKeyValue('#{prefix}')", + "ng-disabled" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value == '')"} + %span{:class => "fa fa-plus tag-add"} - %tr{"ng-repeat" => "(key, key_value) in #{ng_model}.#{prefix}_variables track by $index", "ng-form" => "rowForm"} - %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} - {{key}} - %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} - %input.form-control{"type" => "text", - "name" => "key", - "ng-model" => "key", - "checkchange" => "", - "miqrequired" => ""} - %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} - {{key_value}} - %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} - %input.form-control{"type" => "text", - "name" => "key_value", - "ng-model" => "key_value", - "checkchange" => "", - "miqrequired" => ""} + %tr{"ng-repeat" => "(key, key_value) in #{ng_model}.#{prefix}_variables track by $index", "ng-form" => "rowForm"} + %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} + {{key}} + %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} + %input.form-control{:type => "text", + :name => "key", + 'ng-model' => "#{ng_model}.key", + "ng-change" => "", + "miqrequired" => ""} + %td{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)"} + {{key_value}} + %td{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} + %input.form-control{:type => "text", + :name => "key_value", + 'ng-model' => "#{ng_model}.key_value", + "ng-change" => "", + "miqrequired" => ""} - -#%td{:class => "action-cell", :style => "width: 15px"} - -# %div{:class => "btn-container"} - %td - %div{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index", :class => "pull-right"} - %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "!#{ng_model}.#{prefix}_editMode", "ng-click" => "saveKeyValue('#{prefix}', this.key)"} - =_("Save") - %button{:class => "btn btn-default", :type => "button", "ng-click" => "cancelKeyValue('#{prefix}', this.key)"} - =_("Cancel") + -#%td{:class => "action-cell", :style => "width: 15px"} + -# %div{:class => "btn-container"} + %td + %div{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} + %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "(#{ng_model}.key === '' || #{ng_model}.key_value === '')", "ng-click" => "saveKeyValue('#{prefix}', $index)"} + =_("Save") + %button{:class => "btn btn-default", :type => "button", "ng-click" => "cancelKeyValue('#{prefix}', this.key, this.key_value, $index)"} + =_("Cancel") - %div{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)", :class => "btn-container"} - %button{:class => "btn btn-link", :type => "button", "ng-click" => "editKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} - %span{:class => "pficon pficon-edit"} - %button{:class => "btn btn-link", :type => "button", "ng-click" => "removeKeyValue('#{prefix}', this.key)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} - %span{:class => "pficon pficon-delete"} + %div{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)", :class => "btn-container"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "editKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %span{:class => "pficon pficon-edit"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "removeKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %span{:class => "pficon pficon-delete"} .form-group %label.col-md-2.control-label @@ -155,17 +153,17 @@ {{#{ng_model}.#{prefix}_dialog_existing}} .col-md-4 %label.radio - %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} + %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-click" => "toggleDialogSelection('#{prefix}', 'existing')", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} = _("Use Existing") %label.radio - %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "create", "ng-checked" => ("#{ng_model}.#{prefix}_dialog_existing == create")} + %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "create", "ng-click" => "toggleDialogSelection('#{prefix}', 'create')", "ng-checked" => ("#{ng_model}.#{prefix}_dialog_existing == 'create'")} = _("Create New") .col-md-4 - .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_id.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_id.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} %select{"ng-model" => "_#{prefix}_dialog", "name" => "#{prefix}_dialog_id", 'ng-options' => 'dialog as dialog.label for dialog in dialogs', - "required" => "", + "ng-required" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'", :miqrequired => true, :checkchange => true, 'pf-select' => true} @@ -174,11 +172,12 @@ %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_id.$error.miqrequired"} = _("Required") - .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_name.$invalid}", "ng-show" => "#{ng_model}.#{prefix}_dialog_existing == 'create'"} + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_name.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'create'"} %input.form-control{:type => "text", 'ng-model' => "#{ng_model}.#{prefix}_dialog_name", :name => "#{prefix}_dialog_name", :maxlength => 50, + "ng-required" => "#{ng_model}.#{prefix}_dialog_existing == 'create'", "miqrequired" => "", "checkchange" => ""} %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_name.$error.miqrequired"} From 0c581b7f7a9b985db16eb527aa0299e3b8599a80 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 9 Feb 2017 17:25:53 -0500 Subject: [PATCH 06/13] renamed function name 'repositoryRequired' to 'fieldsRequired' Made changes to mark fields on Provisioning tab as required fields, fields on Retirement tab are not required for now. https://www.pivotaltracker.com/story/show/138302747 --- .../catalog/catalog_item_form_controller.js | 2 +- .../angular/_ansible_form_options_angular.html.haml | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 78ba1d25e8c..59b15f9516e 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -226,7 +226,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog $scope.catalogItemModel[prefix + "_dialog_existing"] = selected_value }; - $scope.repositoryRequired = function(prefix) { + $scope.fieldsRequired = function(prefix) { return prefix == "provisioning"; }; diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index 9622d8c1cec..e74617971cb 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -8,7 +8,7 @@ %select{"ng-model" => "_#{prefix}_repository", "name" => "#{prefix}_repository_id", 'ng-options' => 'repository as repository.name for repository in repositories', - "ng-required" => "repositoryRequired('#{prefix}')", + "ng-required" => "fieldsRequired('#{prefix}')", 'ng_change' => "repository_changed()", 'pf-select' => true} %option{"value" => ""} @@ -163,13 +163,12 @@ %select{"ng-model" => "_#{prefix}_dialog", "name" => "#{prefix}_dialog_id", 'ng-options' => 'dialog as dialog.label for dialog in dialogs', - "ng-required" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'", - :miqrequired => true, + "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'existing'", :checkchange => true, 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" - %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_id.$error.miqrequired"} + %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_id.$error.$invalid"} = _("Required") .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_name.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'create'"} @@ -177,8 +176,7 @@ 'ng-model' => "#{ng_model}.#{prefix}_dialog_name", :name => "#{prefix}_dialog_name", :maxlength => 50, - "ng-required" => "#{ng_model}.#{prefix}_dialog_existing == 'create'", - "miqrequired" => "", + "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'create'", "checkchange" => ""} - %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_name.$error.miqrequired"} + %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_name.$error.$invalid"} = _("Required") From 0b392146ca6767bd1e6fa7b453460949fbbec3b6 Mon Sep 17 00:00:00 2001 From: lgalis Date: Fri, 10 Feb 2017 02:03:43 -0500 Subject: [PATCH 07/13] Use controllerAs syntax in the angular form --- .../catalog/catalog_item_form_controller.js | 198 ++++++++++-------- app/views/catalog/_st_angular_form.html.haml | 20 +- .../_ansible_form_options_angular.html.haml | 46 ++-- 3 files changed, 144 insertions(+), 120 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 59b15f9516e..42f90876d54 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -1,6 +1,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalogItemFormId', 'miqService', 'postService', 'API', 'catalogItemDataFactory', function($scope, catalogItemFormId, miqService, postService, API, catalogItemDataFactory) { + var vm = this; var init = function() { - $scope.catalogItemModel = { + vm.catalogItemModel = { name: '', description: '', display: false, @@ -35,38 +36,38 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog retirement_variables: {"r_var1": "r_val1", "r_var2": "r_val2"}, retirement_editMode: false }; - $scope.formId = catalogItemFormId; - $scope.afterGet = false; - $scope.modelCopy = angular.copy( $scope.catalogItemModel ); - $scope.model = "catalogItemModel"; + vm.formId = catalogItemFormId; + vm.afterGet = false; + vm.modelCopy = angular.copy( vm.catalogItemModel ); + vm.model = "catalogItemModel"; ManageIQ.angular.scope = $scope; if (catalogItemFormId == 'new') { - $scope.newRecord = true; - $scope.catalogItemModel.name = ''; - $scope.catalogItemModel.description = ''; - $scope.catalogItemModel.catalog_id = ''; - $scope.catalogItemModel.display = false; - $scope.catalogItemModel.provisioning_dialog_id = ''; - $scope.catalogItemModel.retirement_dialog_id = ''; - $scope.catalogItemModel.prov_type = 'generic_ansible_playbook'; - $scope.formOptions(); - $scope.afterGet = true; - $scope.modelCopy = angular.copy( $scope.catalogItemModel ); + vm.newRecord = true; + vm.catalogItemModel.name = ''; + vm.catalogItemModel.description = ''; + vm.catalogItemModel.catalog_id = ''; + vm.catalogItemModel.display = false; + vm.catalogItemModel.provisioning_dialog_id = ''; + vm.catalogItemModel.retirement_dialog_id = ''; + vm.catalogItemModel.prov_type = 'generic_ansible_playbook'; + vm.formOptions(); + vm.afterGet = true; + vm.modelCopy = angular.copy( vm.catalogItemModel ); } else { - $scope.newRecord = false; + vm.newRecord = false; catalogItemDataFactory.getCatalogItemData(catalogItemFormId).then(function (catalogItemData) { - $scope.newRecord = false; - $scope.catalogItemModel.name = catalogItemData.name; - $scope.catalogItemModel.description = catalogItemData.description; - $scope.catalogItemModel.display = catalogItemData.display; - $scope.catalogItemModel.catalog_id = catalogItemData.service_template_catalog_id; - $scope.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id;; - $scope.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id;; - $scope.formOptions(); - $scope.afterGet = true; - $scope.modelCopy = angular.copy($scope.catalogItemModel); + vm.newRecord = false; + vm.catalogItemModel.name = catalogItemData.name; + vm.catalogItemModel.description = catalogItemData.description; + vm.catalogItemModel.display = catalogItemData.display; + vm.catalogItemModel.catalog_id = catalogItemData.service_template_catalog_id; + vm.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id;; + vm.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id;; + vm.formOptions(); + vm.afterGet = true; + vm.modelCopy = angular.copy(vm.catalogItemModel); }); } }; @@ -103,132 +104,153 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog }; // list of service catalogs - $scope.formOptions = function() { + vm.formOptions = function() { API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function(data) { - $scope.catalogs = data.resources; - $scope._catalog = _.find($scope.catalogs, {id: $scope.catalogItemModel.catalog_id}) + vm.catalogs = data.resources; + vm._catalog = _.find(vm.catalogs, {id: vm.catalogItemModel.catalog_id}) }) // list of service dailaogs API.get("/api/service_dialogs/?expand=resources&attributes=id,label").then(function (data) { - $scope.dialogs = data.resources - $scope._retirement_dialog = _.find($scope.dialogs, {id: $scope.catalogItemModel.retirement_dialog_id}) - $scope._provisioning_dialog = _.find($scope.dialogs, {id: $scope.catalogItemModel.provisioning_dialog_id}) + vm.dialogs = data.resources + vm._retirement_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.retirement_dialog_id}) + vm._provisioning_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.provisioning_dialog_id}) }) // list of repositories API.get("/api/configuration_script_sources/?expand=resources&attributes=id,name").then(function (data) { - $scope.repositories = data.resources; - $scope._retirement_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.retirement_repository_id}) - $scope._provisioning_repository = _.find($scope.repositories, {id: $scope.catalogItemModel.provisioning_repository_id}) + vm.repositories = data.resources; + vm._retirement_repository = _.find(vm.repositories, {id: vm.catalogItemModel.retirement_repository_id}) + vm._provisioning_repository = _.find(vm.repositories, {id: vm.catalogItemModel.provisioning_repository_id}) }) // list of machine credentials // check if the type of credentials can be specified in the API //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.machine_credentials = data.resources; - $scope._retirement_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.retirement_machine_credential_id}) - $scope._provisioning_machine_credential = _.find($scope.machine_credentials, {id: $scope.catalogItemModel.provisioning_machine_credential_id}) + vm.machine_credentials = data.resources; + vm._retirement_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.retirement_machine_credential_id}) + vm._provisioning_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.provisioning_machine_credential_id}) }) // list of network credentials // check if the type of credentials can be specified in the API //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.network_credentials = data.resources; - $scope._retirement_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.retirement_network_credential_id}) - $scope._provisioning_network_credential = _.find($scope.network_credentials, {id: $scope.catalogItemModel.provisioning_network_credential_id}) + vm.network_credentials = data.resources; + vm._retirement_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.retirement_network_credential_id}) + vm._provisioning_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.provisioning_network_credential_id}) }) // list of cloud credentials // check if the type of credentials can be specified in the API //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - $scope.cloud_credentials = data.resources; - $scope._retirement_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.retirement_cloud_credential_id}) - $scope._provisioning_cloud_credential = _.find($scope.cloud_credentials, {id: $scope.catalogItemModel.provisioning_cloud_credential_id}) + vm.cloud_credentials = data.resources; + vm._retirement_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.retirement_cloud_credential_id}) + vm._provisioning_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.provisioning_cloud_credential_id}) }) }; // get playbooks for selected repository - $scope.repositoryChanged = function(prefix, id) { + vm.repositoryChanged = function(prefix, id) { API.get("/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads").then(function(data){ - $scope.catalogItemModel[prefix + '_playbook_id'] = ''; - $scope.catalogItemModel[prefix + '_repository_id'] = id; - $scope[prefix + '_playbooks'] = data.configuration_script_payloads; + vm.catalogItemModel[prefix + '_playbook_id'] = ''; + vm.catalogItemModel[prefix + '_repository_id'] = id; + vm[prefix + '_playbooks'] = data.configuration_script_payloads; }) }; - $scope.$watch('_provisioning_repository', function(value) { + $scope.$watch('vm._provisioning_repository', function(value) { if (value) { - $scope.repositoryChanged("provisioning", value.id) + vm.repositoryChanged("provisioning", value.id) } else - $scope.catalogItemModel['provisioning_repository_id'] = '' + vm.catalogItemModel['provisioning_repository_id'] = '' }); - $scope.$watch('_retirement_repository', function(value) { + $scope.$watch('vm._retirement_repository', function(value) { if (value) { - $scope.repositoryChanged("retirement", value.id) + vm.repositoryChanged("retirement", value.id) } else - $scope.catalogItemModel['retirement_repository_id'] = '' + vm.catalogItemModel['retirement_repository_id'] = '' }); - $scope.$watch('catalogItemModel.display', function(value) { - $scope.catalogItemModel.display = value; - return $scope.catalogItemModel.display; + $scope.$watch('vm.catalogItemModel.display', function(value) { + vm.catalogItemModel.display = value; + return vm.catalogItemModel.display; }) - $scope.addKeyValue = function(prefix) { - $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel[prefix + "_key"]] = $scope.catalogItemModel[prefix + "_value"] - $scope.catalogItemModel[prefix + "_key"] = ''; - $scope.catalogItemModel[prefix + "_value"] = ''; + vm.addKeyValue = function(prefix) { + vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel[prefix + "_key"]] = vm.catalogItemModel[prefix + "_value"] + vm.catalogItemModel[prefix + "_key"] = ''; + vm.catalogItemModel[prefix + "_value"] = ''; } - $scope.provisioning_repository_selected = function() { - return $scope.catalogItemModel.provisioning_repository_id !== ''; + vm.provisioning_repository_selected = function() { + return vm.catalogItemModel.provisioning_repository_id !== ''; } - $scope.retirement_repository_selected = function() { - return $scope.catalogItemModel.retirement_repository_id !== ''; + vm.retirement_repository_selected = function() { + return vm.catalogItemModel.retirement_repository_id !== ''; } - $scope.removeKeyValue = function(prefix, key) { - delete $scope.catalogItemModel[prefix + "_variables"][key]; + vm.removeKeyValue = function(prefix, key) { + delete vm.catalogItemModel[prefix + "_variables"][key]; } - $scope.editKeyValue = function(prefix, key, key_value, index) { - $scope.catalogItemModel[prefix + "_editMode"] = true; - $scope.catalogItemModel.s_index = index; - $scope.catalogItemModel.key = key; - $scope.catalogItemModel.key_value = key_value; - $scope.catalogItemModel.original_key = key; - $scope.catalogItemModel.original_key_value = key_value; + vm.editKeyValue = function(prefix, key, key_value, index) { + vm.catalogItemModel[prefix + "_editMode"] = true; + vm.catalogItemModel.s_index = index; + vm.catalogItemModel.key = key; + vm.catalogItemModel.key_value = key_value; + vm.catalogItemModel.original_key = key; + vm.catalogItemModel.original_key_value = key_value; } - $scope.cancelKeyValue = function(prefix, key, key_value, index) { - $scope.catalogItemModel[prefix + "_editMode"] = false; - $scope.catalogItemModel.s_index = ''; - $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key] = $scope.catalogItemModel.original_key_value; + vm.cancelKeyValue = function(prefix, key, key_value, index) { + vm.catalogItemModel[prefix + "_editMode"] = false; + vm.catalogItemModel.s_index = ''; + vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel.original_key] = vm.catalogItemModel.original_key_value; } - $scope.saveKeyValue = function(prefix, index) { - $scope.catalogItemModel[prefix + "_editMode"] = false; - $scope.catalogItemModel.s_index = ''; + vm.saveKeyValue = function(prefix, index) { + vm.catalogItemModel[prefix + "_editMode"] = false; + vm.catalogItemModel.s_index = ''; // delete key if key name was edited, and a add new key to hash with new name - if ($scope.catalogItemModel.original_key !== $scope.catalogItemModel.key) - delete $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.original_key]; + if (vm.catalogItemModel.original_key !== vm.catalogItemModel.key) + delete vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel.original_key]; - $scope.catalogItemModel[prefix + "_variables"][$scope.catalogItemModel.key] = $scope.catalogItemModel.key_value; + vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel.key] = vm.catalogItemModel.key_value; } - $scope.toggleDialogSelection = function(prefix, selected_value) { - $scope.catalogItemModel[prefix + "_dialog_existing"] = selected_value + vm.toggleDialogSelection = function(prefix, selected_value) { + vm.catalogItemModel[prefix + "_dialog_existing"] = selected_value }; - $scope.fieldsRequired = function(prefix) { + vm.fieldsRequired = function(prefix) { return prefix == "provisioning"; }; + $scope.cancelClicked = function() { + catalogItemEditButtonClicked('cancel'); + $scope.angularForm.$setPristine(true); + }; + + $scope.resetClicked = function() { + vm.catalogItemModel = angular.copy( vm.modelCopy ); + $scope.angularForm.$setUntouched(true); + $scope.angularForm.$setPristine(true); + miqService.miqFlash("warn", __("All changes have been reset")); + }; + + $scope.saveClicked = function() { + catalogItemEditButtonClicked('save', true); + $scope.angularForm.$setPristine(true); + }; + + $scope.addClicked = function() { + $scope.saveClicked(); + }; + init(); }]); diff --git a/app/views/catalog/_st_angular_form.html.haml b/app/views/catalog/_st_angular_form.html.haml index b4cb9ddce64..a903a18988d 100644 --- a/app/views/catalog/_st_angular_form.html.haml +++ b/app/views/catalog/_st_angular_form.html.haml @@ -1,8 +1,10 @@ - @angular_form = true %form.form-horizontal#form_div{"name" => "angularForm", - "ng-controller" => "catalogItemFormController", - "ng-show" => "afterGet"} + "ng-controller" => "catalogItemFormController as vm", + "miq-form" => 'true', + "ng-show" => "vm.afterGet", + "model-copy" => 'vm.modelCopy'} = render :partial => "layouts/flash_msg" %div %div @@ -13,7 +15,7 @@ %input.form-control{"type" => "text", "id" => "name", "name" => "name", - "ng-model" => "catalogItemModel.name", + "ng-model" => "vm.catalogItemModel.name", "maxlength" => "#{MAX_NAME_LEN}", "miqrequired" => "", "checkchange" => "", @@ -27,7 +29,7 @@ %input.form-control{"type" => "text", "id" => "description", "name" => "description", - "ng-model" => "catalogItemModel.description", + "ng-model" => "vm.catalogItemModel.description", "maxlength" => "#{MAX_DESC_LEN}", "miqrequired" => "", "checkchange" => ""} @@ -40,18 +42,18 @@ %input#use_config{"bs-switch" => "", "type" => "checkbox", "name" => "display", - "ng-model" => "catalogItemModel.display", + "ng-model" => "vm.catalogItemModel.display", "switch-on-text" => "Yes", "switch-off-text" => "No", "checkchange" => ""} - .form-group{"ng-class" => "{'has-error': catalogItemModel.display}"} + .form-group{"ng-class" => "{'has-error': vm.catalogItemModel.display}"} %label.col-md-2.control-label{"for" => "catalog_id"} = _('Catalog') .col-md-8 - %select{"ng-model" => "_catalog", + %select{"ng-model" => "vm._catalog", "name" => "catalog_id", - "ng-required" => "catalogItemModel.display", + "ng-required" => "vm.catalogItemModel.display", 'ng-options' => 'catalog as catalog.name for catalog in catalogs', 'pf-select' => true} %option{"value" => ""} @@ -60,7 +62,7 @@ = _("Required") = render :partial => "layouts/angular/multi_tab_ansible_form_options", - :locals => {:record => @record, :ng_model => "catalogItemModel"} + :locals => {:record => @record, :ng_model => "vm.catalogItemModel"} = render :partial => "layouts/angular/x_edit_buttons_angular" :javascript diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index e74617971cb..f973d217797 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -2,26 +2,26 @@ .row .col-md-12.col-lg-6 .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_repository_id.$invalid}"} - %label.col-md-2.control-label{"for" => "#{prefix}_repository_id"} + %label.col-md-2.control-label{"for" => "vm.#{prefix}_repository_id"} = _('Repository') .col-md-8 - %select{"ng-model" => "_#{prefix}_repository", + %select{"ng-model" => "vm._#{prefix}_repository", "name" => "#{prefix}_repository_id", - 'ng-options' => 'repository as repository.name for repository in repositories', - "ng-required" => "fieldsRequired('#{prefix}')", - 'ng_change' => "repository_changed()", + 'ng-options' => 'repository as repository.name for repository in vm.repositories', + "ng-required" => "vm.fieldsRequired('#{prefix}')", + 'ng_change' => "vm.repository_changed()", 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" - #playbook_div{"ng-if" => "#{prefix}_repository_selected()"} + #playbook_div{"ng-if" => "vm.#{prefix}_repository_selected()"} .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_playbook_id.$invalid}"} - %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} + %label.col-md-2.control-label{"for" => "vm.#{prefix}_playbook_id"} = _('Playbook') .col-md-8 - %select{"ng-model" => "_#{prefix}_playbook", + %select{"ng-model" => "vm._#{prefix}_playbook", "name" => "#{prefix}_playbook_id", - 'ng-options' => "playbook as playbook.name for playbook in #{prefix}_playbooks", + 'ng-options' => "playbook as playbook.name for playbook in vm.#{prefix}_playbooks", "required" => "", :miqrequired => true, :checkchange => true, @@ -29,14 +29,14 @@ %option{"value" => ""} = "<#{_('Choose')}>" - #credentials_div{"ng-show" => "#{prefix}_repository_selected()"} + #credentials_div{"ng-show" => "vm.#{prefix}_repository_selected()"} .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_machine_credential_id.$invalid}"} %label.col-md-2.control-label{"for" => "#{prefix}_machine_credential_id"} = _('Machine Credentials') .col-md-8 - %select{"ng-model" => "_#{prefix}_machine_credential", + %select{"ng-model" => "vm._#{prefix}_machine_credential", "name" => "#{prefix}_machine_credential_id", - 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in machine_credentials', + 'ng-options' => 'machine_credential as machine_credential.name for machine_credential in vm.machine_credentials', "required" => "", :miqrequired => true, :checkchange => true, @@ -45,24 +45,24 @@ = "<#{_('Choose')}>" .form-group - %label.col-md-2.control-label{"for" => "#{prefix}_network_credential_id"} + %label.col-md-2.control-label{"for" => "vm.#{prefix}_network_credential_id"} = _('Network Credentials') .col-md-8 - %select{"ng-model" => "_#{prefix}_network_credential", + %select{"ng-model" => "vm._#{prefix}_network_credential", "name" => "#{prefix}_network_credential_id", - 'ng-options' => 'network_credential as network_credential.name for network_credential in network_credentials', + 'ng-options' => 'network_credential as network_credential.name for network_credential in vm.network_credentials', :checkchange => true, 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" .form-group - %label.col-md-2.control-label{"for" => "#{prefix}_cloud_credential_id"} + %label.col-md-2.control-label{"for" => "vm.#{prefix}_cloud_credential_id"} = _('Cloud Credentials') .col-md-8 - %select{"ng-model" => "_#{prefix}_cloud_credential", + %select{"ng-model" => "vm._#{prefix}_cloud_credential", "name" => "#{prefix}_cloud_credential_id", - 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in cloud_credentials', + 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in vm.cloud_credentials', :checkchange => true, 'pf-select' => true} %option{"value" => ""} @@ -73,7 +73,7 @@ = _("Inventory") .col-md-8 %input.form-control{:type => "text", - 'ng-model' => "#{ng_model}.#{prefix}_inventory", + 'ng-model' => "vm.#{ng_model}.#{prefix}_inventory", :name => "#{prefix}_inventory", :maxlength => 50, "miqrequired" => "", @@ -153,14 +153,14 @@ {{#{ng_model}.#{prefix}_dialog_existing}} .col-md-4 %label.radio - %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-click" => "toggleDialogSelection('#{prefix}', 'existing')", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} + %input{"ng-model" => "vm.#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-click" => "vm.toggleDialogSelection('#{prefix}', 'existing')", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} = _("Use Existing") %label.radio - %input{"ng-model" => "#{prefix}_dialog_existing", :type => "radio", :value => "create", "ng-click" => "toggleDialogSelection('#{prefix}', 'create')", "ng-checked" => ("#{ng_model}.#{prefix}_dialog_existing == 'create'")} + %input{"ng-model" => "vm.#{prefix}_dialog_existing", :type => "radio", :value => "create", "ng-click" => "vm.toggleDialogSelection('#{prefix}', 'create')", "ng-checked" => ("#{ng_model}.#{prefix}_dialog_existing == 'create'")} = _("Create New") .col-md-4 .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_id.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} - %select{"ng-model" => "_#{prefix}_dialog", + %select{"ng-model" => "vm._#{prefix}_dialog", "name" => "#{prefix}_dialog_id", 'ng-options' => 'dialog as dialog.label for dialog in dialogs', "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'existing'", @@ -174,7 +174,7 @@ .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_name.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'create'"} %input.form-control{:type => "text", 'ng-model' => "#{ng_model}.#{prefix}_dialog_name", - :name => "#{prefix}_dialog_name", + :name => "vm.#{prefix}_dialog_name", :maxlength => 50, "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'create'", "checkchange" => ""} From aaa53152f7e55aa9ae2f37a5fe57c229bf00382c Mon Sep 17 00:00:00 2001 From: lgalis Date: Fri, 10 Feb 2017 08:46:49 -0500 Subject: [PATCH 08/13] controllerAs changes - fix for edit/update key values and lists --- .../catalog/catalog_item_form_controller.js | 4 ++-- app/views/catalog/_st_angular_form.html.haml | 2 +- .../_ansible_form_options_angular.html.haml | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 42f90876d54..153e136860b 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -44,7 +44,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog ManageIQ.angular.scope = $scope; if (catalogItemFormId == 'new') { - vm.newRecord = true; + $scope.newRecord = true; vm.catalogItemModel.name = ''; vm.catalogItemModel.description = ''; vm.catalogItemModel.catalog_id = ''; @@ -58,7 +58,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog } else { vm.newRecord = false; catalogItemDataFactory.getCatalogItemData(catalogItemFormId).then(function (catalogItemData) { - vm.newRecord = false; + $scope.newRecord = false; vm.catalogItemModel.name = catalogItemData.name; vm.catalogItemModel.description = catalogItemData.description; vm.catalogItemModel.display = catalogItemData.display; diff --git a/app/views/catalog/_st_angular_form.html.haml b/app/views/catalog/_st_angular_form.html.haml index a903a18988d..e850d724de9 100644 --- a/app/views/catalog/_st_angular_form.html.haml +++ b/app/views/catalog/_st_angular_form.html.haml @@ -54,7 +54,7 @@ %select{"ng-model" => "vm._catalog", "name" => "catalog_id", "ng-required" => "vm.catalogItemModel.display", - 'ng-options' => 'catalog as catalog.name for catalog in catalogs', + 'ng-options' => 'catalog as catalog.name for catalog in vm.catalogs', 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index f973d217797..61907bfebd1 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -110,7 +110,7 @@ %div{:class => "btn-container"} %button{:class => "btn btn-link", :type => "button", - "ng-click" => "addKeyValue('#{prefix}')", + "ng-click" => "vm.addKeyValue('#{prefix}')", "ng-disabled" => "(#{ng_model}.#{prefix}_key == '' || #{ng_model}.#{prefix}_value == '')"} %span{:class => "fa fa-plus tag-add"} @@ -136,15 +136,15 @@ -# %div{:class => "btn-container"} %td %div{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} - %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "(#{ng_model}.key === '' || #{ng_model}.key_value === '')", "ng-click" => "saveKeyValue('#{prefix}', $index)"} + %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "(#{ng_model}.key === '' || #{ng_model}.key_value === '')", "ng-click" => "vm.saveKeyValue('#{prefix}', $index)"} =_("Save") - %button{:class => "btn btn-default", :type => "button", "ng-click" => "cancelKeyValue('#{prefix}', this.key, this.key_value, $index)"} + %button{:class => "btn btn-default", :type => "button", "ng-click" => "vm.cancelKeyValue('#{prefix}', this.key, this.key_value, $index)"} =_("Cancel") %div{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)", :class => "btn-container"} - %button{:class => "btn btn-link", :type => "button", "ng-click" => "editKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "vm.editKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} %span{:class => "pficon pficon-edit"} - %button{:class => "btn btn-link", :type => "button", "ng-click" => "removeKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} + %button{:class => "btn btn-link", :type => "button", "ng-click" => "vm.removeKeyValue('#{prefix}', this.key, this.key_value, $index)", "ng-disabled" => "#{ng_model}.#{prefix}_editMode"} %span{:class => "pficon pficon-delete"} .form-group @@ -162,8 +162,8 @@ .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_dialog_id.$invalid}", "ng-if" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"} %select{"ng-model" => "vm._#{prefix}_dialog", "name" => "#{prefix}_dialog_id", - 'ng-options' => 'dialog as dialog.label for dialog in dialogs', - "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'existing'", + 'ng-options' => 'dialog as dialog.label for dialog in vm.dialogs', + "ng-required" => "vm.fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'existing'", :checkchange => true, 'pf-select' => true} %option{"value" => ""} @@ -176,7 +176,7 @@ 'ng-model' => "#{ng_model}.#{prefix}_dialog_name", :name => "vm.#{prefix}_dialog_name", :maxlength => 50, - "ng-required" => "fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'create'", + "ng-required" => "vm.fieldsRequired('#{prefix}') && #{ng_model}.#{prefix}_dialog_existing == 'create'", "checkchange" => ""} %span.help-block{"ng-show" => "angularForm.#{prefix}_dialog_name.$error.$invalid"} = _("Required") From ebfadce743dcc1c68a943b80e94e2bdce53ee5cf Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 16 Feb 2017 17:04:30 -0500 Subject: [PATCH 09/13] Further changes to playbook Catalog Item form Did some cleanup of redundant code. Added changes to consume API to populate and when add/save form buttons are clicked. Added cloud type drop down to the form to be able to show cloud credentials for only selected type. https://www.pivotaltracker.com/story/show/138302747 --- .../catalog/catalog_item_form_controller.js | 212 ++++++++++++------ app/controllers/catalog_controller.rb | 38 +--- app/views/catalog/_st_angular_form.html.haml | 2 +- .../_ansible_form_options_angular.html.haml | 37 +-- config/routes.rb | 1 - 5 files changed, 173 insertions(+), 117 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 153e136860b..5ee600dfe2d 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -5,14 +5,14 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog name: '', description: '', display: false, - prov_type: '', + prov_type: 'generic_ansible_playbook', catalog_id: '', key: '', key_value: '', provisioning_repository_id: '', provisioning_playbook_id: '', provisioning_machine_credential_id: '', - provisioning_netowrk_credential_id: '', + provisioning_network_credential_id: '', provisioning_cloud_credential_id: '', provisioning_inventory: 'localhost', provisioning_dialog_existing: 'existing', @@ -20,8 +20,9 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog provisioning_dialog_name: '', provisioning_key: '', provisioning_value: '', - provisioning_variables: {"p_var1": "p_val1", "p_var2": "p_val2"}, + provisioning_variables: {}, provisioning_editMode: false, + provisioning_cloud_type: '', retirement_repository_id: '', retirement_playbook_id: '', retirement_machine_credential_id: '', @@ -33,25 +34,19 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog retirement_dialog_name: '', retirement_key: '', retirement_value: '', - retirement_variables: {"r_var1": "r_val1", "r_var2": "r_val2"}, - retirement_editMode: false + retirement_variables: {}, + retirement_editMode: false, + retirement_cloud_type: '', + cloud_types: ["Amazon", "Azure", "Google", "Openstack", "Vmware"] }; vm.formId = catalogItemFormId; vm.afterGet = false; - vm.modelCopy = angular.copy( vm.catalogItemModel ); vm.model = "catalogItemModel"; ManageIQ.angular.scope = $scope; if (catalogItemFormId == 'new') { - $scope.newRecord = true; - vm.catalogItemModel.name = ''; - vm.catalogItemModel.description = ''; - vm.catalogItemModel.catalog_id = ''; - vm.catalogItemModel.display = false; - vm.catalogItemModel.provisioning_dialog_id = ''; - vm.catalogItemModel.retirement_dialog_id = ''; - vm.catalogItemModel.prov_type = 'generic_ansible_playbook'; + $scope.newRecord = true; vm.formOptions(); vm.afterGet = true; vm.modelCopy = angular.copy( vm.catalogItemModel ); @@ -66,43 +61,137 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id;; vm.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id;; vm.formOptions(); + getConfigInfo(catalogItemData.config_info); vm.afterGet = true; vm.modelCopy = angular.copy(vm.catalogItemModel); }); } }; - var catalogItemEditButtonClicked = function(buttonName, serializeFields) { - miqService.sparkleOn(); - var url = '/catalog/catalog_item_edit/' + catalogItemFormId + '?button=' + buttonName; - if (serializeFields === undefined) { - miqService.miqAjaxButton(url); - } else { - miqService.miqAjaxButton(url, serializeFields); + var getConfigInfo = function(configData) { + vm.catalogItemModel.provisioning_repository_id = configData.provision.repository_id + vm.catalogItemModel.provisioning_playbook_id = configData.provision.playbook_id + vm.catalogItemModel.provisioning_machine_credential_id = configData.provision.credential_id + vm.catalogItemModel.provisioning_network_credential_id = configData.provision.network_credential_id + vm.catalogItemModel.provisioning_cloud_credential_id = configData.provision.cloud_credential_id + vm.catalogItemModel.provisioning_inventory = configData.provision.inventory + vm.catalogItemModel.provisioning_dialog_existing = configData.provision.dialog_id ? "existing" : "create" + vm.catalogItemModel.provisioning_dialog_id = configData.provision.dialog_id + vm.catalogItemModel.provisioning_dialog_name = configData.provision.new_dialog_name + vm.catalogItemModel.provisioning_key = '' + vm.catalogItemModel.provisioning_value = '' + vm.catalogItemModel.provisioning_variables = configData.provision.extra_vars + + if (typeof configData.retirement !== 'undefined') { + vm.catalogItemModel.retirement_repository_id = configData.retirement.repository_id + vm.catalogItemModel.retirement_playbook_id = configData.retirement.playbook_id + vm.catalogItemModel.retirement_machine_credential_id = configData.retirement.credential_id + vm.catalogItemModel.retirement_network_credential_id = configData.retirement.network_credential_id + vm.catalogItemModel.retirement_cloud_credential_id = configData.retirement.cloud_credential_id + vm.catalogItemModel.retirement_inventory = configData.retirement.inventory + vm.catalogItemModel.retirement_dialog_existing = configData.retirement.dialog_id ? "existing" : "create" + vm.catalogItemModel.retirement_dialog_id = configData.retirement.dialog_id + vm.catalogItemModel.retirement_dialog_name = configData.retirement.new_dialog_name + vm.catalogItemModel.retirement_key = '' + vm.catalogItemModel.retirement_value = '' + vm.catalogItemModel.retirement_variables = configData.retirement.extra_vars } - }; + } + + var redirectUrl = '/catalog/explorer/' + catalogItemFormId; $scope.cancelClicked = function() { - catalogItemEditButtonClicked('cancel'); + if ($scope.newRecord) + var msg = sprintf(__("Add of Catalog Item was cancelled by the user")); + else + var msg = sprintf(__("Edit of Catalog Item %s was cancelled by the user"), vm.catalogItemModel.description); + postService.cancelOperation('/catalog/explorer?', msg); $scope.angularForm.$setPristine(true); }; $scope.resetClicked = function() { - $scope.catalogItemModel = angular.copy( $scope.modelCopy ); + vm.catalogItemModel = angular.copy( vm.modelCopy ); + vm.formOptions(); $scope.angularForm.$setUntouched(true); $scope.angularForm.$setPristine(true); miqService.miqFlash("warn", __("All changes have been reset")); }; $scope.saveClicked = function() { - catalogItemEditButtonClicked('save', true); + var successMsg = sprintf(__("Catalog Item %s was saved"), vm.catalogItemModel.name); + postService.saveRecord('/api/service_templates/' + catalogItemFormId, + redirectUrl + '?button=save', + setConfigInfo(vm.catalogItemModel), + successMsg); $scope.angularForm.$setPristine(true); }; - $scope.addClicked = function() { - $scope.saveClicked(); + $scope.addClicked = function($event, formSubmit) { + var successMsg = sprintf(__("Catalog Item %s was added"), vm.catalogItemModel.name); + postService.createRecord('/api/service_templates', + redirectUrl + '?button=add', + setConfigInfo(vm.catalogItemModel), + successMsg); + $scope.angularForm.$setPristine(true); }; + var setConfigInfo = function(configData) { + catalog_item = { + name: configData.name, + description: configData.description, + display: configData.display, + service_template_catalog_id: configData.catalog_id, + prov_type: "generic_ansible_playbook", + type: "ServiceTemplateAnsiblePlaybook", + config_info: { + provision: { + repository_id: configData.provisioning_repository_id, + playbook_id: configData.provisioning_playbook_id, + credential_id: configData.provisioning_machine_credential_id, + hosts: configData.provisioning_inventory, + extra_vars: configData.provisioning_variables + } + } + } + + if (configData.provisioning_network_credential_id !== '') + catalog_item['config_info']['provision']['network_credential_id'] = configData.provisioning_network_credential_id; + + if (configData.provisioning_cloud_credential_id !== '') + catalog_item['config_info']['provision']['cloud_credential_id'] = configData.provisioning_cloud_credential_id; + + if (configData.provisioning_dialog_id !== '') { + catalog_item['config_info']['provision']['dialog_id'] = configData.provisioning_dialog_id; + } else if (configData.provisioning_dialog_name !== '') + catalog_item['config_info']['provision']['new_dialog_name'] = configData.provisioning_dialog_name; + + // add 'retirement' key only if required fields were selected + if (configData.retirement_repository_id !== '') { + catalog_item['config_info']['retirement'] = { + repository_id: configData.retirement_repository_id, + playbook_id: configData.retirement_playbook_id, + credential_id: configData.retirement_machine_credential_id, + hosts: configData.retirement_inventory, + dialog_id: configData.retirement_dialog_id, + extra_vars: configData.retirement_variables + } + + if (configData.retirement_network_credential_id !== '') + catalog_item['config_info']['retirement']['network_credential_id'] = configData.retirement_network_credential_id; + + if (configData.retirement_cloud_credential_id !== '') + catalog_item['config_info']['retirement']['cloud_credential_id'] = configData.retirement_cloud_credential_id; + + if (configData.retirement_dialog_id !== '') { + catalog_item['config_info']['retirement']['dialog_id'] = configData.retirement_dialog_id; + } else if (configData.retirement_dialog_name !== '') + catalog_item['config_info']['retirement']['new_dialog_name'] = configData.retirement_dialog_name; + } + + return catalog_item; + } + + // list of service catalogs vm.formOptions = function() { API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function(data) { @@ -125,39 +214,31 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog }) // list of machine credentials - // check if the type of credentials can be specified in the API - //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") - API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + API.get("/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::MachineCredential&expand=resources&attributes=id,name").then(function (data) { vm.machine_credentials = data.resources; vm._retirement_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.retirement_machine_credential_id}) vm._provisioning_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.provisioning_machine_credential_id}) }) // list of network credentials - // check if the type of credentials can be specified in the API - //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") - API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { + API.get("/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::NetworkCredential&expand=resources&attributes=id,name").then(function (data) { vm.network_credentials = data.resources; vm._retirement_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.retirement_network_credential_id}) vm._provisioning_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.provisioning_network_credential_id}) }) - - // list of cloud credentials - // check if the type of credentials can be specified in the API - //API.get("/api/automation_manager_authentications/?expand=resources&attributes=id,name") - API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function (data) { - vm.cloud_credentials = data.resources; - vm._retirement_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.retirement_cloud_credential_id}) - vm._provisioning_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.provisioning_cloud_credential_id}) - }) }; // get playbooks for selected repository vm.repositoryChanged = function(prefix, id) { - API.get("/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads").then(function(data){ - vm.catalogItemModel[prefix + '_playbook_id'] = ''; - vm.catalogItemModel[prefix + '_repository_id'] = id; + API.get("/api/configuration_script_sources/" + id + "?attributes=configuration_script_payloads").then(function(data) { vm[prefix + '_playbooks'] = data.configuration_script_payloads; + // if repository has changed + if (id !== vm.catalogItemModel[prefix + '_repository_id']) { + vm.catalogItemModel[prefix + '_playbook_id'] = ''; + vm.catalogItemModel[prefix + '_repository_id'] = id; + } else { + vm['_' + prefix + '_playbook'] = _.find(vm[prefix + '_playbooks'], {id: vm.catalogItemModel[prefix + '_playbook_id']}); + } }) }; @@ -175,6 +256,17 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel['retirement_repository_id'] = '' }); + $scope.cloudTypeChanged = function(prefix) { + typ = vm.catalogItemModel[prefix + "_cloud_type"]; + // list of cloud credentials based upon selected cloud type + url = "/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::" + typ + "Credential&expand=resources&attributes=id,name" + API.get(url).then(function (data) { + vm.cloud_credentials = data.resources; + vm._retirement_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.retirement_cloud_credential_id}) + vm._provisioning_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.provisioning_cloud_credential_id}) + }) + } + $scope.$watch('vm.catalogItemModel.display', function(value) { vm.catalogItemModel.display = value; return vm.catalogItemModel.display; @@ -207,7 +299,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel.original_key_value = key_value; } - vm.cancelKeyValue = function(prefix, key, key_value, index) { + vm.cancelKeyValue = function(prefix) { vm.catalogItemModel[prefix + "_editMode"] = false; vm.catalogItemModel.s_index = ''; vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel.original_key] = vm.catalogItemModel.original_key_value; @@ -231,26 +323,16 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog return prefix == "provisioning"; }; - $scope.cancelClicked = function() { - catalogItemEditButtonClicked('cancel'); - $scope.angularForm.$setPristine(true); - }; - - $scope.resetClicked = function() { - vm.catalogItemModel = angular.copy( vm.modelCopy ); - $scope.angularForm.$setUntouched(true); - $scope.angularForm.$setPristine(true); - miqService.miqFlash("warn", __("All changes have been reset")); - }; - - $scope.saveClicked = function() { - catalogItemEditButtonClicked('save', true); - $scope.angularForm.$setPristine(true); - }; + // watch for all the drop downs on screen + "catalog provisioning_playbook retirement_playbook provisioning_machine_credential retirement_machine_credential provisioning_network_credential retirement_network_credential provisioning_cloud_credential retirement_cloud_credential provisioning_dialog retirement_dialog".split(" ").forEach(idWatch) - $scope.addClicked = function() { - $scope.saveClicked(); - }; + function idWatch(name) { + field_name = "vm._" + name + $scope.$watch(field_name, function(value) { + if (value) + vm.catalogItemModel[name + '_id'] = value.id; + }); + } init(); }]); diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 9c8622a3f27..efad4cfd889 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -126,42 +126,6 @@ def atomic_st_edit end end - def catalog_item_edit - assert_privileges("atomic_catalogitem_edit") - case params[:button] - when "cancel" - service_template = ServiceTemplate.find_by_id(params[:id]) - if service_template.try(:id).nil? - add_flash(_("Add of new Catalog Item was cancelled by the user")) - else - add_flash(_("Edit of Catalog Item \"%{name}\" was cancelled by the user") % - {:name => service_template.name}) - end - get_node_info(x_node) - replace_right_cell(:nodetype => x_node) - when "save", "add" - service_template = params[:id] != "new" ? ServiceTemplate.find_by_id(params[:id]) : ServiceTemplate.new - - # This should be changed to something like service_template.changed? and service_template.changes - # when we have a version of Rails that supports detecting changes on serialized - # fields - old_service_template_attributes = service_template.attributes.clone - service_template_set_record_vars(service_template) - - begin - service_template.save! - rescue => bang - add_flash(_("Error when adding a new Catalog Item: %{message}") % {:message => bang.message}, :error) - javascript_flash - else - AuditEvent.success(build_saved_audit_hash(old_service_template_attributes, service_template, params[:button] == "add")) - add_flash(_("Catalog Item \"%{name}\" was saved") % - {:name => service_template.name}) - replace_right_cell(:replace_trees => trees_to_replace([:sandt, :svccat, :stcat])) - end - end - end - def atomic_form_field_changed # need to check req_id in session since we are using common code for prov requests and atomic ST screens id = session[:edit][:req_id] || "new" @@ -241,7 +205,7 @@ def explorer build_accordions_and_trees - if params[:id] # If a tree node id came in, show in one of the trees + if params[:id] && !params[:button] # If a tree node id came in, show in one of the trees @nodetype, id = parse_nodetype_and_id(params[:id]) self.x_active_tree = 'sandt_tree' self.x_active_accord = 'sandt' diff --git a/app/views/catalog/_st_angular_form.html.haml b/app/views/catalog/_st_angular_form.html.haml index e850d724de9..88abf68b84a 100644 --- a/app/views/catalog/_st_angular_form.html.haml +++ b/app/views/catalog/_st_angular_form.html.haml @@ -47,7 +47,7 @@ "switch-off-text" => "No", "checkchange" => ""} - .form-group{"ng-class" => "{'has-error': vm.catalogItemModel.display}"} + .form-group{"ng-class" => "{'has-error': vm.catalogItemModel.display && angularForm.catalog_id.$invalid}"} %label.col-md-2.control-label{"for" => "catalog_id"} = _('Catalog') .col-md-8 diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index 61907bfebd1..16eb5b0d8bb 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -9,14 +9,13 @@ "name" => "#{prefix}_repository_id", 'ng-options' => 'repository as repository.name for repository in vm.repositories', "ng-required" => "vm.fieldsRequired('#{prefix}')", - 'ng_change' => "vm.repository_changed()", 'pf-select' => true} %option{"value" => ""} = "<#{_('Choose')}>" #playbook_div{"ng-if" => "vm.#{prefix}_repository_selected()"} .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_playbook_id.$invalid}"} - %label.col-md-2.control-label{"for" => "vm.#{prefix}_playbook_id"} + %label.col-md-2.control-label{"for" => "#{prefix}_playbook_id"} = _('Playbook') .col-md-8 %select{"ng-model" => "vm._#{prefix}_playbook", @@ -57,20 +56,34 @@ = "<#{_('Choose')}>" .form-group - %label.col-md-2.control-label{"for" => "vm.#{prefix}_cloud_credential_id"} - = _('Cloud Credentials') + %label.col-md-2.control-label{"for" => "vm.#{prefix}_cloud_type"} + = _('Cloud Type') .col-md-8 - %select{"ng-model" => "vm._#{prefix}_cloud_credential", - "name" => "#{prefix}_cloud_credential_id", - 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in vm.cloud_credentials', - :checkchange => true, - 'pf-select' => true} + %select{"ng-model" => "#{ng_model}.#{prefix}_cloud_type", + "name" => "#{prefix}_cloud_type", + 'ng-options' => "cloud_type for cloud_type in #{ng_model}.cloud_types", + "ng-change" => "cloudTypeChanged('#{prefix}')", + :checkchange => "", + "pf-select" => true} %option{"value" => ""} = "<#{_('Choose')}>" + #cloud_credentials_div{"ng-show" => "#{ng_model}.#{prefix}_cloud_type !== ''"} + .form-group + %label.col-md-2.control-label{"for" => "vm.#{prefix}_cloud_credential_id"} + = _('Cloud Credentials') + .col-md-8 + %select{"ng-model" => "vm._#{prefix}_cloud_credential", + "name" => "#{prefix}_cloud_credential_id", + 'ng-options' => 'cloud_credential as cloud_credential.name for cloud_credential in vm.cloud_credentials', + :checkchange => true, + 'pf-select' => true} + %option{"value" => ""} + = "<#{_('Choose')}>" + .form-group{"ng-class" => "{'has-error': angularForm.#{prefix}_inventory.$invalid}"} %label.col-md-2.control-label - = _("Inventory") + = _("Hosts") .col-md-8 %input.form-control{:type => "text", 'ng-model' => "vm.#{ng_model}.#{prefix}_inventory", @@ -132,13 +145,11 @@ "ng-change" => "", "miqrequired" => ""} - -#%td{:class => "action-cell", :style => "width: 15px"} - -# %div{:class => "btn-container"} %td %div{"ng-if" => "#{ng_model}.#{prefix}_editMode && $index === #{ng_model}.s_index"} %button{:class => "btn btn-primary", :type => "button", "ng-disabled" => "(#{ng_model}.key === '' || #{ng_model}.key_value === '')", "ng-click" => "vm.saveKeyValue('#{prefix}', $index)"} =_("Save") - %button{:class => "btn btn-default", :type => "button", "ng-click" => "vm.cancelKeyValue('#{prefix}', this.key, this.key_value, $index)"} + %button{:class => "btn btn-default", :type => "button", "ng-click" => "vm.cancelKeyValue('#{prefix}')"} =_("Cancel") %div{"ng-if" => "!#{ng_model}.#{prefix}_editMode || (#{ng_model}.#{prefix}_editMode && $index !== #{ng_model}.s_index)", :class => "btn-container"} diff --git a/config/routes.rb b/config/routes.rb index ad57318df13..91be9b47409 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -275,7 +275,6 @@ atomic_form_field_changed atomic_st_edit automate_button_field_changed - catalog_item_edit explorer get_ae_tree_edit_key group_create From 2090adf49fa1d574d517b98ebc8c5e5d123143a6 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 16 Feb 2017 17:46:08 -0500 Subject: [PATCH 10/13] Added missing ; at end of JS statements https://www.pivotaltracker.com/story/show/138302747 --- .../catalog/catalog_item_form_controller.js | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 5ee600dfe2d..5140c0b6958 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -58,8 +58,8 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel.description = catalogItemData.description; vm.catalogItemModel.display = catalogItemData.display; vm.catalogItemModel.catalog_id = catalogItemData.service_template_catalog_id; - vm.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id;; - vm.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id;; + vm.catalogItemModel.provisioning_dialog_id = catalogItemData.provisioning_dialog_id; + vm.catalogItemModel.retirement_dialog_id = catalogItemData.retirement_dialog_id; vm.formOptions(); getConfigInfo(catalogItemData.config_info); vm.afterGet = true; @@ -69,32 +69,32 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog }; var getConfigInfo = function(configData) { - vm.catalogItemModel.provisioning_repository_id = configData.provision.repository_id - vm.catalogItemModel.provisioning_playbook_id = configData.provision.playbook_id - vm.catalogItemModel.provisioning_machine_credential_id = configData.provision.credential_id - vm.catalogItemModel.provisioning_network_credential_id = configData.provision.network_credential_id - vm.catalogItemModel.provisioning_cloud_credential_id = configData.provision.cloud_credential_id - vm.catalogItemModel.provisioning_inventory = configData.provision.inventory - vm.catalogItemModel.provisioning_dialog_existing = configData.provision.dialog_id ? "existing" : "create" - vm.catalogItemModel.provisioning_dialog_id = configData.provision.dialog_id - vm.catalogItemModel.provisioning_dialog_name = configData.provision.new_dialog_name - vm.catalogItemModel.provisioning_key = '' - vm.catalogItemModel.provisioning_value = '' - vm.catalogItemModel.provisioning_variables = configData.provision.extra_vars + vm.catalogItemModel.provisioning_repository_id = configData.provision.repository_id; + vm.catalogItemModel.provisioning_playbook_id = configData.provision.playbook_id; + vm.catalogItemModel.provisioning_machine_credential_id = configData.provision.credential_id; + vm.catalogItemModel.provisioning_network_credential_id = configData.provision.network_credential_id; + vm.catalogItemModel.provisioning_cloud_credential_id = configData.provision.cloud_credential_id; + vm.catalogItemModel.provisioning_inventory = configData.provision.inventory; + vm.catalogItemModel.provisioning_dialog_existing = configData.provision.dialog_id ? "existing" : "create"; + vm.catalogItemModel.provisioning_dialog_id = configData.provision.dialog_id; + vm.catalogItemModel.provisioning_dialog_name = configData.provision.new_dialog_name; + vm.catalogItemModel.provisioning_key = ''; + vm.catalogItemModel.provisioning_value = ''; + vm.catalogItemModel.provisioning_variables = configData.provision.extra_vars; if (typeof configData.retirement !== 'undefined') { - vm.catalogItemModel.retirement_repository_id = configData.retirement.repository_id - vm.catalogItemModel.retirement_playbook_id = configData.retirement.playbook_id - vm.catalogItemModel.retirement_machine_credential_id = configData.retirement.credential_id - vm.catalogItemModel.retirement_network_credential_id = configData.retirement.network_credential_id - vm.catalogItemModel.retirement_cloud_credential_id = configData.retirement.cloud_credential_id - vm.catalogItemModel.retirement_inventory = configData.retirement.inventory - vm.catalogItemModel.retirement_dialog_existing = configData.retirement.dialog_id ? "existing" : "create" - vm.catalogItemModel.retirement_dialog_id = configData.retirement.dialog_id - vm.catalogItemModel.retirement_dialog_name = configData.retirement.new_dialog_name - vm.catalogItemModel.retirement_key = '' - vm.catalogItemModel.retirement_value = '' - vm.catalogItemModel.retirement_variables = configData.retirement.extra_vars + vm.catalogItemModel.retirement_repository_id = configData.retirement.repository_id; + vm.catalogItemModel.retirement_playbook_id = configData.retirement.playbook_id; + vm.catalogItemModel.retirement_machine_credential_id = configData.retirement.credential_id; + vm.catalogItemModel.retirement_network_credential_id = configData.retirement.network_credential_id; + vm.catalogItemModel.retirement_cloud_credential_id = configData.retirement.cloud_credential_id; + vm.catalogItemModel.retirement_inventory = configData.retirement.inventory; + vm.catalogItemModel.retirement_dialog_existing = configData.retirement.dialog_id ? "existing" : "create"; + vm.catalogItemModel.retirement_dialog_id = configData.retirement.dialog_id; + vm.catalogItemModel.retirement_dialog_name = configData.retirement.new_dialog_name; + vm.catalogItemModel.retirement_key = ''; + vm.catalogItemModel.retirement_value = ''; + vm.catalogItemModel.retirement_variables = configData.retirement.extra_vars; } } @@ -196,35 +196,35 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.formOptions = function() { API.get("/api/service_catalogs/?expand=resources&attributes=id,name").then(function(data) { vm.catalogs = data.resources; - vm._catalog = _.find(vm.catalogs, {id: vm.catalogItemModel.catalog_id}) + vm._catalog = _.find(vm.catalogs, {id: vm.catalogItemModel.catalog_id}); }) // list of service dailaogs API.get("/api/service_dialogs/?expand=resources&attributes=id,label").then(function (data) { vm.dialogs = data.resources - vm._retirement_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.retirement_dialog_id}) - vm._provisioning_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.provisioning_dialog_id}) + vm._retirement_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.retirement_dialog_id}); + vm._provisioning_dialog = _.find(vm.dialogs, {id: vm.catalogItemModel.provisioning_dialog_id}); }) // list of repositories API.get("/api/configuration_script_sources/?expand=resources&attributes=id,name").then(function (data) { vm.repositories = data.resources; - vm._retirement_repository = _.find(vm.repositories, {id: vm.catalogItemModel.retirement_repository_id}) - vm._provisioning_repository = _.find(vm.repositories, {id: vm.catalogItemModel.provisioning_repository_id}) + vm._retirement_repository = _.find(vm.repositories, {id: vm.catalogItemModel.retirement_repository_id}); + vm._provisioning_repository = _.find(vm.repositories, {id: vm.catalogItemModel.provisioning_repository_id}); }) // list of machine credentials API.get("/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::MachineCredential&expand=resources&attributes=id,name").then(function (data) { vm.machine_credentials = data.resources; - vm._retirement_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.retirement_machine_credential_id}) - vm._provisioning_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.provisioning_machine_credential_id}) + vm._retirement_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.retirement_machine_credential_id}); + vm._provisioning_machine_credential = _.find(vm.machine_credentials, {id: vm.catalogItemModel.provisioning_machine_credential_id}); }) // list of network credentials API.get("/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::NetworkCredential&expand=resources&attributes=id,name").then(function (data) { vm.network_credentials = data.resources; - vm._retirement_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.retirement_network_credential_id}) - vm._provisioning_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.provisioning_network_credential_id}) + vm._retirement_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.retirement_network_credential_id}); + vm._provisioning_network_credential = _.find(vm.network_credentials, {id: vm.catalogItemModel.provisioning_network_credential_id}); }) }; @@ -246,14 +246,14 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog if (value) { vm.repositoryChanged("provisioning", value.id) } else - vm.catalogItemModel['provisioning_repository_id'] = '' + vm.catalogItemModel['provisioning_repository_id'] = ''; }); $scope.$watch('vm._retirement_repository', function(value) { if (value) { vm.repositoryChanged("retirement", value.id) } else - vm.catalogItemModel['retirement_repository_id'] = '' + vm.catalogItemModel['retirement_repository_id'] = ''; }); $scope.cloudTypeChanged = function(prefix) { @@ -262,8 +262,8 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog url = "/api/authentications?collection_class=ManageIQ::Providers::AnsibleTower::AutomationManager::" + typ + "Credential&expand=resources&attributes=id,name" API.get(url).then(function (data) { vm.cloud_credentials = data.resources; - vm._retirement_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.retirement_cloud_credential_id}) - vm._provisioning_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.provisioning_cloud_credential_id}) + vm._retirement_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.retirement_cloud_credential_id}); + vm._provisioning_cloud_credential = _.find(vm.cloud_credentials, {id: vm.catalogItemModel.provisioning_cloud_credential_id}); }) } @@ -273,7 +273,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog }) vm.addKeyValue = function(prefix) { - vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel[prefix + "_key"]] = vm.catalogItemModel[prefix + "_value"] + vm.catalogItemModel[prefix + "_variables"][vm.catalogItemModel[prefix + "_key"]] = vm.catalogItemModel[prefix + "_value"]; vm.catalogItemModel[prefix + "_key"] = ''; vm.catalogItemModel[prefix + "_value"] = ''; } @@ -316,7 +316,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog } vm.toggleDialogSelection = function(prefix, selected_value) { - vm.catalogItemModel[prefix + "_dialog_existing"] = selected_value + vm.catalogItemModel[prefix + "_dialog_existing"] = selected_value; }; vm.fieldsRequired = function(prefix) { @@ -327,7 +327,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog "catalog provisioning_playbook retirement_playbook provisioning_machine_credential retirement_machine_credential provisioning_network_credential retirement_network_credential provisioning_cloud_credential retirement_cloud_credential provisioning_dialog retirement_dialog".split(" ").forEach(idWatch) function idWatch(name) { - field_name = "vm._" + name + field_name = "vm._" + name; $scope.$watch(field_name, function(value) { if (value) vm.catalogItemModel[name + '_id'] = value.id; From 2f6125b1ee491a4cab4cc9e13993347064a4bd20 Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Thu, 16 Feb 2017 18:31:04 -0500 Subject: [PATCH 11/13] Fixed form buttons on edit form. Made changes to disable save/reset form button on initial load of Edit form https://www.pivotaltracker.com/story/show/138302747 --- .../layouts/angular/_ansible_form_options_angular.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index 16eb5b0d8bb..bfdc6042c5f 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -63,7 +63,7 @@ "name" => "#{prefix}_cloud_type", 'ng-options' => "cloud_type for cloud_type in #{ng_model}.cloud_types", "ng-change" => "cloudTypeChanged('#{prefix}')", - :checkchange => "", + :checkchange => true, "pf-select" => true} %option{"value" => ""} = "<#{_('Choose')}>" From f90a52079faf0975d66fc68b2f604bc4a66d1bcc Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Fri, 17 Feb 2017 18:07:19 -0500 Subject: [PATCH 12/13] added Jasmine spec tests minor cleanup to address rubocop warnings. Fixed nil error on edit screen https://www.pivotaltracker.com/story/show/138302747 --- app/controllers/catalog_controller.rb | 21 +-- .../catalog_item_form_controller_spec.js | 132 ++++++++++++++++++ 2 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 spec/javascripts/controllers/catalog/catalog_item_form_controller_spec.js diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index efad4cfd889..288141c8795 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -138,11 +138,12 @@ def atomic_form_field_changed @_params[:org_controller] = "service_template" if ansible_playbook? @record = ServiceTemplate.new - if false - add_flash(_("Before adding Ansible Service, at least 1 repository, 1 playbook, 1 credential must exist in VMDB"), :error) - javascript_flash - return - end + # waiting for back-end PR to be merged to implement this + # if false + # add_flash(_("Before adding Ansible Service, at least 1 repository, 1 playbook, 1 credential must exist in VMDB"), :error) + # javascript_flash + # return + # end else prov_set_form_vars if need_prov_dialogs?(params[:st_prov_type]) @record = class_service_template(params[:st_prov_type]).new @@ -157,15 +158,17 @@ def atomic_form_field_changed end render :update do |page| page << javascript_prologue - if ansible_playbook? + if @edit[:new][:st_prov_type] == "generic_ansible_playbook" page.replace("form_div", :partial => "st_angular_form") page << javascript_hide("form_buttons_div") else - # for generic/orchestration type tabs do not show up on screen as there is only a single tab when form is initialized + # for generic/orchestration type tabs do not show up on screen + # as there is only a single tab when form is initialized # when display in catalog is checked, replace div so tabs can be redrawn page.replace("form_div", :partial => "st_form") if params[:st_prov_type] || (params[:display] && @edit[:new][:st_prov_type].starts_with?("generic")) - page.replace_html("basic_info_div", :partial => "form_basic_info") if params[:display] || params[:template_id] || params[:manager_id] + page.replace_html("basic_info_div", :partial => "form_basic_info") if params[:display] || + params[:template_id] || params[:manager_id] if params[:display] page << "miq_tabs_show_hide('#details_tab', '#{(params[:display] == "1")}')" end @@ -205,7 +208,7 @@ def explorer build_accordions_and_trees - if params[:id] && !params[:button] # If a tree node id came in, show in one of the trees + if params[:id] && !params[:button] # If a tree node id came in, show in one of the trees @nodetype, id = parse_nodetype_and_id(params[:id]) self.x_active_tree = 'sandt_tree' self.x_active_accord = 'sandt' diff --git a/spec/javascripts/controllers/catalog/catalog_item_form_controller_spec.js b/spec/javascripts/controllers/catalog/catalog_item_form_controller_spec.js new file mode 100644 index 00000000000..d016a085de4 --- /dev/null +++ b/spec/javascripts/controllers/catalog/catalog_item_form_controller_spec.js @@ -0,0 +1,132 @@ +describe('catalogItemFormController', function() { + var $scope, $controller, postService; + + beforeEach(module('ManageIQ')); + + beforeEach(inject(function($rootScope, $location, _$controller_, miqService, _postService_, catalogItemDataFactory) { + postService = _postService_; + spyOn(miqService, 'showButtons'); + spyOn(miqService, 'hideButtons'); + spyOn(miqService, 'miqAjaxButton'); + spyOn(miqService, 'sparkleOn'); + spyOn(miqService, 'sparkleOff'); + spyOn(postService, 'cancelOperation'); + spyOn(postService, 'saveRecord'); + spyOn(postService, 'createRecord'); + $scope = $rootScope.$new(); + $scope.vm = {}; + $scope.vm.catalogItemModel = { + name: 'catalogItemName', + description: 'catalogItemDescription', + service_template_catalog_id: 10000000000012, + display: true, + prov_type: 'generic_ansible_playbook', + type: 'ServiceTemplateAnsiblePlaybook', + config_info: { + provision: { + dialog_id: '10000000000031', + repository_id: undefined, + playbook_id: 10000000000493, + credential_id: 10000000000090, + hosts: undefined, + extra_vars: { + 'var1': 'default_val1', + 'var2': 'default_val2' + }, + network_credential_id: undefined, + cloud_credential_id: undefined + } + } + }; + + spyOn(catalogItemDataFactory, 'getCatalogItemData').and.returnValue(Promise.resolve($scope.vm.catalogItemModel)); + + $controller = _$controller_('catalogItemFormController', { + $scope: $scope, + catalogItemFormId: 1000000000001 + }); + })); + + var redirectUrl = '/catalog/explorer'; + + describe('initialization', function() { + it('sets the catalogItemData name to the value returned via the http request', function(done) { + setTimeout(function () { + expect($scope.vm.catalogItemModel.name).toEqual('catalogItemName'); + expect($scope.vm.catalogItemModel.description).toEqual('catalogItemDescription'); + done(); + }); + }); + }); + + describe('#cancelClicked', function() { + beforeEach(function() { + $scope.angularForm = { + $setPristine: function (value){} + }; + setTimeout($scope.cancelClicked); + }); + + it('delegates to postService.cancelOperation', function(done) { + setTimeout(function () { + var msg = "Edit of Catalog Item catalogItemDescription was cancelled by the user"; + expect(postService.cancelOperation).toHaveBeenCalledWith(redirectUrl + "?", msg); + done(); + }); + }); + }); + + describe('#resetClicked', function() { + beforeEach(function() { + $scope.vm.catalogItemModel.name = 'catalogItemName'; + $scope.angularForm = { + $setPristine: function (value){}, + $setUntouched: function (value){}, + }; + setTimeout($scope.resetClicked); + }); + + it('resets value of name field to initial value', function(done) { + setTimeout(function() { + expect($scope.vm.catalogItemModel.name).toEqual('catalogItemName'); + done(); + }); + }); + }); + + describe('#saveClicked', function() { + beforeEach(function() { + setTimeout($scope.saveClicked); + }); + + it('delegates to postService.saveRecord', function(done) { + setTimeout(function() { + expect(postService.saveRecord).toHaveBeenCalledWith( + '/api/service_templates/1000000000001', + redirectUrl + '/1000000000001?button=save', + $scope.vm.catalogItemModel, + 'Catalog Item catalogItemName was saved' + ); + done(); + }); + }); + }); + + describe('#addClicked', function() { + beforeEach(function () { + setTimeout($scope.addClicked); + }); + + it('delegates to postService.createRecord', function (done) { + setTimeout(function () { + expect(postService.createRecord).toHaveBeenCalledWith( + '/api/service_templates', + redirectUrl + '/1000000000001?button=add', + $scope.vm.catalogItemModel, + 'Catalog Item catalogItemName was added' + ); + done(); + }); + }); + }); +}); From d39b62c80fe464be3c196e1cfdf04e7967ffa92b Mon Sep 17 00:00:00 2001 From: Harpreet Kataria Date: Tue, 21 Feb 2017 12:10:13 -0500 Subject: [PATCH 13/13] Removed a debug statement Fixed Hosts form field to save/display data. https://bugzilla.redhat.com/show_bug.cgi?id=1422449 --- .../controllers/catalog/catalog_item_form_controller.js | 4 ++-- .../layouts/angular/_ansible_form_options_angular.html.haml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js index 5140c0b6958..34ba4f23a0b 100644 --- a/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js +++ b/app/assets/javascripts/controllers/catalog/catalog_item_form_controller.js @@ -74,7 +74,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel.provisioning_machine_credential_id = configData.provision.credential_id; vm.catalogItemModel.provisioning_network_credential_id = configData.provision.network_credential_id; vm.catalogItemModel.provisioning_cloud_credential_id = configData.provision.cloud_credential_id; - vm.catalogItemModel.provisioning_inventory = configData.provision.inventory; + vm.catalogItemModel.provisioning_inventory = configData.provision.hosts; vm.catalogItemModel.provisioning_dialog_existing = configData.provision.dialog_id ? "existing" : "create"; vm.catalogItemModel.provisioning_dialog_id = configData.provision.dialog_id; vm.catalogItemModel.provisioning_dialog_name = configData.provision.new_dialog_name; @@ -88,7 +88,7 @@ ManageIQ.angular.app.controller('catalogItemFormController', ['$scope', 'catalog vm.catalogItemModel.retirement_machine_credential_id = configData.retirement.credential_id; vm.catalogItemModel.retirement_network_credential_id = configData.retirement.network_credential_id; vm.catalogItemModel.retirement_cloud_credential_id = configData.retirement.cloud_credential_id; - vm.catalogItemModel.retirement_inventory = configData.retirement.inventory; + vm.catalogItemModel.retirement_inventory = configData.retirement.hosts; vm.catalogItemModel.retirement_dialog_existing = configData.retirement.dialog_id ? "existing" : "create"; vm.catalogItemModel.retirement_dialog_id = configData.retirement.dialog_id; vm.catalogItemModel.retirement_dialog_name = configData.retirement.new_dialog_name; diff --git a/app/views/layouts/angular/_ansible_form_options_angular.html.haml b/app/views/layouts/angular/_ansible_form_options_angular.html.haml index bfdc6042c5f..6d900fb89da 100644 --- a/app/views/layouts/angular/_ansible_form_options_angular.html.haml +++ b/app/views/layouts/angular/_ansible_form_options_angular.html.haml @@ -86,7 +86,7 @@ = _("Hosts") .col-md-8 %input.form-control{:type => "text", - 'ng-model' => "vm.#{ng_model}.#{prefix}_inventory", + 'ng-model' => "#{ng_model}.#{prefix}_inventory", :name => "#{prefix}_inventory", :maxlength => 50, "miqrequired" => "", @@ -161,7 +161,6 @@ .form-group %label.col-md-2.control-label = _("Dialog") - {{#{ng_model}.#{prefix}_dialog_existing}} .col-md-4 %label.radio %input{"ng-model" => "vm.#{prefix}_dialog_existing", :type => "radio", :value => "existing", "ng-click" => "vm.toggleDialogSelection('#{prefix}', 'existing')", "ng-checked" => "#{ng_model}.#{prefix}_dialog_existing == 'existing'"}