Add support for kfet/history page

This commit is contained in:
Ludovic Stephan 2017-03-18 14:05:11 -03:00
parent 1d532616b7
commit b8a307b4a6
6 changed files with 76 additions and 154 deletions

View file

@ -1,6 +1,6 @@
class History { class History {
constructor() { constructor(api_options, display_options) {
this.templates = { this.templates = {
'purchase': '<div class="ope"><span class="amount"></span><span class="infos1"></span><span class="infos2"></span><span class="addcost"></span><span class="canceled"></span></div>', 'purchase': '<div class="ope"><span class="amount"></span><span class="infos1"></span><span class="infos2"></span><span class="addcost"></span><span class="canceled"></span></div>',
'specialope': '<div class="ope"><span class="amount"></span><span class="infos1"></span><span class="infos2"></span><span class="addcost"></span><span class="canceled"></span></div>', 'specialope': '<div class="ope"><span class="amount"></span><span class="infos1"></span><span class="infos2"></span><span class="addcost"></span><span class="canceled"></span></div>',
@ -11,14 +11,12 @@ class History {
}; };
this._$container = $('#history'); this._$container = $('#history');
this._$nb_opes = $('#nb_opes');
this.list = new OperationList(); this.list = new OperationList();
this.api_options = { this.api_options =
'from': moment().subtract(3, 'days').format('YYYY-MM-DD HH:mm:ss'), api_options || { from: moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss'), };
}; this.display_options = display_options || {};
this.display_options = {} ;
this.lock = 0 ;
this._init_selection(); this._init_selection();
this._init_events(); this._init_events();
@ -26,6 +24,8 @@ class History {
display() { display() {
this.list.display(this._$container, this.templates, this.display_options); this.list.display(this._$container, this.templates, this.display_options);
var nb_opes = this._$container.find('.ope[canceled="false"]').length;
$('#nb_opes').text(nb_opes);
} }
reset() { reset() {
@ -70,10 +70,11 @@ class History {
} }
//TODO: permission management in another class ? //TODO: permission management in another class ?
//TODO: idem for confirmation
cancel_operations(to_cancel, password='') { cancel_operations(to_cancel, password='') {
if (this.lock == 1) if (lock == 1)
return false; return false;
this.lock = 1; lock = 1;
var that = this; var that = this;
if (window.kpsul) { if (window.kpsul) {
@ -100,7 +101,7 @@ class History {
}) })
.done(function(data) { .done(function(data) {
on_success(); on_success();
that.lock = 0; lock = 0;
}) })
.fail(function($xhr) { .fail(function($xhr) {
var data = $xhr.responseJSON; var data = $xhr.responseJSON;
@ -114,7 +115,7 @@ class History {
displayErrors(getErrorsHtml(data)); displayErrors(getErrorsHtml(data));
break; break;
} }
that.lock = 0; lock = 0;
}); });
} }
@ -167,5 +168,8 @@ class History {
this.add_node(opegroup); this.add_node(opegroup);
} }
} }
var nb_opes = this._$container.find('.ope[canceled="false"]').length;
$('#nb_opes').text(nb_opes);
} }
} }

View file

@ -1087,12 +1087,17 @@ class APIModelForest extends ModelForest {
api_options['format'] = 'json'; api_options['format'] = 'json';
$.getJSON(this.constructor.url_model, api_options) $.ajax({
.done(function(json, textStatus, jqXHR) { dataType: "json",
that.from(json); url : this.constructor.url_model,
on_success(json, textStatus, jqXHR); method : "POST",
}) data : api_options,
.fail(on_error); })
.done(function(json, textStatus, jqXHR) {
that.from(json);
on_success(json, textStatus, jqXHR);
})
.fail(on_error);
} }
} }
@ -1244,6 +1249,9 @@ class Formatter {
var props = options.override_props ? options.props : this.props.concat(options.props); var props = options.override_props ? options.props : this.props.concat(options.props);
var attrs = options.override_attrs ? options.attrs : this.attrs.concat(options.attrs); var attrs = options.override_attrs ? options.attrs : this.attrs.concat(options.attrs);
props = options.remove_props ? props.diff(options.remove_props) : props;
attrs = options.remove_attrs ? props.diff(options.remove_attrs) : attrs;
var prefix_prop = options.prefix_prop !== undefined ? options.prefix_prop : '.'; var prefix_prop = options.prefix_prop !== undefined ? options.prefix_prop : '.';
var prefix_attr = options.prefix_attr !== undefined ? options.prefix_attr : ''; var prefix_attr = options.prefix_attr !== undefined ? options.prefix_attr : '';

View file

@ -24,6 +24,36 @@ String.prototype.isValidTri = function() {
return pattern.test(this); return pattern.test(this);
} }
/**
* Array method
* @global
* @return {[]} Array elements not in given argument
*/
// Note : we define it this way to avoid problems in for loops
Object.defineProperty(Array.prototype, 'diff', {
enumerable: false,
configurable: true,
value: function(a) {
return this.filter(function (elt) {
return a.indexOf(elt) < 0 ;
});
}
});
/**
* Checks if given argument is float ;
* if not, parses given argument to float value.
* @global
* @return {float}
*/
function floatCheck(v) {
if (typeof v === 'number')
return v;
return Number.parseFloat(v);
}
$(document).ready(function() { $(document).ready(function() {
$(window).scroll(function() { $(window).scroll(function() {

View file

@ -5,8 +5,7 @@ class KPsulManager {
this.account_manager = new AccountManager(this); this.account_manager = new AccountManager(this);
this.checkout_manager = new CheckoutManager(this); this.checkout_manager = new CheckoutManager(this);
this.article_manager = new ArticleManager(this); this.article_manager = new ArticleManager(this);
this.history = new History(this); this.history = new History();
this.lock = 0 ;
} }
reset(soft) { reset(soft) {

View file

@ -15,7 +15,9 @@
<script type="text/javascript" src="{% static 'kfet/js/moment-timezone-with-data-2010-2020.js' %}"></script> <script type="text/javascript" src="{% static 'kfet/js/moment-timezone-with-data-2010-2020.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/bootstrap-datetimepicker.min.js' %}"></script> <script type="text/javascript" src="{% static 'kfet/js/bootstrap-datetimepicker.min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/multiple-select.js' %}"></script> <script type="text/javascript" src="{% static 'kfet/js/multiple-select.js' %}"></script>
<script type="text/javascript" src="{% url 'js_reverse' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/kfet.js' %}"></script> <script type="text/javascript" src="{% static 'kfet/js/kfet.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/kfet.api.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/history.js' %}"></script> <script type="text/javascript" src="{% static 'kfet/js/history.js' %}"></script>
{% endblock %} {% endblock %}
@ -61,11 +63,12 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
settings = { 'subvention_cof': parseFloat({{ settings.subvention_cof|unlocalize }})}
lock = 0 ; // Lock to avoid multiple requests
window.lock = 0;
khistory = new KHistory();
var history = new History();
var $from_date = $('#from_date'); var $from_date = $('#from_date');
var $to_date = $('#to_date'); var $to_date = $('#to_date');
@ -80,7 +83,9 @@ $(document).ready(function() {
return selected; return selected;
} }
function getHistory() { function updateHistory() {
// Get API options
var data = {}; var data = {};
if ($from_date.val()) if ($from_date.val())
data['from'] = moment($from_date.val()).format('YYYY-MM-DD HH:mm:ss'); data['from'] = moment($from_date.val()).format('YYYY-MM-DD HH:mm:ss');
@ -91,20 +96,10 @@ $(document).ready(function() {
data['checkouts'] = checkouts; data['checkouts'] = checkouts;
var accounts = getSelectedMultiple($accounts); var accounts = getSelectedMultiple($accounts);
data['accounts'] = accounts; data['accounts'] = accounts;
history.api_options = data ;
$.ajax({ // Update history
dataType: "json", history.reset();
url : "{% url 'kfet.history.json' %}",
method : "POST",
data : data,
})
.done(function(data) {
for (var i=0; i<data['opegroups'].length; i++) {
khistory.addOpeGroup(data['opegroups'][i]);
}
var nb_opes = khistory.$container.find('.ope:not(.canceled)').length;
$('#nb_opes').text(nb_opes);
});
} }
$('#from_date').datetimepicker({ $('#from_date').datetimepicker({
@ -136,96 +131,13 @@ $(document).ready(function() {
}); });
$("input").on('dp.change change', function() { $("input").on('dp.change change', function() {
khistory.reset(); updateHistory();
getHistory();
}); });
khistory.$container.selectable({
filter: 'div.opegroup, div.ope',
selected: function(e, ui) {
$(ui.selected).each(function() {
if ($(this).hasClass('opegroup')) {
var type = $(this).data('type');
var id = $(this).data('id');
$(this).siblings('.ope').filter(function() {
return $(this).data(type) == id
}).addClass('ui-selected');
}
});
},
});
$(document).on('keydown', function (e) {
if (e.keyCode == 46) {
// DEL (Suppr)
var opes_to_cancel = [];
khistory.$container.find('.ope.ui-selected').each(function () {
opes_to_cancel.push($(this).data('type')+' '+$(this).data('id'));
});
if (opes_to_cancel.length > 0)
confirmCancel(opes_to_cancel);
}
});
function confirmCancel(opes_to_cancel) {
var nb = opes_to_cancel.length;
var content = nb+' opération va être annulée'.pluralize(nb, ' opérations vont être annulées')
$.confirm({
title: 'Confirmation',
content: content,
backgroundDismiss: true,
animation: 'top',
closeAnimation: 'bottom',
keyboardEnabled: true,
confirm: function() {
cancelOperations(opes_to_cancel);
}
});
}
function cancelOperations(opes_array, password = '') {
if (lock == 1)
return false
lock = 1 ;
var data = { 'operations' : opes_array }
$.ajax({
dataType: "json",
url : "{% url 'kfet.kpsul.cancel_operations' %}",
method : "POST",
data : data,
beforeSend: function ($xhr) {
$xhr.setRequestHeader("X-CSRFToken", csrftoken);
if (password != '')
$xhr.setRequestHeader("KFetPassword", password);
},
})
.done(function(data) {
khistory.$container.find('.ui-selected').removeClass('ui-selected');
lock = 0 ;
})
.fail(function($xhr) {
var data = $xhr.responseJSON;
switch ($xhr.status) {
case 403:
requestAuth(data, function(password) {
cancelOperations(opes_array, password);
});
break;
case 400:
displayErrors(getErrorsHtml(data));
break;
}
lock = 0 ;
});
}
// ----- // -----
// Synchronization // Synchronization
// ----- // -----
websocket_msg_default = {'opegroups':[],'opes':[]} websocket_msg_default = {'opegroups':[],'opes':[]}
var websocket_protocol = window.location.protocol == 'https:' ? 'wss' : 'ws'; var websocket_protocol = window.location.protocol == 'https:' ? 'wss' : 'ws';
@ -234,21 +146,11 @@ $(document).ready(function() {
socket = new ReconnectingWebSocket(websocket_protocol+"://" + location_url + "/ws/k-fet/k-psul/"); socket = new ReconnectingWebSocket(websocket_protocol+"://" + location_url + "/ws/k-fet/k-psul/");
socket.onmessage = function(e) { socket.onmessage = function(e) {
data = $.extend({}, websocket_msg_default, JSON.parse(e.data)); data = $.extend({}, websocket_msg_default, JSON.parse(e.data));
history.update_data(data);
for (var i=0; i<data['opegroups'].length; i++) {
if (data['opegroups'][i]['cancellation']) {
khistory.cancelOpeGroup(data['opegroups'][i]);
}
}
for (var i=0; i<data['opes'].length; i++) {
if (data['opes'][i]['cancellation']) {
khistory.cancelOpe(data['opes'][i]);
}
}
} }
getHistory(); updateHistory();
}); });
</script> </script>

View file

@ -167,27 +167,6 @@
{% csrf_token %} {% csrf_token %}
<script type="text/javascript"> <script type="text/javascript">
function intCheck(v) {
return Number.parseInt(v);
}
function floatCheck(v) {
if (typeof v === 'number')
return v;
return Number.parseFloat(v);
}
function booleanCheck(v) {
return v == true;
}
function functionCheck(v) {
if (typeof v === 'function')
return v;
return function(){};
}
$(document).ready(function() { $(document).ready(function() {
'use strict'; 'use strict';
// ----- // -----
@ -195,7 +174,7 @@ $(document).ready(function() {
// ----- // -----
// Lock to avoid multiple requests // Lock to avoid multiple requests
var lock = 0; window.lock = 0;
// ----- // -----
// Auth // Auth