diff --git a/app/controllers/application_controller/explorer.rb b/app/controllers/application_controller/explorer.rb index 02ebb7e9a220..231bcbfaabb9 100644 --- a/app/controllers/application_controller/explorer.rb +++ b/app/controllers/application_controller/explorer.rb @@ -46,14 +46,15 @@ def x_history 'manager_pause' => :s1, 'manager_resume' => :s1, # group 2 - 'clone' => :s2, 'compare' => :s2, 'drift' => :s2, - 'edit' => :s2, 'evm_relationship' => :s2, 'migrate' => :s2, - 'ownership' => :s2, 'policy_sim' => :s2, 'protect' => :s2, - 'publish' => :s2, 'reconfigure' => :s2, 'miq_request_new' => :s2, - 'retire' => :s2, 'right_size' => :s2, 'snapshot_add' => :s2, - 'tag' => :s2, 'timeline' => :s2, 'resize' => :s2, - 'live_migrate' => :s2, 'attach' => :s2, 'detach' => :s2, - 'evacuate' => :s2, 'service_dialog' => :s2, + 'clone' => :s2, 'compare' => :s2, 'drift' => :s2, + 'edit_description' => :s2, + 'edit' => :s2, 'evm_relationship' => :s2, 'migrate' => :s2, + 'ownership' => :s2, 'policy_sim' => :s2, 'protect' => :s2, + 'publish' => :s2, 'reconfigure' => :s2, 'miq_request_new' => :s2, + 'retire' => :s2, 'right_size' => :s2, 'snapshot_add' => :s2, + 'tag' => :s2, 'timeline' => :s2, 'resize' => :s2, + 'live_migrate' => :s2, 'attach' => :s2, 'detach' => :s2, + 'evacuate' => :s2, 'service_dialog' => :s2, 'manager_configuration_script_service_dialog' => :s2, 'associate_floating_ip' => :s2, 'disassociate_floating_ip' => :s2, diff --git a/app/controllers/vm_common.rb b/app/controllers/vm_common.rb index 67fc9b1f84b6..2b86e33e8f6b 100644 --- a/app/controllers/vm_common.rb +++ b/app/controllers/vm_common.rb @@ -578,25 +578,36 @@ def remove_service end end - def edit + def edit_data(edit_description) @record = find_record_with_rbac(VmOrTemplate, params[:id]) # Set the VM object - + # reset @explorer if coming from explorer views @edit ||= {} @edit[:explorer] = true if params[:action] == "x_button" || session.fetch_path(:edit, :explorer) @explorer = true if @edit[:explorer] @in_a_form = true - @title = _("Editing %{vm_or_template} \"%{name}\"") % {:name => @record.name, :vm_or_template => model_for_vm(@record).display_name} + title = edit_description ? _("Editing Description of %{vm_or_template} \"%{name}\"") : _("Editing%{vm_or_template} \"%{name}\"") + @title = title % {:name => @record.name, :vm_or_template => model_for_vm(@record).display_name} @right_cell_text = @title drop_breadcrumb(:name => @title, :url => "/vm/edit") unless @explorer @lastaction = "show_list" @refresh_partial = "vm_common/form" + @edit_description = edit_description + end + + def edit + edit_data(false) + end + + def edit_description + edit_data(true) end # FIXME: these match toolbar button names/features alias_method :image_edit, :edit alias_method :instance_edit, :edit alias_method :vm_edit, :edit + alias_method :vm_edit_description, :edit_description alias_method :miq_template_edit, :edit def set_checked_items @@ -1222,6 +1233,9 @@ def set_right_cell_vars(options = {}) when "edit" partial = "vm_common/form" header = _("Editing %{vm_or_template} \"%{name}\"") % {:name => name, :vm_or_template => model_for_vm(@record).display_name} + when "edit_description" + partial = "vm_common/form" + header = _("Editing Description of %{vm_or_template} \"%{name}\"") % {:name => name, :vm_or_template => model_for_vm(@record).display_name} when 'chargeback' partial = @refresh_partial header = _('Chargeback preview for "%{vm_name}"') % { :vm_name => name } diff --git a/app/helpers/application_helper/toolbar/x_vm_center.rb b/app/helpers/application_helper/toolbar/x_vm_center.rb index b5524bd30067..1e290809602e 100644 --- a/app/helpers/application_helper/toolbar/x_vm_center.rb +++ b/app/helpers/application_helper/toolbar/x_vm_center.rb @@ -43,6 +43,12 @@ class ApplicationHelper::Toolbar::XVmCenter < ApplicationHelper::Toolbar::Basic 'pficon pficon-edit fa-lg', t = N_('Edit this VM'), t), + button( + :vm_edit_description, + 'pficon pficon-edit fa-lg', + t = N_('Edit this VM Description'), + t, + :options => {:feature => :set_description}), button( :vm_rename, 'pficon pficon-edit fa-lg', diff --git a/app/javascript/components/vm-edit-form/helper.js b/app/javascript/components/vm-edit-form/helper.js index 7db15d5676d4..4188879b2c78 100644 --- a/app/javascript/components/vm-edit-form/helper.js +++ b/app/javascript/components/vm-edit-form/helper.js @@ -76,6 +76,11 @@ export const getNoEmsInitialValues = (recordId, isTemplate, setState) => { }); }; +export const descriptionData = (values) => ({ + action: 'edit', + resource: { description: values.description ? values.description : '' }, +}); + export const getSubmitData = (values) => { let customIdentifier = ''; let description = ''; diff --git a/app/javascript/components/vm-edit-form/index.jsx b/app/javascript/components/vm-edit-form/index.jsx index 79cd5e02eb4d..7d79cc68c40f 100644 --- a/app/javascript/components/vm-edit-form/index.jsx +++ b/app/javascript/components/vm-edit-form/index.jsx @@ -7,11 +7,23 @@ import createSchema from './vm-edit-form.schema'; import { API } from '../../http_api'; import miqRedirectBack from '../../helpers/miq-redirect-back'; import handleFailure from '../../helpers/handle-failure'; -import { getInitialValues, getNoEmsInitialValues, getSubmitData } from './helper'; +import { + getInitialValues, getNoEmsInitialValues, getSubmitData, descriptionData, +} from './helper'; const VmEditForm = ({ - recordId, emsId, displayName, isTemplate, + recordId, emsId, displayName, isTemplate, editDescription, }) => { + let returnURL = '/vm_infra/explorer/'; + if (displayName === 'Image' || displayName === 'Instance') { + returnURL = '/vm_cloud/explorer/'; + } + + let URL = `/api/vms/${recordId}`; + if (isTemplate) { + URL = `/api/templates/${recordId}`; + } + const [{ initialValues, parentOptions, isLoading, }, setState] = useState({ @@ -34,20 +46,22 @@ const VmEditForm = ({ } }); - const onSubmit = (values) => { - miqSparkleOn(); - let URL = `/api/vms/${recordId}`; - let returnURL = '/vm_infra/explorer/'; - const data = getSubmitData(values); - - if (displayName === 'Image' || displayName === 'Instance') { - returnURL = '/vm_cloud/explorer/'; - } - - if (isTemplate) { - URL = `/api/templates/${recordId}`; - } + /** Function to update just the description of the record on form submit. */ + const updateDescription = (values) => { + // const data = descriptionData(values); + const payload = { action: 'set_description', resource: { new_description: 'test_description' } }; + return API.post(URL, payload) + .then(() => { + miqSparkleOn(); + const message = sprintf(__('%s "%s" description was saved'), displayName, initialValues.name); + miqRedirectBack(message, 'success', returnURL); + }) + .catch(handleFailure); + }; + /** Function to update the entire record on form submit. */ + const updateRecord = (values) => { + const data = getSubmitData(values); return API.post(URL, data) .then(() => { miqSparkleOn(); @@ -57,6 +71,13 @@ const VmEditForm = ({ .catch(handleFailure); }; + /** Function to handle the form submit event. */ + const onSubmit = (values) => { + miqSparkleOn(); + return editDescription ? updateDescription(values) : updateRecord(values); + }; + + /** Function to handle the form cancel event. */ const onCancel = () => { miqSparkleOn(); let returnURL = '/vm_infra/explorer/'; @@ -70,7 +91,7 @@ const VmEditForm = ({ if (isLoading) return ; return !isLoading && ( ([{ + component: componentTypes.TEXTAREA, + name: 'description', + label: __('Description'), + maxLength: 100, +}]); + +/** Function to return the form schema. */ +const defaultFields = (emsId, parentOptions) => ([ + { + component: componentTypes.SUB_FORM, + name: 'BasicInformation', + title: __('Basic Information'), + fields: [ + { + component: componentTypes.TEXT_FIELD, + name: 'custom_1', + label: __('Custom Identifier'), + maxLength: 50, + autoFocus: true, + }, + descriptionField(), + ], + }, + { + component: componentTypes.SUB_FORM, + name: 'ParentVmSelection', + title: __('Parent VM Selection'), + fields: [ + { + component: componentTypes.SELECT, + label: __('Parent VM'), + name: 'parent_vm', + id: 'parent_vm', + placeholder: __('No Parent'), + includeEmpty: true, + validateOnMount: true, + options: parentOptions, + }, + ], + }, + { + component: componentTypes.SUB_FORM, + name: 'ChildVMSelection', + fields: [ + { + component: 'dual-list-select', + id: 'child_vms', + name: 'child_vms', + key: `alerts-${emsId}`, + label: __('Child VM Selection'), + rightTitle: __('Child VMs:'), + leftTitle: __('Available VMs:'), + allToRight: true, + moveLeftTitle: __('Move selected VMs to left'), + moveRightTitle: __('Move selected VMs to right'), + moveAllRightTitle: __('Move all VMs to right'), + moveAllLeftTitle: __('Remove All'), + noValueTitle: __('No option selected'), + noOptionsTitle: __('No available options'), + filterOptionsTitle: __('Filter options'), + filterValuesTitle: __('Filter values'), + AddButtonProps: { + id: 'addButtonProps', + className: 'addButtonProps', + size: 'small', + iconDescription: 'Add Selected', }, - { - component: componentTypes.TEXTAREA, - name: 'description', - label: __('Description'), - maxLength: 100, + AddAllButtonProps: { + size: 'small', + iconDescription: 'Add All', }, - ], - }, - { - component: componentTypes.SUB_FORM, - name: 'ParentVmSelection', - title: __('Parent VM Selection'), - fields: [ - { - component: componentTypes.SELECT, - label: __('Parent VM'), - name: 'parent_vm', - id: 'parent_vm', - placeholder: __('No Parent'), - includeEmpty: true, - validateOnMount: true, - options: parentOptions, + RemoveButtonProps: { + id: 'removeButtonProps', + className: 'removeButtonProps', + size: 'small', + iconDescription: 'Remove Selected', }, - ], - }, - { - component: componentTypes.SUB_FORM, - name: 'ChildVMSelection', - fields: [ - { - component: 'dual-list-select', - id: 'child_vms', - name: 'child_vms', - key: `alerts-${emsId}`, - label: __('Child VM Selection'), - rightTitle: __('Child VMs:'), - leftTitle: __('Available VMs:'), - allToRight: true, - moveLeftTitle: __('Move selected VMs to left'), - moveRightTitle: __('Move selected VMs to right'), - moveAllRightTitle: __('Move all VMs to right'), - moveAllLeftTitle: __('Remove All'), - noValueTitle: __('No option selected'), - noOptionsTitle: __('No available options'), - filterOptionsTitle: __('Filter options'), - filterValuesTitle: __('Filter values'), - AddButtonProps: { - id: 'addButtonProps', - className: 'addButtonProps', - size: 'small', - iconDescription: "Add Selected", - }, - AddAllButtonProps: { - size: 'small', - iconDescription: "Add All", - }, - RemoveButtonProps: { - id: 'removeButtonProps', - className: 'removeButtonProps', - size: 'small', - iconDescription: "Remove Selected", - }, - RemoveAllButtonProps: { - size: 'small', - iconDescription: "Remove All", - }, - options: parentOptions, + RemoveAllButtonProps: { + size: 'small', + iconDescription: 'Remove All', }, - ], - }, - ]; - return { fields }; + options: parentOptions, + }, + ], + }, +]); + +function createSchema(emsId, parentOptions, editDescription) { + console.log(editDescription); + if (editDescription) { + return { fields: descriptionField(emsId, parentOptions) }; + } + return { fields: defaultFields(emsId, parentOptions) }; } export default createSchema; diff --git a/app/views/vm_common/_form.html.haml b/app/views/vm_common/_form.html.haml index 9592b2c7698d..a579d75d3387 100644 --- a/app/views/vm_common/_form.html.haml +++ b/app/views/vm_common/_form.html.haml @@ -1,7 +1,8 @@ #main_div = render :partial => "layouts/flash_msg" - = react('VmEditForm', {:recordId => @record.id&.to_s, - :emsId => @record.ems_id&.to_s, - :showTitle => !@edit[:explorer], - :isTemplate => @record.kind_of?(::MiqTemplate), - :displayName => model_for_vm(@record).display_name}) + = react('VmEditForm', {:recordId => @record.id&.to_s, + :emsId => @record.ems_id&.to_s, + :showTitle => !@edit[:explorer], + :isTemplate => @record.kind_of?(::MiqTemplate), + :displayName => model_for_vm(@record).display_name, + :editDescription => @edit_description || false})