From 17d96f177537006bcc55499c5fd0f0c8b3c717af Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Wed, 25 Dec 2019 20:11:53 +0100 Subject: [PATCH] New account manager logic --- kfet/static/kfet/js/kfet.js | 161 ++++++++++++++++++----------------- kfet/static/kfet/js/kpsul.js | 150 ++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 76 deletions(-) create mode 100644 kfet/static/kfet/js/kpsul.js diff --git a/kfet/static/kfet/js/kfet.js b/kfet/static/kfet/js/kfet.js index 1002fc32..32493088 100644 --- a/kfet/static/kfet/js/kfet.js +++ b/kfet/static/kfet/js/kfet.js @@ -1,3 +1,17 @@ +/* + * Fonctions d'aide à la gestion de trigrammes + */ + +String.prototype.format_trigramme = function () { + return this.toUpperCase().substr(0, 3) +} + +String.prototype.is_valid_tri = function () { + var pattern = /^[^a-z]{3}$/; + return pattern.test(this); +} + + /** * CSRF Token */ @@ -14,7 +28,7 @@ function csrfSafeMethod(method) { } $.ajaxSetup({ - beforeSend: function(xhr, settings) { + beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } @@ -23,7 +37,7 @@ $.ajaxSetup({ function add_csrf_form($form) { $form.append( - $('', {'name': 'csrfmiddlewaretoken', 'value': csrftoken}) + $('', { 'name': 'csrfmiddlewaretoken', 'value': csrftoken }) ); } @@ -66,7 +80,7 @@ class KfetWebsocket { var that = this; this.socket = new ReconnectingWebSocket(this.url); - this.socket.onmessage = function(e) { + this.socket.onmessage = function (e) { var data = $.extend({}, that.default_msg, JSON.parse(e.data)); for (let handler of that.handlers) { handler(data); @@ -77,26 +91,21 @@ class KfetWebsocket { var OperationWebSocket = new KfetWebsocket({ 'relative_url': 'k-psul/', - 'default_msg': {'opegroups':[],'opes':[],'checkouts':[],'articles':[]}, + 'default_msg': { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] }, }); -function amountDisplay(amount, is_cof=false, tri='') { +function amountDisplay(amount, is_cof = false, tri = '') { if (tri == 'LIQ') - return (- amount).toFixed(2) +'€'; + return (- amount).toFixed(2) + '€'; return amountToUKF(amount, is_cof); } -function amountToUKF(amount, is_cof=false, account=false) { - var rounding = account ? Math.floor : Math.round ; +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 isValidTrigramme(trigramme) { - var pattern = /^[^a-z]{3}$/; - return trigramme.match(pattern); -} - function getErrorsHtml(data) { var content = ''; if (!data) @@ -113,8 +122,8 @@ function getErrorsHtml(data) { if ('missing_perms' in data['errors']) { content += 'Permissions manquantes'; content += ''; } if ('negative' in data['errors']) { @@ -123,8 +132,8 @@ function getErrorsHtml(data) { } else { var url_base = '/k-fet/accounts/'; } - for (var i=0; iAutorisation de négatif requise pour '+data['errors']['negative'][i]+''; + for (var i = 0; i < data['errors']['negative'].length; i++) { + content += 'Autorisation de négatif requise pour ' + data['errors']['negative'][i] + ''; } } if ('addcost' in data['errors']) { @@ -138,7 +147,7 @@ function getErrorsHtml(data) { if ('account' in data['errors']) { content += 'Général'; content += ''; } return content; @@ -147,54 +156,54 @@ function getErrorsHtml(data) { function requestAuth(data, callback, focus_next = null) { var content = getErrorsHtml(data); content += '
', - $.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(); + $.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; - } + 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; + } - }); + }); } @@ -249,7 +258,7 @@ function submit_url(el) { function registerBoolParser(id, true_str, false_str) { $.tablesorter.addParser({ id: id, - format: function(s) { + format: function (s) { return s.toLowerCase() .replace(true_str, 1) .replace(false_str, 0); @@ -270,9 +279,9 @@ registerBoolParser('article__hidden', 'caché', 'affiché'); $.extend(true, $.tablesorter.defaults, { headerTemplate: '{content} {icon}', - cssIconAsc : 'glyphicon glyphicon-chevron-up', - cssIconDesc : 'glyphicon glyphicon-chevron-down', - cssIconNone : 'glyphicon glyphicon-resize-vertical', + 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'. @@ -292,16 +301,16 @@ $.extend(true, $.tablesorter.defaults, { // 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' + 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() { +$(function () { $('.sortable').tablesorter(); }); diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js new file mode 100644 index 00000000..ae37939c --- /dev/null +++ b/kfet/static/kfet/js/kpsul.js @@ -0,0 +1,150 @@ +class AccountManager { + // Classe pour gérer la partie "compte" de K-Psul + // Devrait être la seule interface entre le JS de K-Psul et la logique des comptes. + constructor() { + // jQuery elements + this._$input = $("#id_trigramme"); + this._$container = $("#account"); + this._$article_select = $("#article_autocomplete") + + // Subordinated classes + this.account = new Account({ "trigramme": "" }); + this.search = new AccountSearch(this) + + // Initialization + this._init_events(); + } + + get data() { + return this.account.toJSON(); + } + + _init_events() { + var that = this; + + // L'input change ; on met à jour le compte + this._$input.on("input", () => this.update()) + + // Raccourci LIQ + this._$input.on("keydown", function (e) { + // keycode 40: Down Arrow + if (e.keyCode == 40) { + that.set("LIQ") + } + }) + + // Fonction de recherche + this._$container.on('click', '.search', function () { + that.search.open(); + }); + + this._$container.on('keydown', function (e) { + if (e.which == 70 && e.ctrlKey) { + // Ctrl + F : universal search shortcut + that.search.open(); + e.preventDefault(); + } + }); + } + + set(trigramme) { + this._$input.val(trigramme); + this.update(); + } + + update() { + var trigramme = this._$input.val().format_trigramme(); + this.account.set({ "trigramme": trigramme }) + if (trigramme.is_valid_tri()) { + this.account.fetch({ + "success": this._on_success.bind(this), + "error": this.reset.bind(this, false), + }) + } else { + this.reset() + } + } + + _on_success() { + // On utilise l'objet global window pour accéder aux fonctions nécessaires + this.account.render(); + this._$article_select.focus(); + window.updateBasketAmount(); + window.updateBasketRel(); + } + + reset(hard_reset = false) { + this.account.reset(); + this.account.render(); + + if (hard_reset) { + this._$input.val(""); + this.update() + } + } +} + +class AccountSearch { + + constructor(manager) { + this.manager = manager; + + this._content = '
'; + this._input = '#search_autocomplete'; + this._results_container = '#account_results'; + + } + + open() { + var that = this; + this._$dialog = $.dialog({ + title: 'Recherche de compte', + content: this._content, + backgroundDismiss: true, + animation: 'top', + closeAnimation: 'bottom', + keyboardEnabled: true, + onOpen: function () { + that._$input = $(that._input); + that._$results_container = $(that._results_container); + that._init_form() + ._init_events(); + }, + }); + } + + _init_form() { + var that = this; + + this._$input.yourlabsAutocomplete({ + url: django_urls['kfet.account.search.autocomplete'](), + minimumCharacters: 2, + id: 'search_autocomplete', + choiceSelector: '.choice', + placeholder: "Chercher un utilisateur K-Fêt", + container: that._$results_container, + box: that._$results_container, + fixPosition: function () { }, + }); + + return this; + } + + _init_events() { + this._$input.bind('selectChoice', + (e, choice, autocomplete) => this._on_select(e, choice, autocomplete) + ); + return this; + } + + _on_select(e, choice, autocomplete) { + this.manager.set(choice.find('.trigramme').text()); + this.close(); + } + + close() { + if (this._$dialog !== undefined) { + this._$dialog.close(); + } + } +}