Skip to content

Commit

Permalink
Fixes #26078 - cleanup window call, calls go through redux.
Browse files Browse the repository at this point in the history
  • Loading branch information
ezr-ondrej committed Feb 27, 2019
1 parent dbc5b4e commit 702c9eb
Showing 15 changed files with 392 additions and 341 deletions.
116 changes: 25 additions & 91 deletions app/assets/javascripts/host_edit_interfaces.js
Original file line number Diff line number Diff line change
@@ -3,20 +3,6 @@ $(document).ready(function() {
$('#host_name').focus();
})

function remove_interface(interface_id) {
tfm.hosts.removeInterface(interface_id);
}

function add_interface() {
const form = get_interface_template_clone();
show_interface_modal(form);
}

function edit_interface(interface_id) {
const form = $('#interfaces #interfaceHidden'+interface_id).clone(true);
show_interface_modal(form);
}

function show_interface_modal(modal_content) {
var modal_window = $('#interfaceModal');
var interface_id = modal_content.data('interface-id');
@@ -25,7 +11,6 @@ function show_interface_modal(modal_content) {

var identifier = modal_content.find('.interface_identifier').val();


modal_window.find('.modal-body').html('');
modal_window.find('.modal-body').append(modal_content.contents());
modal_window.find('.modal-title').text(__('Interface') + ' ' + String(identifier));
@@ -38,6 +23,7 @@ function show_interface_modal(modal_content) {
function save_interface_modal() {
var modal_window = $('#interfaceModal');
var interface_id = modal_window.data('current-id');
var is_new = modal_window.data('new-interface');

//destroy ui tools so when opening the modal again they will show correctly
modal_window.find('a[rel="popover-modal"]').popover('destroy');
@@ -48,58 +34,29 @@ function save_interface_modal() {

var modal_form = modal_window.find('.modal-body').contents();

var interface_hidden = get_interface_hidden(interface_id);
var interface_hidden = $(tfm.hosts.getInterfaceHiddenFields(interface_id));
interface_hidden.html('');
interface_hidden.append(modal_form);

close_interface_modal();
update_interface_info(interface_id, interface_hidden);
if (is_new) {
add_interface(interface_id, interface_hidden);
} else {
update_interface_info(interface_id, interface_hidden);
}
}

function close_interface_modal() {
var modal_window = $('#interfaceModal');

modal_window.modal('hide');
modal_window.removeData('current-id');
modal_window.removeData('new-interface');
modal_window.find('.modal-body').html('');
}

function get_interface_template_clone() {
var content = $('#interfaces .interfaces_fields_template').html();
var interface_id = new Date().getTime();

content = fix_template_names(content, 'interfaces', interface_id);

var hidden = $(content);

$('#interfaceForms').closest("form").trigger({type: 'nested:fieldAdded', field: hidden});
$('a[rel="popover"]').popover();
$('a[rel="twipsy"]').tooltip();

hidden.attr('id', 'interfaceHidden'+interface_id);
hidden.data('interface-id', interface_id);
hidden.find('.destroyFlag').val(0);

return hidden;
}

function get_interface_hidden(interface_id) {
var interface_hidden = $('#interfaceHidden'+interface_id);
if ( interface_hidden.length == 0) {

interface_hidden = $('<div></div>');
interface_hidden.attr('class', 'hidden');
interface_hidden.attr('id', 'interfaceHidden'+interface_id);
interface_hidden.data('interface-id', interface_id);
interface_hidden.data('new-interface', true);

$('#interfaceForms').append(interface_hidden);
}
return interface_hidden;
}

function update_interface_info(interface_id, interface_form) {
const interfaceData = {
function get_interface_data(interface_form) {
return {
name: interface_form.find('.interface_name').val(),
domain: interface_form.find('.interface_domain option:selected').text(),
type: interface_form.find('.interface_type').val(),
@@ -112,50 +69,22 @@ function update_interface_info(interface_id, interface_form) {
provision: interface_form.find('.interface_provision').is(':checked'),
virtual: interface_form.find('.virtual').is(':checked'),
attachedTo: interface_form.find('.attached').val(),
providerSpecificInfo: providerSpecificInterfaceInfo(interface_form),
hasErrors: interface_form.find('.has-error').length > 0,
editing: false,
};
if (interface_form.data('new-interface')) {
tfm.hosts.addInterface({id: interface_id, ...interfaceData});
interface_form.removeData('new-interface');
} else {
tfm.hosts.updateInterface(interface_id, interfaceData);
}
}

function updateInterfaceTable(state, prevState) {
var pathname = window.location.pathname;

state.interfaces.forEach(function(interfaceData, idx) {
var prevData = prevState.interfaces.filter(function(i){ return i.id == interfaceData.id })[0];
if (prevData && prevData == interfaceData) return;

var hiddenFields = get_interface_hidden(interfaceData.id)[0];
var nameEl = hiddenFields.getElementsByClassName('interface_name')[0];
var primaryCheck = hiddenFields.getElementsByClassName('interface_primary')[0];
var provisionCheck = hiddenFields.getElementsByClassName('interface_provision')[0];
var virtualCheck = hiddenFields.getElementsByClassName('virtual')[0];

nameEl.value = interfaceData.name;
primaryCheck.checked = interfaceData.primary;
provisionCheck.checked = interfaceData.provision;
virtualCheck.checked = interfaceData.virtual;

if (interfaceData.primary) {
$('#host_name').val(interfaceData.name);
function add_interface(interface_id, interface_form) {
var interfaceData = get_interface_data(interface_form);
interfaceData.id = interface_id;
tfm.hosts.addInterface(interfaceData);
}

var fqdn_val = tfm.hosts.fqdn(interfaceData.name, interfaceData.domain);
if (fqdn_val.length > 0 && pathname === '/hosts/new') {
tfm.breadcrumbs.updateTitle(__("Create Host") + " | " + fqdn_val);
}
}
});
state.destroyed.forEach(function(destroyedId, idx) {
$('#interfaceHidden'+destroyedId+' .destroyFlag').val(1);
});
function update_interface_info(interface_id, interface_form) {
var interfaceData = get_interface_data(interface_form);
tfm.hosts.updateInterface(interface_id, interfaceData);
}
tfm.observeStore(updateInterfaceTable, function(store) {
return store.hosts.interfaces;
});

function active_interface_forms() {
return $.grep($('#interfaceForms > div'), function(f) {
@@ -212,6 +141,11 @@ $(document).on('change', '#host_name', function () {
});

var providerSpecificNICInfo = null;
function providerSpecificInterfaceInfo(formFields) {
if (typeof window.providerSpecificNICInfo === 'function')
return window.providerSpecificNICInfo($(formFields));
return null;
};

$(document).on('change', '.compute_attributes', function () {
// remove "from profile" note if any of the fields changes
3 changes: 1 addition & 2 deletions app/assets/javascripts/lookup_keys.js
Original file line number Diff line number Diff line change
@@ -52,8 +52,7 @@ function fix_template_context(content, context) {
}

function fix_template_names(content, assoc, new_id) {
var regexp = new RegExp('new_' + assoc, 'g');
return content.replace(regexp, new_id);
tfm.nestedForms.fixTemplateNames(content, assoc, new_id);
}

function add_child_node(item) {
2 changes: 1 addition & 1 deletion app/views/hosts/_interfaces.html.erb
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
<span id="interfaceListWrapper"></span>

<div class="btn-toolbar">
<button type="button" onclick="add_interface();return false;"
<button type="button" onclick="tfm.hosts.showNewInterfaceModal();return false;"
class="info btn btn-success" id="addInterface"
title="add new network interface">+ <%= _('Add Interface') %>
</button>
2 changes: 1 addition & 1 deletion app/views/nic/_hidden_layout.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<div class="hidden" id="interfaceHidden<%= local_assigns[:id] %>" data-interface-id="<%= local_assigns[:id] %>">
<%= field_set_tag "", :id => "interface", :'data-url' => new_interface_path do %>
<%= field_set_tag "", data: { url: new_interface_path } do %>
<%= f.hidden_field(:_destroy, :class => :destroyFlag, :value => (local_assigns[:id].nil? ? 1 : 0)) %>
<%= yield %>
<% end %>
1 change: 1 addition & 0 deletions webpack/assets/javascripts/bundle.js
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ window.tfm = Object.assign(window.tfm || {}, {
reactMounter: require('./react_app/common/MountingService'),
editor: require('./foreman_editor'),
nav: require('./foreman_navigation'),
nestedForms: require('./foreman_nested_forms'),
medium: require('./foreman_medium'),
templateInputs: require('./foreman_template_inputs'),
advancedFields: require('./foreman_advanced_fields'),
99 changes: 98 additions & 1 deletion webpack/assets/javascripts/foreman_hosts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { uniq, set } from 'lodash';
import store from './react_app/redux';
import $ from 'jquery';

import store, { observeStore } from './react_app/redux';

import { fixTemplateNames } from './foreman_nested_forms';
import * as breadcrumbs from './foreman_breadcrumbs';
import * as interfaceActions from './react_app/redux/actions/hosts/interfaces';

const pluginEditAttributes = {
@@ -43,6 +47,99 @@ export const fqdn = (name, domain) => {
return `${name}.${domain}`;
};

export const createInterfaceHiddenWrapper = interfaceId => {
const interfaceHidden = document.createElement('div');
interfaceHidden.id = `interfaceHidden${interfaceId}`;
interfaceHidden.className = 'hidden';
interfaceHidden.dataset.interfaceId = interfaceId;

document.getElementById('interfaceForms').appendChild(interfaceHidden);
return interfaceHidden;
}

export const getInterfaceHiddenFields = interfaceId =>
document.getElementById(`interfaceHidden${interfaceId}`) ||
createInterfaceHiddenWrapper(interfaceId);

const updateInterfaceHiddenForms = (state, prevState) => {
const pathname = window.location.pathname;

state.interfaces.forEach((interfaceData, idx) => {
const prevData = prevState.interfaces.filter(i => i.id == interfaceData.id)[0];
if (prevData && prevData === interfaceData) return;

const hiddenFields = getInterfaceHiddenFields(interfaceData.id);
const nameEl = hiddenFields.getElementsByClassName('interface_name')[0];
const primaryCheck = hiddenFields.getElementsByClassName('interface_primary')[0];
const provisionCheck = hiddenFields.getElementsByClassName('interface_provision')[0];
const virtualCheck = hiddenFields.getElementsByClassName('virtual')[0];

nameEl.value = interfaceData.name;
primaryCheck.checked = interfaceData.primary;
provisionCheck.checked = interfaceData.provision;
virtualCheck.checked = interfaceData.virtual;

if (interfaceData.primary) {
$('#host_name').val(interfaceData.name);

const fqdnVal = fqdn(interfaceData.name, interfaceData.domain);
if (fqdnVal.length > 0 && pathname === '/hosts/new') {
breadcrumbs.updateTitle(__("Create Host") + " | " + fqdnVal);
}
}

if (interfaceData.editing) {
showEditInterfaceModal(interfaceData.id);
}

if (!interfaceData.providerSpecificInfo) {
const providerSpecificInfo = window.providerSpecificInterfaceInfo($(hiddenFields));
if (providerSpecificInfo)
tfm.hosts.updateInterface(interfaceData.id, { providerSpecificInfo });
}
});
state.destroyed.forEach((destroyedId, idx) => {
$('#interfaceHidden'+destroyedId+' .destroyFlag').val(1);
});
}
observeStore(updateInterfaceHiddenForms, store => store.hosts.interfaces);

function getInterfaceFormTemplateClone() {
var content = $('#interfaces .interfaces_fields_template').html();
var interfaceId = new Date().getTime();

content = fixTemplateNames(content, 'interfaces', interfaceId);

var hidden = $(content);

$('#interfaceForms').closest("form").trigger({ type: 'nested:fieldAdded', field: hidden });
$('a[rel="popover"]').popover();
$('a[rel="twipsy"]').tooltip();

hidden.attr('id', 'interfaceHidden'+interfaceId);
hidden.data('interface-id', interfaceId);
hidden.find('.destroyFlag').val(0);

return hidden;
}

const showInterfaceModal = ($form, newInterface = false) => {
$('#interfaceModal').data('new-interface', newInterface);
window.show_interface_modal($form);
};

export const showEditInterfaceModal = interfaceId => {
const $form = $(getInterfaceHiddenFields(interfaceId)).clone(true);
showInterfaceModal($form, false);
};

export const showNewInterfaceModal = () => {
const $form = getInterfaceFormTemplateClone();
showInterfaceModal($form, true);
};

export const getInterfacesData = () => store.getState().hosts.interfaces;

export const initializeInterfaces = interfaces => {
store.dispatch(interfaceActions.initializeInterfaces(interfaces));
};
4 changes: 4 additions & 0 deletions webpack/assets/javascripts/foreman_nested_forms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function fixTemplateNames(content, assoc, newId) {
const regexp = new RegExp(`new_${assoc}`, 'g');
return content.replace(regexp, newId);
}
Loading

0 comments on commit 702c9eb

Please sign in to comment.