diff --git a/apps/dashboard/app/controllers/scripts_controller.rb b/apps/dashboard/app/controllers/scripts_controller.rb index 3f5a76aa52..fe93fdaae0 100644 --- a/apps/dashboard/app/controllers/scripts_controller.rb +++ b/apps/dashboard/app/controllers/scripts_controller.rb @@ -7,10 +7,12 @@ class ScriptsController < ApplicationController before_action :find_script, only: [:show, :edit, :destroy, :submit, :save] SAVE_SCRIPT_KEYS = [ - :cluster, :auto_accounts, :auto_accounts_exclude, :auto_scripts, :auto_scripts_exclude, - :auto_queues, :auto_queues_exclude, :auto_batch_clusters, :auto_batch_clusters_exclude, - :bc_num_slots, :bc_num_slots_min, :bc_num_slots_max, - :bc_num_hours, :bc_num_hours_min, :bc_num_hours_max + :cluster, :auto_accounts, :auto_accounts_exclude, :auto_accounts_fixed, + :auto_scripts, :auto_scripts_exclude, :auto_scripts_fixed, + :auto_queues, :auto_queues_exclude, :auto_queues_fixed, + :auto_batch_clusters, :auto_batch_clusters_exclude, :auto_batch_clusters_fixed, + :bc_num_slots, :bc_num_slots_fixed, :bc_num_slots_min, :bc_num_slots_max, + :bc_num_hours, :bc_num_hours_fixed, :bc_num_hours_min, :bc_num_hours_max ].freeze def new diff --git a/apps/dashboard/app/helpers/batch_connect/session_contexts_helper.rb b/apps/dashboard/app/helpers/batch_connect/session_contexts_helper.rb index 7304dedeb3..85c6590ecc 100644 --- a/apps/dashboard/app/helpers/batch_connect/session_contexts_helper.rb +++ b/apps/dashboard/app/helpers/batch_connect/session_contexts_helper.rb @@ -1,13 +1,17 @@ # Helper for creating new batch connect sessions. module BatchConnect::SessionContextsHelper - def create_widget(form, attrib, format: nil, hide_excludable: true) - return '' if attrib.fixed? + def create_widget(form, attrib, format: nil, hide_excludable: true, hide_fixed: true) + return '' if hide_fixed && attrib.fixed? return '' if attrib.hide_when_empty? && attrib.value.blank? widget = attrib.widget field_options = attrib.field_options(fmt: format) all_options = attrib.all_options(fmt: format) + if attrib.fixed? + return render :partial => "batch_connect/session_contexts/fixed", :locals => { form: form, attrib: attrib, field_options: field_options, format: format } + end + case widget when 'select' form.select(attrib.id, attrib.select_choices(hide_excludable: hide_excludable), field_options, attrib.html_options) diff --git a/apps/dashboard/app/helpers/scripts_helper.rb b/apps/dashboard/app/helpers/scripts_helper.rb index f461e1561d..804edda226 100644 --- a/apps/dashboard/app/helpers/scripts_helper.rb +++ b/apps/dashboard/app/helpers/scripts_helper.rb @@ -5,7 +5,11 @@ module ScriptsHelper def create_editable_widget(form, attrib, format: nil) widget = attrib.widget attrib.html_options = { class: 'real-field', autocomplete: 'off' } - locals = { form: form, attrib: attrib, format: format } + # For editable script elements, we want the standard render form even when they are fixed. + # We need to reset the fixed attribute to avoid being render as a read only text field. + fixed_attribute = attrib.fixed? + attrib.opts[:fixed] = false + locals = { form: form, attrib: attrib, format: format, fixed: fixed_attribute } case widget when 'number_field' diff --git a/apps/dashboard/app/javascript/packs/script_edit.js b/apps/dashboard/app/javascript/packs/script_edit.js index 861551c9cd..63bdb8f4c9 100644 --- a/apps/dashboard/app/javascript/packs/script_edit.js +++ b/apps/dashboard/app/javascript/packs/script_edit.js @@ -44,8 +44,8 @@ function addNewField(_event) { } function updateNewFieldOptions(selectMenu) { - for(var newField in newFieldData) { - field = document.getElementById(`script_${newField}`); + for(let newField in newFieldData) { + const field = document.getElementById(`script_${newField}`); // if the field doesn't already exist, it's an option for a new field. if(field === null) { @@ -121,10 +121,36 @@ function addInProgressField(event) { justAdded.find('[data-select-toggler]') .on('click', (event) => { enableOrDisableSelectOption(event) }); + justAdded.find('[data-fixed-toggler]') + .on('click', (event) => { toggleFixedField(event) }); + const entireDiv = event.target.parentElement.parentElement.parentElement; entireDiv.remove(); } +function fixedFieldEnabled(checkbox, dataElement) { + // Disable the element to avoid updates from the user + dataElement.disabled = true; + // As it is disabled, need to add a hidden field with the same name to send the fixed field value to the backend. + const input = $('').attr('type','hidden').attr('name', dataElement.name).attr('value', dataElement.value); + $(checkbox).after(input); +} + +function toggleFixedField(event) { + event.target.disabled = true; + const elementId = event.target.dataset.fixedToggler; + const dataElement = document.getElementById(elementId); + if (event.target.checked) { + fixedFieldEnabled(event.target, dataElement) + } else { + dataElement.disabled = false; + // Field enabled, remove the hidden field with the same name needed when disabled. + $(`input[type=hidden][name="${dataElement.name}"]`).remove(); + } + + event.target.disabled = false; +} + function enableOrDisableSelectOption(event) { const toggleAction = event.target.dataset.selectToggler; const li = event.target.parentElement; @@ -199,6 +225,20 @@ function initSelectFields(){ }); } + +function initFixedFields(){ + const fixedCheckboxes = Array.from($('[data-fixed-toggler]')); + + // find all the enabled 'fixed' checkboxes + fixedCheckboxes.filter((fixedFieldCheckbox) => { + return fixedFieldCheckbox.checked; + // now fix the value of the related field + }).map((fixedFieldCheckbox) => { + const dataElement = document.getElementById(fixedFieldCheckbox.dataset.fixedToggler); + fixedFieldEnabled(fixedFieldCheckbox, dataElement) + }); +} + jQuery(() => { newFieldTemplate = $('#new_field_template'); $('#add_new_field_button').on('click', (event) => { addNewField(event) }); @@ -215,5 +255,9 @@ jQuery(() => { $('[data-select-toggler]') .on('click', (event) => { enableOrDisableSelectOption(event) }); + $('[data-fixed-toggler]') + .on('click', (event) => { toggleFixedField(event) }); + initSelectFields(); + initFixedFields(); }); diff --git a/apps/dashboard/app/models/script.rb b/apps/dashboard/app/models/script.rb index e7cb0e55a7..15e678c295 100644 --- a/apps/dashboard/app/models/script.rb +++ b/apps/dashboard/app/models/script.rb @@ -111,7 +111,7 @@ def respond_to_missing?(method_name, include_private = false) end def original_parameter(string) - match = /([\w_]+)_(?:min|max|exclude)/.match(string) + match = /([\w_]+)_(?:min|max|exclude|fixed)/.match(string) match[1] end @@ -201,7 +201,7 @@ def self.script_form_file(script_path) # parameters you got from the controller that affect the attributes, not form. # i.e., mins & maxes you set in the form but get serialized to the 'attributes' section. def attribute_parameter?(name) - name.end_with?('_min') || name.end_with?('_max') || name.end_with?('_exclude') + ['min', 'max', 'exclude', 'fixed'].any? { |postfix| name && name.end_with?("_#{postfix}") } end # update the 'form' portion of the yaml file given 'params' from the controller. @@ -222,6 +222,7 @@ def update_attributes(params) orig_param = original_parameter(key).to_sym self[orig_param].min = value if key.end_with?('_min') && !value.to_s.empty? self[orig_param].max = value if key.end_with?('_max') && !value.to_s.empty? + self[orig_param].opts[:fixed] = true if key.end_with?('_fixed') if key.end_with?('_exclude') exclude_list = value.split(',').to_a diff --git a/apps/dashboard/app/views/batch_connect/session_contexts/_fixed.html.erb b/apps/dashboard/app/views/batch_connect/session_contexts/_fixed.html.erb new file mode 100644 index 0000000000..56de8de31a --- /dev/null +++ b/apps/dashboard/app/views/batch_connect/session_contexts/_fixed.html.erb @@ -0,0 +1,6 @@ +<%- + all_options = attrib.all_options(fmt: format) + all_options[:readonly] = true +%> + +<%= form.text_field(attrib.id, all_options) %> \ No newline at end of file diff --git a/apps/dashboard/app/views/scripts/editable_form_fields/_edit_fixed_field.html.erb b/apps/dashboard/app/views/scripts/editable_form_fields/_edit_fixed_field.html.erb new file mode 100644 index 0000000000..a2670ec631 --- /dev/null +++ b/apps/dashboard/app/views/scripts/editable_form_fields/_edit_fixed_field.html.erb @@ -0,0 +1,12 @@ +<%- + field_id = "#{form.object_name}_#{attrib.id}" + + fixed_id = "#{field_id}_fixed" + fixed_name = "#{form.object_name}[#{attrib.id}_fixed]" +-%> +