mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-27 02:43:01 +00:00
Merge branch 'front_club' into 'master'
Finitions sur l'interface club See merge request bde/nk20!70
This commit is contained in:
commit
8b4c39269c
@ -14,12 +14,12 @@ urlpatterns = [
|
|||||||
path('club/create/', views.ClubCreateView.as_view(), name="club_create"),
|
path('club/create/', views.ClubCreateView.as_view(), name="club_create"),
|
||||||
path('club/<int:pk>/update', views.ClubUpdateView.as_view(), name="club_update"),
|
path('club/<int:pk>/update', views.ClubUpdateView.as_view(), name="club_update"),
|
||||||
path('club/<int:pk>/update_pic', views.ClubPictureUpdateView.as_view(), name="club_update_pic"),
|
path('club/<int:pk>/update_pic', views.ClubPictureUpdateView.as_view(), name="club_update_pic"),
|
||||||
|
path('club/<int:pk>/aliases', views.ClubAliasView.as_view(), name="club_alias"),
|
||||||
path('user/', views.UserListView.as_view(), name="user_list"),
|
path('user/', views.UserListView.as_view(), name="user_list"),
|
||||||
path('user/<int:pk>', views.UserDetailView.as_view(), name="user_detail"),
|
path('user/<int:pk>', views.UserDetailView.as_view(), name="user_detail"),
|
||||||
path('user/<int:pk>/update', views.UserUpdateView.as_view(), name="user_update_profile"),
|
path('user/<int:pk>/update', views.UserUpdateView.as_view(), name="user_update_profile"),
|
||||||
path('user/<int:pk>/update_pic', views.ProfilePictureUpdateView.as_view(), name="user_update_pic"),
|
path('user/<int:pk>/update_pic', views.ProfilePictureUpdateView.as_view(), name="user_update_pic"),
|
||||||
path('user/<int:pk>/aliases', views.AliasView.as_view(), name="user_alias"),
|
path('user/<int:pk>/aliases', views.ProfileAliasView.as_view(), name="user_alias"),
|
||||||
path('user/aliases/delete/<int:pk>', views.DeleteAliasView.as_view(), name="user_alias_delete"),
|
|
||||||
path('manage-auth-token/', views.ManageAuthTokens.as_view(), name='auth_token'),
|
path('manage-auth-token/', views.ManageAuthTokens.as_view(), name='auth_token'),
|
||||||
# API for the user autocompleter
|
# API for the user autocompleter
|
||||||
path('user/user-autocomplete', views.UserAutocomplete.as_view(), name="user_autocomplete"),
|
path('user/user-autocomplete', views.UserAutocomplete.as_view(), name="user_autocomplete"),
|
||||||
|
@ -20,7 +20,8 @@ from django.views.generic import CreateView, DetailView, UpdateView, TemplateVie
|
|||||||
from django.views.generic.edit import FormMixin
|
from django.views.generic.edit import FormMixin
|
||||||
from django_tables2.views import SingleTableView
|
from django_tables2.views import SingleTableView
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
from note.forms import AliasForm, ImageForm
|
from note.forms import ImageForm
|
||||||
|
#from note.forms import AliasForm, ImageForm
|
||||||
from note.models import Alias, NoteUser
|
from note.models import Alias, NoteUser
|
||||||
from note.models.transactions import Transaction
|
from note.models.transactions import Transaction
|
||||||
from note.tables import HistoryTable, AliasTable
|
from note.tables import HistoryTable, AliasTable
|
||||||
@ -143,10 +144,6 @@ class UserDetailView(LoginRequiredMixin, DetailView):
|
|||||||
club_list = \
|
club_list = \
|
||||||
Membership.objects.all().filter(user=user).only("club")
|
Membership.objects.all().filter(user=user).only("club")
|
||||||
context['club_list'] = ClubTable(club_list)
|
context['club_list'] = ClubTable(club_list)
|
||||||
context['title'] = _("Account #%(id)s: %(username)s") % {
|
|
||||||
'id': user.pk,
|
|
||||||
'username': user.username,
|
|
||||||
}
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
@ -172,56 +169,17 @@ class UserListView(LoginRequiredMixin, SingleTableView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class AliasView(LoginRequiredMixin, FormMixin, DetailView):
|
class ProfileAliasView(LoginRequiredMixin, DetailView):
|
||||||
model = User
|
model = User
|
||||||
template_name = 'member/profile_alias.html'
|
template_name = 'member/profile_alias.html'
|
||||||
context_object_name = 'user_object'
|
context_object_name = 'user_object'
|
||||||
form_class = AliasForm
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
note = context['user_object'].note
|
note = context['object'].note
|
||||||
context["aliases"] = AliasTable(note.alias_set.all())
|
context["aliases"] = AliasTable(note.alias_set.all())
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return reverse_lazy('member:user_alias', kwargs={'pk': self.object.id})
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
self.object = self.get_object()
|
|
||||||
form = self.get_form()
|
|
||||||
if form.is_valid():
|
|
||||||
return self.form_valid(form)
|
|
||||||
else:
|
|
||||||
return self.form_invalid(form)
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
alias = form.save(commit=False)
|
|
||||||
alias.note = self.object.note
|
|
||||||
alias.save()
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteAliasView(LoginRequiredMixin, DeleteView):
|
|
||||||
model = Alias
|
|
||||||
|
|
||||||
def delete(self, request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
self.object = self.get_object()
|
|
||||||
self.object.delete()
|
|
||||||
except ValidationError as e:
|
|
||||||
# TODO: pass message to redirected view.
|
|
||||||
messages.error(self.request, str(e))
|
|
||||||
else:
|
|
||||||
messages.success(self.request, _("Alias successfully deleted"))
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return reverse_lazy('member:user_alias', kwargs={'pk': self.object.note.user.pk})
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
return self.post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class PictureUpdateView(LoginRequiredMixin, FormMixin, DetailView):
|
class PictureUpdateView(LoginRequiredMixin, FormMixin, DetailView):
|
||||||
form_class = ImageForm
|
form_class = ImageForm
|
||||||
@ -368,6 +326,17 @@ class ClubDetailView(LoginRequiredMixin, DetailView):
|
|||||||
context['member_list'] = club_member
|
context['member_list'] = club_member
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
class ClubAliasView(LoginRequiredMixin, DetailView):
|
||||||
|
model = Club
|
||||||
|
template_name = 'member/club_alias.html'
|
||||||
|
context_object_name = 'club'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
note = context['object'].note
|
||||||
|
context["aliases"] = AliasTable(note.alias_set.all())
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ClubUpdateView(LoginRequiredMixin, UpdateView):
|
class ClubUpdateView(LoginRequiredMixin, UpdateView):
|
||||||
model = Club
|
model = Club
|
||||||
@ -395,12 +364,12 @@ class ClubAddMemberView(LoginRequiredMixin, CreateView):
|
|||||||
return super().get_queryset().filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view")
|
return super().get_queryset().filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view")
|
||||||
| PermissionBackend.filter_queryset(self.request.user, Membership,
|
| PermissionBackend.filter_queryset(self.request.user, Membership,
|
||||||
"change"))
|
"change"))
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
club = Club.objects.get(pk=self.kwargs["pk"])
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['formset'] = MemberFormSet()
|
context['formset'] = MemberFormSet()
|
||||||
context['helper'] = FormSetHelper()
|
context['helper'] = FormSetHelper()
|
||||||
|
context['club'] = club
|
||||||
context['no_cache'] = True
|
context['no_cache'] = True
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
@ -78,7 +78,11 @@ class AliasSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Alias
|
model = Alias
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
read_only_fields = ('note', )
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
instance = Alias(**attrs)
|
||||||
|
instance.clean()
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
class NotePolymorphicSerializer(PolymorphicSerializer):
|
class NotePolymorphicSerializer(PolymorphicSerializer):
|
||||||
|
@ -2,10 +2,14 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet
|
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet
|
||||||
|
|
||||||
from .serializers import NotePolymorphicSerializer, AliasSerializer, TemplateCategorySerializer, \
|
from .serializers import NotePolymorphicSerializer, AliasSerializer, TemplateCategorySerializer, \
|
||||||
TransactionTemplateSerializer, TransactionPolymorphicSerializer
|
TransactionTemplateSerializer, TransactionPolymorphicSerializer
|
||||||
@ -53,6 +57,22 @@ class AliasViewSet(ReadProtectedModelViewSet):
|
|||||||
search_fields = ['$normalized_name', '$name', '$note__polymorphic_ctype__model', ]
|
search_fields = ['$normalized_name', '$name', '$note__polymorphic_ctype__model', ]
|
||||||
ordering_fields = ['name', 'normalized_name']
|
ordering_fields = ['name', 'normalized_name']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
serializer_class = self.serializer_class
|
||||||
|
if self.request.method in ['PUT', 'PATCH']:
|
||||||
|
#alias owner cannot be change once establish
|
||||||
|
setattr(serializer_class.Meta, 'read_only_fields', ('note',))
|
||||||
|
return serializer_class
|
||||||
|
|
||||||
|
def destroy(self, request, *args, **kwargs):
|
||||||
|
instance = self.get_object()
|
||||||
|
try:
|
||||||
|
self.perform_destroy(instance)
|
||||||
|
except ValidationError as e:
|
||||||
|
print(e)
|
||||||
|
return Response({e.code:e.message},status.HTTP_400_BAD_REQUEST)
|
||||||
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""
|
"""
|
||||||
Parse query and apply filters.
|
Parse query and apply filters.
|
||||||
|
58
apps/note/fixtures/button.json
Normal file
58
apps/note/fixtures/button.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 1,
|
||||||
|
"fields": {
|
||||||
|
"name": "Soft"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 2,
|
||||||
|
"fields": {
|
||||||
|
"name": "Pulls"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 3,
|
||||||
|
"fields": {
|
||||||
|
"name": "Gala"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 4,
|
||||||
|
"fields": {
|
||||||
|
"name": "Clubs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 5,
|
||||||
|
"fields": {
|
||||||
|
"name": "Bouffe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 6,
|
||||||
|
"fields": {
|
||||||
|
"name": "BDA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"name": "Autre"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.templatecategory",
|
||||||
|
"pk": 8,
|
||||||
|
"fields": {
|
||||||
|
"name": "Alcool"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -184,61 +184,5 @@
|
|||||||
"normalized_name": "kfet",
|
"normalized_name": "kfet",
|
||||||
"note": 6
|
"note": 6
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 1,
|
|
||||||
"fields": {
|
|
||||||
"name": "Soft"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 2,
|
|
||||||
"fields": {
|
|
||||||
"name": "Pulls"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 3,
|
|
||||||
"fields": {
|
|
||||||
"name": "Gala"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 4,
|
|
||||||
"fields": {
|
|
||||||
"name": "Clubs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 5,
|
|
||||||
"fields": {
|
|
||||||
"name": "Bouffe"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 6,
|
|
||||||
"fields": {
|
|
||||||
"name": "BDA"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 7,
|
|
||||||
"fields": {
|
|
||||||
"name": "Autre"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "note.templatecategory",
|
|
||||||
"pk": 8,
|
|
||||||
"fields": {
|
|
||||||
"name": "Alcool"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -9,17 +9,6 @@ from .models import Alias
|
|||||||
from .models import TransactionTemplate
|
from .models import TransactionTemplate
|
||||||
|
|
||||||
|
|
||||||
class AliasForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Alias
|
|
||||||
fields = ("name",)
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.fields["name"].label = False
|
|
||||||
self.fields["name"].widget.attrs = {"placeholder": _('New Alias')}
|
|
||||||
|
|
||||||
|
|
||||||
class ImageForm(forms.Form):
|
class ImageForm(forms.Form):
|
||||||
image = forms.ImageField(required=False,
|
image = forms.ImageField(required=False,
|
||||||
label=_('select an image'),
|
label=_('select an image'),
|
||||||
|
@ -228,7 +228,7 @@ class Alias(models.Model):
|
|||||||
for cat in {'M', 'P', 'Z', 'C'})).casefold()
|
for cat in {'M', 'P', 'Z', 'C'})).casefold()
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
normalized_name = Alias.normalize(self.name)
|
normalized_name = self.normalize(self.name)
|
||||||
if len(normalized_name) >= 255:
|
if len(normalized_name) >= 255:
|
||||||
raise ValidationError(_('Alias is too long.'),
|
raise ValidationError(_('Alias is too long.'),
|
||||||
code='alias_too_long')
|
code='alias_too_long')
|
||||||
@ -242,8 +242,12 @@ class Alias(models.Model):
|
|||||||
pass
|
pass
|
||||||
self.normalized_name = normalized_name
|
self.normalized_name = normalized_name
|
||||||
|
|
||||||
|
def save(self,*args,**kwargs):
|
||||||
|
self.normalized_name = self.normalize(self.name)
|
||||||
|
super().save(*args,**kwargs)
|
||||||
|
|
||||||
def delete(self, using=None, keep_parents=False):
|
def delete(self, using=None, keep_parents=False):
|
||||||
if self.name == str(self.note):
|
if self.name == str(self.note):
|
||||||
raise ValidationError(_("You can't delete your main alias."),
|
raise ValidationError(_("You can't delete your main alias."),
|
||||||
code="cant_delete_main_alias")
|
code="main_alias")
|
||||||
return super().delete(using, keep_parents)
|
return super().delete(using, keep_parents)
|
||||||
|
@ -99,7 +99,7 @@ class HistoryTable(tables.Table):
|
|||||||
|
|
||||||
# function delete_button(id) provided in template file
|
# function delete_button(id) provided in template file
|
||||||
DELETE_TEMPLATE = """
|
DELETE_TEMPLATE = """
|
||||||
<button id="{{ record.pk }}" class="btn btn-danger" onclick="delete_button(this.id)"> {{ delete_trans }}</button>
|
<button id="{{ record.pk }}" class="btn btn-danger btn-sm" onclick="delete_button(this.id)"> {{ delete_trans }}</button>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@ -107,7 +107,8 @@ class AliasTable(tables.Table):
|
|||||||
class Meta:
|
class Meta:
|
||||||
attrs = {
|
attrs = {
|
||||||
'class':
|
'class':
|
||||||
'table table condensed table-striped table-hover'
|
'table table condensed table-striped table-hover',
|
||||||
|
'id':"alias_table"
|
||||||
}
|
}
|
||||||
model = Alias
|
model = Alias
|
||||||
fields = ('name',)
|
fields = ('name',)
|
||||||
@ -115,15 +116,11 @@ class AliasTable(tables.Table):
|
|||||||
|
|
||||||
show_header = False
|
show_header = False
|
||||||
name = tables.Column(attrs={'td': {'class': 'text-center'}})
|
name = tables.Column(attrs={'td': {'class': 'text-center'}})
|
||||||
# delete = tables.TemplateColumn(template_code=delete_template,
|
|
||||||
# attrs={'td':{'class': 'col-sm-1'}})
|
|
||||||
|
|
||||||
delete = tables.LinkColumn('member:user_alias_delete',
|
delete_col = tables.TemplateColumn(template_code=DELETE_TEMPLATE,
|
||||||
args=[A('pk')],
|
extra_context={"delete_trans": _('delete')},
|
||||||
attrs={
|
attrs={'td': {'class': 'col-sm-1'}})
|
||||||
'td': {'class': 'col-sm-2'},
|
|
||||||
'a': {'class': 'btn btn-danger'}},
|
|
||||||
text='delete', accessor='pk')
|
|
||||||
|
|
||||||
|
|
||||||
class ButtonTable(tables.Table):
|
class ButtonTable(tables.Table):
|
||||||
@ -143,11 +140,11 @@ class ButtonTable(tables.Table):
|
|||||||
edit = tables.LinkColumn('note:template_update',
|
edit = tables.LinkColumn('note:template_update',
|
||||||
args=[A('pk')],
|
args=[A('pk')],
|
||||||
attrs={'td': {'class': 'col-sm-1'},
|
attrs={'td': {'class': 'col-sm-1'},
|
||||||
'a': {'class': 'btn btn-primary'}},
|
'a': {'class': 'btn btn-sm btn-primary'}},
|
||||||
text=_('edit'),
|
text=_('edit'),
|
||||||
accessor='pk')
|
accessor='pk')
|
||||||
|
|
||||||
delete = tables.TemplateColumn(template_code=DELETE_TEMPLATE,
|
delete_col = tables.TemplateColumn(template_code=DELETE_TEMPLATE,
|
||||||
extra_context={"delete_trans": _('delete')},
|
extra_context={"delete_trans": _('delete')},
|
||||||
attrs={'td': {'class': 'col-sm-1'}})
|
attrs={'td': {'class': 'col-sm-1'}})
|
||||||
|
|
||||||
|
37
static/js/alias.js
Normal file
37
static/js/alias.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
$("#alias_input").on('keypress',function(e) {
|
||||||
|
if(e.which == 13) {
|
||||||
|
$("#alias_submit").click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function create_alias(note_id){
|
||||||
|
$.post("/api/note/alias/",
|
||||||
|
{
|
||||||
|
"csrfmiddlewaretoken": CSRF_TOKEN,
|
||||||
|
"name": $("#alias_input").val(),
|
||||||
|
"note": note_id
|
||||||
|
}
|
||||||
|
).done(function(){
|
||||||
|
$("#alias_table").load(location.href+ " #alias_table");
|
||||||
|
addMsg("Alias ajouté","success");
|
||||||
|
})
|
||||||
|
.fail(function(xhr, textStatus, error){
|
||||||
|
errMsg(xhr.responseJSON);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// on click of button "delete" , call the API
|
||||||
|
function delete_button(button_id){
|
||||||
|
$.ajax({
|
||||||
|
url:"/api/note/alias/"+button_id+"/",
|
||||||
|
method:"DELETE",
|
||||||
|
headers: {"X-CSRFTOKEN": CSRF_TOKEN}
|
||||||
|
})
|
||||||
|
.done(function(){
|
||||||
|
addMsg('Alias supprimé','success');
|
||||||
|
$("#alias_table").load(location.href + " #alias_table");
|
||||||
|
})
|
||||||
|
.fail(function(xhr,textStatus, error){
|
||||||
|
errMsg(xhr.responseJSON);
|
||||||
|
});
|
||||||
|
}
|
@ -28,7 +28,15 @@ function addMsg(msg, alert_type) {
|
|||||||
+ msg + "</div>\n";
|
+ msg + "</div>\n";
|
||||||
msgDiv.html(html);
|
msgDiv.html(html);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* add Muliple error message from err_obj
|
||||||
|
* @param err_obj {error_code:erro_message}
|
||||||
|
*/
|
||||||
|
function errMsg(errs_obj){
|
||||||
|
for (const err_msg of Object.values(errs_obj)) {
|
||||||
|
addMsg(err_msg,'danger');
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Reload the balance of the user on the right top corner
|
* Reload the balance of the user on the right top corner
|
||||||
*/
|
*/
|
||||||
|
@ -221,7 +221,7 @@ function consume(source, source_alias, dest, quantity, amount, reason, type, cat
|
|||||||
addMsg("La transaction n'a pas pu être validée pour cause de solde insuffisant.", "danger");
|
addMsg("La transaction n'a pas pu être validée pour cause de solde insuffisant.", "danger");
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
reset();
|
reset();
|
||||||
addMsg("Une erreur est survenue lors de la transaction : " + e.responseText, "danger");
|
errMsg(e.responseJSON);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
<a class="nav-link" href="{% url 'note:consos' %}"><i class="fa fa-coffee"></i> {% trans 'Consumptions' %}</a>
|
<a class="nav-link" href="{% url 'note:consos' %}"><i class="fa fa-coffee"></i> {% trans 'Consumptions' %}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if "note.transaction"|not_empty_model_list %}
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{% url 'note:transfer' %}"><i class="fa fa-exchange"></i>{% trans 'Transfer' %} </a>
|
<a class="nav-link" href="{% url 'note:transfer' %}"><i class="fa fa-exchange"></i>{% trans 'Transfer' %} </a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% if "member.club"|not_empty_model_list %}
|
{% if "member.club"|not_empty_model_list %}
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{% url 'member:club_list' %}"><i class="fa fa-users"></i> {% trans 'Clubs' %}</a>
|
<a class="nav-link" href="{% url 'member:club_list' %}"><i class="fa fa-users"></i> {% trans 'Clubs' %}</a>
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "member/noteowner_detail.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% block content %}
|
|
||||||
|
{% block profile_info %}
|
||||||
|
{% include "member/club_info.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block profile_content %}
|
||||||
|
|
||||||
<form method="post" action="">
|
<form method="post" action="">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@ -10,9 +14,9 @@
|
|||||||
<input type="submit" name="submit" value="Add Members" class="btn btn-primary" id="submit-save">
|
<input type="submit" name="submit" value="Add Members" class="btn btn-primary" id="submit-save">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Include formset plugin - including jQuery dependency -->
|
{% block extrajavascript %}
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
|
||||||
<script src="{% static 'js/dynamic-formset.js' %}"></script>
|
<script src="{% static 'js/dynamic-formset.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
$('.formset-row').formset({
|
$('.formset-row').formset({
|
||||||
|
12
templates/member/alias_update.html
Normal file
12
templates/member/alias_update.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% load django_tables2 crispy_forms_tags i18n %}
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<input id="alias_input" type="text" value=""/>
|
||||||
|
<button id="alias_submit" class="btn btn-primary mx-2" onclick="create_alias( {{ object.note.pk }} )" type="submit">
|
||||||
|
{% trans "Add alias" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="card bg-light shadow">
|
||||||
|
<div class="card-body">
|
||||||
|
{% render_table aliases %}
|
||||||
|
</div>
|
||||||
|
</div>
|
10
templates/member/club_alias.html
Normal file
10
templates/member/club_alias.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{% extends "member/club_detail.html" %}
|
||||||
|
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block profile_content %}
|
||||||
|
{% include "member/alias_update.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extrajavascript %}
|
||||||
|
<script src="/static/js/alias.js"></script>
|
||||||
|
{% endblock%}
|
@ -1,5 +1,8 @@
|
|||||||
{% load i18n static pretty_money %}
|
{% load i18n static pretty_money %}
|
||||||
<div class="card bg-light shadow">
|
<div class="card bg-light shadow">
|
||||||
|
<div class="card-header text-center">
|
||||||
|
<h4> Club {{ club.name }} </h4>
|
||||||
|
</div>
|
||||||
<div class="card-top text-center">
|
<div class="card-top text-center">
|
||||||
<a href="{% url 'member:club_update_pic' club.pk %}">
|
<a href="{% url 'member:club_update_pic' club.pk %}">
|
||||||
<img src="{{ club.note.display_image.url }}" class="img-thumbnail mt-2" >
|
<img src="{{ club.note.display_image.url }}" class="img-thumbnail mt-2" >
|
||||||
@ -10,6 +13,9 @@
|
|||||||
<dt class="col-xl-6">{% trans 'name'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'name'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ club.name}}</dd>
|
<dd class="col-xl-6">{{ club.name}}</dd>
|
||||||
|
|
||||||
|
<dt class="col-xl-6"><a href="{% url 'member:club_detail' club.parent_club.pk %}">{% trans 'Club Parent'|capfirst %}</a></dt>
|
||||||
|
<dd class="col-xl-6"> {{ club.parent_club.name}}</dd>
|
||||||
|
|
||||||
<dt class="col-xl-6">{% trans 'membership start'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'membership start'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ club.membership_start }}</dd>
|
<dd class="col-xl-6">{{ club.membership_start }}</dd>
|
||||||
|
|
||||||
@ -22,11 +28,19 @@
|
|||||||
<dt class="col-xl-6">{% trans 'membership fee'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'membership fee'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ club.membership_fee|pretty_money }}</dd>
|
<dd class="col-xl-6">{{ club.membership_fee|pretty_money }}</dd>
|
||||||
|
|
||||||
<dt class="col-xl-6"><a href="{% url 'member:user_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
<dt class="col-xl-6"><a href="{% url 'member:club_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
||||||
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
|
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
|
||||||
|
|
||||||
<dt class="col-xl-3">{% trans 'email'|capfirst %}</dt>
|
<dt class="col-xl-3">{% trans 'email'|capfirst %}</dt>
|
||||||
<dd class="col-xl-9"><a href="mailto:{{ club.email }}">{{ club.email}}</a></dd>
|
<dd class="col-xl-9"><a href="mailto:{{ club.email }}">{{ club.email}}</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
<a class="btn btn-primary btn-sm my-1" href="{% url 'member:club_add_member' pk=club.pk %}"> {% trans "Add member" %}</a>
|
||||||
|
<a class="btn btn-primary btn-sm my-1" href="{% url 'member:club_update' pk=club.pk %}"> {% trans "Edit" %}</a>
|
||||||
|
<a class="btn btn-primary btn-sm my-1" href="{% url 'member:club_add_member' pk=club.pk %}"> {% trans "Add roles" %}</a>
|
||||||
|
{% url 'member:club_detail' club.pk as club_detail_url %}
|
||||||
|
{%if request.get_full_path != club_detail_url %}
|
||||||
|
<a class="btn btn-primary btn-sm my-1" href="{{ user_profile_url }}">{% trans 'View Profile' %}</a>
|
||||||
|
{% endif %} </div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
{% extends "member/club_detail.html" %}
|
{% extends "member/club_detail.html" %}
|
||||||
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
||||||
|
|
||||||
{% block profile_info %}
|
|
||||||
{% include "member/club_info.html" %}
|
|
||||||
{% endblock%}
|
|
||||||
|
|
||||||
{% block profile_content%}
|
{% block profile_content%}
|
||||||
{% include "member/picture_update.html" %}
|
{% include "member/picture_update.html" %}
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
|
@ -2,18 +2,9 @@
|
|||||||
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
||||||
|
|
||||||
{% block profile_content %}
|
{% block profile_content %}
|
||||||
<div class="d-flex justify-content-center">
|
{% include "member/alias_update.html"%}
|
||||||
<form class=" text-center form my-2" action="" method="post">
|
{% endblock %}
|
||||||
{% csrf_token %}
|
|
||||||
{{ form |crispy }}
|
{% block extrajavascript %}
|
||||||
<button class="btn btn-primary mx-2" type="submit">
|
<script src="/static/js/alias.js"></script>
|
||||||
{% trans "Add alias" %}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="card bg-light shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
{% render_table aliases %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{% load i18n static pretty_money %}
|
{% load i18n static pretty_money %}
|
||||||
|
|
||||||
<div class="card bg-light shadow">
|
<div class="card bg-light shadow">
|
||||||
|
<div class="card-header text-center" >
|
||||||
|
<h4> {% trans "Account #" %} {{ object.pk }}</h4>
|
||||||
|
</div>
|
||||||
<div class="card-top text-center">
|
<div class="card-top text-center">
|
||||||
<a href="{% url 'member:user_update_pic' object.pk %}">
|
<a href="{% url 'member:user_update_pic' object.pk %}">
|
||||||
<img src="{{ object.note.display_image.url }}" class="img-thumbnail mt-2" >
|
<img src="{{ object.note.display_image.url }}" class="img-thumbnail mt-2" >
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
{% extends "member/noteowner_detail.html" %}
|
{% extends "member/profile_detail.html" %}
|
||||||
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
||||||
|
|
||||||
{% block profile_info %}
|
|
||||||
{% include "member/profile_info.html" %}
|
|
||||||
{% endblock%}
|
|
||||||
|
|
||||||
{% block profile_content%}
|
{% block profile_content%}
|
||||||
{% include "member/picture_update.html" %}
|
{% include "member/picture_update.html" %}
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
|
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
|
||||||
<hr>
|
<hr>
|
||||||
<a class="btn btn-primary text-center my-4" href="{% url 'note:template_create' %}">Créer un bouton</a>
|
<a class="btn btn-primary text-center my-1" href="{% url 'note:template_create' %}">{% trans "New button" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
|
Loading…
Reference in New Issue
Block a user