aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/libs/application.js
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-05-18 16:29:19 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-05-19 18:20:09 +0200
commite59e4aa2c06a57566f148f4217d286461231ae58 (patch)
treead0918eb06b2474a6c71997b7ff573bbb93e0170 /server/sonar-web/src/main/js/libs/application.js
parent8d82c9cf9ba88c1517604b4063ad0fc2a9a1bb9a (diff)
downloadsonarqube-e59e4aa2c06a57566f148f4217d286461231ae58.tar.gz
sonarqube-e59e4aa2c06a57566f148f4217d286461231ae58.zip
change web structure: separate components
Diffstat (limited to 'server/sonar-web/src/main/js/libs/application.js')
-rw-r--r--server/sonar-web/src/main/js/libs/application.js575
1 files changed, 575 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/libs/application.js b/server/sonar-web/src/main/js/libs/application.js
new file mode 100644
index 00000000000..2d16dd4ff5d
--- /dev/null
+++ b/server/sonar-web/src/main/js/libs/application.js
@@ -0,0 +1,575 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+/*
+ * Global Messages
+ */
+
+(function () {
+ /**
+ * Show a global message
+ * @param {string} id
+ * @param {string} message
+ */
+ window.showMessage = function (id, message) {
+ $j('#' + id + 'msg').html(message);
+ $j('#' + id).removeClass('hidden');
+ $j('#messages-panel').removeClass('hidden');
+ };
+
+ /**
+ * Hide a global message
+ * @param {string} id
+ * @returns {boolean} always false
+ */
+ window.hideMessage = function (id) {
+ $j('#' + id).addClass('hidden');
+ var messagePanel = $j('#messages-panel'),
+ isEmpty = messagePanel.children('*:not(.hidden)').length === 0;
+ messagePanel.toggleClass('hidden', isEmpty);
+ return false;
+ };
+
+ /**
+ * Show a global error message
+ * @param {string} message
+ */
+ window.error = function (message) {
+ showMessage('error', message);
+ };
+
+ /**
+ * Show a global warning message
+ * @param {string} message
+ */
+ window.warning = function (message) {
+ showMessage('warning', message);
+ };
+
+ /**
+ * Show a global info message
+ * @param {string} message
+ */
+ window.info = function (message) {
+ showMessage('info', message);
+ };
+
+ /**
+ * Hide a global error message
+ * @returns {boolean} always false
+ */
+ window.hideError = function () {
+ return hideMessage('error');
+ };
+
+ /**
+ * Hide a global warning message
+ * @returns {boolean} always false
+ */
+ window.hideWarning = function () {
+ return hideMessage('warning');
+ };
+
+ /**
+ * Hide a global info message
+ * @returns {boolean} always false
+ */
+ window.hideInfo = function () {
+ return hideMessage('info');
+ };
+})();
+
+
+
+function toggleFav (resourceId, elt) {
+ $j.ajax({
+ type: 'POST', dataType: 'json', url: baseUrl + '/favourites/toggle/' + resourceId,
+ success: function (data) {
+ var star = $j(elt);
+ star.removeClass('icon-favorite icon-not-favorite');
+ star.addClass(data.css);
+ star.attr('title', data.title);
+ }
+ });
+}
+
+function dashboardParameters (urlHasSomething) {
+ var queryString = window.location.search;
+ var parameters = [];
+
+ var matchDashboard = queryString.match(/did=\d+/);
+ if (matchDashboard && $j('#is-project-dashboard').length === 1) {
+ parameters.push(matchDashboard[0]);
+ }
+
+ var matchPeriod = queryString.match(/period=\d+/);
+ if (matchPeriod) {
+ // If we have a match for period, check that it is not project-specific
+ var period = parseInt(/period=(\d+)/.exec(queryString)[1], 10);
+ if (period <= 3) {
+ parameters.push(matchPeriod[0]);
+ }
+ }
+
+ var query = parameters.join('&');
+ if (query !== '') {
+ query = (urlHasSomething ? '&' : '?') + query;
+ }
+ return query;
+}
+
+function openModalWindow (url, options) {
+ var width = (options && options.width) || 540;
+ var $dialog = $j('#modal');
+ if (!$dialog.length) {
+ $dialog = $j('<div id="modal" class="ui-widget-overlay ui-front"></div>').appendTo('body');
+ }
+ $j.get(url, function (html) {
+ $dialog.removeClass('ui-widget-overlay');
+ $dialog.html(html);
+ $dialog
+ .dialog({
+ dialogClass: 'no-close',
+ width: width,
+ draggable: false,
+ autoOpen: false,
+ modal: true,
+ minHeight: 50,
+ resizable: false,
+ title: null,
+ close: function () {
+ $j('#modal').remove();
+ }
+ });
+ $dialog.dialog('open');
+ }).always(function () {
+ $dialog.removeClass('ui-widget-overlay');
+ });
+ return false;
+}
+
+(function ($j) {
+ $j.fn.extend({
+ openModal: function () {
+ return this.each(function () {
+ var obj = $j(this);
+ var url = obj.attr('modal-url') || obj.attr('href');
+ return openModalWindow(url, { 'width': obj.attr('modal-width') });
+ });
+ },
+ modal: function () {
+ return this.each(function () {
+ var obj = $j(this);
+ obj.unbind('click');
+ var $link = obj.bind('click', function () {
+ $link.openModal();
+ return false;
+ });
+ });
+ },
+ modalForm: function (ajax_options) {
+ return this.each(function () {
+ var obj = $j(this);
+ obj.submit(function () {
+ $j('input[type=submit]', this).attr('disabled', 'disabled');
+ $j.ajax($j.extend({
+ type: 'POST',
+ url: obj.attr('action'),
+ data: obj.serialize(),
+ success: function () {
+ window.location.reload();
+ },
+ error: function (xhr) {
+ // If the modal window has defined a modal-error element, then returned text must be displayed in it
+ var errorElt = obj.find('.modal-error');
+ if (errorElt.length) {
+ // Hide all loading images
+ $j('.loading-image').addClass('hidden');
+ // Re activate submit button
+ $j('input[type=submit]', obj).removeAttr('disabled');
+ errorElt.show();
+ errorElt.html($j('<div/>').html(xhr.responseText).text());
+ } else {
+ // otherwise replace modal window by the returned text
+ $j('#modal').html(xhr.responseText);
+ }
+ }
+ }, ajax_options));
+ return false;
+ });
+ });
+ }
+ });
+})(jQuery);
+
+function closeModalWindow () {
+ $j('#modal').dialog('close');
+ return false;
+}
+
+
+
+/*
+ * File Path
+ */
+
+(function () {
+ /**
+ * Return a collapsed path without a file name
+ * @example
+ * // returns 'src/.../js/components/navigator/app/models/'
+ * collapsedDirFromPath('src/main/js/components/navigator/app/models/state.js')
+ * @param {string} path
+ * @returns {string|null}
+ */
+ window.collapsedDirFromPath = function (path) {
+ var limit = 30;
+ if (typeof path === 'string') {
+ var tokens = _.initial(path.split('/'));
+ if (tokens.length > 2) {
+ var head = _.first(tokens),
+ tail = _.last(tokens),
+ middle = _.initial(_.rest(tokens)),
+ cut = false;
+ while (middle.join().length > limit && middle.length > 0) {
+ middle.shift();
+ cut = true;
+ }
+ var body = [].concat(head, cut ? ['...'] : [], middle, tail);
+ return body.join('/') + '/';
+ } else {
+ return tokens.join('/') + '/';
+ }
+ } else {
+ return null;
+ }
+ };
+
+ /**
+ * Return a file name for a given file path
+ * * @example
+ * // returns 'state.js'
+ * collapsedDirFromPath('src/main/js/components/navigator/app/models/state.js')
+ * @param {string} path
+ * @returns {string|null}
+ */
+ window.fileFromPath = function (path) {
+ if (typeof path === 'string') {
+ var tokens = path.split('/');
+ return _.last(tokens);
+ } else {
+ return null;
+ }
+ };
+})();
+
+
+
+/*
+ * Measures
+ */
+
+(function () {
+
+ function shortIntFormatter (value) {
+ var format = '0,0';
+ if (value >= 1000) {
+ format = '0.[0]a';
+ }
+ if (value >= 10000) {
+ format = '0a';
+ }
+ return numeral(value).format(format);
+ }
+
+ function shortIntVariationFormatter (value) {
+ if (value === 0) {
+ return '0';
+ }
+ var format = '+0,0';
+ if (Math.abs(value) >= 1000) {
+ format = '+0.[0]a';
+ }
+ if (Math.abs(value) >= 10000) {
+ format = '+0a';
+ }
+ return numeral(value).format(format);
+ }
+
+ /**
+ * Check if days should be displayed for a work duration
+ * @param {number} days
+ * @returns {boolean}
+ */
+ function shouldDisplayDays (days) {
+ return days > 0;
+ }
+
+ /**
+ * Check if hours should be displayed for a work duration
+ * @param {number} days
+ * @param {number} hours
+ * @returns {boolean}
+ */
+ function shouldDisplayHours (days, hours) {
+ return hours > 0 && days < 10;
+ }
+
+ /**
+ * Check if minutes should be displayed for a work duration
+ * @param {number} days
+ * @param {number} hours
+ * @param {number} minutes
+ * @returns {boolean}
+ */
+ function shouldDisplayMinutes (days, hours, minutes) {
+ return minutes > 0 && hours < 10 && days === 0;
+ }
+
+ /**
+ * Add a space between units if needed
+ * @param {string} value
+ * @returns {string}
+ */
+ function addSpaceIfNeeded (value) {
+ return value.length > 0 ? value + ' ' : value;
+ }
+
+ /**
+ * Format a work duration based on parameters
+ * @param {bool} isNegative
+ * @param {number} days
+ * @param {number} hours
+ * @param {number} minutes
+ * @returns {string}
+ */
+ function formatDuration (isNegative, days, hours, minutes) {
+ var formatted = '';
+ if (shouldDisplayDays(days)) {
+ formatted += tp('work_duration.x_days', isNegative ? -1 * days : days);
+ }
+ if (shouldDisplayHours(days, hours)) {
+ formatted = addSpaceIfNeeded(formatted);
+ formatted += tp('work_duration.x_hours', isNegative && formatted.length === 0 ? -1 * hours : hours);
+ }
+ if (shouldDisplayMinutes(days, hours, minutes)) {
+ formatted = addSpaceIfNeeded(formatted);
+ formatted += tp('work_duration.x_minutes', isNegative && formatted.length === 0 ? -1 * minutes : minutes);
+ }
+ return formatted;
+ }
+
+ /**
+ * Format a work duration measure
+ * @param {number} value
+ * @returns {string}
+ */
+ var durationFormatter = function (value) {
+ if (value === 0) {
+ return '0';
+ }
+ var hoursInDay = window.SS.hoursInDay || 8,
+ isNegative = value < 0,
+ absValue = Math.abs(value);
+ var days = Math.floor(absValue / hoursInDay / 60);
+ var remainingValue = absValue - days * hoursInDay * 60;
+ var hours = Math.floor(remainingValue / 60);
+ remainingValue -= hours * 60;
+ return formatDuration(isNegative, days, hours, remainingValue);
+ };
+
+ /**
+ * Format a work duration variation
+ * @param {number} value
+ */
+ var durationVariationFormatter = function (value) {
+ if (value === 0) {
+ return '0';
+ }
+ var formatted = durationFormatter(value);
+ return formatted[0] !== '-' ? '+' + formatted : formatted;
+ };
+
+ /**
+ * Format a rating measure
+ * @param {number} value
+ */
+ var ratingFormatter = function (value) {
+ return String.fromCharCode(97 + value - 1).toUpperCase();
+ };
+
+ /**
+ * Format a measure according to its type
+ * @param measure
+ * @param {string} type
+ * @returns {string|null}
+ */
+ window.formatMeasure = function (measure, type) {
+ var formatted = null,
+ formatters = {
+ 'INT': function (value) {
+ return numeral(value).format('0,0');
+ },
+ 'SHORT_INT': shortIntFormatter,
+ 'FLOAT': function (value) {
+ return numeral(value).format('0,0.0');
+ },
+ 'PERCENT': function (value) {
+ return numeral(+value / 100).format('0,0.0%');
+ },
+ 'WORK_DUR': durationFormatter,
+ 'RATING': ratingFormatter
+ };
+ if (measure != null && type != null) {
+ formatted = formatters[type] != null ? formatters[type](measure) : measure;
+ }
+ return formatted;
+ };
+
+ /**
+ * Format a measure variation according to its type
+ * @param measure
+ * @param {string} type
+ * @returns {string|null}
+ */
+ window.formatMeasureVariation = function (measure, type) {
+ var formatted = null,
+ formatters = {
+ 'INT': function (value) {
+ return value === 0 ? '0' : numeral(value).format('+0,0');
+ },
+ 'SHORT_INT': shortIntVariationFormatter,
+ 'FLOAT': function (value) {
+ return value === 0 ? '0' : numeral(value).format('+0,0.0');
+ },
+ 'PERCENT': function (value) {
+ return value === 0 ? '0%' : numeral(+value / 100).format('+0,0.0%');
+ },
+ 'WORK_DUR': durationVariationFormatter
+ };
+ if (measure != null && type != null) {
+ formatted = formatters[type] != null ? formatters[type](measure) : measure;
+ }
+ return formatted;
+ };
+})();
+
+
+
+/*
+ * Users
+ */
+
+(function() {
+
+ /**
+ * Convert the result of api/users/search to select2 format
+ */
+ window.usersToSelect2 = function (response) {
+ return {
+ more: false,
+ results: _.map(response.users, function(user) {
+ return {
+ id: user.login,
+ text: user.name + ' (' + user.login + ')'
+ };
+ })
+ };
+ };
+
+})();
+
+
+
+/*
+ * Misc
+ */
+
+(function () {
+
+ /**
+ * Comparator for _.sortBy()-like functions
+ *
+ * Fit for natural severities order
+ * @param {string} severity
+ * @returns {number}
+ */
+ window.severityComparator = function (severity) {
+ var SEVERITIES_ORDER = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'];
+ return SEVERITIES_ORDER.indexOf(severity);
+ };
+
+
+ /**
+ * Comparator for _.sortBy()-like functions
+ *
+ * Fit for facet-like display:
+ * BLOCKER MINOR
+ * CRITICAL INFO
+ * MAJOR
+ * @param {string} severity
+ * @returns {number}
+ */
+ window.severityColumnsComparator = function (severity) {
+ var SEVERITIES_ORDER = ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'];
+ return SEVERITIES_ORDER.indexOf(severity);
+ };
+
+
+ /**
+ * Return a hash of GET parameters
+ * @returns {object}
+ */
+ window.getQueryParams = function () {
+ var qs = window.location.search.split('+').join(' '),
+ params = {},
+ re = /[?&]?([^=]+)=([^&]*)/g,
+ tokens = re.exec(qs);
+ while (tokens) {
+ params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
+ tokens = re.exec(qs);
+ }
+ return params;
+ };
+
+})();
+
+(function () {
+ jQuery(function () {
+
+ // Process login link in order to add the anchor
+ jQuery('#login-link').on('click', function (e) {
+ e.preventDefault();
+ var href = jQuery(this).prop('href'),
+ hash = window.location.hash;
+ if (hash.length > 0) {
+ href += decodeURIComponent(hash);
+ }
+ window.location = href;
+ });
+
+
+ // Define global shortcuts
+ key('s', function () {
+ jQuery('.js-search-dropdown-toggle').dropdown('toggle');
+ return false;
+ });
+ });
+})();