From 99f5a11f90d11720a2913e773665a4744eb7d69f Mon Sep 17 00:00:00 2001 From: Jose Miguel Gallas Olmedo Date: Mon, 6 May 2024 12:41:58 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9Clean=20(and=20update)=20applicatio?= =?UTF-8?q?n.js=20(#3754)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * moves application.js from assets to webpack (admin portal) * moves fields_definitions script to its own pack * remove legacy, unused event handlers --- app/assets/javascripts/application.js | 244 ------------------ .../javascripts/provider/layout/provider.js | 1 - .../packs/fields_definitions_form.ts | 109 ++++++++ app/javascript/packs/provider.ts | 3 + app/javascript/src/Common/application.ts | 65 +++++ app/javascript/src/Types/jquery/v1/index.d.ts | 5 + .../admin/fields_definitions/_form.html.erb | 4 + app/views/plans/_selector_widget.html.erb | 2 + 8 files changed, 188 insertions(+), 245 deletions(-) delete mode 100644 app/assets/javascripts/application.js create mode 100644 app/javascript/packs/fields_definitions_form.ts create mode 100644 app/javascript/src/Common/application.ts diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js deleted file mode 100644 index e8b59cc3db..0000000000 --- a/app/assets/javascripts/application.js +++ /dev/null @@ -1,244 +0,0 @@ -(function($) { - $(document).on('click', '.show-trace-lr', function(e){ - e.preventDefault(); - // Show the next tr - $(this).parents('tr').next().toggle(); - $(this).parents('tr').toggleClass('showing'); - }); - - // rest - $(document).ready(function() { - - // disable links with 'data-disabled' attribute and display alert instead - // delegation on body fires before rails.js - $('body').delegate('a[data-disabled]', 'click', function(event) { - event.preventDefault(); - event.stopImmediatePropagation(); - alert($(this).data('disabled')); - return false; - }); - - (function(){ - // return if not in correct pages - if($("#fields_definition_name").size() == 0 ) return; - // define functions - function disableInterface(){ - function enable_checkboxes(){ - checkboxes_disabled(false); - } - - function disable_checkboxes(){ - checkboxes_disabled(true); - } - function checkboxes_disabled(action){ - $("#fields_definition_hidden").attr('disabled',action); - $("#fields_definition_read_only").attr('disabled',action); - $("#fields_definition_required").attr('disabled',action); - } - function disable_name_field(){ - $("#fields_definition_name")[0].value = $("#fields_definition_fieldname")[0].value; - $("#fields_definition_name").attr('readonly', true); - } - function clear_checkboxes(){ - $("#fields_definition_hidden")[0].checked=false; - $("#fields_definition_read_only")[0].checked=false; - $("#fields_definition_required")[0].checked=false; - } - - function clear_choices(){ - $("#fields_definition_choices_for_views")[0].value = ''; - } - function read_only_choices(action){ - $("#fields_definition_choices_for_views").attr('readonly', action); - } - function enable_choices(){ - read_only_choices(false); - } - function disable_choices(){ - read_only_choices(true); - } - - // new view - if($("#fields_definition_fieldname").size() != 0){ - $("#fields_definition_fieldname").change(function() { - if($("#fields_definition_fieldname")[0].value == "[new field]"){ - $("#fields_definition_name").attr('readonly', false); - $("#fields_definition_name")[0].value=''; - clear_checkboxes(); - enable_checkboxes(); - clear_choices(); - enable_choices(); - } - else if($.inArray($("#fields_definition_fieldname")[0].value, - $("#required_fields")[0].value.split(",")) != -1){ - //non_modifiable fields - disable_name_field(); - clear_checkboxes(); - disable_checkboxes(); - clear_choices(); - enable_choices(); - } - else { - disable_name_field(); - clear_checkboxes(); - enable_checkboxes(); - clear_choices(); - enable_choices(); - } - }); - } - - if (($("#fields_definition_required").size() != 0 ) && - ($("#fields_definition_required")[0].checked)){ - $("#fields_definition_hidden")[0].checked=false; - $("#fields_definition_read_only")[0].checked=false; - $("#fields_definition_hidden").attr('disabled',true); - $("#fields_definition_read_only").attr('disabled',true); - } - - //edit view - if($("#fields-definitions-edit-view").size() != 0 ){ - $("#fields_definition_name").attr('readonly', true); - $("#fields_definition_name").attr('disabled', true); -} }; - - disableInterface(); - // disableCheckboxesOnload(); - })(); - - (function(){ - // return if not in correct pages - if($("#fields_definition_required").lenght==0) return; - // define functions - function synchronize_checkboxes(){ - $("#fields_definition_required").change(function(){ - if ($("#fields_definition_required")[0].checked){ - $("#fields_definition_hidden")[0].checked=false; - $("#fields_definition_read_only")[0].checked=false; - $("#fields_definition_hidden").attr('disabled',true); - $("#fields_definition_read_only").attr('disabled',true); - } - else{ - $("#fields_definition_hidden").attr('disabled',false); - $("#fields_definition_read_only").attr('disabled',false); - }}); - }; - // call function - synchronize_checkboxes(); - })(); - - (function(){ - if ($('#plan-select').length == 0) return; - var currentPlanID = $('#plans-selector').attr('data-plan-id'); - var $plans = $('div.plan-preview'); - - $('#plan-select')[0].options[0].value - var options = $('#plan-select')[0].options; - - for (var i = options.length - 1; i >= 0; i--){ - if(options[i].value == currentPlanID) { - options.selectedIndex = (i - length); - } - }; - - function attachEvents(){ - $('#plan-select').change(function(){ - - var planID = this.options[this.selectedIndex].value; - $plans.hide(); - $('div.plan-preview[data-plan-id="'+planID+'"]').show(); - - // HACK HACK HACK - redo the plan selector! - if ($('#plans-selector').attr('data-plan-id') == planID) { - $('#plan-change-submit').hide(); - } else { - $('#plan-change-submit').show(); - } - - return false; - }); - } - - attachEvents(); - })(); - - // DEPRECATED: since the introduction of PF4 and React, colorbox is being removed. - // Response of this form will be presented inside a colorbox. - $(document).on('submit', 'form.colorbox[data-remote]', function (e) { - $(this).on('ajax:complete', function(event, xhr, status){ - var form = $(this).closest('form'); - var width = form.data('width'); - $.colorbox({ - open: true, - html: xhr.responseText, - width: width, - maxWidth: '85%', - maxHeight: '90%' - }); - }) - }); - - $(document).on("click", "a.fancybox, a.colorbox", function (e) { - $(this).colorbox({ open:true }); - e.preventDefault(); - }); - - $(document).on('click', '.fancybox-close', function () { - $.colorbox.close(); - return false; - }); - - // Show panel on click. - $("a.show-panel").click(function() { - findPanel($(this)).fadeIn("fast"); - return false; - }) - - // Hide panel on click. - $("a.hide-panel").click(function() { - findPanel($(this)).fadeOut("fast"); - return false; - }) - - // Toggle panel on click. - $("a.toggle-panel").click(function() { - var panel = findPanel($(this)); - - if (panel.is(":visible")) { - panel.fadeOut("fast"); - } else { - panel.fadeIn("fast"); - } - - return false; - }); - - var findPanel = function(link) { - var id = link.attr("data-panel"); - - if (id) { - return $("#" + id); - } else { - return $(link.attr("href")); - } - } - - // DEPRECATED: since the introduction of PF4 and React, colorbox is being removed. Also jquery-ujs has been replaced with rails-ujs. - // Added #colorbox selector to target only non-React forms - // show errors from ajax in formtastic - $(document).on('ajax:error', 'form:not(.pf-c-form)', function (event, xhr, status, error) { - switch(status){ - case 'error': - $.colorbox({html: xhr.responseText}); - event.stopPropagation() - break; - } - }); - - - $(document).on('change', '#search_deleted_accounts', function () { - $(this.form).submit(); - }); - }); - -})(jQuery); diff --git a/app/assets/javascripts/provider/layout/provider.js b/app/assets/javascripts/provider/layout/provider.js index dadc8e2e15..865da1e108 100644 --- a/app/assets/javascripts/provider/layout/provider.js +++ b/app/assets/javascripts/provider/layout/provider.js @@ -7,7 +7,6 @@ //= require extra_fields //= require vendor/underscore.min.js //= require provider -//= require application //= require vendor/jquery.iframe-post-form.js //= require vendor/colorbox/jquery.colorbox.js //= require threescale diff --git a/app/javascript/packs/fields_definitions_form.ts b/app/javascript/packs/fields_definitions_form.ts new file mode 100644 index 0000000000..697c19ac34 --- /dev/null +++ b/app/javascript/packs/fields_definitions_form.ts @@ -0,0 +1,109 @@ +import $ from 'jquery' + +document.addEventListener('DOMContentLoaded', () => { + function enableCheckboxes () { + checkboxesDisabled(false) + } + + function disableCheckboxes () { + checkboxesDisabled(true) + } + + function checkboxesDisabled (action: boolean) { + $('#fields_definition_hidden').attr('disabled', action ? 'true' : null) + $('#fields_definition_read_only').attr('disabled', action ? 'true' : null) + $('#fields_definition_required').attr('disabled', action ? 'true' : null) + } + + function disableNameField () { + $('#fields_definition_name')[0].value = $('#fields_definition_fieldname')[0].value + $('#fields_definition_name').attr('readonly', 'true') + } + + function clearCheckboxes () { + $('#fields_definition_hidden')[0].checked = false + $('#fields_definition_read_only')[0].checked = false + $('#fields_definition_required')[0].checked = false + } + + function clearChoices () { + $('#fields_definition_choices_for_views')[0].value = '' + } + + function readOnlyChoices (action: boolean) { + $('#fields_definition_choices_for_views').attr('readonly', action ? 'true' : null) + } + + function enableChoices () { + readOnlyChoices(false) + } + + // new view + const $fieldname = $('#fields_definition_fieldname') + const requiredFields = $('#required_fields')[0].value.split(',') + + const fieldNameValue = $fieldname[0].value + + if ($fieldname.length !== 0) { + $fieldname.on('change', () => { + if (fieldNameValue === '[new field]') { + const $name = $('#fields_definition_name') + $name.attr('readonly', null) + $name[0].value = '' + clearCheckboxes() + enableCheckboxes() + clearChoices() + enableChoices() + + } else if (requiredFields.includes(fieldNameValue)) { + //non_modifiable fields + disableNameField() + clearCheckboxes() + disableCheckboxes() + clearChoices() + enableChoices() + + } else { + disableNameField() + clearCheckboxes() + enableCheckboxes() + clearChoices() + enableChoices() + } + }) + } + + const $required = $('#fields_definition_required') + + if ($required.length > 0 && $required[0].checked) { + const $hidden = $('#fields_definition_hidden') + $hidden[0].checked = false + $hidden.attr('disabled', 'true') + + const $readonly = $('#fields_definition_read_only') + $readonly[0].checked = false + $readonly.attr('disabled', 'true') + } + + //edit view + if (document.getElementById('fields-definitions-edit-view') !== null) { + const $name = $('#fields_definition_name') + $name.attr('readonly', 'true') + $name.attr('disabled', 'true') + } + + $required.on('change', () => { + const $hidden = $('#fields_definition_hidden') + const $readonly = $('#fields_definition_read_only') + + if ($required[0].checked) { + $hidden[0].checked = false + $readonly[0].checked = false + $hidden.attr('disabled', 'true') + $readonly.attr('disabled', 'true') + } else { + $hidden.attr('disabled', null) + $readonly.attr('disabled', null) + } + }) +}) diff --git a/app/javascript/packs/provider.ts b/app/javascript/packs/provider.ts index fe7e45f3b4..164e8542b4 100644 --- a/app/javascript/packs/provider.ts +++ b/app/javascript/packs/provider.ts @@ -1,5 +1,6 @@ import { renderVerticalNav } from 'Navigation/renderVerticalNav' import { renderQuickStarts } from 'QuickStarts/renderQuickStarts' +import application from 'Common/application' const jQuery1 = window.$ @@ -7,6 +8,8 @@ document.addEventListener('DOMContentLoaded', () => { renderVerticalNav() renderQuickStarts() + application() + /** * This is a legacy functionality that could be replaced with standard PF forms. */ diff --git a/app/javascript/src/Common/application.ts b/app/javascript/src/Common/application.ts new file mode 100644 index 0000000000..f36859ea99 --- /dev/null +++ b/app/javascript/src/Common/application.ts @@ -0,0 +1,65 @@ +import type { JQueryXHR } from 'Types/jquery/v1' + +const jQuery1 = window.$ + +export default function (): void { + // disable links with 'data-disabled' attribute and display alert instead + // delegation on body fires before rails.js. FIXME: this is not a valid guard. If "data-disabled" + // removed manually from the DOM, the request will still go through. The link should be disabled + // (not clickable) and the server should return a flash error. + $('body').on('click', 'a[data-disabled]', (event) => { + event.preventDefault() + event.stopImmediatePropagation() + alert((event.currentTarget as HTMLAnchorElement).dataset.disabled) + }) + + /** + * This seems to be used only in app/views/master/providers/plans/_widget.html.slim:23 + * DEPRECATED: replace jquery/colorbox modals with Patternfly modals. + * TODO: add a more specific selector to separate this form from all other "remote" ones. + */ + $(document).on('submit', 'form.colorbox[data-remote]', (e) => { + // MUST USE RAILS-JQUERY since ajax:complete is triggered by rails (do not use $ from node_modules). + const $form = jQuery1(e.currentTarget as HTMLFormElement) + const width = $form.data('width') as string | undefined + $form.on('ajax:complete', (_event, xhr: JQueryXHR) => { + jQuery1.colorbox({ + open: true, + html: xhr.responseText, + width, + maxWidth: '85%', + maxHeight: '90%' + }) + }) + }) + + // TODO: replace .fancybox with .colorbox + // This link will load its content into a colorbox modal + $(document).on('click', 'a.fancybox, a.colorbox', (e) => { + jQuery1(e.currentTarget as HTMLAnchorElement).colorbox({ open: true }) + e.preventDefault() + }) + + // TODO: replace .fancybox with .colorbox + // This is used in some modals with a "Cancel" button. + $(document).on('click', '.fancybox-close', (e) => { + jQuery1.colorbox.close() + e.preventDefault() + e.stopPropagation() + }) + + /** + * Handle errors in formtastic forms rendered inside a colorbox. The error template is passed a + * responseText inside the XHR response. MUST USE RAILS-JQUERY since ajax:error is triggered by + * rails (do not use $ from node_modules). + * + * DEPRECATED: replace jquery/colorbox modals with Patternfly modals. + * TODO: add a colorbox specific selector to separate this with non-legacy implementations. + */ + jQuery1(document).on('ajax:error', 'form:not(.pf-c-form)', (event, xhr: JQueryXHR, status) => { + if (status === 'error') { + jQuery1.colorbox({ html: xhr.responseText }) + event.stopPropagation() + } + }) +} diff --git a/app/javascript/src/Types/jquery/v1/index.d.ts b/app/javascript/src/Types/jquery/v1/index.d.ts index aeaa9cf47c..495a19d554 100644 --- a/app/javascript/src/Types/jquery/v1/index.d.ts +++ b/app/javascript/src/Types/jquery/v1/index.d.ts @@ -1518,6 +1518,11 @@ export interface JQueryStatic { * @see {@link https://api.jquery.com/Types/#jQuery} */ interface JQuery { + /** + * HACK: Added manually. This is specific to porta not jquery. + */ + colorbox: ColorboxStatic; + /** * Register a handler to be called when Ajax requests complete. This is an AjaxEvent. * diff --git a/app/views/admin/fields_definitions/_form.html.erb b/app/views/admin/fields_definitions/_form.html.erb index 41ddc6caf3..80175ced59 100644 --- a/app/views/admin/fields_definitions/_form.html.erb +++ b/app/views/admin/fields_definitions/_form.html.erb @@ -1,3 +1,7 @@ +<% content_for :javascripts do %> + <%= javascript_packs_with_chunks_tag 'fields_definitions_form' %> +<% end %> + <%= f.input :target, :as => :hidden %> <%= f.input :name , :hint => true, :html => {:id => "fields_definition_name" } %> <%= f.input :label , :hint => true %> diff --git a/app/views/plans/_selector_widget.html.erb b/app/views/plans/_selector_widget.html.erb index f3670cee25..e143279b69 100644 --- a/app/views/plans/_selector_widget.html.erb +++ b/app/views/plans/_selector_widget.html.erb @@ -1,3 +1,5 @@ +<%# DELETEME: it seems this template is no longer used %> +