Merge branch 'front_club' into 'master'

Finitions sur l'interface club

See merge request bde/nk20!70
This commit is contained in:
Pierre-antoine Comby 2020-03-27 14:11:28 +01:00
commit 8b4c39269c
22 changed files with 224 additions and 166 deletions

View File

@ -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"),

View File

@ -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

View File

@ -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):

View File

@ -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.

View 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"
}
}
]

View File

@ -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"
}
} }
] ]

View File

@ -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'),

View File

@ -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)

View File

@ -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
View 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);
});
}

View File

@ -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
*/ */

View File

@ -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);
}); });
}); });
} }

View File

@ -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>

View File

@ -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({

View 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>

View 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%}

View File

@ -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>

View File

@ -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%}

View File

@ -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">
{% csrf_token %}
{{ form |crispy }}
<button class="btn btn-primary mx-2" type="submit">
{% trans "Add alias" %}
</button>
</form>
</div>
<div class="card bg-light shadow">
<div class="card-body">
{% render_table aliases %}
</div>
</div>
{% endblock %} {% endblock %}
{% block extrajavascript %}
<script src="/static/js/alias.js"></script>
{% endblock%}

View File

@ -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" >

View File

@ -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%}

View File

@ -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">