Merge branch 'Aufinal/backbone' into 'master'

Refactor le JS de K-Psul via Backbone : 1ère étape

See merge request klub-dev-ens/gestioCOF!388
This commit is contained in:
Antonin Reitz 2019-12-11 23:19:44 +01:00
commit e97c873b4f
14 changed files with 3985 additions and 78 deletions

View file

@ -64,7 +64,8 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.sites",
"django.contrib.messages",
"cof.apps.IgnoreSrcStaticFilesConfig", # Must be before django admin
"cof.apps.IgnoreSrcStaticFilesConfig",
# Must be before django admin
# https://github.com/infoportugal/wagtail-modeltranslation/issues/193
"wagtail_modeltranslation",
"wagtail_modeltranslation.makemigrations",
@ -102,6 +103,7 @@ INSTALLED_APPS = [
"kfet.auth",
"kfet.cms",
"gestioncof.cms",
"django_js_reverse",
]
@ -259,3 +261,8 @@ FORMAT_MODULE_PATH = "cof.locale"
WAGTAIL_SITE_NAME = "GestioCOF"
WAGTAIL_ENABLE_UPDATE_CHECK = False
TAGGIT_CASE_INSENSITIVE = True
# Django-js-reverse settings
JS_REVERSE_JS_VAR_NAME = "django_urls"
# Quand on aura namespace les urls...
# JS_REVERSE_INCLUDE_ONLY_NAMESPACES = ['k-fet']

View file

@ -8,8 +8,10 @@ from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth import views as django_auth_views
from django.urls import include, path
from django.views.decorators.cache import cache_page
from django.views.generic.base import TemplateView
from django_cas_ng import views as django_cas_views
from django_js_reverse.views import urls_js
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
@ -121,6 +123,8 @@ urlpatterns = [
path("documents/", include(wagtaildocs_urls)),
# djconfig
path("config", gestioncof_views.ConfigUpdate.as_view(), name="config.edit"),
# js-reverse
path("jsreverse/", urls_js, name="js_reverse"),
]
if "events" in settings.INSTALLED_APPS:

View file

@ -98,6 +98,10 @@ input[type=number]::-webkit-outer-spin-button {
font-weight:bold;
}
#account_data #account-is_cof {
font-weight:bold;
}
#account-name {
font-weight:bold;
}

View file

@ -0,0 +1,132 @@
var Account = Backbone.Model.extend({
defaults: {
'id': 0,
'name': '',
'email': '',
'is_cof': '',
'promo': '',
'balance': '',
'is_frozen': false,
'departement': '',
'nickname': '',
'trigramme': '',
},
url: function () {
return django_urls["kfet.account.read.json"](this.get("trigramme"))
},
reset: function () {
// On ne veut pas trigger un `change` deux fois
this.clear({ silent: true }).set(this.defaults)
},
parse: function (resp, options) {
if (_.has(resp, 'balance')) {
return _.extend(resp, { 'balance': parseFloat(resp.balance) });
} else {
return resp;
}
},
view: function () {
view_class = this.get("trigramme") == 'LIQ' ? LIQView : AccountView;
return new view_class({ model: this })
},
render: function () {
this.view().render();
}
})
var AccountView = Backbone.View.extend({
el: '#account',
input: '#id_trigramme',
buttons: '.buttons',
props: _.keys(Account.prototype.defaults),
get: function (property) {
/* If the function this.get_<property> is defined,
we call it ; else we call this.model.<property>. */
getter_name = 'get_' + property;
if (_.functions(this).includes(getter_name))
return this[getter_name]()
else
return this.model.get(property)
},
get_is_cof: function () {
return this.model.get("is_cof") ? 'COF' : 'Non-COF';
},
get_balance: function () {
return amountToUKF(this.model.get("balance"), this.model.get("is_COF"), true)
},
attr_data_balance: function () {
if (this.model.id == 0) {
return '';
} else if (this.model.get("balance") < 0) {
return 'neg';
} else if (this.model.get("balance") <= 5) {
return 'low';
} else {
return 'ok';
}
},
get_buttons: function () {
var buttons = '';
if (this.model.id != 0) {
var url = django_urls["kfet.account.read"](this.model.get("trigramme"))
buttons += `<a href="${url}" class="btn btn-primary" target="_blank" title="Modifier"><span class="glyphicon glyphicon-cog"></span></a>`;
} else {
var trigramme = this.$(this.input).val().toUpperCase();
if (isValidTrigramme(trigramme)) {
trigramme = encodeURIComponent(trigramme);
var url_base = django_urls["kfet.account.create"]();
var url = `${url_base}?trigramme=${trigramme}`;
buttons += `<a href="${url}" class="btn btn-primary" target="_blank" title="Créer"><span class="glyphicon glyphicon-plus"></span></a>`;
} else {
buttons += '<button class="btn btn-primary search" title="Rechercher"><span class="glyphicon glyphicon-search"></span></button>';
}
}
return buttons
},
render: function () {
for (let prop of this.props) {
var selector = "#account-" + prop;
this.$(selector).text(this.get(prop));
}
this.$el.attr("data-balance", this.attr_data_balance());
this.$(this.buttons).html(this.get_buttons());
},
reset: function () {
for (let prop of this.props) {
console.log(prop)
var selector = "#account-" + prop;
this.$(selector).text('');
}
this.$el.attr("data-balance", '');
this.$(this.buttons).html(this.get_buttons());
},
})
var LIQView = AccountView.extend({
get_balance: function () {
return "";
},
attr_data_balance: function () {
return 'ok';
}
})

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,6 +6,10 @@
<script type="text/javascript" src="{% static 'vendor/jquery/jquery.autocomplete-light.min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/vendor/moment/moment-timezone-with-data-2012-2022.min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/history.js' %}"></script>
<script type="text/javascript" src="{% url 'js_reverse' %}" ></script>
<script type="text/javascript" src="{% static 'kfet/vendor/underscore-min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/vendor/backbone-min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/account.js' %}"></script>
{% endblock %}
{% block title %}K-Psul{% endblock %}
@ -210,6 +214,7 @@ $(document).ready(function() {
// -----
// Initializing
var account = new Account()
var account_container = $('#account');
var triInput = $('#id_trigramme');
var account_data = {};
@ -226,56 +231,6 @@ $(document).ready(function() {
'nickname' : '',
};
// Display data
function displayAccountData() {
var balance = account_data['trigramme'] != 'LIQ' ? account_data['balance'] : '';
if (balance != '')
balance = amountToUKF(account_data['balance'], account_data['is_cof'], true);
var is_cof = account_data['trigramme'] ? account_data['is_cof'] : '';
if (is_cof !== '')
is_cof = is_cof ? '<b>COF</b>' : '<b>Non-COF</b>';
for (var elem in account_data) {
if (elem == 'balance') {
$('#account-balance').text(balance);
} else if (elem == 'is_cof') {
$('#account-is_cof').html(is_cof);
} else {
$('#account-'+elem).text(account_data[elem]);
}
}
if (account_data['is_frozen']) {
$('#account').attr('data-balance', 'frozen');
} else if (account_data['balance'] >= 5 || account_data['trigramme'] == 'LIQ') {
$('#account').attr('data-balance', 'ok');
} else if (account_data['balance'] == '') {
$('#account').attr('data-balance', '');
} else if (account_data['balance'] >= 0) {
$('#account').attr('data-balance', 'low');
} else {
$('#account').attr('data-balance', 'neg');
}
var buttons = '';
if (account_data['id'] != 0) {
var url_base = '{% url 'kfet.account.read' 'LIQ' %}';
url_base = url_base.substr(0, url_base.length - 3);
trigramme = encodeURIComponent(account_data['trigramme']) ;
buttons += '<a href="'+ url_base + trigramme +'" class="btn btn-primary" target="_blank" title="Modifier"><span class="glyphicon glyphicon-cog"></span></a>';
}
if (account_data['id'] == 0) {
var trigramme = triInput.val().toUpperCase();
if (isValidTrigramme(trigramme)) {
var url_base = '{% url 'kfet.account.create' %}'
trigramme = encodeURIComponent(trigramme);
buttons += '<a href="'+url_base+'?trigramme='+trigramme+'" class="btn btn-primary" target="_blank" title="Créer"><span class="glyphicon glyphicon-plus"></span></a>';
} else {
var url_base = '{% url 'kfet.account' %}'
buttons += '<button class="btn btn-primary search" title="Rechercher"><span class="glyphicon glyphicon-search"></span></button>';
}
}
account_container.find('.buttons').html(buttons);
}
// Search for an account
function searchAccount() {
var content = '<input type="text" name="q" id="search_autocomplete" spellcheck="false" autofocus><div id="account_results"></div>' ;
@ -326,7 +281,8 @@ $(document).ready(function() {
function resetAccountData() {
account_data = account_data_default;
$('#id_on_acc').val(0);
displayAccountData();
account.reset();
account.view().reset()
}
function resetAccount() {
@ -335,28 +291,26 @@ $(document).ready(function() {
}
// Store data
function storeAccountData(data) {
account_data = $.extend({}, account_data_default, data);
account_data['balance'] = parseFloat(account_data['balance']);
$('#id_on_acc').val(account_data['id']);
displayAccountData();
function storeAccountData() {
account_data = account.toJSON();
$('#id_on_acc').val(account.id);
account.render();
}
// Retrieve via ajax
function retrieveAccountData(tri) {
$.ajax({
dataType: "json",
url : "{% url 'kfet.account.read.json' %}",
method : "POST",
data : { trigramme: tri },
account.set({'trigramme': tri});
account.fetch({
'success': function() {
storeAccountData();
articleSelect.focus();
updateBasketAmount();
updateBasketRel();
},
'error': function() {
resetAccountData();
},
})
.done(function(data) {
storeAccountData(data);
articleSelect.focus();
updateBasketAmount();
updateBasketRel();
})
.fail(function() { resetAccountData() });
}
// Event listener

View file

@ -3,6 +3,7 @@
{% block extra_head %}
<link rel="stylesheet" type="text/css" href="{% static 'kfet/css/transfers_form.css' %}">
<script type="text/javascript" src="{% url 'js_reverse' %}" ></script>
{% endblock %}
{% block title %}Nouveaux transferts{% endblock %}
@ -54,9 +55,8 @@ $(document).ready(function () {
function getAccountData(trigramme, callback = function() {}) {
$.ajax({
dataType: "json",
url : "{% url 'kfet.account.read.json' %}",
method : "POST",
data : { trigramme: trigramme },
url : django_urls["kfet.account.read.json"]({trigramme: trigramme}),
method : "GET",
success : callback,
});
}

View file

@ -4127,15 +4127,22 @@ class HistoryJSONViewTests(ViewTestCaseMixin, TestCase):
class AccountReadJSONViewTests(ViewTestCaseMixin, TestCase):
url_name = "kfet.account.read.json"
url_expected = "/k-fet/accounts/read.json"
http_methods = ["POST"]
http_methods = ["GET"]
auth_user = "team"
auth_forbidden = [None, "user"]
@property
def url_kwargs(self):
return {"trigramme": self.accounts["user"].trigramme}
@property
def url_expected(self):
return "/k-fet/accounts/{}/.json".format(self.accounts["user"].trigramme)
def test_ok(self):
r = self.client.post(self.url, {"trigramme": "000"})
r = self.client.get(self.url)
self.assertEqual(r.status_code, 200)
content = json.loads(r.content.decode("utf-8"))

View file

@ -239,7 +239,11 @@ urlpatterns = [
# JSON urls
# -----
path("history.json", views.history_json, name="kfet.history.json"),
path("accounts/read.json", views.account_read_json, name="kfet.account.read.json"),
path(
"accounts/<trigramme:trigramme>/.json",
views.account_read_json,
name="kfet.account.read.json",
),
# -----
# Settings urls
# -----

View file

@ -908,8 +908,7 @@ def kpsul_get_settings(request):
@teamkfet_required
def account_read_json(request):
trigramme = request.POST.get("trigramme", "")
def account_read_json(request, trigramme):
account = get_object_or_404(Account, trigramme=trigramme)
data = {
"id": account.pk,

View file

@ -17,3 +17,4 @@ wagtail==2.7.*
wagtailmenus==3.*
wagtail-modeltranslation==0.10.*
django-cors-headers==2.2.0
django-js-reverse