"baseUrl": true,
"key": true,
"Backbone": true,
+ "Marionette": true,
"Handlebars": true,
+ "Templates": true,
"t": true,
"tp": true,
"moment": true,
App.fetchReports = ->
- process = window.process.addBackgroundProcess()
fetch = if @state.get 'active' then @reports.fetchActive() else @reports.fetchHistory()
@layout.showSpinner 'actionsRegion'
@layout.resultsRegion.reset()
collection: @reports
@layout.actionsRegion.show @actionsView
- window.process.finishBackgroundProcess process
-
App.fetchNextPage = ->
- process = window.process.addBackgroundProcess()
@reports.fetchHistory
data:
p: @state.get('page') + 1
remove: false
.done =>
@state.set page: @reports.paging.page
- window.process.finishBackgroundProcess process
App.addInitializer ->
+++ /dev/null
-$ = jQuery
-
-process = {}
-process.queue = {}
-process.timeout = 300
-process.fadeTimeout = 100
-
-_.extend process,
-
- addBackgroundProcess: ->
- uid = _.uniqueId 'process'
- @renderSpinner uid
- @queue[uid] = setTimeout (=> @showSpinner uid), @timeout
- uid
-
-
- isBackgroundProcessAlive: (uid) ->
- @queue[uid]?
-
-
- finishBackgroundProcess: (uid) ->
- if @isBackgroundProcessAlive uid
- clearInterval @queue[uid]
- delete @queue[uid]
- @removeSpinner uid
-
-
- failBackgroundProcess: (uid) ->
- if @isBackgroundProcessAlive uid
- clearInterval @queue[uid]
- delete @queue[uid]
- spinner = @getSpinner uid
- spinner.addClass 'process-spinner-failed shown'
- spinner.text t 'process.fail'
- close = $('<button></button>').html('<i class="icon-close"></i>').addClass 'process-spinner-close'
- close.appendTo spinner
- close.on 'click', => @removeSpinner uid
-
-
- renderSpinner: (uid) ->
- id = "spinner-#{uid}"
- spinner = $ '<div></div>'
- spinner.addClass 'process-spinner'
- spinner.prop 'id', id
- text = t 'process.still_working'
- text = 'Still Working...' if text == 'process.still_working'
- spinner.text text
- spinner.appendTo $('body')
-
-
- showSpinner: (uid) ->
- spinner = @getSpinner(uid)
- setTimeout (-> spinner.addClass 'shown'), @fadeTimeout
-
-
- removeSpinner: (uid) ->
- @getSpinner(uid).remove()
-
-
- getSpinner: (uid) ->
- id = "spinner-#{uid}"
- $('#' + id)
-
-
-_.extend window, process: process
-
-
@$el.attr 'data-key', @model.get('key')
- resetIssue: (options, p) ->
+ resetIssue: (options) ->
key = @model.get 'key'
componentUuid = @model.get 'componentUuid'
@model.clear silent: true
@model.fetch(options)
.done =>
@trigger 'reset'
- window.process.finishBackgroundProcess p if p?
- .fail ->
- window.process.failBackgroundProcess p if p?
showChangeLog: (e) ->
updateAfterAction: (fetch) ->
@popup.close() if @popup
if fetch
- p = window.process.addBackgroundProcess()
- $.when(@resetIssue()).done =>
- window.process.finishBackgroundProcess p
+ @resetIssue()
comment: (e) ->
deleteComment: (e) ->
- p = window.process.addBackgroundProcess()
commentKey = $(e.target).closest('[data-comment-key]').data 'comment-key'
confirmMsg = $(e.target).data 'confirm-msg'
url: baseUrl + "/api/issues/delete_comment?key=" + commentKey
.done =>
@updateAfterAction true
- window.process.finishBackgroundProcess p
- .fail =>
- window.process.failBackgroundProcess p
transition: (e) ->
plan: (e) ->
- p = window.process.addBackgroundProcess()
t = $(e.currentTarget)
actionPlans = new ActionPlans()
actionPlans.fetch
model: @model
collection: actionPlans
@popup.render()
- window.process.finishBackgroundProcess p
- .fail =>
- window.process.failBackgroundProcess p
showMoreActions: (e) ->
action: (action) ->
- p = window.process.addBackgroundProcess()
$.post "#{baseUrl}/api/issues/do_action", issue: @model.id, actionKey: action
.done =>
- window.process.finishBackgroundProcess p
@resetIssue()
- .fail =>
- window.process.failBackgroundProcess p
showRule: ->
changeTags: ->
- p = window.process.addBackgroundProcess()
jQuery.ajax
url: "#{baseUrl}/api/issues/tags?ps=0"
.done (r) =>
- window.process.finishBackgroundProcess p
if @ui.tagInput.select2
# Prevent synchronization issue with navigation
@ui.tagInput.select2
)
@ui.tagInput.select2 'focus'
- .fail =>
- window.process.failBackgroundProcess p
cancelEdit: ->
tags = @ui.tagInput.val()
splitTags = if tags then tags.split(',') else null
- p = window.process.addBackgroundProcess()
@model.set 'tags', splitTags
$.post "#{baseUrl}/api/issues/set_tags", key: @model.get('key'), tags: tags
.done =>
- window.process.finishBackgroundProcess p
@cancelEdit()
.fail =>
@model.set 'tags', _tags
- window.process.failBackgroundProcess p
.always =>
@render()
_assignee = @getAssignee()
_assigneeName = @getAssigneeName()
return if assignee == _assignee
- p = window.process.addBackgroundProcess()
if assignee == ''
@model.set assignee: null, assigneeName: null
else
data:
issue: @model.id
assignee: assignee
- .done =>
- window.process.finishBackgroundProcess p
.fail =>
@model.set assignee: _assignee, assigneeName: _assigneeName
- window.process.failBackgroundProcess p
onInputClick: (e) ->
search: (query) ->
if query.length > 1
- p = window.process.addBackgroundProcess()
$.get "#{baseUrl}/api/users/search", s: query
.done (data) =>
@resetAssignees data.users
- window.process.finishBackgroundProcess p
- .fail =>
- window.process.failBackgroundProcess p
else
@resetAssignees []
submit: ->
- p = window.process.addBackgroundProcess()
text = @ui.textarea.val()
update = @model && @model.has('key')
method = if update then 'edit_comment' else 'add_comment'
data.issue = @options.issue.id
$.post url, data
.done =>
- window.process.finishBackgroundProcess p
@options.detailView.updateAfterAction true
- .fail =>
- window.process.failBackgroundProcess p
_actionPlan = @getActionPlan()
_actionPlanName = @getActionPlanName()
return if actionPlan == _actionPlan
- p = window.process.addBackgroundProcess()
if actionPlan == ''
@model.set actionPlan: null, actionPlanName: null
else
data:
issue: @model.id
plan: actionPlan
- .done =>
- window.process.finishBackgroundProcess p
.fail =>
@model.set assignee: _actionPlan, assigneeName: _actionPlanName
- window.process.failBackgroundProcess p
getActionPlans: ->
submit: (severity) ->
_severity = @getTransition()
return if severity == _severity
- p = window.process.addBackgroundProcess()
@model.set severity: severity
$.ajax
type: 'POST'
data:
issue: @model.id
severity: severity
- .done =>
- window.process.finishBackgroundProcess p
.fail =>
@model.set severity: _severity
- window.process.failBackgroundProcess p
serializeData: ->
submit: (tags) ->
_tags = @getTags()
@model.set tags: tags
- p = window.process.addBackgroundProcess()
$.ajax
type: 'POST'
url: "#{baseUrl}/api/issues/set_tags"
data:
key: @model.id
tags: tags.join()
- .done =>
- window.process.finishBackgroundProcess p
.fail =>
@model.set tags: _tags
- window.process.failBackgroundProcess p
onInputClick: (e) ->
submit: (transition) ->
- p = window.process.addBackgroundProcess()
$.ajax
type: 'POST',
url: baseUrl + '/api/issues/do_transition',
issue: @model.get('key')
transition: transition
.done =>
- @options.view.resetIssue {}, p
- .fail =>
- window.process.failBackgroundProcess p
+ @options.view.resetIssue {}
$ = jQuery
App = new Marionette.Application
- issuesAppProcess = window.process.addBackgroundProcess()
App.getContextQuery = ->
key.setScope 'list'
@router = new Router app: @
Backbone.history.start()
- window.process.finishBackgroundProcess issuesAppProcess
l10nXHR = window.requestMessages()
$ = jQuery
App = new Marionette.Application
- issuesAppProcess = window.process.addBackgroundProcess()
App.addInitializer ->
@state = new State()
key.setScope 'list'
@router = new Router app: @
Backbone.history.start()
- window.process.finishBackgroundProcess issuesAppProcess
l10nXHR = window.requestMessages()
_.extend data, @options.app.state.get 'query'
_.extend data, @options.app.state.get 'contextQuery' if @options.app.state.get 'isContext'
- fetchIssuesProcess = window.process.addBackgroundProcess()
$.get "#{baseUrl}/api/issues/search", data
.done (r) =>
issues = @options.app.list.parseIssues r
pageSize: r.ps
total: r.total
maxResultsReached: r.p * r.ps >= r.total
- window.process.finishBackgroundProcess fetchIssuesProcess
if firstPage && @isIssuePermalink()
@showComponentViewer @options.app.list.first()
- .fail ->
- window.process.failBackgroundProcess fetchIssuesProcess
isIssuePermalink: ->
@options.app.state.set selectedIndex: @model.get('index')
- resetIssue: (options, p) ->
+ resetIssue: (options) ->
key = @model.get 'key'
componentUuid = @model.get 'componentUuid'
index = @model.get 'index'
@model.fetch(options)
.done =>
@trigger 'reset'
- window.process.finishBackgroundProcess p if p?
- .fail ->
- window.process.failBackgroundProcess p if p?
openComponentViewer: ->
QualityGateLayout
) ->
- # Create a generic error handler for ajax requests
- jQuery.ajaxSetup
- error: (jqXHR) ->
- text = jqXHR.responseText
- errorBox = jQuery('.modal-error')
- if jqXHR.responseJSON?.errors?
- text = _.pluck(jqXHR.responseJSON.errors, 'msg').join '. '
- else
- text = t 'default_error_message'
- if errorBox.length > 0
- errorBox.show().text text
- else
- alert text
-
-
# Add html class to mark the page as navigator page
jQuery('html').addClass('navigator-page quality-gates-page');
FiltersView) {
var $ = jQuery,
- App = new Marionette.Application(),
- p = window.process.addBackgroundProcess();
+ App = new Marionette.Application();
App.addInitializer(function () {
this.layout = new Layout();
app: this
});
Backbone.history.start();
- window.process.finishBackgroundProcess(p);
});
App.manualRepository = function () {
sendRequests: function (url, options, profiles) {
var that = this,
- p = window.process.addBackgroundProcess(),
looper = $.Deferred().resolve();
profiles.forEach(function (profile) {
var opts = _.extend({}, options, { profile_key: profile });
looper.done(function () {
that.options.app.controller.fetchList();
that.$(that.ui.codingRulesSubmitBulkChange.selector).hide();
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
},
var that = this,
url = baseUrl + '/api/rules/search',
- options = _.extend(this._searchParameters(), this.app.state.get('query')),
- p = window.process.addBackgroundProcess();
+ options = _.extend(this._searchParameters(), this.app.state.get('query'));
return $.get(url, options).done(function (r) {
var rules = that.app.list.parseRules(r);
if (firstPage) {
total: r.total,
maxResultsReached: r.p * r.ps >= r.total
});
- window.process.finishBackgroundProcess(p);
if (firstPage && that.isRulePermalink()) {
that.showDetails(that.app.list.first());
}
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
},
title: t('delete'),
html: tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')),
yesHandler: function () {
- var p = window.process.addBackgroundProcess(),
- url = baseUrl + '/api/rules/delete',
+ var url = baseUrl + '/api/rules/delete',
options = { key: that.model.id };
$.post(url, options).done(function () {
that.options.app.controller.fetchList();
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
}
});
title: t('delete'),
html: t('are_you_sure'),
yesHandler: function () {
- var p = window.process.addBackgroundProcess(),
- url = baseUrl + '/api/rules/delete',
+ var url = baseUrl + '/api/rules/delete',
options = { key: that.model.id };
$.post(url, options).done(function () {
that.model.collection.remove(that.model);
that.close();
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
}
});
this.$('.modal-error').hide();
this.$('.modal-warning').hide();
var that = this,
- p = window.process.addBackgroundProcess(),
url = baseUrl + '/api/rules/' + action;
return $.post(url, options).done(function (r) {
if (typeof r === 'string') {
} else {
that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
}
- }).always(function () {
- window.process.finishBackgroundProcess(p);
});
},
activate: function (e) {
e.preventDefault();
var that = this,
- p = window.process.addBackgroundProcess(),
profileKey = this.ui.qualityProfileSelect.val(),
params = this.ui.qualityProfileParameters.map(function () {
return {
}
}).done(function () {
that.trigger('profileActivated', severity, params);
- window.process.finishBackgroundProcess(p);
}).fail(function () {
that.trigger('profileActivationFailed');
- window.process.failBackgroundProcess(p);
});
},
},
submitExtendDescription: function () {
- var that = this,
- p = window.process.addBackgroundProcess();
+ var that = this;
this.ui.extendDescriptionForm.addClass('hidden');
return jQuery.ajax({
type: 'POST',
mdNote: r.rule.mdNote
});
that.render();
- window.process.finishBackgroundProcess(p);
}).fail(function () {
that.render();
- window.process.failBackgroundProcess(p);
});
},
editDone: function () {
var that = this,
- p = window.process.addBackgroundProcess(),
tags = this.ui.tagInput.val();
return jQuery.ajax({
type: 'POST',
}).done(function (r) {
that.model.set('tags', r.rule.tags);
that.cancelEdit();
- window.process.finishBackgroundProcess(p);
}).always(function () {
that.cancelEdit();
- window.process.failBackgroundProcess(p);
});
},
title: t('coding_rules.revert_to_parent_definition'),
html: tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name),
yesHandler: function () {
- var p = window.process.addBackgroundProcess();
return jQuery.ajax({
type: 'POST',
url: baseUrl + '/api/qualityprofiles/activate_rule',
reset: true
}
}).done(function () {
- window.process.finishBackgroundProcess(p);
that.options.app.controller.showDetails(that.options.rule);
});
}
title: t('coding_rules.deactivate'),
html: tp('coding_rules.deactivate.confirm'),
yesHandler: function () {
- var p = window.process.addBackgroundProcess();
return jQuery.ajax({
type: 'POST',
url: baseUrl + '/api/qualityprofiles/deactivate_rule',
rule_key: ruleKey
}
}).done(function () {
- window.process.finishBackgroundProcess(p);
that.options.app.controller.showDetails(that.options.rule);
});
}
RuleDetailsView) {
var $ = jQuery,
- App = new Marionette.Application(),
- p = window.process.addBackgroundProcess();
+ App = new Marionette.Application();
App.addInitializer(function () {
var url = baseUrl + '/api/rules/show',
actives: data.actives
});
this.ruleDetailsView.render().$el.appendTo($('.page'));
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
});
title: t('coding_rules.deactivate'),
html: tp('coding_rules.deactivate.confirm'),
yesHandler: function () {
- var p = window.process.addBackgroundProcess();
return jQuery.ajax({
type: 'POST',
url: baseUrl + '/api/qualityprofiles/deactivate_rule',
rule_key: ruleKey
}
}).done(function () {
- window.process.finishBackgroundProcess(p);
that.model.unset('activation');
});
}
--- /dev/null
+(function ($) {
+
+ var options = {
+ queue: {},
+ timeout: 300,
+ fadeTimeout: 100
+ };
+
+ var Process = Backbone.Model.extend({
+ defaults: {
+ state: 'ok'
+ },
+
+ timeout: function () {
+ this.set({
+ state: 'timeout',
+ message: 'Still Working...'
+ });
+ },
+
+ finish: function (options) {
+ options = _.defaults(options || {}, { force: false });
+ if (this.get('state') !== 'failed' || !!options.force) {
+ this.trigger('destroy', this, this.collection, options);
+ }
+ },
+
+ fail: function (message) {
+ clearInterval(this.get('timer'));
+ this.set({
+ state: 'failed',
+ message: message || t('process.fail')
+ });
+ this.set('state', 'failed');
+ }
+ }),
+
+ Processes = Backbone.Collection.extend({
+ model: Process
+ }),
+
+ ProcessView = Marionette.ItemView.extend({
+ tagName: 'li',
+ className: 'process-spinner',
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ render: function () {
+ var that = this;
+ switch (this.model.get('state')) {
+ case 'timeout':
+ this.$el.html(this.model.get('message')).addClass('shown');
+ break;
+ case 'failed':
+ this.$el.html(this.model.get('message')).addClass('process-spinner-failed shown');
+ var close = $('<button></button>').html('<i class="icon-close"></i>').addClass('process-spinner-close');
+ close.appendTo(this.$el);
+ close.on('click', function () {
+ var a = { force: true };
+ that.model.finish(a);
+ });
+ break;
+ case 'finished':
+ this.$el.addClass('hidden');
+ break;
+ }
+ return this;
+ }
+ }),
+
+ ProcessesView = Marionette.CollectionView.extend({
+ tagName: 'ul',
+ className: 'processes-container',
+ itemView: ProcessView
+ });
+
+
+ var processes = new Processes(),
+ processesView = new ProcessesView({
+ collection: processes
+ });
+
+ /**
+ * Add background process
+ * @returns {number}
+ */
+ function addBackgroundProcess () {
+ var uid = _.uniqueId('process'),
+ process = new Process({
+ id: uid,
+ timer: setTimeout(function () {
+ process.timeout();
+ }, options.timeout)
+ });
+ processes.add(process);
+ return uid;
+ }
+
+ /**
+ * Finish background process
+ * @param {number} uid
+ */
+ function finishBackgroundProcess (uid) {
+ var process = processes.get(uid);
+ if (process != null) {
+ process.finish();
+ }
+ }
+
+ /**
+ * Fail background process
+ * @param {number} uid
+ * @param {string} message
+ */
+ function failBackgroundProcess (uid, message) {
+ var process = processes.get(uid);
+ if (process != null) {
+ process.fail(message);
+ }
+ }
+
+ /**
+ * Handle ajax error
+ * @param jqXHR
+ */
+ function handleAjaxError (jqXHR) {
+ if (jqXHR.processId != null) {
+ var message = null;
+ if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) {
+ message = _.pluck(jqXHR.responseJSON.errors, 'msg').join('. ');
+ }
+ failBackgroundProcess(jqXHR.processId, message);
+ }
+ }
+
+
+ $.ajaxSetup({
+ beforeSend: function (jqXHR) {
+ jqXHR.processId = addBackgroundProcess();
+ },
+ complete: function (jqXHR) {
+ if (jqXHR.processId != null) {
+ finishBackgroundProcess(jqXHR.processId);
+ }
+ },
+ statusCode: {
+ 400: handleAjaxError,
+ 401: handleAjaxError,
+ 403: handleAjaxError,
+ 500: handleAjaxError
+ }
+ });
+
+
+ $(function () {
+
+ processesView.render().$el.appendTo(document.body);
+
+ });
+
+})(window.jQuery);
if (facet.has('values') || this.options.app.state.get('facetsFromServer').indexOf(id) === -1) {
facet.set({enabled: true});
} else {
- var p = window.process.addBackgroundProcess();
this.requestFacet(id)
.done(function () {
facet.set({enabled: true});
- window.process.finishBackgroundProcess(p);
- })
- .fail(function () {
- window.process.failBackgroundProcess(p);
});
}
},
onFavoriteClick: function () {
var that = this,
- p = window.process.addBackgroundProcess(),
url = baseUrl + '/favourites/toggle/' + this.model.get('contextId'),
isContextFavorite = this.model.get('isContextFavorite');
this.model.set({ isContextFavorite: !isContextFavorite });
- return $.post(url).done(function () {
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
+ return $.post(url).fail(function () {
that.model.set({ isContextFavorite: isContextFavorite });
- window.process.failBackgroundProcess(p);
});
},
}
var that = this,
url = baseUrl + '/api/components/suggestions',
- options = { s: q },
- p = window.process.addBackgroundProcess();
+ options = { s: q };
return $.get(url, options).done(function (r) {
var collection = [];
r.results.forEach(function (domain) {
});
});
that.results.reset(collection);
- window.process.finishBackgroundProcess(p);
- }).fail(function() {
- window.process.failBackgroundProcess(p);
});
}
});
initialize: function () {
var that = this,
- p = window.process.addBackgroundProcess(),
requests = [this.requestMeasures(), this.requestIssues()];
if (this.model.get('isUnitTest')) {
requests.push(this.requestTests());
this.testsScroll = 0;
$.when.apply($, requests).done(function () {
that.render();
- window.process.finishBackgroundProcess(p);
- }).fail(function () {
- window.process.failBackgroundProcess(p);
});
},
showTest: function (e) {
var that = this,
- p = window.process.addBackgroundProcess(),
name = $(e.currentTarget).data('name'),
url = baseUrl + '/api/tests/covered_files',
options = {
that.coveredFiles = data.files;
that.selectedTest = _.findWhere(that.model.get('tests'), { name: name });
that.render();
- window.process.finishBackgroundProcess(p);
});
},
open: function (id) {
var that = this,
- r = window.process.addBackgroundProcess(),
finalize = function () {
that.requestIssues().done(function () {
that.render();
- window.process.finishBackgroundProcess(r);
that.trigger('loaded');
});
};
showCoveragePopup: function (e) {
e.stopPropagation();
$('body').click();
- var r = window.process.addBackgroundProcess(),
- line = $(e.currentTarget).data('line-number'),
+ var line = $(e.currentTarget).data('line-number'),
row = _.findWhere(this.model.get('source'), {line: line}),
url = baseUrl + '/api/tests/test_cases',
options = {
triggerEl: $(e.currentTarget)
});
popup.render();
- window.process.finishBackgroundProcess(r);
- }).fail(function () {
- window.process.failBackgroundProcess(r);
});
},
}
+.processes-container {
+ position: fixed;
+ z-index: 9999;
+ top: 0;
+ left: 50%;
+ width: 350px;
+ margin-left: -175px;
+}
.process-spinner {
- position: fixed;
- z-index: 2000;
- top: 0; left: 50%;
- min-width: 300px;
- max-width: 900px;
- margin-left: -150px;
padding: 0 10px;
line-height: @formControlHeight;
- background-color: #f0e8ac;
border-radius: 0 0 3px 3px;
+ .box-sizing(border-box);
+ background-color: #f0e8ac;
text-align: center;
opacity: 0;
.trans;
&.shown { opacity: 1; }
}
+.process-spinner + .process-spinner {
+ margin-top: 5px;
+ border-radius: 3px;
+}
+
.process-spinner-failed {
+ padding-right: 30px;
background-color: @red;
color: @white;
}
.process-spinner-close {
- float: right;
- margin-right: 5px;
+ position: absolute;
+ top: 0;
+ right: 0;
padding: 3px;
background: none !important;
border: none !important;