diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 25babb1b055..c8567762016 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -38,7 +38,7 @@ function onContentLoad() {
if ($('input[focus_on_load=true]').length > 0) {
$('input[focus_on_load]')
.first()
- .focus();
+ .trigger("focus");
}
// highlight tabs with errors
@@ -79,24 +79,71 @@ function onContentLoad() {
password_caps_lock_hint();
- tfm.i18n.intl.ready.then(function() {
- var tz = jstz.determine();
- $.cookie('timezone', tz.name(), {
- path: '/',
- secure: location.protocol === 'https:',
- });
- });
-
$('.full-value').SelectOnClick();
activate_select2(':root');
$('input.remove_form_templates')
.closest('form')
- .submit(function(event) {
+ .on('submit', function(event) {
$(this)
.find('.form_template')
.remove();
});
+
+ const autoUpdateSelect2Titles = function() {
+ const targetNodes = document.querySelectorAll(
+ '.select2-selection__rendered'
+ );
+
+ const config = { attributes: true, attributeFilter: ['title'] };
+
+ const callback = function(mutationsList, observer) {
+ for (let mutation of mutationsList) {
+ if (
+ mutation.type === 'attributes' &&
+ mutation.attributeName === 'title'
+ ) {
+ mutation.target.setAttribute(
+ 'data-original-title',
+ mutation.target.getAttribute('title')
+ );
+ }
+ }
+ };
+
+ targetNodes.forEach(targetNode => {
+ const observer = new MutationObserver(callback);
+ observer.observe(targetNode, config);
+ });
+ };
+
+ const hideSelect2ClearTooltip = function() {
+ $(document).on('blur', '.select2-selection__clear', function() {
+ $('.tooltip').tooltip('hide');
+ });
+
+ const targetNode = document.querySelector('body');
+ const config = { attributes: false, childList: true, subtree: true };
+ const callback = function(mutationsList) {
+ for (let mutation of mutationsList) {
+ if (mutation.type === 'childList') {
+ const node = Array.from(mutation.removedNodes).find(
+ node =>
+ node.classList &&
+ node.classList.contains('select2-selection__clear')
+ );
+ if (node) {
+ $('.tooltip').tooltip('hide');
+ }
+ }
+ }
+ };
+ const observer = new MutationObserver(callback);
+ observer.observe(targetNode, config);
+ };
+
+ hideSelect2ClearTooltip();
+ autoUpdateSelect2Titles();
}
function preserve_selected_options(elem) {
@@ -106,7 +153,7 @@ function preserve_selected_options(elem) {
}
function password_caps_lock_hint() {
- $('[type=password]').keypress(function(e) {
+ $('[type=password]').trigger('keypress', function(e) {
var $addon = $(this)
.parent()
.children('.input-addon'),
@@ -309,7 +356,7 @@ function ignore_subnet(item) {
// shows provisioning templates in a new window
$(function() {
- $('[data-provisioning-template=true]').click(function() {
+ $('[data-provisioning-template=true]').on('click', function() {
window.open(this.href, [
(width = '300'),
(height = '400'),
@@ -431,18 +478,34 @@ function disableButtonToggle(item, explicit) {
$(formControl).val('');
}
- $(item).blur();
+ $(item).trigger('blur');
}
-function activate_select2(container, allowClear) {
- allowClear = typeof allowClear !== 'undefined' ? allowClear : true;
+function activate_select2(container, allowClear ) {
+ const htmlElemnt = document.getElementsByTagName('html')[0];
+ const langAttr = htmlElemnt.getAttribute('lang') || 'en';
$(container)
.find('select:not(.without_select2)')
.not('.form_template select')
.not('#interfaceForms select')
- .select2({
- allowClear: allowClear,
- formatNoMatches: __('No matches found'),
+ .each(function() {
+ const placeholder = $(this).data('placeholder');
+ let selectAllowClear = allowClear
+ if (typeof selectAllowClear === 'undefined') {
+ if ($(this).hasClass('include_blank')) {
+ selectAllowClear = true;
+ } else {
+ selectAllowClear = false;
+ }
+ }
+ $(this).select2({
+ debug: true,
+ language: langAttr,
+ width: '100%',
+ allowClear: selectAllowClear,
+ formatNoMatches: __('No matches found'),
+ placeholder: selectAllowClear? placeholder || '' : { id: '-1', text: '' },
+ });
});
}
@@ -463,3 +526,14 @@ function clearError(field) {
.children('.error-message');
error_block.remove();
}
+
+// jQuery deprecated functions
+// used by gridster and bootstrap
+$.fn.isFunction = function(func) {
+ return typeof func === 'function';
+};
+$.fn.isArray = Array.isArray;
+$.fn.trim = String.prototype.trim;
+$.fn.bind = function(event, func) {
+ return this.on(event, func);
+};
diff --git a/app/assets/javascripts/hidden_values.js b/app/assets/javascripts/hidden_values.js
index 8a52e79102b..ee386774f78 100644
--- a/app/assets/javascripts/hidden_values.js
+++ b/app/assets/javascripts/hidden_values.js
@@ -3,7 +3,7 @@ function turn_textarea_switch() {
}
function hidden_value_control() {
- $('.toggle-hidden-value a').click(function(event) {
+ $('.toggle-hidden-value a').on('click', function(event) {
event.preventDefault();
var link = $(event.currentTarget);
link
diff --git a/app/assets/javascripts/host_edit.js b/app/assets/javascripts/host_edit.js
index 742a5ea7ad8..57f663fea4b 100644
--- a/app/assets/javascripts/host_edit.js
+++ b/app/assets/javascripts/host_edit.js
@@ -1,13 +1,11 @@
//= require parameter_override
-$(document).ready(function() {
+$(document).on('ContentLoad', function() {
var searchParams = new URLSearchParams(window.location.search);
if(searchParams.has('hostgroup_id')) {
var param = searchParams.get('hostgroup_id');
$('#host_hostgroup_id').val(param).trigger('change');
}
-});
-$(document).on('ContentLoad', function() {
onHostEditLoad();
});
$(document)
@@ -145,11 +143,11 @@ function update_capabilities(capabilities) {
var build = capabilities.indexOf('build') > -1;
if (build) {
$('#manage_network_build').show();
- $('#host_provision_method_build').click();
+ $('#host_provision_method_build').trigger('click');
build_provision_method_selected();
} else if (capabilities.length > 0) {
$('#manage_network_build').hide();
- $('#host_provision_method_' + capabilities[0]).click();
+ $('#host_provision_method_' + capabilities[0]).trigger('click');
if (capabilities[0].toLowerCase() === 'image') {
image_provision_method_selected();
}
@@ -329,7 +327,7 @@ function update_form(element, options) {
if (host_compute_resource_id.exists()) {
// to handle case if def process_taxonomy changed compute_resource_id to nil
if (!host_compute_resource_id.val()) {
- host_compute_resource_id.change();
+ host_compute_resource_id.trigger('change');
} else {
// in case the compute resource was selected, we still want to check for
// free ip if applicable
diff --git a/app/assets/javascripts/host_edit_interfaces.js b/app/assets/javascripts/host_edit_interfaces.js
index 75cc3f5a4f2..4de94404107 100644
--- a/app/assets/javascripts/host_edit_interfaces.js
+++ b/app/assets/javascripts/host_edit_interfaces.js
@@ -1,6 +1,6 @@
-$(document).ready(function() {
- $('#host_name').select();
- $('#host_name').focus();
+$(document).on('ContentLoad', function() {
+ $('#host_name').trigger("select");
+ $('#host_name').trigger("focus");
});
function remove_interface(interface_id) {
@@ -107,12 +107,12 @@ function get_interface_row(interface_id) {
interface_row.attr('id', 'interface' + interface_id);
interface_row.data('interface-id', interface_id);
- interface_row.find('.showModal').click(function() {
+ interface_row.find('.showModal').on('click', function() {
edit_interface(interface_id);
return false;
});
- interface_row.find('.removeInterface').click(function() {
+ interface_row.find('.removeInterface').on('click', function() {
remove_interface(interface_id);
return false;
});
diff --git a/app/assets/javascripts/hosts.js b/app/assets/javascripts/hosts.js
index b5df44012b6..54125e10a97 100644
--- a/app/assets/javascripts/hosts.js
+++ b/app/assets/javascripts/hosts.js
@@ -2,7 +2,7 @@ $(document).on('ContentLoad', function() {
tfm.tools.setTab();
var dialog = $('#review_before_build');
- $('#build-review').click(function() {
+ $('#build-review').on('click', function() {
dialog.find('.modal-body #build_status').html('');
$('.loading').addClass('visible');
$.ajax({
@@ -26,7 +26,7 @@ $(document).on('ContentLoad', function() {
});
dialog.on('click', '#recheck_review', function() {
- $('#build-review').click();
+ $('#build-review').trigger('click');
});
var action_buttons = $('.btn-toolbar a')
diff --git a/app/assets/javascripts/jquery.multi-select.js b/app/assets/javascripts/jquery.multi-select.js
index dd5bb993dd3..938ce7077eb 100644
--- a/app/assets/javascripts/jquery.multi-select.js
+++ b/app/assets/javascripts/jquery.multi-select.js
@@ -27,28 +27,28 @@ function multiSelectToolTips(){
var msid = '#ms-'+item.id;
// it an
items match multiple tooltips, then only the first tooltip will show
if (!(mismatches == null || mismatches == 'undefined')) {
- var missing_ids = $.parseJSON(mismatches);
+ var missing_ids = JSON.parse(mismatches);
$.each(missing_ids, function(index,missing_id){
opt_id = sanitize(missing_id+'');
$(msid).find('li#'+opt_id+'-selectable').addClass('delete').tooltip({container: 'body', title: __("Select this since it belongs to a host"), placement: "left"});
})
}
if (!(useds == null || descendants == 'useds')) {
- var used_ids = $.parseJSON(useds);
+ var used_ids = JSON.parse(useds);
$.each(used_ids, function(index,used_id){
opt_id = sanitize(used_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('used_by_hosts').tooltip({container: 'body', title: __("This is used by a host"), placement: "right"});
})
}
if (!(inheriteds == null || inheriteds == 'undefined')) {
- var inherited_ids = $.parseJSON(inheriteds);
+ var inherited_ids = JSON.parse(inheriteds);
$.each(inherited_ids, function(index,inherited_id){
opt_id = sanitize(inherited_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('inherited').tooltip({container: 'body', title: __("This is inherited from parent"), placement: "right"});
})
}
if (!(descendants == null || descendants == 'undefined')) {
- var descendant_ids = $.parseJSON(descendants);
+ var descendant_ids = JSON.parse(descendants);
$.each(descendant_ids, function(index,descendant_id){
opt_id = sanitize(descendant_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('descendants').tooltip({container: 'body', title: __("Parent is already selected"), placement: "right"});
@@ -77,7 +77,7 @@ $(document).on('click', '.ms-select-all', function () {
$(this).tooltip('hide')
.closest('.form-group')
.find('.ms-selectable .ms-list :visible')
- .click();
+ .trigger('click');
return false;
});
diff --git a/app/assets/javascripts/lookup_keys.js b/app/assets/javascripts/lookup_keys.js
index 618636807dc..720155fb771 100644
--- a/app/assets/javascripts/lookup_keys.js
+++ b/app/assets/javascripts/lookup_keys.js
@@ -28,7 +28,7 @@ function select_first_tab() {
pills
.find('a:visible')
.first()
- .click();
+ .trigger('click');
}
}
@@ -39,7 +39,7 @@ function remove_node(item) {
.attr('href')
)
.children('.btn-danger')
- .click();
+ .trigger('click');
}
function fix_template_context(content, context) {
diff --git a/app/assets/javascripts/parameter_override.js b/app/assets/javascripts/parameter_override.js
index 1a66b6a7087..cd58ce7d60c 100644
--- a/app/assets/javascripts/parameter_override.js
+++ b/app/assets/javascripts/parameter_override.js
@@ -8,7 +8,7 @@ function override_param(item) {
var v = param_value.val();
var addParameterButton = $('#parameters').find('.btn-primary');
- addParameterButton.click();
+ addParameterButton.trigger('click');
var directionOfAddedItems = addParameterButton.attr('direction');
var new_param = $('#parameters').find('.fields');
if(directionOfAddedItems === 'append'){
@@ -26,6 +26,6 @@ function override_param(item) {
hiddenValueCheckBox = new_param.find('.set_hidden_value');
hiddenValueCheckBox.prop('checked', true);
hiddenValueCheckBox.val('1');
- alink.click();
+ alink.trigger('click');
}
}
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 6f4164bd450..bd2409c17a0 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -119,6 +119,9 @@ def select_f(f, attr, array, id, method, select_options = {}, html_options = {})
# that was defined in the struct.
blank_option.instance_eval('undef to_s', __FILE__, __LINE__) if method.to_s == 'to_s' || id.to_s == 'to_s'
array.insert(0, blank_option)
+ html_options['data-placeholder'] = blank_value || html_options['placeholder']
+ elsif html_options[:placeholder]
+ html_options['data-placeholder'] = html_options.delete(:placeholder)
end
select_options[:disabled] = '' if select_options[:disabled] == include_blank
@@ -127,7 +130,9 @@ def select_f(f, attr, array, id, method, select_options = {}, html_options = {})
html_options[:size] = 'col-md-10' if html_options[:multiple]
field(f, attr, html_options) do
addClass html_options, "form-control"
-
+ if include_blank.is_a?(TrueClass)
+ addClass html_options, "include_blank"
+ end
collection_select = f.collection_select(attr, array, id, method, select_options, html_options)
if disable_button
diff --git a/bundler.d/assets.rb b/bundler.d/assets.rb
index 606f604cc45..cd60de58e7e 100644
--- a/bundler.d/assets.rb
+++ b/bundler.d/assets.rb
@@ -1,5 +1,5 @@
group :assets do
- gem 'jquery-ui-rails', '~> 6.0'
+ gem 'jquery-ui-rails', '~> 7.0'
gem 'patternfly-sass', '~> 3.59.4'
gem 'gettext_i18n_rails_js', '~> 1.4'
gem 'po_to_json', '~> 1.1'
diff --git a/package.json b/package.json
index 98a59097288..d08b20471eb 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"graphql-tag": "^2.11.0",
"intl": "~1.2.5",
"jed": "^1.1.1",
+ "js-cookie": "^3.0.5",
"os-browserify": "^0.3.0",
"react-intl": "^2.8.0"
},
diff --git a/test/integration/compute_profile_js_test.rb b/test/integration/compute_profile_js_test.rb
index 41233fa6d60..4f08f703ced 100644
--- a/test/integration/compute_profile_js_test.rb
+++ b/test/integration/compute_profile_js_test.rb
@@ -38,10 +38,10 @@ class ComputeProfileJSTest < IntegrationTestWithJavascript
click_link("amazon123 (eu-west-1-EC2)")
assert page.has_selector?('.pf-c-page__main-breadcrumb .active', :text => compute_profiles(:one).name), "#{compute_profiles(:one).name} was expected in the breadcrumb active, but was not found"
- selected_profile = find("#s2id_compute_attribute_compute_profile_id .select2-chosen").text
+ selected_profile = select2_chosen_selector('compute_attribute_compute_profile_id').text
assert_equal compute_profiles(:one).name, selected_profile
- selected_compute = find("#s2id_compute_attribute_compute_resource_id .select2-chosen").text
+ selected_compute = select2_chosen_selector('compute_attribute_compute_resource_id').text
assert_equal "amazon123 (eu-west-1-EC2)", selected_compute
click_button('Submit')
@@ -54,7 +54,7 @@ class ComputeProfileJSTest < IntegrationTestWithJavascript
fill_in('compute_profile_name', :with => 'test')
click_on("Submit")
assert click_link(compute_resources(:ovirt).to_s)
- selected_profile = find("#s2id_compute_attribute_compute_profile_id .select2-chosen").text
+ selected_profile = select2_chosen_selector('compute_attribute_compute_profile_id').text
assert select2('hwp_small', :from => 'compute_attribute_vm_attrs_template')
wait_for_ajax
assert click_button("Submit")
diff --git a/test/integration/host_js_test.rb b/test/integration/host_js_test.rb
index 1f0b6aca8ef..65cc933845e 100644
--- a/test/integration/host_js_test.rb
+++ b/test/integration/host_js_test.rb
@@ -292,7 +292,8 @@ class HostJSTest < IntegrationTestWithJavascript
wait_for_ajax
click_on_inherit('compute_resource')
select2(overridden_hostgroup.name, :from => 'host_hostgroup_id')
- assert page.find('#s2id_host_compute_resource_id .select2-chosen').has_text? overridden_hostgroup.compute_resource.name
+ wait_for_ajax
+ assert page.find(select2_selector('host_compute_resource_id'), visible: false, wait: 10).ancestor('.select2-container').has_text? overridden_hostgroup.compute_resource.name
end
test 'choosing a hostgroup with compute resource works' do
@@ -712,8 +713,7 @@ class HostJSTest < IntegrationTestWithJavascript
private
def subnet_and_domain_are_selected(modal, domain)
- modal.assert_selector("#interfaceModal #s2id_host_interfaces_attributes_0_domain_id .select2-chosen",
- text: domain.name)
+ assert select2_chosen_selector('host_interfaces_attributes_0_domain_id').has_text? domain.name
modal.assert_selector('#interfaceModal #host_interfaces_attributes_0_subnet_id option',
visible: false,
count: domain.subnets.count + 1) # plus one empty
diff --git a/test/integration/provisioning_template_js_test.rb b/test/integration/provisioning_template_js_test.rb
index ec6b31ed773..ef7d0d4bfd9 100644
--- a/test/integration/provisioning_template_js_test.rb
+++ b/test/integration/provisioning_template_js_test.rb
@@ -16,14 +16,13 @@ class ProvisioningTemplateJSTest < IntegrationTestWithJavascript
click_link 'Type'
assert has_unchecked_field?('provisioning_template_snippet')
- assert_equal template.template_kind.name, find("#s2id_provisioning_template_template_kind_id .select2-chosen").text
-
+ assert select2_chosen_selector('provisioning_template_template_kind_id').has_text? template.template_kind.name
# check the type dropdown is hidden when snippet is checked
- assert has_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_selector?(select2_selector('provisioning_template_template_kind_id'))
find_field('provisioning_template_snippet').click
- assert has_no_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_no_selector?(select2_selector('provisioning_template_template_kind_id'))
find_field('provisioning_template_snippet').click
- assert has_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_selector?(select2_selector('provisioning_template_template_kind_id'))
assert_submit_button(provisioning_templates_path)
assert page.has_link? 'updated template'
@@ -39,11 +38,11 @@ class ProvisioningTemplateJSTest < IntegrationTestWithJavascript
assert has_checked_field?('provisioning_template_snippet')
# check the type dropdown is visible when snippet is unchecked
- assert has_no_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_no_selector?('#kind_selector')
find_field('provisioning_template_snippet').click
- assert has_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_selector?('#kind_selector')
find_field('provisioning_template_snippet').click
- assert has_no_selector?('#s2id_provisioning_template_template_kind_id')
+ assert has_no_selector?('#kind_selector')
assert_submit_button(provisioning_templates_path)
assert page.has_link? 'updated snippet'
diff --git a/test/integration/report_template_js_test.rb b/test/integration/report_template_js_test.rb
index 0b697190c3a..ed68810e2af 100644
--- a/test/integration/report_template_js_test.rb
+++ b/test/integration/report_template_js_test.rb
@@ -62,7 +62,7 @@ class ReportTemplateJSIntegrationTest < IntegrationTestWithJavascript
output_options = ['CSV', 'JSON', 'YAML', 'HTML']
visit generate_report_template_path(template)
- find('#s2id_report_template_report_format').click
+ find(select2_selector('report_template_report_format')).click
output_options.each { |opt| assert page.has_content? opt }
end
@@ -71,10 +71,10 @@ class ReportTemplateJSIntegrationTest < IntegrationTestWithJavascript
template = FactoryBot.create(:report_template)
visit generate_report_template_path(template)
- select = find('#s2id_report_template_report_format')
+ select = find(select2_selector('report_template_report_format'), visible: false).ancestor('.select2-container')
assert select.text ''
- assert select[:class].include?('select2-container-disabled'), true
+ assert select[:class].include?('select2-container--disabled'), true
end
test "should have correct generate_at field" do
diff --git a/test/integration/shared/host_finders.rb b/test/integration/shared/host_finders.rb
index d8b45c403fe..61a583113ae 100644
--- a/test/integration/shared/host_finders.rb
+++ b/test/integration/shared/host_finders.rb
@@ -54,7 +54,7 @@ def multiple_actions_div
end
def click_on_inherit(attribute, prefix: 'host_')
- find("##{prefix}#{attribute}_id + .input-group-btn .btn").click
+ find("##{prefix}#{attribute}_id").ancestor('.input-group').find(".input-group-btn .btn").click
end
def current_hosts_path(*args)
diff --git a/test/integration/user_test.rb b/test/integration/user_test.rb
index 077938b3fa9..900ad505a62 100644
--- a/test/integration/user_test.rb
+++ b/test/integration/user_test.rb
@@ -26,8 +26,8 @@ class UserIntegrationTest < IntegrationTestWithJavascript
visit users_path
click_link "Create User"
assert fill_in "user_login", :with => "new_user"
- find("#s2id_user_auth_source_id").click
- all(".select2-result-label").find do |result|
+ find(select2_selector('user_auth_source_id'), visible: false).ancestor('.select2-container').click
+ all(".select2-results__option").find do |result|
result.text == 'INTERNAL'
end.click
assert click_button("Submit")
diff --git a/test/integration_test_helper.rb b/test/integration_test_helper.rb
index fd3c0ee6888..df472c73a7b 100644
--- a/test/integration_test_helper.rb
+++ b/test/integration_test_helper.rb
@@ -98,17 +98,29 @@ def fix_mismatches
Organization.all_import_missing_ids
end
+ def select2_selector(name)
+ "#select2-#{name}-container"
+ end
+
+ def select2_result_selector(name)
+ "#select2-#{name}-container .select2-results"
+ end
+
+ def select2_chosen_selector(name)
+ page.find(select2_selector(name), visible: false, wait: 10).ancestor('.select2-container')
+ end
+
def select2(value, attrs)
- find("#s2id_#{attrs[:from]}").click
- wait_for { find('.select2-input').visible? rescue false }
- wait_for { find(".select2-input").set(value) }
+ find(select2_selector(attrs[:from]), visible: false).ancestor('.select2-container').click
+ wait_for { find('.select2-search__field').visible? rescue false }
+ wait_for { find(".select2-search__field").set(value) }
wait_for { find('.select2-results').visible? rescue false }
- within ".select2-results" do
- wait_for { find(".select2-results span", text: value).visible? rescue false }
- find("span", text: value).click
+ within ".select2-results__options" do
+ wait_for { find(".select2-results__options li", text: value).visible? rescue false }
+ find("li", text: value).click
end
wait_for do
- page.find("#s2id_#{attrs[:from]} .select2-chosen").has_text? value
+ select2_chosen_selector(attrs[:from]).has_text? value
end
end
diff --git a/webpack/assets/javascripts/bundle.js b/webpack/assets/javascripts/bundle.js
index 397994b337c..8074352d344 100644
--- a/webpack/assets/javascripts/bundle.js
+++ b/webpack/assets/javascripts/bundle.js
@@ -1,5 +1,6 @@
import 'core-js/shim';
import 'regenerator-runtime/runtime';
+import Cookies from 'js-cookie';
import compute from './foreman_compute_resource';
import componentRegistry from './react_app/components/componentRegistry';
@@ -56,4 +57,5 @@ window.tfm = Object.assign(window.tfm || {}, {
componentRegistry,
store,
lookupKeys,
+ Cookies,
});
diff --git a/webpack/assets/javascripts/foreman_auth_source.js b/webpack/assets/javascripts/foreman_auth_source.js
index 285ab0546d0..b8e0a2ce952 100644
--- a/webpack/assets/javascripts/foreman_auth_source.js
+++ b/webpack/assets/javascripts/foreman_auth_source.js
@@ -25,7 +25,7 @@ export function testConnection(item, url) {
notify({ message, type: 'success' });
},
error({ responseText }) {
- const error = $.parseJSON(responseText).message;
+ const error = JSON.parse(responseText).message;
notify({ message: error, type: 'danger' });
},
complete(result) {
diff --git a/webpack/assets/javascripts/foreman_http_proxies.js b/webpack/assets/javascripts/foreman_http_proxies.js
index b07c6adae9d..2f8da6e7655 100644
--- a/webpack/assets/javascripts/foreman_http_proxies.js
+++ b/webpack/assets/javascripts/foreman_http_proxies.js
@@ -21,7 +21,7 @@ export function testConnection(item, url) {
notify({ message: result.message, type: 'success' });
},
error(xhr) {
- const error = $.parseJSON(xhr.responseText).message;
+ const error = JSON.parse(xhr.responseText).message;
notify({ message: error, type: 'danger' });
},
diff --git a/webpack/assets/javascripts/foreman_tools.js b/webpack/assets/javascripts/foreman_tools.js
index 5cb10eccc6f..3868bff3ea3 100644
--- a/webpack/assets/javascripts/foreman_tools.js
+++ b/webpack/assets/javascripts/foreman_tools.js
@@ -123,16 +123,19 @@ export function highlightTabErrors() {
errorFields.parents('.tab-pane').each(function fn() {
$(`a[href="#${this.id}"]`).addClass('tab-error');
});
- $('.tab-error')
- .first()
- .click();
- $('.nav-pills .tab-error')
- .first()
- .click();
+ const firstTabError = document.querySelector('.tab-error');
+ if (firstTabError) {
+ $(firstTabError).tab('show');
+ }
+ const firstNestedTabError = document.querySelector('.nav-pills .tab-error');
+ if (firstNestedTabError) {
+ $(firstNestedTabError).tab('show');
+ }
+
errorFields
.first()
.find('.form-control')
- .focus();
+ .trigger('focus');
}
export const loadPluginModule = async (url, scope, module, plugin = true) => {
diff --git a/webpack/assets/javascripts/foreman_users.js b/webpack/assets/javascripts/foreman_users.js
index d4b6a42b9a5..2da22ae8441 100644
--- a/webpack/assets/javascripts/foreman_users.js
+++ b/webpack/assets/javascripts/foreman_users.js
@@ -1,3 +1,4 @@
+/* eslint-disable jquery/no-trigger */
/* eslint-disable jquery/no-toggle */
/* eslint-disable jquery/no-ajax */
/* eslint-disable jquery/no-hide */
@@ -11,7 +12,7 @@ import { notify } from './foreman_toast_notifications';
export function initInheritedRoles() {
$('#inherited-roles .dropdown-menu a')
- .click(({ target }) => {
+ .on('click', ({ target }) => {
$('#roles_tab li').hide();
$(`#roles_tab li[data-id = '${target.getAttribute('data-id')}']`).show();
$(target)
@@ -20,7 +21,7 @@ export function initInheritedRoles() {
.html(`${escape(target.text)} `);
})
.first()
- .click();
+ .trigger('click');
}
function getSelectValues({ options = [] }) {
diff --git a/webpack/assets/javascripts/hosts/tableCheckboxes.js b/webpack/assets/javascripts/hosts/tableCheckboxes.js
index 5e1a1df6c85..d360d048166 100644
--- a/webpack/assets/javascripts/hosts/tableCheckboxes.js
+++ b/webpack/assets/javascripts/hosts/tableCheckboxes.js
@@ -14,6 +14,7 @@
/* eslint-disable jquery/no-in-array */
import $ from 'jquery';
+import Cookies from 'js-cookie';
import {
sprintf,
@@ -43,7 +44,7 @@ export function hostChecked({ id, checked }) {
multipleAlert.data('multiple', false);
}
}
- $.cookie(cookieName, JSON.stringify(foremanSelectedHosts), {
+ Cookies.set(cookieName, JSON.stringify(foremanSelectedHosts), {
secure: window.location.protocol === 'https:',
});
toggleActions();
@@ -62,8 +63,8 @@ function rmHostId(id) {
function readFromCookie() {
try {
- const r = $.cookie(cookieName);
- if (r) return $.parseJSON(r);
+ const r = Cookies.get(cookieName);
+ if (r) return JSON.parse(r);
return [];
} catch (err) {
removeForemanHostsCookie();
@@ -116,7 +117,7 @@ $(document).on('ContentLoad', () => {
});
function removeForemanHostsCookie() {
- $.removeCookie(cookieName);
+ Cookies.remove(cookieName);
}
export function resetSelection() {
diff --git a/webpack/assets/javascripts/react_app/common/I18n.js b/webpack/assets/javascripts/react_app/common/I18n.js
index ad2030d70a6..654caf885cb 100644
--- a/webpack/assets/javascripts/react_app/common/I18n.js
+++ b/webpack/assets/javascripts/react_app/common/I18n.js
@@ -2,6 +2,8 @@
/* eslint-disable import/no-dynamic-require */
import Jed from 'jed';
import { addLocaleData } from 'react-intl';
+import Cookies from 'js-cookie';
+import jstz from 'jstz';
import forceSingleton from './forceSingleton';
class IntlLoader {
@@ -18,6 +20,10 @@ class IntlLoader {
await this.fetchIntl();
const localeData = require(/* webpackChunkName: 'react-intl/locale/[request]' */ `react-intl/locale-data/${this.locale}`);
addLocaleData(localeData);
+ Cookies.set('timezone', jstz.determine().name(), {
+ path: '/',
+ secure: window.location.protocol === 'https:',
+ });
return true;
}