mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-31 07:49:57 +01:00 
			
		
		
		
	Add teams
This commit is contained in:
		| @@ -4,9 +4,9 @@ | ||||
| from django import forms | ||||
| from django.contrib.auth.models import User | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete | ||||
| from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget | ||||
|  | ||||
| from .models import WEIClub, WEIRegistration, Bus | ||||
| from .models import WEIClub, WEIRegistration, Bus, BusTeam | ||||
|  | ||||
|  | ||||
| class WEIForm(forms.ModelForm): | ||||
| @@ -62,7 +62,7 @@ class BusForm(forms.ModelForm): | ||||
|  | ||||
| class BusTeamForm(forms.ModelForm): | ||||
|     class Meta: | ||||
|         model = Bus | ||||
|         model = BusTeam | ||||
|         fields = '__all__' | ||||
|         widgets = { | ||||
|             "bus": Autocomplete( | ||||
| @@ -72,4 +72,5 @@ class BusTeamForm(forms.ModelForm): | ||||
|                     'placeholder': 'Bus ...', | ||||
|                 }, | ||||
|             ), | ||||
|             "color": ColorWidget(), | ||||
|         } | ||||
|   | ||||
| @@ -50,6 +50,12 @@ class Bus(models.Model): | ||||
|         verbose_name=_("name"), | ||||
|     ) | ||||
|  | ||||
|     description = models.TextField( | ||||
|         blank=True, | ||||
|         default="", | ||||
|         verbose_name=_("description"), | ||||
|     ) | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.name | ||||
|  | ||||
| @@ -77,6 +83,12 @@ class BusTeam(models.Model): | ||||
|         help_text=_("The color of the T-Shirt, stored with its number equivalent"), | ||||
|     ) | ||||
|  | ||||
|     description = models.TextField( | ||||
|         blank=True, | ||||
|         default="", | ||||
|         verbose_name=_("description"), | ||||
|     ) | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.name + " (" + str(self.bus) + ")" | ||||
|  | ||||
|   | ||||
| @@ -107,18 +107,22 @@ class BusTeamTable(tables.Table): | ||||
|     color = tables.Column( | ||||
|         attrs={ | ||||
|             "td": { | ||||
|                 "style": lambda record: "background-color: #" + "".format(record.color) + ";" | ||||
|                 "style": lambda record: "background-color: #{:06X}; color: #{:06X};" | ||||
|                                         .format(record.color, 0xFFFFFF - record.color, ) | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
|  | ||||
|     def render_color(self, value): | ||||
|         return "#{:06X}".format(value) | ||||
|  | ||||
|     class Meta: | ||||
|         attrs = { | ||||
|             'class': 'table table-condensed table-striped table-hover' | ||||
|         } | ||||
|         model = BusTeam | ||||
|         template_name = 'django_tables2/bootstrap4.html' | ||||
|         fields = ('name', 'color', 'team',) | ||||
|         fields = ('name', 'color',) | ||||
|         row_attrs = { | ||||
|             'class': 'table-row', | ||||
|             'id': lambda record: "row-" + str(record.pk), | ||||
|   | ||||
| @@ -3,7 +3,8 @@ | ||||
|  | ||||
| from django.urls import path | ||||
|  | ||||
| from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView, BusCreateView,\ | ||||
| from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\ | ||||
|     BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView,\ | ||||
|     WEIRegisterView, WEIUpdateRegistrationView | ||||
|  | ||||
|  | ||||
| @@ -14,6 +15,9 @@ urlpatterns = [ | ||||
|     path('detail/<int:pk>/', WEIDetailView.as_view(), name="wei_detail"), | ||||
|     path('update/<int:pk>/', WEIUpdateView.as_view(), name="wei_update"), | ||||
|     path('add-bus/<int:pk>/', BusCreateView.as_view(), name="add_bus"), | ||||
|     path('manage-bus/<int:pk>/', BusManageView.as_view(), name="manage_bus"), | ||||
|     path('update-bus/<int:pk>/', BusUpdateView.as_view(), name="update_bus"), | ||||
|     path('add-bus-team/<int:pk>/', BusTeamCreateView.as_view(), name="add_team"), | ||||
|     path('register/<int:wei_pk>/', WEIRegisterView.as_view(), name="wei_register"), | ||||
|     path('edit-registration/<int:pk>/', WEIUpdateRegistrationView.as_view(), name="wei_update_registration"), | ||||
| ] | ||||
|   | ||||
| @@ -16,9 +16,9 @@ from note.tables import HistoryTable | ||||
| from permission.backends import PermissionBackend | ||||
| from permission.views import ProtectQuerysetMixin | ||||
|  | ||||
| from .models import WEIClub, WEIRegistration, WEIMembership, Bus | ||||
| from .forms import WEIForm, WEIRegistrationForm, BusForm | ||||
| from .tables import WEITable, WEIRegistrationTable, BusTable | ||||
| from .models import WEIClub, WEIRegistration, WEIMembership, Bus, BusTeam | ||||
| from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm | ||||
| from .tables import WEITable, WEIRegistrationTable, BusTable, BusTeamTable | ||||
|  | ||||
|  | ||||
| class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): | ||||
| @@ -141,7 +141,71 @@ class BusCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         self.object.refresh_from_db() | ||||
|         return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk}) | ||||
|         return reverse_lazy("wei:manage_bus", kwargs={"pk": self.object.pk}) | ||||
|  | ||||
|  | ||||
| class BusUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): | ||||
|     """ | ||||
|     Update Bus | ||||
|     """ | ||||
|     model = Bus | ||||
|     form_class = BusForm | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         context["club"] = self.object.wei | ||||
|         return context | ||||
|  | ||||
|     def get_form(self, form_class=None): | ||||
|         form = super().get_form(form_class) | ||||
|         form.fields["wei"].disabled = True | ||||
|         return form | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         self.object.refresh_from_db() | ||||
|         return reverse_lazy("wei:manage_bus", kwargs={"pk": self.object.pk}) | ||||
|  | ||||
|  | ||||
| class BusManageView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): | ||||
|     """ | ||||
|     Manage Bus | ||||
|     """ | ||||
|     model = Bus | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         context["club"] = self.object.wei | ||||
|  | ||||
|         bus = self.object | ||||
|         teams = BusTeam.objects.filter(PermissionBackend.filter_queryset(self.request.user, BusTeam, "view"))\ | ||||
|             .filter(bus=bus) | ||||
|         teams_table = BusTeamTable(data=teams, prefix="teams-") | ||||
|         context["teams"] = teams_table | ||||
|  | ||||
|         return context | ||||
|  | ||||
|  | ||||
| class BusTeamCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): | ||||
|     """ | ||||
|     Create BusTeam | ||||
|     """ | ||||
|     model = BusTeam | ||||
|     form_class = BusTeamForm | ||||
|  | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super().get_context_data(**kwargs) | ||||
|         bus = Bus.objects.get(pk=self.kwargs["pk"]) | ||||
|         context["club"] = bus.wei | ||||
|         return context | ||||
|  | ||||
|     def get_form(self, form_class=None): | ||||
|         form = super().get_form(form_class) | ||||
|         form.fields["bus"].initial = Bus.objects.get(pk=self.kwargs["pk"]) | ||||
|         return form | ||||
|  | ||||
|     def get_success_url(self): | ||||
|         self.object.refresh_from_db() | ||||
|         return reverse_lazy("wei:manage_bus", kwargs={"pk": self.object.bus.pk}) | ||||
|  | ||||
|  | ||||
| class WEIRegisterView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): | ||||
| @@ -180,4 +244,3 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update | ||||
|     def get_success_url(self): | ||||
|         self.object.refresh_from_db() | ||||
|         return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk}) | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  | ||||
| from json import dumps as json_dumps | ||||
|  | ||||
| from django.forms.widgets import DateTimeBaseInput, NumberInput, TextInput | ||||
| from django.forms.widgets import DateTimeBaseInput, NumberInput, TextInput, Widget | ||||
|  | ||||
|  | ||||
| class AmountInput(NumberInput): | ||||
| @@ -41,6 +41,29 @@ class Autocomplete(TextInput): | ||||
|         return "" | ||||
|  | ||||
|  | ||||
| class ColorWidget(Widget): | ||||
|     """ | ||||
|     Pulled from django-colorfield. | ||||
|     Select a color. | ||||
|     """ | ||||
|     template_name = 'colorfield/color.html' | ||||
|  | ||||
|     class Media: | ||||
|         js = [ | ||||
|             'colorfield/jscolor/jscolor.min.js', | ||||
|             'colorfield/colorfield.js', | ||||
|         ] | ||||
|  | ||||
|     def format_value(self, value): | ||||
|         if value is None: | ||||
|             value = 0xFFFFFF | ||||
|         return "#{:06X}".format(value) | ||||
|  | ||||
|     def value_from_datadict(self, data, files, name): | ||||
|         val = super().value_from_datadict(data, files, name) | ||||
|         return int(val[1:], 16) | ||||
|  | ||||
|  | ||||
| """ | ||||
| The remaining of this file comes from the project `django-bootstrap-datepicker-plus` available on Github: | ||||
| https://github.com/monim67/django-bootstrap-datepicker-plus | ||||
|   | ||||
							
								
								
									
										12
									
								
								static/colorfield/colorfield.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								static/colorfield/colorfield.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| /** global: django */ | ||||
|  | ||||
| window.onload = function() { | ||||
|     if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') { | ||||
|         (function($) { | ||||
|             // add colopicker to inlines added dynamically | ||||
|             $(document).on('formset:added', function onFormsetAdded(event, row) { | ||||
|                 jscolor.installByClassName('jscolor'); | ||||
|             }); | ||||
|         }(django.jQuery)); | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										1855
									
								
								static/colorfield/jscolor/jscolor.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1855
									
								
								static/colorfield/jscolor/jscolor.js
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								static/colorfield/jscolor/jscolor.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								static/colorfield/jscolor/jscolor.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8
									
								
								templates/colorfield/color.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								templates/colorfield/color.html
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| <input type="text" | ||||
|  id="{{ widget.attrs.id }}" | ||||
|  class="form-control colorfield_field jscolor" | ||||
|  name="{{ widget.name }}" | ||||
|  value="{% firstof widget.value widget.attrs.default '' %}" | ||||
|  placeholder="{% firstof widget.value widget.attrs.default '' %}" | ||||
|  data-jscolor="{hash:true,width:225,height:150,required:{% if widget.attrs.required %}true{% else %}false{% endif %}}" | ||||
|  {% if widget.attrs.required %}required{% endif %} /> | ||||
							
								
								
									
										9
									
								
								templates/wei/bus_detail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								templates/wei/bus_detail.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| {% extends "member/noteowner_detail.html" %} | ||||
|  | ||||
| {% block profile_info %} | ||||
| {% include "wei/weiclub_info.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block profile_content %} | ||||
| {% include "wei/bus_tables.html" %} | ||||
| {% endblock %} | ||||
| @@ -3,9 +3,7 @@ | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block profile_info %} | ||||
|     {% if club %} | ||||
|         {% include "wei/weiclub_info.html" %} | ||||
|     {% endif %} | ||||
|     {% include "wei/weiclub_info.html" %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block profile_content %} | ||||
|   | ||||
							
								
								
									
										33
									
								
								templates/wei/bus_tables.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								templates/wei/bus_tables.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| {% load render_table from django_tables2 %} | ||||
| {% load i18n %} | ||||
|  | ||||
| <div class="card"> | ||||
|     <div class="card-header text-center"> | ||||
|         <h4>{{ object.name }}</h4> | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|     <div class="card-body"> | ||||
|         {{ object.description }} | ||||
|     </div> | ||||
|  | ||||
|     <div class="card-footer text-center"> | ||||
|         <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:update_bus' pk=object.pk %}">{% trans "Edit" %}</a> | ||||
|         <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:add_team' pk=object.pk %}">{% trans "Add team" %}</a> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| {% if teams.data or True %} | ||||
|     <div class="card"> | ||||
|         <div class="card-header position-relative" id="clubListHeading"> | ||||
|             <a class="btn btn-link stretched-link font-weight-bold"> | ||||
|                 <i class="fa fa-bus"></i> {% trans "Teams" %} | ||||
|             </a> | ||||
|         </div> | ||||
|         {% render_table teams %} | ||||
|     </div> | ||||
|  | ||||
|     <hr> | ||||
| {% endif %} | ||||
							
								
								
									
										15
									
								
								templates/wei/busteam_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								templates/wei/busteam_form.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| {% extends "member/noteowner_detail.html" %} | ||||
| {% load crispy_forms_tags %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block profile_info %} | ||||
|     {% include "wei/weiclub_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 %} | ||||
| @@ -59,7 +59,7 @@ | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| {% if buses.data or True %} | ||||
| {% if buses.data %} | ||||
|     <div class="card"> | ||||
|         <div class="card-header position-relative" id="clubListHeading"> | ||||
|             <a class="btn btn-link stretched-link font-weight-bold"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user