gestioCOF/kfet/static/kfet/js/kfet.js
2021-06-17 10:49:35 +02:00

297 lines
8 KiB
JavaScript

/*
* Fonctions d'aide à la gestion de trigrammes
*/
String.prototype.format_trigramme = function () {
return this.toUpperCase().substr(0, 3)
}
String.prototype.is_valid_trigramme = function () {
var pattern = /^[^a-z]{3}$/;
return pattern.test(this);
}
/**
* CSRF Token
*/
var csrftoken = '';
if (typeof Cookies !== 'undefined')
csrftoken = Cookies.get('csrftoken');
// Add CSRF token in header of AJAX requests.
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
function add_csrf_form($form) {
$form.append(
$('<input>', { 'name': 'csrfmiddlewaretoken', 'value': csrftoken })
);
}
/*
* Generic Websocket class and k-psul ws instanciation
*/
class KfetWebsocket {
static get defaults() {
return {
relative_url: '',
default_msg: {},
handlers: [],
base_path: '/ws/k-fet/'
};
}
constructor(data) {
$.extend(this, this.constructor.defaults, data);
if (window.location.pathname.startsWith('/gestion/'))
this.base_path = '/gestion' + this.base_path;
}
get url() {
var protocol = window.location.protocol == 'https:' ? 'wss' : 'ws';
var host = window.location.host;
return protocol + "://" + host + this.base_path + this.relative_url;
}
add_handler(handler) {
if (!this.socket)
this.listen();
this.handlers.push(handler);
}
listen() {
var that = this;
this.socket = new ReconnectingWebSocket(this.url);
this.socket.onmessage = function (e) {
var data = $.extend({}, that.default_msg, JSON.parse(e.data));
for (let handler of that.handlers) {
handler(data);
}
}
}
}
var OperationWebSocket = new KfetWebsocket({
'relative_url': 'k-psul/',
'default_msg': { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] },
});
function amountDisplay(amount, is_cof = false, tri = '') {
if (tri == 'LIQ')
return (- amount).toFixed(2) + '€';
return amountToUKF(amount, is_cof);
}
function amountToUKF(amount, is_cof = false, account = false) {
var rounding = account ? Math.floor : Math.round;
var coef_cof = is_cof ? 1 + settings['subvention_cof'] / 100 : 1;
return rounding(amount * coef_cof * 10);
}
function getErrorsHtml(data, is_error = true) {
if (is_error) {
data = data.map(error => error.message)
}
var content = is_error ? "Général :" : "Permissions manquantes :";
content += "<ul>";
for (const message of data) {
content += '<li>' + message + '</li>';
}
content += "</ul>";
return content;
}
function requestAuth(data, callback, focus_next = null) {
var content = getErrorsHtml(data["missing_perms"], is_error = false);
content += '<div class="capslock"><span class="glyphicon glyphicon-lock"></span><input type="password" name="password" autofocus><div>';
$.confirm({
title: 'Authentification requise',
content: content,
backgroundDismiss: true,
animation: 'top',
closeAnimation: 'bottom',
keyboardEnabled: true,
confirm: function () {
var password = this.$content.find('input').val();
callback(password);
},
onOpen: function () {
var that = this;
var capslock = -1; // 1 -> caps on ; 0 -> caps off ; -1 or 2 -> unknown
this.$content.find('input').on('keypress', function (e) {
if (e.keyCode == 13)
that.$confirmButton.click();
var s = String.fromCharCode(e.which);
if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey) || //caps on, shift off
(s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) { //caps on, shift on
capslock = 1;
} else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey) || //caps off, shift off
(s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps off, shift on
capslock = 0;
}
if (capslock == 1)
$('.capslock .glyphicon').show();
else if (capslock == 0)
$('.capslock .glyphicon').hide();
});
// Capslock key is not detected by keypress
this.$content.find('input').on('keydown', function (e) {
if (e.which == 20) {
capslock = 1 - capslock;
}
if (capslock == 1)
$('.capslock .glyphicon').show();
else if (capslock == 0)
$('.capslock .glyphicon').hide();
});
},
onClose: function () {
if (focus_next)
this._lastFocused = focus_next;
}
});
}
function displayErrors(data) {
const content = getErrorsHtml(data["errors"], is_error = true);
$.alert({
title: 'Erreurs',
content: content,
backgroundDismiss: true,
animation: 'top',
closeAnimation: 'bottom',
keyboardEnabled: true,
});
}
/**
* Setup jquery-confirm
*/
jconfirm.defaults = {
confirmButton: '<span class="glyphicon glyphicon-ok"></span>',
cancelButton: '<span class="glyphicon glyphicon-remove"></span>'
};
/**
* Create form node, given an url used as 'action', with csrftoken set.
*/
function create_form(url) {
let $form = $('<form>', {
'action': url,
'method': 'post',
});
add_csrf_form($form);
return $form;
}
/**
* Emit a POST request from <a> tag.
*
* Usage:
* <a href="#" data-url="{target url}" onclick="submit_url(this)">{…}</a>
*/
function submit_url(el) {
let url = $(el).data('url');
create_form(url).appendTo($('body')).submit();
}
/**
* jquery-tablesorter
* https://mottie.github.io/tablesorter/docs/
*
* Known bugs (v2.29.0):
* - Sort order icons in sticky headers are not updated.
* Status: Fixed in next release.
*
* TODO:
* - Handle i18n.
*/
function registerBoolParser(id, true_str, false_str) {
$.tablesorter.addParser({
id: id,
format: function (s) {
return s.toLowerCase()
.replace(true_str, 1)
.replace(false_str, 0);
},
type: 'numeric'
});
}
// Parsers for the text representations of boolean.
registerBoolParser('yesno', 'oui', 'non');
registerBoolParser('article__is_sold', 'en vente', 'non vendu');
registerBoolParser('article__hidden', 'caché', 'affiché');
// https://mottie.github.io/tablesorter/docs/index.html#variable-defaults
$.extend(true, $.tablesorter.defaults, {
headerTemplate: '{content} {icon}',
cssIconAsc: 'glyphicon glyphicon-chevron-up',
cssIconDesc: 'glyphicon glyphicon-chevron-down',
cssIconNone: 'glyphicon glyphicon-resize-vertical',
// Only four-digits format year is handled by the builtin parser
// 'shortDate'.
dateFormat: 'ddmmyyyy',
// Accented characters are replaced with their non-accented one.
sortLocaleCompare: true,
// French format: 1 234,56
usNumberFormat: false,
widgets: ['stickyHeaders'],
widgetOptions: {
stickyHeaders_offset: '.navbar',
}
});
// https://mottie.github.io/tablesorter/docs/index.html#variable-language
$.extend($.tablesorter.language, {
sortAsc: 'Trié par ordre croissant, ',
sortDesc: 'Trié par ordre décroissant, ',
sortNone: 'Non trié, ',
sortDisabled: 'tri désactivé et/ou non-modifiable',
nextAsc: 'cliquer pour trier par ordre croissant',
nextDesc: 'cliquer pour trier par ordre décroissant',
nextNone: 'cliquer pour retirer le tri'
});
$(function () {
$('.sortable').tablesorter();
});