eoredmine/javascripts/theme.js

311 lines
11 KiB
JavaScript

function sort_table() {
var table = $(this).parents('tbody')[0];
/* get table column index */
var child = $(this)[0];
var col = 0;
while( (child = child.previousSibling) != null ) {
if (child.tagName == 'TD') col++;
}
/* save sorting preferences */
var asc = parseInt($(table).data('sort-asc') || 1);
var ccol = parseInt($(table).data('sort-col') || 0);
if (col == ccol) { asc = -asc; } else { asc = 1; }
$(table).data('sort-col', col);
$(table).data('sort-asc', asc);
/* fill the array with values from the table */
var rows = table.rows, rlen = rows.length, arr = new Array(), i, j, cells, clen;
for (i=0; i<rlen; i++){
cells = rows[i].cells;
clen = cells.length;
arr[i] = new Array();
for (j = 0; j < clen; j++){
var v = cells[j].innerHTML;
/* try to guess column type */
var date = v.match(/(\d\d?)\/(\d\d?)\/(\d\d\d\d)/i);
if (date) {
v = new Date();
v.setYear(date[3]);
v.setMonth(date[2]);
v.setDate(date[1]);
} else {
var date = v.match(/(\d\d?)\/(\d\d\d\d)/i);
if (date) {
v = new Date();
v.setYear(date[2]);
v.setMonth(date[1]);
v.setDate(1);
} else {
v = v.match(/\d+/i);
if (v) {
v = parseInt(v);
} else {
v = cells[j].innerHTML;
}
}
}
if (cells[j].innerText == '') {
v = null;
}
/* store both original html and typed value */
arr[i][j] = Array(cells[j].innerHTML, v);
}
}
var first_row = arr.shift(); /* skip first row (header) */
/* sort rows, empty cells last */
arr.sort(function(a, b){
a = a[col][1]; b = b[col][1];
if (a === null && b === null) return 0;
if (a === null) return 1;
if (b === null) return -1;
return (a == b) ? 0 : ((a > b) ? asc : -1*asc);
});
arr.unshift(first_row); /* pub back first row */
/* recreate content */
for (i = 0; i < rlen; i++){
arr[i] = "<td>"+arr[i].map(function(x) {return x[0];}).join("</td><td>")+"</td>";
}
table.innerHTML = "<tr>"+arr.join("</tr><tr>")+"</tr>";
/* set back callback */
$(table).find('tr:first-child td').on('click', sort_table).css('cursor', 'row-resize');
}
function alter_new_issue_page() {
// on global new issue page select "client" project by default
$('#issue_project_id option:contains("Projets Client")').next().attr('selected', 'selected')
// limit exclamation marks
$('input#issue_subject').on('keypress', function(evt) {
/* initial code from
* https://stackoverflow.com/questions/3579219/show-different-keyboard-character-from-the-typed-one-in-google-chrome/3580352#3580352
*/
var val = this.value;
evt = evt || window.event;
// Ensure we only handle printable keys, excluding enter and space
var charCode = typeof evt.which == "number" ? evt.which : evt.keyCode;
if (charCode && charCode != 13 && charCode != 32) {
var keyChar = String.fromCharCode(charCode);
if (keyChar != '!') return true;
if (val.indexOf('!') == -1) return true; /* we still allow one */
var mappedChar = '❤';
var start, end;
if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") {
// Non-IE browsers and IE 9
start = this.selectionStart;
end = this.selectionEnd;
this.value = val.slice(0, start) + mappedChar + val.slice(end);
// Move the caret
this.selectionStart = this.selectionEnd = start + 1;
}
return false;
}
});
$('input#issue_subject').on('change', function(evt) {
var val = $(this).val();
var uppercases = val.match(/[A-Z]/g).length;
var all_letters = val.match(/[^\s+]/g).length;
var ratio = uppercases / all_letters;
if (ratio > 0.6) { // more than 60% of uppercase letters
// change to lower case
$(this).val(val.toLowerCase());
// and disable high priority values
$('#issue_priority_id option + option + option').attr('disabled', true);
}
return true;
});
}
$(function() {
$('.wiki table tr:first-child td').on('click', sort_table).css('cursor', 'row-resize');
/* 440 is header image height (500px) - header height (60px) */
var timestamp = ((new Date().getTime() / 1000) % 86400 ) / (86400 / 440);
$('#top-menu').css('background-position', '0 -' + timestamp + 'px');
// don't allow assigning issues to Entr'ouvert group
$('body.controller-issues #issue_assigned_to_id [value=21]').hide();
if ($('body.controller-issues.action-new').length == 1) {
alter_new_issue_page();
return;
}
if ($('body.controller-issues.action-show').length == 0) {
return;
}
if ($('#attachments_fields').length) {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
$('input.filename.readonly').each(function(idx, elem) {
var filename = $(elem).val();
var extension = filename.substring(filename.lastIndexOf('.'));
if (extension == '.patch') {
$('#issue_custom_field_values_2').prop('checked', true);
if ($('#issue_status_id option[value=12]').length) {
$('#issue_status_id').val('12');
} else if ($('#issue_tracker_id option[value=1]').length) { // "bug" tracker
$('#issue_tracker_id').val('1');
$('<option value="12">Solution proposée</option>').appendTo($('#issue_status_id'));
$('#issue_status_id').val('12');
} else if ($('#issue_status_id option[value=2]').length) {
$('#issue_status_id').val('2');
}
}
});
});
});
var target = $('#attachments_fields')[0];
observer.observe(target, {attributes: false, childList: true, characterData: false});
}
$('textarea#issue_notes').on('keyup change', function() {
if ($(this).val().indexOf('<pre>\ncommit ') != -1) {
var issue_status = $('#issue_status_id').val();
if (issue_status == '1' || issue_status == '2' || issue_status == '12' || issue_status == '13') {
$('#issue_status_id').val('3');
}
}
});
// global keyboard shortcuts
$(document).on('keypress', function(ev) {
var element = ev.target;
if (element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable) {
return true; // let it handle
}
if (ev.key == 'm') {
// m: open modify/comment section
$('.contextual .icon-edit').last().trigger('click');
}
return true;
});
$('textarea#issue_notes').on('keydown', function(e) {
// ctrl-enter in comment area -> focus on submit button
if ((e.ctrlKey || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) {
$('input[name=commit]').last().focus()
return false;
}
return true;
});
function handle_jobs(jobs) {
$(jobs).each(function(idx, job) {
if (job.name.indexOf('wip%2F' + issue_no) == 0) {
$.ajax({
url: job.url + 'lastBuild/api/json',
async: true,
dataType: 'json',
crossDomain: true,
success: function(data) {
var date = new Date(data.timestamp);
var $jenkins_link = $('<div class="jenkins jenkins-' + data.result + '"><a href="' +
data.url + '">Jenkins: ' + data.fullDisplayName + ': ' + data.result + '</a>' +
' (' + date.toLocaleString() + ') ' +
'+ <a href="https://git.entrouvert.org/' + project_name + '.git/log?h=' + job.name + '">Gitolite</a>' +
'</div>');
$jenkins_link.appendTo($('#history'));
}
});
}
});
}
if ($('.controller-issues.action-show a.overview').length) {
var project_name = $('a.overview').attr('href').split('/')[2];
if (project_name == 'lingo') {
project_name = 'combo';
}
var issue_no = $('a.atom').attr('href').split('/')[2].split('.')[0];
var call1 = $.ajax({
url: 'https://jenkins.entrouvert.org/job/' + project_name + '-wip/api/json',
async: true,
dataType: 'json',
crossDomain: true,
});
call1.then(function (data) {
handle_jobs(data.jobs);
}, function () {
var call2 = $.ajax({
url: 'https://jenkins.entrouvert.org/job/' + project_name + '/api/json',
async: true,
dataType: 'json',
crossDomain: true,
});
call2.then(function (data) {
handle_jobs(data.jobs);
});
});
}
var user_href = $('#loggedas a').attr('href');
if (user_href) {
$('div.journal.has-notes').each(function(idx, entry) {
var user_entry_href = $(entry).find('a.user').attr('href');
if (user_entry_href && user_entry_href != user_href) {
$(entry).find('.icon-edit').hide();
}
});
}
if ($('div.issue.closed').length) { /* on a closed issue */
var last_activity_url = $('#history a[href*=activity]').last().attr('href');
var date = new Date(last_activity_url.split('=')[1]);
var today = new Date();
if (today - date > (60 * 86400*1000)) { /* older than 60 days */
$('div#content > div.contextual .icon-edit').hide();
}
}
if ($('.administration').length == 0) {
/* fake access control */
return;
}
/* always display edit link to admins */
$('div#content > div.contextual .icon-edit').show();
var issue_no = $('a.atom').attr('href').split('/')[2].split('.')[0];
$.ajax({
url: 'https://scrutiny.entrouvert.org/projects/api/issues/' + issue_no + '/',
async: true,
dataType: 'jsonp',
crossDomain: true,
success: function(data) {
if (data.platforms) {
$('<h3>Déploiements</h3><ul id="deployed"></ul>').appendTo('#sidebar');
var platforms = Object.keys(data.platforms);
platforms.sort();
platforms.forEach(function(val) {
var status = data.platforms[val];
$('<li class="' + status.status + '">' + val + ': ' + status.version + '</li>').appendTo($('#deployed'));
});
}
}
});
var marks = ($('#history').text().match(/wtf/i) || []).length;
if (marks && $('#history').html().match(/users\/(7|20)/)) {
var url = "https://perso.entrouvert.org/~fred/review/?";
for (i=0; i<marks; i++) {
url += Math.floor(Math.random() * 7) + 1;
}
var $main = $('#main');
$main.css('background-repeat', 'no-repeat');
$main.css('background-position', '99% 100%');
$main.css('background-size', '17%');
$main.css('background-attachment', 'fixed');
$main.css('background-image', 'url(' + url + ')');
}
});