mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-31 15:50:03 +01:00 
			
		
		
		
	Implement a new type of note (see #45)
This commit is contained in:
		| @@ -7,7 +7,8 @@ from crispy_forms.layout import Layout | ||||
| from django import forms | ||||
| from django.contrib.auth.forms import UserCreationForm, AuthenticationForm | ||||
| from django.contrib.auth.models import User | ||||
| from note_kfet.inputs import Autocomplete | ||||
| from note.models.notes import NoteActivity | ||||
| from note_kfet.inputs import Autocomplete, AmountInput | ||||
| from permission.models import PermissionMask | ||||
|  | ||||
| from .models import Profile, Club, Membership | ||||
| @@ -47,6 +48,31 @@ class ClubForm(forms.ModelForm): | ||||
|     class Meta: | ||||
|         model = Club | ||||
|         fields = '__all__' | ||||
|         widgets = { | ||||
|             "membership_fee": AmountInput() | ||||
|         } | ||||
|  | ||||
|  | ||||
| class NoteActivityForm(forms.ModelForm): | ||||
|     class Meta: | ||||
|         model = NoteActivity | ||||
|         fields = ('note_name', 'club', 'controller', ) | ||||
|         widgets = { | ||||
|             "club": Autocomplete( | ||||
|                 Club, | ||||
|                 attrs={ | ||||
|                     'api_url': '/api/members/club/', | ||||
|                 } | ||||
|             ), | ||||
|             "controller": Autocomplete( | ||||
|                 User, | ||||
|                 attrs={ | ||||
|                     'api_url': '/api/user/', | ||||
|                     'name_field': 'username', | ||||
|                     'placeholder': 'Nom ...', | ||||
|                 } | ||||
|             ) | ||||
|         } | ||||
|  | ||||
|  | ||||
| class AddMembersForm(forms.Form): | ||||
|   | ||||
| @@ -8,13 +8,23 @@ from . import views | ||||
| app_name = 'member' | ||||
| urlpatterns = [ | ||||
|     path('signup/', views.UserCreateView.as_view(), name="signup"), | ||||
|  | ||||
|     path('club/', views.ClubListView.as_view(), name="club_list"), | ||||
|     path('club/<int:pk>/', views.ClubDetailView.as_view(), name="club_detail"), | ||||
|     path('club/<int:pk>/add_member/', views.ClubAddMemberView.as_view(), name="club_add_member"), | ||||
|     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_pic', views.ClubPictureUpdateView.as_view(), name="club_update_pic"), | ||||
|     path('club/<int:pk>/aliases', views.ClubAliasView.as_view(), name="club_alias"), | ||||
|     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>/aliases/', views.ClubAliasView.as_view(), name="club_alias"), | ||||
|     path('club/<int:pk>/linked_notes/', views.ClubLinkedNotesView.as_view(), | ||||
|          name="club_linked_note_list"), | ||||
|     path('club/<int:club_pk>/linked_notes/create/', views.ClubLinkedNoteCreateView.as_view(), | ||||
|          name="club_linked_note_create"), | ||||
|     path('club/<int:club_pk>/linked_notes/<int:pk>/', views.ClubLinkedNoteDetailView.as_view(), | ||||
|          name="club_linked_note_detail"), | ||||
|     path('club/<int:club_pk>/linked_notes/<int:pk>/update/', views.ClubLinkedNoteUpdateView.as_view(), | ||||
|          name="club_linked_note_update"), | ||||
|  | ||||
|     path('user/', views.UserListView.as_view(), name="user_list"), | ||||
|     path('user/<int:pk>', views.UserDetailView.as_view(), name="user_detail"), | ||||
|     path('user/<int:pk>/update', views.UserUpdateView.as_view(), name="user_update_profile"), | ||||
|   | ||||
| @@ -18,13 +18,14 @@ from django_tables2.views import SingleTableView | ||||
| from rest_framework.authtoken.models import Token | ||||
| from note.forms import ImageForm | ||||
| from note.models import Alias, NoteUser | ||||
| from note.models.notes import NoteActivity | ||||
| from note.models.transactions import Transaction | ||||
| from note.tables import HistoryTable, AliasTable | ||||
| from note.tables import HistoryTable, AliasTable, NoteActivityTable | ||||
| from permission.backends import PermissionBackend | ||||
|  | ||||
| from .filters import UserFilter, UserFilterFormHelper | ||||
| from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, MemberFormSet, FormSetHelper, \ | ||||
|     CustomAuthenticationForm | ||||
|     CustomAuthenticationForm, NoteActivityForm | ||||
| from .models import Club, Membership | ||||
| from .tables import ClubTable, UserTable | ||||
|  | ||||
| @@ -134,7 +135,8 @@ class UserDetailView(LoginRequiredMixin, DetailView): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         user = context['user_object'] | ||||
|         history_list = \ | ||||
|             Transaction.objects.all().filter(Q(source=user.note) | Q(destination=user.note)).order_by("-id") | ||||
|             Transaction.objects.all().filter(Q(source=user.note) | Q(destination=user.note)).order_by("-id")\ | ||||
|             .filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view")) | ||||
|         context['history_list'] = HistoryTable(history_list) | ||||
|         club_list = \ | ||||
|             Membership.objects.all().filter(user=user).only("club") | ||||
| @@ -179,8 +181,8 @@ class ProfileAliasView(LoginRequiredMixin, DetailView): | ||||
| class PictureUpdateView(LoginRequiredMixin, FormMixin, DetailView): | ||||
|     form_class = ImageForm | ||||
|  | ||||
|     def get_context_data(self, *args, **kwargs): | ||||
|         context = super().get_context_data(*args, **kwargs) | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         context['form'] = self.form_class(self.request.POST, self.request.FILES) | ||||
|         return context | ||||
|  | ||||
| @@ -290,8 +292,8 @@ class ClubDetailView(LoginRequiredMixin, DetailView): | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         club = context["club"] | ||||
|         club_transactions = \ | ||||
|             Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note)) | ||||
|         club_transactions = Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note))\ | ||||
|             .filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view")).order_by('-id') | ||||
|         context['history_list'] = HistoryTable(club_transactions) | ||||
|         club_member = \ | ||||
|             Membership.objects.all().filter(club=club) | ||||
| @@ -317,7 +319,9 @@ class ClubUpdateView(LoginRequiredMixin, UpdateView): | ||||
|     context_object_name = "club" | ||||
|     form_class = ClubForm | ||||
|     template_name = "member/club_form.html" | ||||
|     success_url = reverse_lazy("member:club_detail") | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         return reverse_lazy("member:club_detail", kwargs={"pk": self.object.pk}) | ||||
|  | ||||
|  | ||||
| class ClubPictureUpdateView(PictureUpdateView): | ||||
| @@ -361,3 +365,77 @@ class ClubAddMemberView(LoginRequiredMixin, CreateView): | ||||
|     def form_valid(self, formset): | ||||
|         formset.save() | ||||
|         return super().form_valid(formset) | ||||
|  | ||||
|  | ||||
| class ClubLinkedNotesView(LoginRequiredMixin, SingleTableView): | ||||
|     model = NoteActivity | ||||
|     table_class = NoteActivityTable | ||||
|  | ||||
|     def get_queryset(self): | ||||
|         return super().get_queryset().filter(club=self.get_object())\ | ||||
|             .filter(PermissionBackend.filter_queryset(self.request.user, NoteActivity, "view")) | ||||
|  | ||||
|     def get_object(self): | ||||
|         if hasattr(self, 'object'): | ||||
|             return self.object | ||||
|         self.object = Club.objects.get(pk=int(self.kwargs["pk"])) | ||||
|         return self.object | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         ctx = super().get_context_data(**kwargs) | ||||
|  | ||||
|         ctx["object"] = ctx["club"] = self.get_object() | ||||
|  | ||||
|         return ctx | ||||
|  | ||||
|  | ||||
| class ClubLinkedNoteCreateView(LoginRequiredMixin, CreateView): | ||||
|     model = NoteActivity | ||||
|     form_class = NoteActivityForm | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         ctx = super().get_context_data(**kwargs) | ||||
|  | ||||
|         club = Club.objects.get(pk=self.kwargs["club_pk"]) | ||||
|         ctx["object"] = ctx["club"] = club | ||||
|         ctx["form"].fields["club"].initial = club | ||||
|  | ||||
|         return ctx | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         self.object.refresh_from_db() | ||||
|         return reverse_lazy('member:club_linked_note_detail', | ||||
|                             kwargs={"club_pk": self.object.club.pk, "pk": self.object.pk}) | ||||
|  | ||||
|  | ||||
| class ClubLinkedNoteUpdateView(LoginRequiredMixin, UpdateView): | ||||
|     model = NoteActivity | ||||
|     form_class = NoteActivityForm | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         ctx = super().get_context_data(**kwargs) | ||||
|  | ||||
|         ctx["club"] = Club.objects.get(pk=self.kwargs["club_pk"]) | ||||
|  | ||||
|         return ctx | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         return reverse_lazy('member:club_linked_note_detail', | ||||
|                             kwargs={"club_pk": self.object.club.pk, "pk": self.object.pk}) | ||||
|  | ||||
|  | ||||
| class ClubLinkedNoteDetailView(LoginRequiredMixin, DetailView): | ||||
|     model = NoteActivity | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         ctx = super().get_context_data(**kwargs) | ||||
|  | ||||
|         note = NoteActivity.objects.get(pk=self.kwargs["pk"]) | ||||
|  | ||||
|         transactions = Transaction.objects.all().filter(Q(source=note) | Q(destination=note))\ | ||||
|             .filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view")).order_by("-id") | ||||
|         ctx['history_list'] = HistoryTable(transactions) | ||||
|         ctx["note"] = note | ||||
|         ctx["club"] = note.club | ||||
|  | ||||
|         return ctx | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _ | ||||
| from polymorphic.admin import PolymorphicChildModelAdmin, \ | ||||
|     PolymorphicChildModelFilter, PolymorphicParentModelAdmin | ||||
|  | ||||
| from .models.notes import Alias, Note, NoteClub, NoteSpecial, NoteUser | ||||
| from .models.notes import Alias, Note, NoteClub, NoteSpecial, NoteUser, NoteActivity | ||||
| from .models.transactions import Transaction, TemplateCategory, TransactionTemplate, \ | ||||
|     RecurrentTransaction, MembershipTransaction | ||||
|  | ||||
| @@ -24,7 +24,7 @@ class NoteAdmin(PolymorphicParentModelAdmin): | ||||
|     """ | ||||
|     Parent regrouping all note types as children | ||||
|     """ | ||||
|     child_models = (NoteClub, NoteSpecial, NoteUser) | ||||
|     child_models = (NoteClub, NoteSpecial, NoteUser, NoteActivity) | ||||
|     list_filter = ( | ||||
|         PolymorphicChildModelFilter, | ||||
|         'is_active', | ||||
| @@ -74,6 +74,14 @@ class NoteSpecialAdmin(PolymorphicChildModelAdmin): | ||||
|     readonly_fields = ('balance',) | ||||
|  | ||||
|  | ||||
| @admin.register(NoteActivity) | ||||
| class NoteActivityAdmin(PolymorphicChildModelAdmin): | ||||
|     """ | ||||
|     Child for a special note, see NoteAdmin | ||||
|     """ | ||||
|     readonly_fields = ('balance',) | ||||
|  | ||||
|  | ||||
| @admin.register(NoteUser) | ||||
| class NoteUserAdmin(PolymorphicChildModelAdmin): | ||||
|     """ | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| from rest_framework import serializers | ||||
| from rest_polymorphic.serializers import PolymorphicSerializer | ||||
|  | ||||
| from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias | ||||
| from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias, NoteActivity | ||||
| from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \ | ||||
|     RecurrentTransaction, SpecialTransaction | ||||
|  | ||||
| @@ -69,6 +69,22 @@ class NoteUserSerializer(serializers.ModelSerializer): | ||||
|         return str(obj) | ||||
|  | ||||
|  | ||||
| class NoteActivitySerializer(serializers.ModelSerializer): | ||||
|     """ | ||||
|     REST API Serializer for User's notes. | ||||
|     The djangorestframework plugin will analyse the model `NoteActivity` and parse all fields in the API. | ||||
|     """ | ||||
|     name = serializers.SerializerMethodField() | ||||
|  | ||||
|     class Meta: | ||||
|         model = NoteActivity | ||||
|         fields = '__all__' | ||||
|         read_only_fields = ('note', 'user', ) | ||||
|  | ||||
|     def get_name(self, obj): | ||||
|         return str(obj) | ||||
|  | ||||
|  | ||||
| class AliasSerializer(serializers.ModelSerializer): | ||||
|     """ | ||||
|     REST API Serializer for Aliases. | ||||
| @@ -90,7 +106,8 @@ class NotePolymorphicSerializer(PolymorphicSerializer): | ||||
|         Note: NoteSerializer, | ||||
|         NoteUser: NoteUserSerializer, | ||||
|         NoteClub: NoteClubSerializer, | ||||
|         NoteSpecial: NoteSpecialSerializer | ||||
|         NoteSpecial: NoteSpecialSerializer, | ||||
|         NoteActivity: NoteActivitySerializer, | ||||
|     } | ||||
|  | ||||
|     class Meta: | ||||
|   | ||||
| @@ -4,11 +4,13 @@ | ||||
| import unicodedata | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.core.validators import RegexValidator | ||||
| from django.db import models | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from polymorphic.models import PolymorphicModel | ||||
| from member.models import Club | ||||
|  | ||||
| """ | ||||
| Defines each note types | ||||
| @@ -174,6 +176,40 @@ class NoteSpecial(Note): | ||||
|         return self.special_type | ||||
|  | ||||
|  | ||||
| class NoteActivity(Note): | ||||
|     """ | ||||
|     A :model:`note.Note` for accounts that are not attached to a user neither to a club, | ||||
|     that only need to store and transfer money (notes for activities, departments, ...) | ||||
|     """ | ||||
|  | ||||
|     note_name = models.CharField( | ||||
|         verbose_name=_('name'), | ||||
|         max_length=255, | ||||
|         unique=True, | ||||
|     ) | ||||
|  | ||||
|     club = models.ForeignKey( | ||||
|         Club, | ||||
|         on_delete=models.PROTECT, | ||||
|         related_name="linked_notes", | ||||
|         verbose_name=_("club"), | ||||
|     ) | ||||
|  | ||||
|     controller = models.ForeignKey( | ||||
|         User, | ||||
|         on_delete=models.PROTECT, | ||||
|         related_name="+", | ||||
|         verbose_name=_("controller"), | ||||
|     ) | ||||
|  | ||||
|     class Meta: | ||||
|         verbose_name = _("common note") | ||||
|         verbose_name_plural = _("common notes") | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.note_name | ||||
|  | ||||
|  | ||||
| class Alias(models.Model): | ||||
|     """ | ||||
|     points toward  a :model:`note.NoteUser` or :model;`note.NoteClub` instance. | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from django.utils.html import format_html | ||||
| from django_tables2.utils import A | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from .models.notes import Alias | ||||
| from .models.notes import Alias, NoteActivity | ||||
| from .models.transactions import Transaction, TransactionTemplate | ||||
| from .templatetags.pretty_money import pretty_money | ||||
|  | ||||
| @@ -121,6 +121,24 @@ class AliasTable(tables.Table): | ||||
|                                        attrs={'td': {'class': 'col-sm-1'}}) | ||||
|  | ||||
|  | ||||
| class NoteActivityTable(tables.Table): | ||||
|     note_name = tables.LinkColumn( | ||||
|         "member:club_linked_note_detail", | ||||
|         args=[A("club.pk"), A("pk")], | ||||
|     ) | ||||
|  | ||||
|     def render_balance(self, value): | ||||
|         return pretty_money(value) | ||||
|  | ||||
|     class Meta: | ||||
|         attrs = { | ||||
|             'class': 'table table-condensed table-striped table-hover' | ||||
|         } | ||||
|         model = NoteActivity | ||||
|         fields = ('note_name', 'balance',) | ||||
|         template_name = 'django_tables2/bootstrap4.html' | ||||
|  | ||||
|  | ||||
| class ButtonTable(tables.Table): | ||||
|     class Meta: | ||||
|         attrs = { | ||||
|   | ||||
| @@ -70,7 +70,7 @@ function refreshBalance() { | ||||
|  * @param fun For each found note with the matched alias `alias`, fun(note, alias) is called. | ||||
|  */ | ||||
| function getMatchedNotes(pattern, fun) { | ||||
|     $.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club&ordering=normalized_name", fun); | ||||
|     $.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club|activity&ordering=normalized_name", fun); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -7,3 +7,12 @@ | ||||
| {% block profile_content %} | ||||
| {% include "member/club_tables.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block extrajavascript %} | ||||
|     <script> | ||||
|     function refreshHistory() { | ||||
|         $("#history_list").load("{% url 'member:club_detail' pk=object.pk %} #history_list"); | ||||
|         $("#profile_infos").load("{% url 'member:club_detail' pk=object.pk %} #profile_infos"); | ||||
|     } | ||||
|     </script> | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -34,7 +34,10 @@ | ||||
|             <dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd> | ||||
|  | ||||
|             <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> | ||||
|  | ||||
|             <dt class="col-xl-6"><a href="{% url 'member:club_linked_note_list' pk=club.pk %}">{% trans 'linked notes'|capfirst %}</a></dt> | ||||
|             <dd class="col-xl-6 text-truncate">{{ club.linked_notes.all|join:", " }}</dd> | ||||
|         </dl> | ||||
|     </div> | ||||
|     <div class="card-footer text-center"> | ||||
| @@ -43,6 +46,6 @@ | ||||
|         <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> | ||||
|         <a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View Profile' %}</a> | ||||
|         {% endif %}    </div> | ||||
| </div> | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|  | ||||
| {% block extrajavascript %} | ||||
|     <script> | ||||
|     function refreshhistory() { | ||||
|     function refreshHistory() { | ||||
|         $("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list"); | ||||
|         $("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos"); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										57
									
								
								templates/note/noteactivity_detail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								templates/note/noteactivity_detail.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| {% extends "member/noteowner_detail.html" %} | ||||
|  | ||||
| {% load i18n %} | ||||
| {% load render_table from django_tables2 %} | ||||
| {% load pretty_money %} | ||||
|  | ||||
| {% block profile_info %} | ||||
| {% include "member/club_info.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block profile_content %} | ||||
|     <div id="activity_info" class="card bg-light shadow"> | ||||
|         <div class="card-header text-center"> | ||||
|             <h4>{% trans "Linked note:" %} {{ note.note_name }}</h4> | ||||
|         </div> | ||||
|         <div class="card-body" id="profile_infos"> | ||||
|             <dl class="row"> | ||||
|                 <dt class="col-xl-6">{% trans 'attached club'|capfirst %}</dt> | ||||
|                 <dd class="col-xl-6"><a href="{% url 'member:club_detail' pk=club.pk %}">{{ club }}</a></dd> | ||||
|  | ||||
|                 <dt class="col-xl-6">{% trans 'controller'|capfirst %}</dt> | ||||
|                 <dd class="col-xl-6"><a href="{% url 'member:user_detail' pk=note.controller.pk %}">{{ note.controller }}</a></dd> | ||||
|  | ||||
|                 <dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt> | ||||
|                 <dd class="col-xl-6">{{ note.balance|pretty_money }}</dd> | ||||
|             </dl> | ||||
|  | ||||
|             <div class="card-footer text-center"> | ||||
|                 <a class="btn btn-primary btn-sm my-1" href="{% url 'member:club_linked_note_update' club_pk=club.pk pk=note.pk %}"> {% trans "Edit" %}</a> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|         <div class="card"> | ||||
|             <div class="card-header position-relative" id="historyListHeading"> | ||||
|                 <a class="btn btn-link stretched-link collapsed font-weight-bold" | ||||
|                    data-toggle="collapse" data-target="#historyListCollapse" | ||||
|                    aria-expanded="false" aria-controls="historyListCollapse"> | ||||
|                     <i class="fa fa-euro"></i> {% trans "Transaction history" %} | ||||
|                 </a> | ||||
|             </div> | ||||
|             <div id="historyListCollapse" aria-labelledby="historyListHeading" data-parent="#accordionProfile"> | ||||
|                 <div id="history_list"> | ||||
|                     {% render_table history_list %} | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block extrajavascript %} | ||||
|     <script> | ||||
|     function refreshHistory() { | ||||
|         $("#history_list").load("{% url 'member:club_linked_note_detail' club_pk=club.pk pk=note.pk %} #history_list"); | ||||
|         $("#profile_infos").load("{% url 'member:club_detail' pk=club.pk%} #profile_infos"); | ||||
|     } | ||||
|     </script> | ||||
| {% endblock %} | ||||
							
								
								
									
										16
									
								
								templates/note/noteactivity_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/note/noteactivity_form.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| {% extends "member/noteowner_detail.html" %} | ||||
|  | ||||
| {% load i18n %} | ||||
| {% load crispy_forms_tags %} | ||||
|  | ||||
| {% block profile_info %} | ||||
| {% include "member/club_info.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block profile_content %} | ||||
|     <form method="post"> | ||||
|     {% csrf_token %} | ||||
|     {{ form|crispy }} | ||||
|     <button class="btn btn-primary" type="submit">{% trans "Submit" %}</button> | ||||
|     </form> | ||||
| {% endblock %} | ||||
							
								
								
									
										27
									
								
								templates/note/noteactivity_list.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								templates/note/noteactivity_list.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| {% extends "member/noteowner_detail.html" %} | ||||
|  | ||||
| {% load i18n %} | ||||
| {% load render_table from django_tables2 %} | ||||
|  | ||||
| {% block profile_info %} | ||||
| {% include "member/club_info.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block profile_content %} | ||||
| <div class="row justify-content-center">    | ||||
|     <div class="col-md-10"> | ||||
|         <div class="card card-border shadow"> | ||||
|             <div class="card-header text-center"> | ||||
|                 <h5> {% trans "linked notes of club"|capfirst %} {{ club.name }}</h5> | ||||
|             </div> | ||||
|             <div class="card-body px-0 py-0" id="club_table"> | ||||
|                 {% render_table table %} | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <a href="{% url 'member:club_linked_note_create' club_pk=club.pk %}"> | ||||
|             <button class="btn btn-primary btn-block">{% trans "Add new note" %}</button> | ||||
|         </a> | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
		Reference in New Issue
	
	Block a user