event base done

This commit is contained in:
Qwann 2018-08-26 21:18:51 +02:00
parent 7ebc34d5aa
commit 7c7adab658
23 changed files with 478 additions and 27 deletions

2
.gitignore vendored
View file

@ -5,4 +5,4 @@ poulpe/settings.py
.*.swp
*.pyc
*.sqlite3
.*..sass-cache/*
*.scssc

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-26 17:49
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('equipment', '0012_auto_20180820_1124'),
]
operations = [
migrations.AlterField(
model_name='equipmentattribution',
name='remarks',
field=models.TextField(blank=True, verbose_name="remarques concernant l'attribution"),
),
]

View file

@ -226,7 +226,10 @@ class EquipmentAttribution(models.Model):
equipment = models.ForeignKey(Equipment, verbose_name=_("matériel"))
activity = models.ForeignKey(Activity)
amount = models.BigIntegerField(_("quantité attribuée"))
remarks = models.TextField(_("remarques concernant l'attribution"))
remarks = models.TextField(
_("remarques concernant l'attribution"),
blank=True,
)
class Meta:
verbose_name = _("attribution de matériel")
@ -234,7 +237,7 @@ class EquipmentAttribution(models.Model):
def __str__(self):
return "%s (%d) -> %s" % (self.equipment.name,
self.amout,
self.amount,
self.activity.get_herited('title'))
def save(self, *args, **kwargs):

View file

@ -92,6 +92,6 @@ class EquipmentListByOwner(EquipmentListAbstract):
return context
class EquipmentView(DetailView):
class EquipmentView(LoginRequiredMixin, DetailView):
model = Equipment
template_name = 'equipment/detail.html'

View file

@ -2,6 +2,13 @@ from django.contrib import admin
from shared.admin import admin_site
from .models import Event, Place, ActivityTag, Activity, ActivityTemplate # TODO add me
from equipment.models import EquipmentAttribution
class EquipmentAttributionExtraInline(admin.TabularInline):
model = EquipmentAttribution
extra = 0
classes = ['collapse']
class EventAdmin(admin.ModelAdmin):
@ -28,6 +35,8 @@ class ActivityTagAdmin(admin.ModelAdmin):
class ActivityTemplateAdmin(admin.ModelAdmin):
save_as_continue = True
save_on_top = True
list_display = ['name', 'title', 'event', 'is_public', ]
ordering = ['name', 'title', 'event', 'has_perm', ]
search_fields = ['name', 'title', 'description', 'remark', ]
@ -55,23 +64,26 @@ class ActivityTemplateAdmin(admin.ModelAdmin):
class ActivityAdmin(admin.ModelAdmin):
save_as_continue = True
save_on_top = True
list_display = ['title', 'event', 'is_public', 'parent', ]
ordering = ['title', 'event', 'has_perm', 'parent', ]
search_fields = ['title', 'description', 'remark', ]
list_filter = ['event', 'is_public', 'has_perm', 'tags', ]
filter_horizontal = ['tags', 'places', ]
filter_horizontal = ['tags', 'places', 'staff', ]
inlines = [EquipmentAttributionExtraInline, ]
fieldsets = (
('Général', {
'fields': ('event', 'parent', 'title', 'is_public', ('beginning', 'end', ), 'places', ),
'description': "Tous ces champs sont héritables (sauf parent et Évènement)",
}),
('Permanences', {
'fields': ('has_perm', ('min_perm', 'max_perm', ), ),
'fields': ('has_perm', ('min_perm', 'max_perm', ), 'staff', ),
'classes': ('collapse',),
'description': "Tous ces champs sont héritables (sauf les gens en perm)",
}),
('Descriptions', {
'fields': ('description', 'tags', 'remarks', 'staff', ),
'fields': ('description', 'tags', 'remarks', ),
'classes': ('collapse',),
'description': "Tous ces champs sont héritables",
}),

View file

@ -308,9 +308,9 @@ class Activity(AbstractActivityTemplate):
if tpl_field.many_to_many:
if value.exists():
return value
else:
elif self.parent is not None:
return getattr(self.parent, attrname)
elif value is None:
elif value is None and self.parent is not None:
return getattr(self.parent, attrname)
else:
return value

View file

@ -0,0 +1,52 @@
{% extends "shared/base.html" %}
{% load i18n staticfiles event_tags %}
{% load render_table from django_tables2 %}
{% block title %}{% trans "Activity" %}{% endblock %}
{% block content %}
<h1>{{ activity.title}}
{% if perms.event.activity_can_change and user.is_staff %}
<a class='glyphicon glyphicon-cog pull-right' href='{% url "admin:event_activity_change" activity.id %}'></a>
{% endif %}
</h1>
{% include "event/activity_summary.html" with activity=activity %}
<h2>Description</h2>
<p><strong>Description</strong>{{activity.description|default:"&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;"}}</p>
<p><strong>Remarque (staff)</strong>{{activity.remark|default:"&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;"}}</p>
<button class="collapsible active"><h3>Matériel</h3></button>
<div class="content fluid">
<table class="table table-responsive table-striped">
<tr>
<th>Matériel</th>
<th>Quantité</th>
<th>Propriétaire</th>
<th>Remarque</th>
</tr>
{% for att in attributions %}
<tr>
<td><a href="{% url 'equipment:detail' att.equipment.id %}">
{{ att.equipment }}</a></td>
<td>{{ att.amount }}</td>
<td>{{ att.equipment.owner }}</td>
<td>{{ att.remark }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
{% block aside %}
<div class="text">
Du
<strong>
{{ activity.beginning | date:"l d F Y H:i" }}
</strong>
au
<strong>
{{ activity.end | date:"l d F Y H:i" }}
</strong>
</p>
</div>
{% endblock %}

View file

@ -0,0 +1,75 @@
{% load i18n event_tags %}
{% with activity|get_herited:'has_perm' as has_perm %}
<table class="table table-responsive table-striped">
<tr>
<td>
<span class="glyphicon glyphicon-tree-deciduous"></span>
{% if activity.places.all %}
<span>{{ activity.places.all |join:", "}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
</td>
<td>
<strong>public</strong>
&nbsp;:&nbsp;
{% with activity|get_herited:'is_public' as is_public %}
<span class="glyphicon {{ is_public|yesno:"yes glyphicon-ok-sign, no glyphicon-remove-sign, dunno glyphicon-question-sign"}}"></span>
{% endwith %}
</td>
<tr>
</tr>
<td>
<span class="glyphicon glyphicon-duplicate"></span>
{% if activity.parent %}
<span>{{ activity.parent}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
</td>
<td>
<strong>perm</strong>
&nbsp;:&nbsp;
<span class="glyphicon {{ has_perm|yesno:"yes glyphicon-ok-sign, no glyphicon-remove-sign, dunno glyphicon-question-sign"}}"></span>
</td>
<tr>
</tr>
<td>
<span class="glyphicon glyphicon-tag"></span>
{% if activity.tags.all %}
<span>{{ activity.tags.all |join:", "}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
</td>
<td>
{% if has_perm %}
{{ activity|get_herited:'min_perm' }}
&le;
<strong>{{ activity.staff.count }}</strong>
&le;
{{ activity|get_herited:'max_perm' }}
{% endif %}
</td>
</tr>
</table>
{% if has_perm %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-8">
<strong>En perm : </strong>
{% with activity.staff.all as staff %}
{% if staff %}
<span>{{ staff |join:", "}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
{% endwith %}
</div>
<div class="col-sm-4">
s'inscrire (TODO)
</div>
</div>
</div>
{% endif %}
{% endwith %}

View file

@ -0,0 +1,78 @@
{% extends "shared/base.html" %}
{% load i18n staticfiles event_tags %}
{% block title %}{% trans "Évènement" %}{% endblock %}
{% block content %}
<h1>{{ event.title}}
{% if perms.event.event_can_change and user.is_staff %}
<a class='glyphicon glyphicon-cog pull-right' href='{% url "admin:event_event_change" event.id %}'></a>
{% endif %}
</h1>
<p>{{ event.description }}</p>
<h2>Boîte à outils</h2>
<div class="module-list">
<a href="#TODO" class="module">
<span class="glyphicon glyphicon-duplicate"></span>
Templates d'activité
</a>
<a href="#TODO" class="module">
<span class="glyphicon glyphicon-tag"></span>
Tags spécifiques
</a>
<a href="#todo" class="module">
<span class="glyphicon glyphicon-tree-deciduous"></span>
lieux spécifiques
</a>
</div>
<h2>Planning</h2>
<div class="planning">
{% regroup activities by beginning|date:"Y-m-d" as days_list %}
{% for day in days_list %}
{% with day.list|first as f_act %}
<button class="collapsible active"><h3>{{ f_act.beginning|date:"l d F" }}</h3></button>
<div class="content fluid">
{% endwith %}
{% for activity in day.list %}
<div class="{% cycle "" "inverted" %} activity">
<div class="activity-title">
<h4>
{% if perms.event.activity_can_change and user.is_staff %}
<a class='glyphicon glyphicon-cog' href='{% url "admin:event_activity_change" activity.id %}'></a>
{% endif %}
<a href="{% url "event:activity" activity.id %}">
{{ activity|get_herited:'title' }}
</a>
</h4>
<span class="pull-right">
de <strong>{{ activity.beginning | time:"H:i" }}</strong>
à <strong>{{ activity.end| time:"H:i" }}</strong>
</span>
{% include "event/activity_summary.html" with activity=activity %}
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}
{% block aside %}
<div class="heading separator">
{{ activities.count }} <span class="sub">activité{{ activities.count|pluralize }}</span>
</div>
<div class="text inverted">
<p>Créé le {{ event.created_at | date:"l d F Y à H:i" }} par {{ event.created_by }}</p>
<p>
Du
<strong>
{{ event.beginning_date | date:"l d F Y H:i" }}
</strong>
au
<strong>
{{ event.ending_date | date:"l d F Y H:i" }}
</strong>
</p>
</div>
{% endblock %}

View file

View file

@ -0,0 +1,9 @@
from django import template
register = template.Library()
@register.filter()
def get_herited(activity, attrname):
return activity.get_herited(attrname)

View file

@ -1,7 +1,10 @@
from django.conf.urls import url
from event.views import Index
from event.views import Index, EventView, ActivityView
app_name = 'event'
urlpatterns = [
url(r'^$', Index.as_view(), name='index'),
# url(r'^$', Index.as_view(), name='index'),
url(r'^(?P<slug>[-\w]+)/$', EventView.as_view(), name='event'),
url(r'^activity/(?P<pk>[0-9]+)/$', ActivityView.as_view(),
name='activity'),
]

View file

@ -1,5 +1,36 @@
from django.views.generic import TemplateView
from django.views.generic import DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Event, Activity
from equipment.models import EquipmentAttribution
class Index(TemplateView):
template_name = "event/index.html"
class EventView(LoginRequiredMixin, DetailView):
model = Event
template_name = 'event/event.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
event = self.object
context['activities'] = (Activity.objects.filter(event=event)
.order_by('beginning').prefetch_related(
'tags', 'places', 'staff', 'parent'))
return context
class ActivityView(LoginRequiredMixin, DetailView):
model = Activity
template_name = 'event/activity.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
activity = self.object
context['attributions'] = (EquipmentAttribution.objects
.filter(activity=activity)
.prefetch_related('equipment'))
return context

View file

@ -299,14 +299,64 @@ a.module {
background-color: #FFC282;
text-decoration: none; }
/* COULD BE USERFULL LATER
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px; }
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px; }
.collapsible:hover {
background-color: #555; }
.collapsible h3 {
margin-top: 0px;
margin-bottom: 0px;
display: inline-block; }
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
*/
.active {
background-color: #555; }
.active:after {
content: "\2212"; }
.content {
padding: 8px 18px;
display: none;
background-color: #f1f1f1; }
.content.fluid {
padding: 0px 0px;
background-color: transparent; }
.content h4 {
font-size: x-large;
font-weight: bold;
display: inline-block;
margin: 0px 0px; }
.planning .activity {
padding: 8px 18px;
padding-top: 8px;
padding-bottom: 12px;
border-left: none;
border-right: 6px solid #FF9191; }
.planning .activity.inverted {
border-left: 6px solid #FF9191;
border-right: none; }
.planning .activity .activity-title {
font-size: large; }
.glyphicon.yes {
color: #55C487 !important; }
.glyphicon.no {
color: #E36268 !important; }
.glyphicon.dunno {
color: #5599C4 !important; }
/*# sourceMappingURL=global.css.map */

File diff suppressed because one or more lines are too long

View file

@ -164,12 +164,89 @@ a.module {
}
}
/* COULD BE USERFULL LATER
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
&:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
&:hover {
background-color: #555;
}
h3 {
margin-top: 0px;
margin-bottom: 0px;
display: inline-block;
}
}
.active {
background-color: #555;
&:after {
content: "\2212";
}
}
.content {
padding: 8px 18px;
display : none;
background-color: #f1f1f1;
&.fluid {
padding: 0px 0px;
background-color: transparent;
}
h4 {
font-size: x-large;
font-weight: bold;
display: inline-block;
margin: 0px 0px;
}
}
.planning {
.activity {
padding: 8px 18px;
padding-top: 8px;
padding-bottom: 12px;
border-left: none;
border-right: 6px solid $main_soft_color;
&.inverted {
border-left: 6px solid $main_soft_color;
border-right: none;
}
.activity-title {
font-size: large;
}
}
}
.glyphicon {
&.yes {
color:$yes_color!important;
}
&.no {
color:$no_color!important;
}
&.dunno {
color:$dunno_color!important;
}
}
*/

View file

@ -18,6 +18,10 @@ $btn-bg-special: $main_soft_color;
$btn-border: $main_bold_color;
$underline-brand: $second_soft_color;
$yes_color: #55C487;
$no_color: #E36268;
$dunno_color: #5599C4;
/* FONTS */
$font_brand:'Lily Script One', cursive;
$font_nav:'Work Sans', cursive;

View file

@ -0,0 +1,19 @@
jQuery(document).ready(function() {
/* VARIABLE */
var coll = $('.collapsible');
var i;
/* EVENTS */
coll.click(function() {
$(this).toggleClass('active');
$content = $(this).next();
$content.slideToggle(200, function () {});
});
/* INIT */
coll.each(function() {
if ($(this).is('.active')) {
$content = $(this).next();
$content.slideToggle(10, function () {});
}
});
});

View file

@ -78,6 +78,7 @@
{# Global javascript #}
<script src="{% static "js/jquery-3.2.1.min.js" %}" type="text/javascript"></script>
<script src="{% static "js/bootstrap.min.js" %}" type="text/javascript"></script>
<script src="{% static "js/global.js" %}" type="text/javascript"></script>
{% block extra_js %}
{# Override this in templates to add extra javascript #}

View file

@ -22,6 +22,15 @@
</a>
{% endif %}
</div>
<h2>Sur le feu</h2>
<div class="module-list">
{% for event in events %}
<a href="{% url 'event:event' event.slug %}" class="module">
<span class="glyphicon glyphicon-calendar"></span>
{{ event }}
</a>
{% endfor %}
</div>
<h2>Outil en construction</h2>
<div class="container-fluid">

View file

@ -1,5 +1,13 @@
from django.views.generic import TemplateView
from django.utils import timezone
from event.models import Event
class Home(TemplateView):
template_name = "shared/home.html"
def get_context_data(self):
context = super().get_context_data()
context['events'] = Event.objects.filter(ending_date__gte=timezone.now()).order_by('beginning_date')
return context