Removed legacy icinga JS
This commit is contained in:
parent
a38a126d42
commit
c0a740ca9e
|
@ -1,172 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* A module to load and manage frontend components
|
||||
*
|
||||
*/
|
||||
define(['jquery', 'logging', 'icinga/componentRegistry'], function ($, log, registry) {
|
||||
'use strict';
|
||||
|
||||
var ComponentLoader = function() {
|
||||
|
||||
/**
|
||||
* Load the component with the given type and attach it to the target
|
||||
*
|
||||
* @param {String} cmpType The component type to load '<module>/<component>'
|
||||
* @param {HTMLElement} target The targeted dom node
|
||||
* @param {function} fin The called when the component was successfully loaded
|
||||
* @param {function} err The error-callback
|
||||
*/
|
||||
var loadComponent = function(cmpType, target, fin, err) {
|
||||
requirejs(
|
||||
['components/' + cmpType],
|
||||
function (Cmp) {
|
||||
var cmp;
|
||||
try {
|
||||
cmp = new Cmp(target);
|
||||
|
||||
} catch (e) {
|
||||
log.emergency('Error in component "' + cmpType + '" : "' + e + '"');
|
||||
err(e);
|
||||
return;
|
||||
}
|
||||
if (fin) {
|
||||
fin(cmp);
|
||||
}
|
||||
},
|
||||
function (ex) {
|
||||
if (!ex) {
|
||||
return;
|
||||
}
|
||||
log.emergency('Component "' + cmpType + '" could not be loaded.', ex);
|
||||
if (err) {
|
||||
err(ex);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all new components and remove components that were removed from
|
||||
* the DOM from the internal registry
|
||||
*
|
||||
* @param {function} fin Called when the loading is completed
|
||||
*/
|
||||
this.load = function(fin) {
|
||||
|
||||
/*
|
||||
* Count the amount of pending callbacks to make sure everything is loaded
|
||||
* when calling the garbage collection.
|
||||
*/
|
||||
var pendingFns = 1;
|
||||
|
||||
var finalize = function() {
|
||||
pendingFns--;
|
||||
/*
|
||||
* Only return when all components are loaded
|
||||
*/
|
||||
if (pendingFns === 0) {
|
||||
registry.removeInactive();
|
||||
if (fin) {
|
||||
fin();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
registry.markAllInactive();
|
||||
|
||||
$('[data-icinga-component]')
|
||||
.each(function(index, el) {
|
||||
var type = $(el).attr('data-icinga-component');
|
||||
pendingFns++;
|
||||
|
||||
if (!el.id || !registry.getById(el.id)) {
|
||||
loadComponent(
|
||||
type,
|
||||
el,
|
||||
function(cmp) {
|
||||
var id = registry.add(cmp, type);
|
||||
registry.markActive(id);
|
||||
el.id = id;
|
||||
finalize();
|
||||
},
|
||||
finalize
|
||||
);
|
||||
} else {
|
||||
registry.markActive(el.id);
|
||||
finalize();
|
||||
}
|
||||
});
|
||||
finalize();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the id of the given component, if one is assigned
|
||||
*
|
||||
* @param {*} component The component of which the id should be retrieved
|
||||
*
|
||||
* @returns {String|null} The id of the component, or null
|
||||
*/
|
||||
this.getId = function(component) {
|
||||
return registry.getId(component);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the component that is assigned to the given id
|
||||
*
|
||||
* @param {String} id The id of the component
|
||||
*
|
||||
* @returns {*} The component or null
|
||||
*/
|
||||
this.getById = function(id) {
|
||||
return registry.getById(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all components that match the given type
|
||||
*
|
||||
* @param {String} type The component type in the form '<module>/<component>'
|
||||
*
|
||||
* @returns {*|Array} The components or an empty array
|
||||
*/
|
||||
this.getByType = function(type) {
|
||||
return registry.getByType(type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all components
|
||||
*
|
||||
* @returns {*|Array} The components or an empty array
|
||||
*/
|
||||
this.getComponents = function() {
|
||||
return registry.getComponents();
|
||||
};
|
||||
};
|
||||
return new ComponentLoader();
|
||||
});
|
|
@ -1,158 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* A component registry that maps components to unique IDs and keeps track
|
||||
* of component types to allow easy querying
|
||||
*
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
"use strict";
|
||||
|
||||
var ComponentRegistry = function() {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Map ids to components
|
||||
*/
|
||||
var components = {};
|
||||
|
||||
/**
|
||||
* Generate a new component id
|
||||
*/
|
||||
var createId = (function() {
|
||||
var id = 0;
|
||||
return function() {
|
||||
return 'icinga-component-' + id++;
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the id of the given component, if one is assigned
|
||||
*
|
||||
* @param {*} component The component of which the id should be retrieved
|
||||
*
|
||||
* @returns {String|null} The id of the component, or null
|
||||
*/
|
||||
this.getId = function(cmp) {
|
||||
var id = null;
|
||||
$.each(components, function(key, value) {
|
||||
if (value && value.cmp === cmp) {
|
||||
id = key;
|
||||
}
|
||||
});
|
||||
return id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the component that is assigned to the given id
|
||||
*
|
||||
* @param {String} id The id of the component
|
||||
*
|
||||
* @returns {*} The component or null
|
||||
*/
|
||||
this.getById = function(id) {
|
||||
return components[id] && components[id].cmp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all components that match the given type
|
||||
*
|
||||
* @param {String} type The component type in the form '<module>/<component>'
|
||||
*
|
||||
* @returns {*|Array} The components or an empty array
|
||||
*/
|
||||
this.getByType = function(type) {
|
||||
return $.map(components, function(entry) {
|
||||
return entry.type === type ? entry.cmp : null;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all components
|
||||
*
|
||||
* @returns {*|Array} The components or an empty array
|
||||
*/
|
||||
this.getComponents = function() {
|
||||
return $.map(components, function(entry) {
|
||||
return entry.cmp;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given component to the registry and return the assigned id
|
||||
*
|
||||
* @param {*} cmp The component to add
|
||||
* @param {String} id The optional id that should be assigned to that component
|
||||
* @param {String} type The component type to load '<module>/<component>'
|
||||
*
|
||||
* @returns {*|Array}
|
||||
*/
|
||||
this.add = function(cmp, type) {
|
||||
var id = createId();
|
||||
components[id] = {
|
||||
cmp: cmp,
|
||||
type: type,
|
||||
active: true
|
||||
};
|
||||
return id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark all components inactive
|
||||
*/
|
||||
this.markAllInactive = function() {
|
||||
$.each(components,function(index, el){
|
||||
if (el && el.active) {
|
||||
el.active = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark the component with the given id as active
|
||||
*/
|
||||
this.markActive = function(id) {
|
||||
if (components[id]) {
|
||||
components[id].active = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Let the garbage collection remove all inactive components
|
||||
*/
|
||||
this.removeInactive = function() {
|
||||
$.each(components, function(key,value) {
|
||||
if (!value || !value.active) {
|
||||
delete components[key];
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
return new ComponentRegistry();
|
||||
});
|
|
@ -1,84 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false define:false require:false base_url:false console:false */
|
||||
|
||||
/**
|
||||
* Icinga app/ajaxPostSubmitForm component.
|
||||
*
|
||||
* This component converts generic post forms into ajax
|
||||
* submit forms.
|
||||
*/
|
||||
define(['components/app/container', 'jquery'], function(Container, $) {
|
||||
"use strict";
|
||||
|
||||
/**;
|
||||
* Handler for ajax post submit
|
||||
*
|
||||
* @param {Event} e
|
||||
*/
|
||||
var submitHandler = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
var form = $(this);
|
||||
var url = form.attr('action');
|
||||
var submit = form.find('button[type="submit"]', 'input[type="submit"]');
|
||||
var data = form.serialize();
|
||||
|
||||
// Submit name is missing for valid submission
|
||||
if (data) {
|
||||
data += '&';
|
||||
}
|
||||
data += submit.attr('name') + '=1';
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
beforeSend: function() {
|
||||
submit.attr('disabled', true);
|
||||
}
|
||||
}).done(function() {
|
||||
var c = new Container(form);
|
||||
c.refresh();
|
||||
}).error(function() {
|
||||
submit.removeAttr('disabled');
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* The component bootstrap
|
||||
*
|
||||
* @param {Element} targetElement
|
||||
*/
|
||||
return function(targetForm) {
|
||||
var form = $(targetForm);
|
||||
form.submit(submitHandler);
|
||||
};
|
||||
});
|
|
@ -1,509 +0,0 @@
|
|||
/*global Icinga:false, Modernizr: false, document: false, History: false, define:false require:false base_url:false console:false */
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url'],
|
||||
function($, logger, componentLoader, URI, Tpl, urlMgr) {
|
||||
'use strict';
|
||||
|
||||
var Icinga;
|
||||
|
||||
/**
|
||||
* Enumeration of possible container types
|
||||
*
|
||||
* @type {{GENERIC: string, MAIN: string, DETAIL: string}}
|
||||
*/
|
||||
var CONTAINER_TYPES = {
|
||||
'GENERIC' : 'generic',
|
||||
'MAIN' : 'icingamain',
|
||||
'DETAIL': 'icingadetail'
|
||||
};
|
||||
|
||||
/**
|
||||
* Static reference to the main container, populated on the first 'getMainContainer' call
|
||||
*
|
||||
* @type {Container}
|
||||
*/
|
||||
var mainContainer = null;
|
||||
|
||||
/**
|
||||
* Static reference to the detail container, populated on the first getDetailContainer call
|
||||
*
|
||||
* @type {Container}
|
||||
*/
|
||||
var detailContainer = null;
|
||||
|
||||
/**
|
||||
* Contains currently pending requests
|
||||
*
|
||||
* @type {jqAJAX}
|
||||
*/
|
||||
var pendingDetailRequest = null;
|
||||
|
||||
/**
|
||||
* Cancel the pending request, if one exists
|
||||
*/
|
||||
var cancelPendingRequest = function() {
|
||||
if (pendingDetailRequest) {
|
||||
pendingDetailRequest.abort();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A handler for accessing icinga containers, i.e. the #icingamain, #icingadetail containers and specific 'app/container'
|
||||
* components.
|
||||
*
|
||||
* This component can be constructed with every object as the parameter and will provide access to the nearest
|
||||
* container (which could be the applied object itself, if it is a container) wrapping this object.
|
||||
*
|
||||
* The windows url should always be modified with this implementation, so an objects context should point to a
|
||||
* new URL, call new Container('#myObject').updateContainerHref('/my/url')
|
||||
*
|
||||
* This requirejs module also registers a global handler catching all links of the main container and rendering
|
||||
* their content to the main container, in case you don't want to extend the container with additional handlers.
|
||||
*
|
||||
* @param {HTMLElement, jQuery, String} target A jQuery resultset, dom element or matcher string
|
||||
*/
|
||||
var Container = function(target) {
|
||||
|
||||
|
||||
/**
|
||||
* Return the container that is at the nearest location to this element, or the element itself if it is a container
|
||||
*
|
||||
* Containers are either the icingamain and icingadetail ids or components tagged as app/container
|
||||
*
|
||||
* @param {String, jQuery, HTMLElement} target The node to use as the starting point
|
||||
*
|
||||
* @returns {HTMLElement|null} The nearest container found or null if target is no container
|
||||
* and no container is above target
|
||||
*/
|
||||
this.findNearestContainer = function(target) {
|
||||
target = $(target);
|
||||
if (target.attr('data-icinga-component') === 'app/container' ||
|
||||
target.attr('id') === 'icingamain' || target.attr('id') === 'icingadetail') {
|
||||
return target;
|
||||
}
|
||||
return target.parents('[data-icinga-component="app/container"], #icingamain, #icingadetail')[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the container responsible for target and determine it's type
|
||||
*
|
||||
* @param {HTMLElement, jQuery, String} target A jQuery resultset, dom element or matcher string
|
||||
*/
|
||||
this.construct = function(target) {
|
||||
this.containerDom = $(this.findNearestContainer(target));
|
||||
this.containerType = CONTAINER_TYPES.GENERIC;
|
||||
|
||||
if (this.containerDom.attr('id') === CONTAINER_TYPES.MAIN) {
|
||||
this.containerType = CONTAINER_TYPES.MAIN;
|
||||
} else if (this.containerDom.attr('id') === CONTAINER_TYPES.DETAIL) {
|
||||
this.containerType = CONTAINER_TYPES.DETAIL;
|
||||
} else {
|
||||
this.containerType = CONTAINER_TYPES.GENERIC;
|
||||
}
|
||||
|
||||
if (this.containerDom.data('loadIndicator') !== true) {
|
||||
this.installDefaultLoadIndicator();
|
||||
this.containerDom.data('loadIndicator', true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the window without the hostname
|
||||
*
|
||||
* @returns {string} path with query, search and hash
|
||||
*/
|
||||
var getWindowLocationWithoutHost = function() {
|
||||
return window.location.pathname + window.location.search + window.location.hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create default load mask
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var createDefaultLoadIndicator = function() {
|
||||
if (this.containerDom.find('div.load-indicator').length === 0) {
|
||||
var content = '<div class="load-indicator">' +
|
||||
'<div class="mask"></div>' +
|
||||
'<div class="label">Loading</div>' +
|
||||
'</div>';
|
||||
$(this.containerDom).append(content);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove default load mask
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var destroyDefaultLoadIndicator = function() {
|
||||
this.containerDom.find('div.load-indicator').remove();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load the provided url, stop all pending requests for this container and call replaceDom for the returned html
|
||||
*
|
||||
* This method relaods the page if a 401 (Authorization required) header is encountered
|
||||
*
|
||||
* @param {String, URI} url The Url to load or and URI.js object encapsulating it
|
||||
*/
|
||||
this.updateFromUrl = function(url) {
|
||||
|
||||
if (this.containerType === CONTAINER_TYPES.DETAIL) {
|
||||
urlMgr.setDetailUrl(url);
|
||||
} else {
|
||||
urlMgr.setMainUrl(url);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.replaceDomAsync = function(url) {
|
||||
urlMgr.syncWithUrl();
|
||||
if (urlMgr.detailUrl === '') {
|
||||
this.hideDetail();
|
||||
}
|
||||
cancelPendingRequest();
|
||||
var loadingTimeout = window.setTimeout(
|
||||
(function(containerDom) {
|
||||
return function() {
|
||||
containerDom.trigger('showLoadIndicator');
|
||||
}
|
||||
})(this.containerDom),
|
||||
500
|
||||
);
|
||||
pendingDetailRequest = $.ajax({
|
||||
'url': url,
|
||||
'data': {
|
||||
'render': 'detail'
|
||||
},
|
||||
'context': this
|
||||
})
|
||||
.done(function (response) {
|
||||
pendingDetailRequest = null;
|
||||
this.replaceDom($(response));
|
||||
})
|
||||
.fail(function (response, reason) {
|
||||
if (reason === 'abort') {
|
||||
return;
|
||||
}
|
||||
if (response.statusCode().status === 401) {
|
||||
var error = JSON.parse(response.responseText);
|
||||
window.location.replace(
|
||||
URI(error.redirectTo).search({
|
||||
redirect: URI(urlMgr.getUrl()).resource().replace(new RegExp('^' + window.base_url), '')
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
var errorReason;
|
||||
if (response.statusCode.toString()[0] === '4') {
|
||||
errorReason = 'The Requested View Couldn\'t Be Found<br/>';
|
||||
} else {
|
||||
errorReason = response.responseText;
|
||||
}
|
||||
this.replaceDom(response.responseText);
|
||||
})
|
||||
.always(function () {
|
||||
window.clearTimeout(loadingTimeout);
|
||||
this.containerDom.trigger('hideLoadIndicator');
|
||||
});
|
||||
};
|
||||
|
||||
this.getUrl = function() {
|
||||
if (this.containerType === CONTAINER_TYPES.DETAIL) {
|
||||
return urlMgr.detailUrl;
|
||||
} else {
|
||||
return urlMgr.mainUrl;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all dom nodes from this container and replace them with the ones from domNodes
|
||||
*
|
||||
* Triggers the custom "updated" event and causes a rescan for components on the DOM nodes
|
||||
*
|
||||
* If keepLayout is given, the detail panel won't be expanded if this is an update for the detail panel,
|
||||
* otherwise it will be automatically shown.
|
||||
*
|
||||
* @param {String, jQuery, HTMLElement, Array} domNodes Any valid representation of the Dom nodes to insert
|
||||
* @param {boolean} keepLayout Whether to keep the layout untouched, even if detail
|
||||
* is updated end collapsed
|
||||
*
|
||||
* @see registerOnUpdate
|
||||
*/
|
||||
this.replaceDom = function(domNodes, keepLayout) {
|
||||
this.containerDom.trigger('showLoadIndicator');
|
||||
this.containerDom.empty().append(domNodes);
|
||||
this.containerDom.trigger('updated', [domNodes]);
|
||||
this.containerDom.trigger('hideLoadIndicator');
|
||||
componentLoader.load();
|
||||
if (!keepLayout) {
|
||||
if (this.containerType === CONTAINER_TYPES.DETAIL) {
|
||||
this.showDetail();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a method to be called when this container is updated
|
||||
*
|
||||
* @param {function} fn The function to call when the container is updated
|
||||
*/
|
||||
this.registerOnUpdate = function(fn) {
|
||||
this.containerDom.on('updated', fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a method to show a load indicator
|
||||
*
|
||||
* @param {function} fn The function to register
|
||||
*/
|
||||
this.registerOnShowLoadIndicator = function(fn) {
|
||||
this.containerDom.on('showLoadIndicator', fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a method when load indicator should be removed
|
||||
*
|
||||
* @param {function} fn The function to register
|
||||
*/
|
||||
this.registerOnHideLoadIndicator = function(fn) {
|
||||
this.containerDom.on('hideLoadIndicator', fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Install default load indicator
|
||||
*/
|
||||
this.installDefaultLoadIndicator = function() {
|
||||
this.registerOnShowLoadIndicator($.proxy(createDefaultLoadIndicator, this));
|
||||
this.registerOnHideLoadIndicator($.proxy(destroyDefaultLoadIndicator, this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove default load indicator
|
||||
*/
|
||||
this.removeDefaultLoadIndicator = function() {
|
||||
this.containerDom.off('showLoadIndicator');
|
||||
this.containerDom.off('hideLoadIndicator');
|
||||
};
|
||||
|
||||
this.onLinkClick = function(ev, target) {
|
||||
if ($.trim($(target).attr('href')) === '#') {
|
||||
return true;
|
||||
}
|
||||
var url = URI($(target).attr('href'));
|
||||
|
||||
var explicitTarget = $(target).attr('data-icinga-target');
|
||||
|
||||
var isHash = ('#' + url.fragment() === url.href());
|
||||
if (isHash) {
|
||||
explicitTarget = this.containerType === CONTAINER_TYPES.MAIN ? 'main' : 'detail';
|
||||
}
|
||||
if (explicitTarget) {
|
||||
|
||||
urlMgr[{
|
||||
'main' : 'setMainUrl',
|
||||
'detail' : 'setDetailUrl',
|
||||
'self' : 'setUrl'
|
||||
}[explicitTarget]](url.href());
|
||||
|
||||
} else if (this.containerType === CONTAINER_TYPES.MAIN) {
|
||||
urlMgr.setDetailUrl(url.href());
|
||||
} else {
|
||||
urlMgr.setMainUrl(url.href());
|
||||
}
|
||||
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
this.setUrl = function(url) {
|
||||
if (typeof url === 'string') {
|
||||
url = URI(url);
|
||||
}
|
||||
console.log(url);
|
||||
if (this.containerType === CONTAINER_TYPES.MAIN) {
|
||||
urlMgr.setMainUrl(url.href());
|
||||
} else {
|
||||
urlMgr.setDetailUrl(url.href());
|
||||
}
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
if (this.containerType === CONTAINER_TYPES.MAIN) {
|
||||
Container.getMainContainer().replaceDomAsync(urlMgr.mainUrl);
|
||||
} else {
|
||||
Container.getDetailContainer().replaceDomAsync(urlMgr.detailUrl);
|
||||
}
|
||||
};
|
||||
|
||||
this.construct(target);
|
||||
};
|
||||
|
||||
/**
|
||||
* Static method for detecting whether the given link is external or only browserside (hash links)
|
||||
*
|
||||
* @param {String} link The link to test for being site-related
|
||||
*
|
||||
* @returns {boolean} True when the link should be executed with the browsers normal behaviour, false
|
||||
* when the link should be catched and processed internally
|
||||
*/
|
||||
Container.isExternalLink = function(link) {
|
||||
return (/^\/\//).test(URI(link).relativeTo(window.location.href).href());
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the page's detail container (which is always there)
|
||||
*
|
||||
* @returns {Container} The detail container of the page
|
||||
*/
|
||||
Container.getDetailContainer = function() {
|
||||
detailContainer = detailContainer || new Container('#icingadetail');
|
||||
if(!jQuery.contains(document.body, mainContainer)) {
|
||||
detailContainer = new Container('#icingadetail');
|
||||
}
|
||||
return detailContainer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the page's main container (which is always there)
|
||||
*
|
||||
* @returns {Container} The main container of the page
|
||||
*/
|
||||
Container.getMainContainer = function() {
|
||||
mainContainer = mainContainer || new Container('#icingamain');
|
||||
if(!jQuery.contains(document.body, mainContainer)) {
|
||||
mainContainer = new Container('#icingamain');
|
||||
}
|
||||
return mainContainer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand the detail container and shrinken the main container
|
||||
*
|
||||
* Available as a static method on the Container object or as an instance method
|
||||
*/
|
||||
Container.prototype.showDetail = Container.showDetail = function() {
|
||||
$('#icingadetailClose').removeClass('hidden');
|
||||
var mainDom = Container.getMainContainer().containerDom,
|
||||
detailDom = Container.getDetailContainer().containerDom;
|
||||
|
||||
if (detailDom.find('*').length === 0) {
|
||||
var mainHeight = $(window).height();
|
||||
detailDom.append('<div style="height: ' + mainHeight + 'px;"></div>');
|
||||
}
|
||||
|
||||
mainDom.removeClass();
|
||||
detailDom.removeClass();
|
||||
|
||||
mainDom.addClass('col-xs-pull-12 col-sm-pull-12 col-md-pull-12 col-lg-7');
|
||||
detailDom.addClass('col-xs-push-12 col-sm-push-12 col-md-push-12 col-lg-5');
|
||||
$(window).trigger('layoutchange');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the detail container and expand the main container
|
||||
*
|
||||
* Also updates the Url by removing the detail part
|
||||
*
|
||||
* Available as a static method on the Container object or as an instance method
|
||||
*/
|
||||
Container.prototype.hideDetail = Container.hideDetail = function() {
|
||||
$('#icingadetailClose').addClass('hidden');
|
||||
cancelPendingRequest();
|
||||
urlMgr.setDetailUrl('');
|
||||
var mainDom = Container.getMainContainer().containerDom,
|
||||
detailDom = Container.getDetailContainer().containerDom;
|
||||
|
||||
mainDom.removeClass();
|
||||
detailDom.removeClass();
|
||||
mainDom.addClass('col-md-12');
|
||||
detailDom.addClass('hidden-md');
|
||||
mainDom.addClass('col-lg-12');
|
||||
detailDom.addClass('hidden-lg');
|
||||
mainDom.addClass('col-xs-12');
|
||||
detailDom.addClass('hidden-xs');
|
||||
mainDom.addClass('col-sm-12');
|
||||
detailDom.addClass('hidden-sm');
|
||||
detailDom.removeAttr('data-icinga-href');
|
||||
$(window).trigger('layoutchange');
|
||||
};
|
||||
/**
|
||||
* Injects the icinga object into the Container class
|
||||
*
|
||||
* This can't be done via requirejs as we would end up in circular references
|
||||
*
|
||||
* @param {Icinga} icingaObj The Icinga object to use for reloading
|
||||
*/
|
||||
Container.setIcinga = function(icingaObj) {
|
||||
Icinga = icingaObj;
|
||||
};
|
||||
|
||||
$('body').on('click', '*[data-icinga-component="app/container"], #icingamain, #icingadetail', function(ev) {
|
||||
var targetEl = ev.target || ev.toElement || ev.relatedTarget;
|
||||
|
||||
if (targetEl.tagName.toLowerCase() !== 'a') {
|
||||
targetEl = $(targetEl).parents('a')[0];
|
||||
if (!targetEl) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (new Container(targetEl)).onLinkClick(ev, targetEl);
|
||||
|
||||
});
|
||||
|
||||
$(window).on('hashchange', (function() {
|
||||
urlMgr.syncWithUrl();
|
||||
if (urlMgr.detailUrl) {
|
||||
Container.getDetailContainer().replaceDomAsync(urlMgr.detailUrl);
|
||||
} else {
|
||||
Container.hideDetail();
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
if (urlMgr.detailUrl) {
|
||||
Container.getDetailContainer().replaceDomAsync(urlMgr.detailUrl);
|
||||
}
|
||||
|
||||
$('#icingadetailClose').click(function(){
|
||||
detailContainer.hideDetail();
|
||||
});
|
||||
|
||||
return Container;
|
||||
});
|
|
@ -1,87 +0,0 @@
|
|||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* Dashboard container, uses freetile for layout
|
||||
*
|
||||
*/
|
||||
define(['jquery', 'logging', 'URIjs/URI', 'icinga/componentLoader', 'icinga/util/url'],
|
||||
function($, log, URI, components, urlMgr) {
|
||||
'use strict';
|
||||
return function(parent) {
|
||||
this.dom = $(parent);
|
||||
var dashboardContainer = this.dom.parent('div');
|
||||
dashboardContainer.freetile();
|
||||
this.container = this.dom.children('.container');
|
||||
this.dashboardUrl = this.dom.attr('data-icinga-url');
|
||||
var reloadTimeout = null;
|
||||
|
||||
/**
|
||||
* Refresh the container content and layout
|
||||
*/
|
||||
this.refresh = function () {
|
||||
$.ajax({
|
||||
url: this.dashboardUrl,
|
||||
context: this
|
||||
})
|
||||
.done(function (response) {
|
||||
this.container.empty();
|
||||
this.container.html(response);
|
||||
components.load();
|
||||
})
|
||||
.fail(function (response, reason) {
|
||||
if (response.statusCode().status === 401) {
|
||||
var error = JSON.parse(response.responseText);
|
||||
window.location.replace(
|
||||
URI(error.redirectTo).search({
|
||||
redirect: URI(urlMgr.getUrl()).resource().replace(new RegExp('^' + window.base_url), '')
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.container.html(response.responseText);
|
||||
})
|
||||
.always(function () {
|
||||
dashboardContainer.freetile('layout');
|
||||
$(window).on('layoutchange', function() {
|
||||
dashboardContainer.freetile('layout');
|
||||
});
|
||||
this.triggerRefresh();
|
||||
})
|
||||
};
|
||||
|
||||
this.triggerRefresh = function() {
|
||||
if (reloadTimeout) {
|
||||
clearTimeout(reloadTimeout);
|
||||
}
|
||||
setTimeout(this.refresh.bind(this), 10000);
|
||||
};
|
||||
this.refresh();
|
||||
};
|
||||
});
|
|
@ -1,52 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
|
||||
/**
|
||||
* Ensures that our date/time controls will work on every browser (natively or javascript based)
|
||||
*/
|
||||
define(['jquery', 'datetimepicker'], function($) {
|
||||
"use strict";
|
||||
|
||||
var DateTimePicker = function(target) {
|
||||
$(target).datetimepicker({
|
||||
format: 'yyyy-mm-dd hh:ii:ss',
|
||||
minuteStep: 10,
|
||||
autoclose: true,
|
||||
todayBtn: true,
|
||||
todayHighlight: true
|
||||
});
|
||||
|
||||
$(target).parent().find('a').click(function(e) {
|
||||
e.preventDefault();
|
||||
$(target).datetimepicker('show');
|
||||
});
|
||||
};
|
||||
|
||||
return DateTimePicker;
|
||||
});
|
|
@ -1,100 +0,0 @@
|
|||
/*global Icinga:false, Modernizr: false, document: false, History: false, define:false require:false base_url:false console:false */
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* Icinga app/ellipsisText component
|
||||
*
|
||||
* This component adds ellipsis with expand functionality
|
||||
* to content.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* <span data-icinga-component="app/ellipsisText">
|
||||
* A very long example text
|
||||
* </span>
|
||||
* </code>
|
||||
* </pre>
|
||||
*/
|
||||
define(['jquery'],
|
||||
function($, logger, componentLoader, URI) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test if a css3 ellipsis is avtive
|
||||
*
|
||||
* @param {Element} element
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var activeEllipsis = function(element) {
|
||||
return (element.offsetWidth < element.scrollWidth);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add classes to element to create a css3 ellipsis
|
||||
*
|
||||
* Parent elements width is used to calculate containing width
|
||||
* and set target element width to a fixed one.
|
||||
*
|
||||
* @param {Element} target
|
||||
* @constructor
|
||||
*/
|
||||
var EllipsisText = function(target) {
|
||||
var parentWidth = $(target).parent().width();
|
||||
|
||||
$(target).width(parentWidth)
|
||||
.css('overflow', 'hidden')
|
||||
.css('text-overflow', 'ellipsis')
|
||||
.css('display', 'block')
|
||||
.css('white-space', 'nowrap');
|
||||
|
||||
if (activeEllipsis(target)) {
|
||||
$(target).wrap('<a></a>')
|
||||
.css('cursor', 'pointer');
|
||||
|
||||
$(target).parent()
|
||||
.attr('data-icinga-ellipsistext', 'true')
|
||||
.attr('data-content', $(target).html())
|
||||
.popover({
|
||||
trigger : 'manual',
|
||||
html : true,
|
||||
placement : 'auto'
|
||||
})
|
||||
.click(function(e) {
|
||||
e.stopImmediatePropagation();
|
||||
$('a[data-icinga-ellipsistext=\'true\']').popover('hide');
|
||||
$(e.currentTarget).popover('toggle');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return EllipsisText;
|
||||
}
|
||||
);
|
|
@ -1,140 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false define:false require:false base_url:false console:false */
|
||||
|
||||
/**
|
||||
* Icinga app/form component.
|
||||
*
|
||||
* This component makes sure a user has to confirm when trying to discard unsaved changes
|
||||
* by leaving the current page. It also implements the code for autosubmitting fields having the
|
||||
* 'data-icinga-form-autosubmit' component.
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The attribute name marking forms as being modified
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
var ATTR_MODIFIED = 'data-icinga-form-modified';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Takes a form and returns an overloaded jQuery object
|
||||
*
|
||||
* The returned object is the jQuery matcher with the following additional methods:
|
||||
*
|
||||
* - isModified: Return true when the form is marked as modified
|
||||
* - setModificationFlag: Mark this form as being modified
|
||||
* - clearModificationFlag: Clear the modification mark
|
||||
*
|
||||
* @param targetForm
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
var getFormObject = function(targetForm) {
|
||||
var form = $(targetForm);
|
||||
/**
|
||||
* Return true when the form is marked as modified
|
||||
*
|
||||
* @returns {boolean} True when the form has the @see ATTR_MODIFIED attribute set to 'true', otherwise false
|
||||
*/
|
||||
form.isModified = function() {
|
||||
return form.attr(ATTR_MODIFIED) === 'true' ||
|
||||
form.attr(ATTR_MODIFIED) === '1';
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark this form as being modified
|
||||
*/
|
||||
form.setModificationFlag = function() {
|
||||
form.attr(ATTR_MODIFIED, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the modification flag on this form
|
||||
*/
|
||||
form.clearModificationFlag = function() {
|
||||
form.attr(ATTR_MODIFIED, false);
|
||||
};
|
||||
return form;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register event handler for detecting form modifications.
|
||||
*
|
||||
* This handler takes care of autosubmit form fields causing submissions on change and
|
||||
* makes sure the modification flag on the form is set when changes occur.
|
||||
*
|
||||
* @param {jQuery} form A form object returned from @see getFormObject()
|
||||
*/
|
||||
var registerFormEventHandler = function(form) {
|
||||
form.change(function(changed) {
|
||||
if ($(changed.target).attr('data-icinga-form-autosubmit')) {
|
||||
form.clearModificationFlag();
|
||||
form.submit();
|
||||
} else {
|
||||
form.setModificationFlag();
|
||||
}
|
||||
});
|
||||
// submissions should clear the modification flag
|
||||
form.submit(function() {
|
||||
form.clearModificationFlag();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Register an eventhandler that triggers a confirmation message when the user tries to leave a modified form
|
||||
*
|
||||
* @param {jQuery} form A form object returned from @see getFormObject()
|
||||
*/
|
||||
var registerLeaveConfirmationHandler = function(form) {
|
||||
|
||||
$(window).on('beforeunload', function() {
|
||||
if (form.isModified()) {
|
||||
return 'All unsaved changes will be lost when leaving this page';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The component bootstrap
|
||||
*/
|
||||
return function(targetForm) {
|
||||
var form = getFormObject(targetForm);
|
||||
|
||||
|
||||
registerFormEventHandler(form);
|
||||
registerLeaveConfirmationHandler(form);
|
||||
|
||||
// Remove DOM level onchange, we registered proper jQuery listeners for them
|
||||
$('[data-icinga-form-autosubmit]').removeAttr('onchange');
|
||||
};
|
||||
});
|
|
@ -1,337 +0,0 @@
|
|||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
define(['components/app/container', 'jquery', 'logging', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url', 'icinga/selection/selectable', 'icinga/selection/multiSelection'],
|
||||
function(Container, $, logger, URI, tpl, urlMgr, Selectable, TableMultiSelection) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Master/Detail grid component handling history, link behaviour, selection (@TODO 3788) and updates of
|
||||
* grids
|
||||
*
|
||||
* @param {HTMLElement} The outer element to apply the behaviour on
|
||||
*/
|
||||
return function(gridDomNode) {
|
||||
|
||||
/**
|
||||
* Reference to the outer container of this component
|
||||
*
|
||||
* @type {*|HTMLElement}
|
||||
*/
|
||||
gridDomNode = $(gridDomNode);
|
||||
|
||||
/**
|
||||
* A container component to use for updating URLs and content
|
||||
*
|
||||
* @type {Container}
|
||||
*/
|
||||
this.container = null;
|
||||
|
||||
/**
|
||||
* The node wrapping the table and pagination
|
||||
*
|
||||
* @type {jQuery}
|
||||
*/
|
||||
var contentNode;
|
||||
|
||||
/**
|
||||
* jQuery matcher result of the form components wrapping the controls
|
||||
*
|
||||
* @type {jQuery}
|
||||
*/
|
||||
var controlForms;
|
||||
|
||||
/**
|
||||
* Handles multi-selection
|
||||
*
|
||||
* @type {TableMultiSelection}
|
||||
*/
|
||||
var selection;
|
||||
|
||||
/**
|
||||
* Defines how row clicks are handled. Can either be 'none', 'single' or 'multi'
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
var selectionMode;
|
||||
|
||||
/**
|
||||
* Detect and select control forms for this table and return them
|
||||
*
|
||||
* Form controls are either all forms underneath the of the component, but not underneath the table
|
||||
* or in a dom node explicitly tagged with the 'data-icinga-actiongrid-controls' attribute
|
||||
*
|
||||
* @param {jQuery|null} domContext The context to use as the root node for matching, if null
|
||||
* the component node given in the constructor is used
|
||||
*
|
||||
* @returns {jQuery} A selector result with all forms modifying this grid
|
||||
*/
|
||||
var determineControlForms = function(domContext) {
|
||||
domContext = domContext || gridDomNode;
|
||||
var controls = $('[data-icinga-grid-controls]', domContext);
|
||||
if (controls.length > 0) {
|
||||
return $('form', controls);
|
||||
} else {
|
||||
return $('form', domContext).filter(function () {
|
||||
return $(this).parentsUntil(domContext, 'table').length === 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect and select the dom of all tables displaying content for this mainDetailGrid component
|
||||
*
|
||||
* The table can either explicitly tagged with the 'data-icinga-grid-content' attribute, if not every table
|
||||
* underneath the components root dom will be used
|
||||
*
|
||||
* @param {jQuery|null} domContext The context to use as the root node for matching, if null
|
||||
* the component node given in the constructor is used
|
||||
*
|
||||
* @returns {jQuery} A selector result with all tables displaying information in the
|
||||
* grid
|
||||
*/
|
||||
var determineContentTable = function(domContext) {
|
||||
domContext = domContext || gridDomNode;
|
||||
var maindetail = $('[data-icinga-grid-content]', domContext);
|
||||
if (maindetail.length > 0) {
|
||||
return maindetail;
|
||||
} else {
|
||||
return $('table', domContext);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show a 'hand' to indicate that the row is selectable,
|
||||
* when hovering.
|
||||
*/
|
||||
this.showMousePointerOnRow = function(domContext) {
|
||||
domContext = domContext || contentNode;
|
||||
$('tbody tr', domContext).css('cursor' ,'pointer');
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate a hover effect on all table rows, to indicate that
|
||||
* this table row is clickable.
|
||||
*
|
||||
* @param domContext
|
||||
*/
|
||||
this.activateRowHovering = function(domContext) {
|
||||
domContext = domContext || contentNode;
|
||||
//$(domContext).addClass('table-hover');
|
||||
$('tbody tr', domContext).hover(
|
||||
function(e) {
|
||||
$(this).addClass('hover');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
},
|
||||
function(e) {
|
||||
$(this).removeClass('hover');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register the row links of tables using the first link found in the table (no matter if visible or not)
|
||||
*
|
||||
* Row level links can only be realized via JavaScript, so every row should provide additional links for
|
||||
* Users that don't have javascript enabled
|
||||
*
|
||||
* @param {jQuery|null} domContext The rootnode to use for selecting rows or null to use contentNode
|
||||
*/
|
||||
this.registerTableLinks = function(domContext) {
|
||||
domContext = domContext || contentNode;
|
||||
$('tbody tr button[type=submit], tbody tr submit', domContext).click(function(ev) {
|
||||
ev.stopPropagation();
|
||||
return true;
|
||||
});
|
||||
$('tbody tr', domContext).click(function(ev) {
|
||||
var targetEl = ev.target || ev.toElement || ev.relatedTarget,
|
||||
a = $(targetEl).closest('a');
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
var nodeNames = [];
|
||||
nodeNames.push($(targetEl).prop('nodeName').toLowerCase());
|
||||
nodeNames.push($(targetEl).parent().prop('nodeName').toLowerCase());
|
||||
if (a.length) {
|
||||
// test if the URL is on the current server, if not open it directly
|
||||
if (Container.isExternalLink(a.attr('href'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var selected = new Selectable(this);
|
||||
switch (selectionMode) {
|
||||
case 'multi':
|
||||
if (ev.ctrlKey || ev.metaKey) {
|
||||
selection.toggle(selected);
|
||||
} else if (ev.shiftKey) {
|
||||
selection.add(selected);
|
||||
} else {
|
||||
var oldState = selected.isActive();
|
||||
if (!oldState) {
|
||||
selection.clear();
|
||||
selection.add(selected);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'single':
|
||||
oldState = selected.isActive();
|
||||
if (!oldState) {
|
||||
selection.clear();
|
||||
selection.add(selected);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// don't open the link
|
||||
return;
|
||||
}
|
||||
var url = URI($('a', this).attr('href'));
|
||||
if (targetEl.tagName.toLowerCase() === 'a') {
|
||||
url = URI($(targetEl).attr('href'));
|
||||
}
|
||||
var segments = url.segment();
|
||||
if (selection.size() === 0) {
|
||||
// don't open anything
|
||||
urlMgr.setDetailUrl('');
|
||||
return false;
|
||||
} else if (selection.size() > 1 && segments.length > 3) {
|
||||
// open detail view for multiple objects
|
||||
segments[2] = 'multi';
|
||||
url.pathname('/' + segments.join('/'));
|
||||
url.search('?');
|
||||
url.setSearch(selection.toQuery());
|
||||
}
|
||||
urlMgr.setDetailUrl(url);
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* Clear the URL when deselected or when a wildcard is used
|
||||
*/
|
||||
$(window).on('hashchange', function(){
|
||||
if (
|
||||
!location.hash ||
|
||||
location.hash.match(/(host=%2A)|(service=%2A)/)
|
||||
) {
|
||||
selection.clear();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Register submit handler for the form controls (sorting, filtering, etc). Reloading happens in the
|
||||
* current container
|
||||
*/
|
||||
this.registerControls = function() {
|
||||
controlForms.on('submit', function(evt) {
|
||||
var container = (new Container(this));
|
||||
var form = $(this);
|
||||
var url = container.getUrl();
|
||||
|
||||
if (url.indexOf('?') >= 0) {
|
||||
url += '&';
|
||||
} else {
|
||||
url += '?';
|
||||
}
|
||||
url += form.serialize();
|
||||
container.setUrl(url);
|
||||
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
return false;
|
||||
|
||||
});
|
||||
$('.pagination li a, a.filter-badge', contentNode.parent()).on('click', function(ev) {
|
||||
|
||||
var container = (new Container(this));
|
||||
|
||||
// Detail will be removed when main pagination changes
|
||||
if (container.containerType === 'icingamain') {
|
||||
urlMgr.setMainUrl(URI($(this).attr('href')));
|
||||
urlMgr.setDetailUrl('');
|
||||
} else {
|
||||
urlMgr.setDetailUrl(URI($(this).attr('href')));
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new TableMultiSelection, attach it to the content node, and use the
|
||||
* current detail url to restore the selection state
|
||||
*/
|
||||
this.initSelection = function() {
|
||||
var detail = urlMgr.getDetailUrl();
|
||||
if (typeof detail !== 'string') {
|
||||
detail = detail[0] || '';
|
||||
}
|
||||
selection = new TableMultiSelection(contentNode,new URI(detail));
|
||||
};
|
||||
|
||||
/**
|
||||
* Init all objects responsible for selection handling
|
||||
*
|
||||
* - Indicate selection by showing active and hovered rows
|
||||
* - Handle click-events according to the selection mode
|
||||
* - Create and follow links according to the row content
|
||||
*/
|
||||
this.initRowSelection = function() {
|
||||
selectionMode = gridDomNode.data('icinga-grid-selection-type');
|
||||
if (selectionMode === 'multi' || selectionMode === 'single') {
|
||||
// indicate selectable rows
|
||||
this.showMousePointerOnRow();
|
||||
this.activateRowHovering();
|
||||
this.initSelection();
|
||||
}
|
||||
this.registerTableLinks();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create this component, setup listeners and behaviour
|
||||
*/
|
||||
this.construct = function(target) {
|
||||
this.container = new Container(target);
|
||||
this.container.removeDefaultLoadIndicator();
|
||||
controlForms = determineControlForms();
|
||||
contentNode = determineContentTable();
|
||||
this.initRowSelection();
|
||||
this.registerControls();
|
||||
};
|
||||
if (typeof $(gridDomNode).attr('id') === 'undefined') {
|
||||
this.construct(gridDomNode);
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,231 +0,0 @@
|
|||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* Ensures that our date/time controls will work on every browser (natively or javascript based)
|
||||
*/
|
||||
define(['jquery', 'logging', 'URIjs/URI', 'components/app/container'], function($, log, URI, Container) {
|
||||
'use strict';
|
||||
|
||||
return function(inputDOM) {
|
||||
this.inputDom = $(inputDOM);
|
||||
this.domain = this.inputDom.attr('data-icinga-filter-domain');
|
||||
this.module = this.inputDom.attr('data-icinga-filter-module');
|
||||
this.form = $(this.inputDom.parents('form').first());
|
||||
this.formUrl = URI(this.form.attr('action'));
|
||||
|
||||
this.lastQueuedEvent = null;
|
||||
this.pendingRequest = null;
|
||||
|
||||
/**
|
||||
* Register the input listener
|
||||
*/
|
||||
this.construct = function() {
|
||||
this.registerControlListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* Request new proposals for the given input box
|
||||
*/
|
||||
this.getProposal = function() {
|
||||
var text = $.trim(this.inputDom.val());
|
||||
|
||||
if (this.pendingRequest) {
|
||||
this.pendingRequest.abort();
|
||||
}
|
||||
this.pendingRequest = $.ajax(this.getRequestParams(text))
|
||||
.done(this.showProposals.bind(this))
|
||||
.fail(this.showError.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a selected proposal to the text box
|
||||
*
|
||||
* String parts encapsulated in {} are parts that already exist in the input
|
||||
*
|
||||
* @param token The selected token
|
||||
*/
|
||||
this.applySelectedProposal = function(token) {
|
||||
var currentText = $.trim(this.inputDom.val());
|
||||
|
||||
var substr = token.match(/^(\{.*\})/);
|
||||
if (substr !== null) {
|
||||
token = token.substr(substr[0].length);
|
||||
} else {
|
||||
token = ' ' + token;
|
||||
}
|
||||
|
||||
currentText += token;
|
||||
this.inputDom.val(currentText);
|
||||
this.inputDom.popover('hide');
|
||||
this.inputDom.focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Display an error in the box if the request failed
|
||||
*
|
||||
* @param {Object} error The error response
|
||||
* @param {String} state The HTTP state as a string
|
||||
*/
|
||||
this.showError = function(error, state) {
|
||||
if (!error.message || state === 'abort') {
|
||||
return;
|
||||
}
|
||||
this.inputDom.popover('destroy').popover({
|
||||
content: '<div class="alert alert-danger"> ' + error.message + ' </div>',
|
||||
html: true,
|
||||
trigger: 'manual'
|
||||
}).popover('show');
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an Object containing the request information for the given query
|
||||
*
|
||||
* @param query
|
||||
* @returns {{data: {cache: number, query: *, filter_domain: (*|Function|Function), filter_module: Function}, headers: {Accept: string}, url: *}}
|
||||
*/
|
||||
this.getRequestParams = function(query) {
|
||||
return {
|
||||
data: {
|
||||
'cache' : (new Date()).getTime(),
|
||||
'query' : query,
|
||||
'filter_domain' : this.domain,
|
||||
'filter_module' : this.module
|
||||
},
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
url: this.formUrl
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback that renders the proposal list after retrieving it from the server
|
||||
*
|
||||
* @param {Object} response The jquery response object inheritn XHttpResponse Attributes
|
||||
*/
|
||||
this.showProposals = function(response) {
|
||||
|
||||
if (!response || !response.proposals || response.proposals.length === 0) {
|
||||
this.inputDom.popover('destroy');
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.valid) {
|
||||
this.inputDom.parent('div').removeClass('has-error').addClass('has-success');
|
||||
} else {
|
||||
this.inputDom.parent('div').removeClass('has-success').addClass('has-error');
|
||||
}
|
||||
var list = $('<ul>').addClass('nav nav-stacked');
|
||||
$.each(response.proposals, (function(idx, token) {
|
||||
var displayToken = token.replace(/(\{|\})/g, '');
|
||||
var proposal = $('<li>').
|
||||
append($('<a href="#">').
|
||||
text(displayToken)
|
||||
).appendTo(list);
|
||||
|
||||
proposal.on('click', (function(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.applySelectedProposal(token);
|
||||
return false;
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
|
||||
this.inputDom.popover('destroy').popover({
|
||||
content: list,
|
||||
placement : 'bottom',
|
||||
html: true,
|
||||
trigger: 'manual'
|
||||
}).popover('show');
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to update the current container with the entered url if it's valid
|
||||
*/
|
||||
this.updateFilter = function() {
|
||||
var query = $.trim(this.inputDom.val());
|
||||
$.ajax(this.getRequestParams(query))
|
||||
.done((function(response) {
|
||||
var domContainer = new Container(this.inputDom);
|
||||
var url = response.urlParam;
|
||||
|
||||
if (url) {
|
||||
domContainer.setUrl(url);
|
||||
}
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Register listeners for the searchbox
|
||||
*
|
||||
* This means:
|
||||
* - Activate/Deactivate the popover on focus and blur
|
||||
* - Add Url tokens and submit on enter
|
||||
*/
|
||||
this.registerControlListener = function() {
|
||||
this.inputDom.on('blur', (function() {
|
||||
$(this).popover('hide');
|
||||
}));
|
||||
this.inputDom.on('focus', updateProposalList.bind(this));
|
||||
this.inputDom.on('keyup', updateProposalList.bind(this));
|
||||
this.inputDom.on('keydown', (function(keyEv) {
|
||||
if ((keyEv.keyCode || keyEv.which) === 13) {
|
||||
this.updateFilter();
|
||||
keyEv.stopPropagation();
|
||||
keyEv.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
this.form.submit(function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to update the proposal list if a slight delay on keyPress
|
||||
*
|
||||
* Needs to be bound to the object scope
|
||||
*
|
||||
* @param {jQuery.Event} keyEv The key Event to react on
|
||||
*/
|
||||
var updateProposalList = function(keyEv) {
|
||||
|
||||
if (this.lastQueuedEvent) {
|
||||
window.clearTimeout(this.lastQueuedEvent);
|
||||
}
|
||||
this.lastQueuedEvent = window.setTimeout(this.getProposal.bind(this), 500);
|
||||
};
|
||||
|
||||
this.construct();
|
||||
};
|
||||
});
|
|
@ -1,40 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
|
||||
/**
|
||||
* Ensures that our date/time controls will work on every browser (natively or javascript based)
|
||||
*/
|
||||
define(['jquery', 'datetimepicker'], function($) {
|
||||
"use strict";
|
||||
|
||||
var triStateCheckbox = function(target) {
|
||||
// TODO: remove radio button group from form and add a tri-state checkbox
|
||||
};
|
||||
return triStateCheckbox;
|
||||
});
|
|
@ -1,145 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'logging',
|
||||
'icinga/componentLoader',
|
||||
'components/app/container',
|
||||
'URIjs/URI',
|
||||
'icinga/util/url'
|
||||
], function ($, log, components, Container, URI, urlMgr) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Icinga prototype
|
||||
*/
|
||||
var Icinga = function() {
|
||||
var pendingRequest = null;
|
||||
|
||||
/**
|
||||
* Initia
|
||||
*/
|
||||
var initialize = function () {
|
||||
components.load();
|
||||
|
||||
// qd, wip, wrong, the nastiest piece of JS code you've ever seen..
|
||||
if (window.name === '') {
|
||||
window.name = request_id; // The request id should survive page reloads..
|
||||
}
|
||||
$(document).on('click', 'a', function() {
|
||||
// TODO: The intention of these lines is sending the "request_id" every
|
||||
// time a request is made, though this approach does not work for
|
||||
// XHR requests and it is also hijacking external links.
|
||||
// An alternative is required, once someone reworked the Javascript
|
||||
// implementation so we have some sort of centralized place to handle
|
||||
// stuff like that properly.
|
||||
var href = $(this).attr('href');
|
||||
window.location.href = URI(href).addSearch('request_id', window.name);
|
||||
return false;
|
||||
});
|
||||
// qd, wip, wrong, the nastiest piece of JS code you've ever seen..
|
||||
|
||||
log.debug("Initialization finished");
|
||||
};
|
||||
|
||||
/**
|
||||
* Globally open the given url and reload the main/detail box to represent it
|
||||
*
|
||||
* @param url The url to load
|
||||
*/
|
||||
this.openUrl = function(url) {
|
||||
if (pendingRequest) {
|
||||
pendingRequest.abort();
|
||||
}
|
||||
pendingRequest = $.ajax({
|
||||
"url": url
|
||||
}).done(function(response) {
|
||||
var dom = $(response);
|
||||
var detailDom = null;
|
||||
if (urlMgr.detailUrl) {
|
||||
detailDom = $('#icingadetail');
|
||||
}
|
||||
$(document.body).empty().append(dom);
|
||||
if (detailDom && detailDom.length) {
|
||||
$('#icingadetail').replaceWith(detailDom);
|
||||
Container.showDetail();
|
||||
}
|
||||
components.load();
|
||||
Container.getMainContainer();
|
||||
}).fail(function(response, reason) {
|
||||
if (reason === 'abort') {
|
||||
return;
|
||||
}
|
||||
log.error("Request failed: ", response.message);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
if (Modernizr.history) {
|
||||
/**
|
||||
* Event handler that will be called when the url change
|
||||
*/
|
||||
urlMgr.syncWithUrl();
|
||||
var lastMain = urlMgr.mainUrl;
|
||||
$(window).on('pushstate', (function() {
|
||||
urlMgr.syncWithUrl();
|
||||
if (urlMgr.mainUrl !== lastMain) {
|
||||
this.openUrl(urlMgr.getUrl());
|
||||
lastMain = urlMgr.mainUrl;
|
||||
}
|
||||
// If an anchor is set, scroll to it's position
|
||||
if ($('#' + urlMgr.anchor).length) {
|
||||
$(document.body).scrollTo($('#' + urlMgr.anchor));
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
/**
|
||||
* Event handler for browser back/forward events
|
||||
*/
|
||||
$(window).on('popstate', (function() {
|
||||
var lastMain = urlMgr.mainUrl;
|
||||
urlMgr.syncWithUrl();
|
||||
if (urlMgr.mainUrl !== lastMain) {
|
||||
this.openUrl(urlMgr.getUrl());
|
||||
}
|
||||
|
||||
}).bind(this));
|
||||
}
|
||||
|
||||
$(document).ready(initialize.bind(this));
|
||||
Container.setIcinga(this);
|
||||
|
||||
this.components = components;
|
||||
|
||||
};
|
||||
|
||||
|
||||
return new Icinga();
|
||||
});
|
|
@ -1,217 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
define(
|
||||
['jquery', 'URIjs/URI', 'icinga/selection/selectable'],
|
||||
function($, URI, Selectable) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Handle the multi-selection of table rows and generate the query string
|
||||
* that can be used to open the selected items.
|
||||
*
|
||||
* NOTE: After each site reload, the state (the current selection) of this object will be
|
||||
* restored automatically. The selectable items are determined by finding all TR elements
|
||||
* in the targeted table. The active selection is determined by checking the query elements
|
||||
* of the given url.
|
||||
*
|
||||
* @param {HtmlElement} The table that contains the selectable rows.
|
||||
*
|
||||
* @param {URI} The query that contains the selected rows.
|
||||
*/
|
||||
return function MultiSelection(table, detailUrl) {
|
||||
|
||||
var self = this;
|
||||
/**
|
||||
* Contains all selected selectables
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var selection = {};
|
||||
|
||||
/**
|
||||
* If the selectable was already added, remove it, otherwise add it.
|
||||
*
|
||||
* @param {Selectable} The selectable to use.
|
||||
*/
|
||||
this.toggle = function(selectable) {
|
||||
if (selection[selectable.getId()]) {
|
||||
self.remove(selectable);
|
||||
} else {
|
||||
self.add(selectable);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the selectable to the current selection.
|
||||
*
|
||||
* @param {Selectable} The selectable to use.
|
||||
*/
|
||||
this.add = function(selectable) {
|
||||
selectable.setActive(true);
|
||||
selection[selectable.getId()] = selectable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the selectable from the current selection.
|
||||
*
|
||||
* @param {Selectable} The selectable to use.
|
||||
*/
|
||||
this.remove = function(selectable) {
|
||||
selectable.setActive(false);
|
||||
delete selection[selectable.getId()];
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the current selection
|
||||
*/
|
||||
this.clear = function() {
|
||||
$.each(selection, function(index, selectable){
|
||||
selectable.setActive(false);
|
||||
});
|
||||
selection = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the current selection to its query-representation.
|
||||
*
|
||||
* @returns {String} The query
|
||||
*/
|
||||
this.toQuery = function() {
|
||||
var query = {};
|
||||
var i = 0;
|
||||
$.each(selection, function(id, selectable) {
|
||||
$.each(selectable.getQuery(), function(key, value) {
|
||||
query[key + '[' + i + ']'] = value;
|
||||
});
|
||||
i++;
|
||||
});
|
||||
return query;
|
||||
};
|
||||
|
||||
this.size = function() {
|
||||
var size = 0;
|
||||
$.each(selection, function(){ size++; });
|
||||
return size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the selections from a query containing multiple selections
|
||||
*/
|
||||
var selectionFromMultiQuery = function(query) {
|
||||
var selections = [];
|
||||
$.each(query, function(key, value) {
|
||||
// Fetch the index from the key
|
||||
var id = key.match(/\[([0-9]+)\]/);
|
||||
if (id) {
|
||||
// Remove the index from the key
|
||||
key = key.replace(/\[[0-9]+\]/,'');
|
||||
// Create an object that contains the queries for each index.
|
||||
var i = id[1];
|
||||
if (!selections[i]) {
|
||||
selections[i] = [];
|
||||
}
|
||||
selections[i].push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
|
||||
}
|
||||
});
|
||||
return selections;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the selections from a default query.
|
||||
*/
|
||||
var selectionFromQuery = function(query) {
|
||||
var selection = [];
|
||||
$.each(query, function(key, value){
|
||||
key = encodeURIComponent(key);
|
||||
value = encodeURIComponent(value);
|
||||
selection.push(key + '=' + value);
|
||||
});
|
||||
return [ selection ];
|
||||
};
|
||||
|
||||
/**
|
||||
* Restore the selected ids from the given URL.
|
||||
*
|
||||
* @param {URI} The used URL
|
||||
*
|
||||
* @returns {Array} The selected ids
|
||||
*/
|
||||
var restoreSelectionStateUrl = function(url) {
|
||||
if (!url) {
|
||||
return [];
|
||||
}
|
||||
var segments = url.segment();
|
||||
var parts;
|
||||
// TODO: Handle it for cases when there is no /icinga-web2/ in the path
|
||||
if (segments.length > 2 && segments[2].toLowerCase() === 'multi') {
|
||||
parts = selectionFromMultiQuery(url.query(true));
|
||||
} else {
|
||||
parts = selectionFromQuery(url.query(true));
|
||||
}
|
||||
return $.map(parts, function(part) {
|
||||
part.sort(function(a, b){
|
||||
a = a.toUpperCase();
|
||||
b = b.toUpperCase();
|
||||
return (a < b ? -1 : (a > b) ? 1 : 0);
|
||||
});
|
||||
return part.join('&');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the selectables from the given table-Html
|
||||
*/
|
||||
var createSelectables = function(table) {
|
||||
var selectables = {};
|
||||
$(table).find('tr').each(function(i, row) {
|
||||
var selectable = new Selectable(row);
|
||||
selectables[selectable.getId()] = selectable;
|
||||
});
|
||||
return selectables;
|
||||
};
|
||||
|
||||
/**
|
||||
* Restore the selectables from the given table and the given url
|
||||
*/
|
||||
var restoreSelection = function() {
|
||||
var selectables = createSelectables(table);
|
||||
var selected = restoreSelectionStateUrl(detailUrl);
|
||||
var selection = {};
|
||||
$.each(selected, function(i, selectionId) {
|
||||
var restored = selectables[selectionId];
|
||||
if (restored) {
|
||||
selection[selectionId] = restored;
|
||||
restored.setActive(true);
|
||||
}
|
||||
});
|
||||
return selection;
|
||||
};
|
||||
|
||||
selection = restoreSelection();
|
||||
};
|
||||
});
|
|
@ -1,99 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
define(['jquery', 'URIjs/URI'], function($, URI) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Wrapper around a selectable table row. Searches the first href and to identify the associated
|
||||
* query and use this query as an Identifier.
|
||||
*
|
||||
* @param {HtmlElement} The table row.
|
||||
*/
|
||||
return function Selectable(tableRow) {
|
||||
|
||||
/**
|
||||
* The href that is called when this row clicked.
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
var href = URI($(tableRow).find('a').first().attr('href'));
|
||||
|
||||
/*
|
||||
* Sort queries alphabetically to ensure non-ambiguous ids.
|
||||
*/
|
||||
var query = href.query();
|
||||
var parts = query.split('&');
|
||||
parts.sort(function(a, b){
|
||||
a = a.toUpperCase();
|
||||
b = b.toUpperCase();
|
||||
return (a < b ? -1 : (a > b) ? 1 : 0);
|
||||
});
|
||||
href.query(parts.join('&'));
|
||||
|
||||
/**
|
||||
* Return an ID for this selectable.
|
||||
*
|
||||
* @returns {String} The id.
|
||||
*/
|
||||
this.getId = function () {
|
||||
return href.query();
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the query object associated with this selectable.
|
||||
*
|
||||
* @returns {String} The id.
|
||||
*/
|
||||
this.getQuery = function() {
|
||||
return href.query(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the current selection state
|
||||
*
|
||||
* @param {boolean} The new state
|
||||
*/
|
||||
this.setActive = function(value) {
|
||||
if (value) {
|
||||
$(tableRow).addClass('active');
|
||||
} else {
|
||||
$(tableRow).removeClass('active');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the current selection state
|
||||
*
|
||||
* @returns {boolean} True when the object is selected
|
||||
*/
|
||||
this.isActive = function()
|
||||
{
|
||||
return $(tableRow).hasClass('active');
|
||||
};
|
||||
};
|
||||
});
|
|
@ -1,98 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false, window:false */
|
||||
|
||||
|
||||
/**
|
||||
* Icinga Logger
|
||||
*
|
||||
* Allows platform independent logging of via logger.info, logger.warn, logger.error and logger.emergency
|
||||
*
|
||||
*/
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Log a message to the console (if available), using the provided tag
|
||||
*
|
||||
* @param {String} tag The tag to use, error and emergency are logged as console.error
|
||||
* @param {String} logArgs The arguments to log
|
||||
*/
|
||||
function logTagged(tag, logArgs) {
|
||||
var now = new Date();
|
||||
var ms = now.getMilliseconds() + '';
|
||||
while (ms.length < length) {
|
||||
ms = '0' + ms;
|
||||
}
|
||||
logArgs = [].slice.call(logArgs);
|
||||
logArgs.unshift(now.toLocaleTimeString() + '.' + ms);
|
||||
|
||||
var args = [tag.toUpperCase() + ' :'];
|
||||
for (var el in logArgs) {
|
||||
args.push(logArgs[el]);
|
||||
}
|
||||
try {
|
||||
if (console[tag]) {
|
||||
console[tag].apply(console, logArgs);
|
||||
} else if (tag === 'emergency') {
|
||||
console.error.apply(console, logArgs);
|
||||
} else {
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
|
||||
} catch (e) { // IE fallback
|
||||
console.log(logArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if(!window.console) {
|
||||
window.console = { log: function() {} };
|
||||
}
|
||||
|
||||
/**
|
||||
* Callinterface for this module
|
||||
*/
|
||||
return {
|
||||
debug: function() {
|
||||
if (!window.ICINGA_DEBUG) {
|
||||
return;
|
||||
}
|
||||
logTagged('debug', arguments);
|
||||
},
|
||||
warn: function() {
|
||||
logTagged('warn', arguments);
|
||||
},
|
||||
error: function() {
|
||||
logTagged('error', arguments);
|
||||
},
|
||||
emergency: function() {
|
||||
logTagged('emergency', arguments);
|
||||
// TODO: log *emergency* errors to the backend
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,194 +0,0 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
define(['jquery', 'logging', 'URIjs/URI'], function($, log, URI, Container) {
|
||||
"use strict";
|
||||
|
||||
var currentUrl = URI(window.location.href);
|
||||
|
||||
/**
|
||||
* Utility class for Url handling
|
||||
*
|
||||
*/
|
||||
var URLMgr = function() {
|
||||
/**
|
||||
* The current url of the main part
|
||||
* @type {string}
|
||||
*/
|
||||
this.mainUrl = '';
|
||||
|
||||
/**
|
||||
* The current main anchor
|
||||
* @type {string}
|
||||
*/
|
||||
this.anchor = '';
|
||||
|
||||
/**
|
||||
* The current detail url
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
this.detailUrl = '';
|
||||
|
||||
/**
|
||||
* The current anchor of the detail url
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
this.detailAnchor = '';
|
||||
|
||||
/**
|
||||
* Extract the anchor of the main url part from the given url
|
||||
*
|
||||
* @param {String|URI} url An URL object to extract the information from
|
||||
* @returns {*}
|
||||
*/
|
||||
this.getMainAnchor = function(url) {
|
||||
url = url || URI(window.location.href);
|
||||
if (typeof url === 'string') {
|
||||
url = URI(url);
|
||||
}
|
||||
var fragment = url.fragment();
|
||||
if (fragment.length === 0) {
|
||||
return '';
|
||||
}
|
||||
var parts = fragment.split('!');
|
||||
if (parts.length > 0) {
|
||||
return parts[0];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract the detail url a the given url. Returns a [URL, ANCHOR] Tupel
|
||||
*
|
||||
* @param String url An optional url to parse (otherwise window.location.href is used)
|
||||
* @returns {Array} A [{String} Url, {String} anchor] tupel
|
||||
*/
|
||||
this.getDetailUrl = function(url) {
|
||||
url = url || URI(window.location.href);
|
||||
if (typeof url === 'string') {
|
||||
url = URI(url);
|
||||
}
|
||||
|
||||
var fragment = url.fragment();
|
||||
if (fragment.length === 0) {
|
||||
return '';
|
||||
}
|
||||
var parts = fragment.split('!', 2);
|
||||
|
||||
if (parts.length === 2) {
|
||||
var result = /detail=(.*)$/.exec(parts[1]);
|
||||
if (!result || result.length < 2) {
|
||||
return '';
|
||||
}
|
||||
return result[1].replace('%23', '#').split('#');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Overwrite the detail Url and update the hash
|
||||
*
|
||||
* @param String url The url to use for the detail part
|
||||
*/
|
||||
this.setDetailUrl = function(url) {
|
||||
if (typeof url === 'string') {
|
||||
url = URI(url);
|
||||
}
|
||||
if( !url.fragment() || url.href() !== '#' + url.fragment()) {
|
||||
this.detailUrl = url.clone().fragment('').href();
|
||||
}
|
||||
this.detailAnchor = this.getMainAnchor(url);
|
||||
window.location.hash = this.getUrlHash();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the hash of the current detail url and anchor i
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
this.getUrlHash = function() {
|
||||
var anchor = '#' + this.anchor +
|
||||
'!' + ($.trim(this.detailUrl) ? 'detail=' : '') + this.detailUrl +
|
||||
(this.detailAnchor ? '%23' : '') + this.detailAnchor;
|
||||
anchor = $.trim(anchor);
|
||||
if (anchor === '#!' || anchor === '#') {
|
||||
anchor = '';
|
||||
}
|
||||
return anchor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the main url to be used
|
||||
*
|
||||
* This triggers the pushstate event or causes a page reload if the history api is
|
||||
* not available
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
this.setMainUrl = function(url) {
|
||||
this.anchor = this.getMainAnchor(url);
|
||||
this.mainUrl = URI(url).clone().fragment('').href();
|
||||
if (!Modernizr.history) {
|
||||
window.location.href = this.mainUrl + this.getUrlHash();
|
||||
} else {
|
||||
window.history.pushState({}, document.title, this.mainUrl + this.getUrlHash());
|
||||
$(window).trigger('pushstate');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the href (main path + hash)
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
this.getUrl = function() {
|
||||
return this.mainUrl + this.getUrlHash();
|
||||
};
|
||||
|
||||
/**
|
||||
* Take the current url and sync the internal state of this url manager with it
|
||||
*/
|
||||
this.syncWithUrl = function() {
|
||||
this.mainUrl = URI(window.location.href).clone().fragment('').href();
|
||||
this.anchor = this.getMainAnchor();
|
||||
var urlAnchorTupel = this.getDetailUrl();
|
||||
this.detailUrl = urlAnchorTupel[0] || '';
|
||||
this.detailAnchor = urlAnchorTupel[1] || '';
|
||||
};
|
||||
|
||||
|
||||
this.syncWithUrl();
|
||||
};
|
||||
var urlMgr = new URLMgr();
|
||||
|
||||
return urlMgr;
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
requirejs.config({
|
||||
'baseUrl': window.base_url + '/js',
|
||||
'urlArgs': "bust=" + (new Date()).getTime(),
|
||||
'paths': {
|
||||
'jquery': 'vendor/jquery-1.8.3',
|
||||
'jquery_scrollto': 'vendor/jquery.scrollto',
|
||||
'freetile': 'vendor/freetile',
|
||||
'bootstrap': 'vendor/bootstrap/bootstrap.min',
|
||||
'logging': 'icinga/util/logging',
|
||||
'URIjs': 'vendor/uri',
|
||||
'datetimepicker': 'vendor/bootstrap/datetimepicker.min'
|
||||
},
|
||||
'shim': {
|
||||
'datetimepicker': {
|
||||
'exports': 'datetimepicker'
|
||||
},
|
||||
|
||||
'jquery_scrollto': {
|
||||
exports: 'jquery_scrollto'
|
||||
},
|
||||
'freetile': {
|
||||
exports: 'freetile'
|
||||
},
|
||||
'jquery' : {
|
||||
exports: 'jquery'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
define(['jquery'], function ($, history) {
|
||||
window.$ = $;
|
||||
window.jQuery = $;
|
||||
|
||||
requirejs(['bootstrap','vendor/imagesLoaded','jquery_scrollto', 'freetile'], function() {
|
||||
requirejs(['datetimepicker']);
|
||||
});
|
||||
requirejs(['icinga/icinga'], function (Icinga) {
|
||||
window.Icinga = Icinga;
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue