Compare commits

..

No commits in common. "master" and "Evarin/fix-inventaire" have entirely different histories.

106 changed files with 451 additions and 8780 deletions

4
.gitignore vendored
View file

@ -1,8 +1,8 @@
.vagrant/
__pycache__
venv
poulpe/settings.py
evenementiel/settings.py
.*.swp
*.pyc
*.sqlite3
*.scssc
.*..sass-cache/*

View file

@ -20,10 +20,7 @@ class Subscription(models.Model):
class UserSubscription(Subscription):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
)
user = models.ForeignKey(User)
is_unsub = models.BooleanField(
_("désinscription"),
default=False
@ -35,10 +32,7 @@ class UserSubscription(Subscription):
class GroupSubscription(Subscription):
group = models.ForeignKey(
Group,
on_delete=models.CASCADE,
)
group = models.ForeignKey(Group)
class Meta:
verbose_name = _("souscription en groupe")

View file

@ -1,9 +1,10 @@
from django.contrib import admin
from django import forms
from .models import Equipment, EquipmentDefault, EquipmentRevision, EquipmentCategory, EquipmentLost, EquipmentAttributeValue, EquipmentAttribute, EquipmentStorage
from .models import Equipment, EquipmentRemark, EquipmentRevision, EquipmentOwner, EquipmentPole, EquipmentCategory
from .fields import IdField, IdWidget
from shared.admin import admin_site
class IdForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
@ -11,8 +12,6 @@ class IdForm(forms.ModelForm):
kwargs.pop('min_value')
if 'num_choices' in kwargs:
num_choices = kwargs.pop('num_choices')
else:
num_choices = None
super(IdForm, self).__init__(*args, **kwargs)
for field in self.instance._meta.fields:
@ -24,7 +23,6 @@ class IdForm(forms.ModelForm):
self.fields[field.name].choices = choices
self.fields[field.name].widget = IdWidget(choices=self.fields[field.name].choices)
class IdFormset(forms.models.BaseInlineFormSet):
def get_form_kwargs(self, index):
kwargs = super().get_form_kwargs(index)
@ -38,96 +36,26 @@ class EquipmentRevisionExtraInline(admin.TabularInline):
extra = 0
form = IdForm
formset = IdFormset
classes = ['collapse']
class EquipmentDefaultExtraInline(admin.TabularInline):
model = EquipmentDefault
class EquipmentRemarkExtraInline(admin.TabularInline):
model = EquipmentRemark
extra = 0
form = IdForm
formset = IdFormset
classes = ['collapse']
class EquipmentLostExtraInline(admin.TabularInline):
model = EquipmentLost
extra = 0
form = IdForm
formset = IdFormset
classes = ['collapse']
class EquipmentAttributeValueInline(admin.TabularInline):
model = EquipmentAttributeValue
extra = 0
class CategoryAdmin(admin.ModelAdmin):
readonly_fields = ['full_name_p']
list_display = ['name', 'parent', "full_name_p"]
ordering = ['name', 'parent']
search_fields = ['name',]
autocomplete_fields = ['parent', ]
class StorageAdmin(admin.ModelAdmin):
class CharFieldModelAdmin(admin.ModelAdmin):
list_display = ['name']
ordering = ['name']
search_fields = ['name']
class EquipmentAttributeAdmin(admin.ModelAdmin):
list_display = ['name']
ordering = ['name']
search_fields = ['name',]
class EquipmentAdmin(admin.ModelAdmin):
save_as_continue = True
save_on_top = True
autocomplete_fields = ['category', 'storage', ]
readonly_fields = ['full_category_p',
'added_at',
'modified_at',
'stock_aviable_p',
'ids_aviable_p',
'stock_lost_p',
'ids_lost_p',
]
list_display = ['name', 'stock', 'owner', 'category', 'storage', 'modified_at']
fieldsets = (
('Général', {
'fields': ('name', 'owner', 'stock', )
}),
('Info stock',
{
'fields': (
'stock_aviable_p',
'ids_aviable_p',
'stock_lost_p',
'ids_lost_p',
),
}),
('Attributs', {
'fields': ('category', 'full_category_p', 'storage'),
}),
('Description', {
'fields': ('description', 'added_at', 'modified_at',),
}),
)
ordering = ['name', 'owner', 'category']
inlines = [EquipmentAttributeValueInline,
EquipmentDefaultExtraInline,
EquipmentLostExtraInline,
EquipmentRevisionExtraInline]
search_fields = ['name', 'description',]
list_filter = ['owner', 'category', 'storage', ]
list_display = ['name', 'stock']
ordering = ['name']
inlines = [EquipmentRemarkExtraInline, EquipmentRevisionExtraInline]
admin_site.register(Equipment, EquipmentAdmin)
admin_site.register(EquipmentOwner, CharFieldModelAdmin)
admin_site.register(EquipmentPole, CharFieldModelAdmin)
admin_site.register(EquipmentCategory, CharFieldModelAdmin)
admin.site.register(Equipment, EquipmentAdmin)
admin.site.register(EquipmentCategory, CategoryAdmin)
admin.site.register(EquipmentStorage, StorageAdmin)
admin.site.register(EquipmentAttribute, EquipmentAttributeAdmin)

View file

@ -37,7 +37,7 @@ class IdField(models.BigIntegerField):
k += 1
return res
def from_db_value(self, value, expression, connection):
def from_db_value(self, value, expression, connection, context):
if value is None:
return value
return self.parse_integer(value)

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-06 17:29
# Generated by Django 1.11.11 on 2018-08-06 15:04
from __future__ import unicode_literals
import datetime
@ -51,8 +51,8 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=200, verbose_name='nom')),
],
options={
'verbose_name': 'catégories',
'verbose_name_plural': 'catégories',
'verbose_name': 'pôle',
'verbose_name_plural': 'pôles',
},
),
migrations.CreateModel(
@ -73,8 +73,8 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=200, verbose_name='nom')),
],
options={
'verbose_name': 'pôle',
'verbose_name_plural': 'pôle',
'verbose_name': 'catégorie',
'verbose_name_plural': 'catégories',
},
),
migrations.CreateModel(

View file

@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-07 16:58
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
import django.db.models.deletion
import equipment.fields
class Migration(migrations.Migration):
dependencies = [
('equipment', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='EquipmentDefault',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('remark', models.TextField(verbose_name='remarque sur le défaut')),
('ids', equipment.fields.IdField()),
('is_unusable', models.BooleanField(verbose_name='inutilisable')),
('send_repare', models.BooleanField(verbose_name='à envoyer réparareur')),
('equipment', models.ForeignKey(help_text='Matériel concerné par le defaut', on_delete=django.db.models.deletion.CASCADE, related_name='remarks', to='equipment.Equipment')),
],
options={
'verbose_name': 'defaut matériel',
'verbose_name_plural': 'défauts sur le matériel',
},
),
migrations.CreateModel(
name='EquipmentLost',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lost_at', models.DateField(default=datetime.date.today, verbose_name='perdu le')),
('ids', equipment.fields.IdField()),
('equipment', models.ForeignKey(help_text='Matériel concerné par la perte', on_delete=django.db.models.deletion.CASCADE, related_name='losts', to='equipment.Equipment')),
],
),
migrations.RemoveField(
model_name='equipmentremark',
name='equipment',
),
migrations.DeleteModel(
name='EquipmentRemark',
),
]

View file

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-07 18:43
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('equipment', '0002_auto_20180807_1658'),
]
operations = [
migrations.RemoveField(
model_name='equipment',
name='owner',
),
migrations.DeleteModel(
name='EquipmentOwner',
),
]

View file

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-07 18:44
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0008_alter_user_username_max_length'),
('equipment', '0003_auto_20180807_1843'),
]
operations = [
migrations.AddField(
model_name='equipment',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
),
]

View file

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-08 10:13
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0004_equipment_owner'),
]
operations = [
migrations.RemoveField(
model_name='equipment',
name='pole',
),
migrations.AddField(
model_name='equipmentcategory',
name='parent',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='equipment.EquipmentCategory'),
),
migrations.DeleteModel(
name='EquipmentPole',
),
]

View file

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-08 13:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0005_auto_20180808_1013'),
]
operations = [
migrations.AlterField(
model_name='equipmentcategory',
name='parent',
field=models.ForeignKey(blank=True, default=None, help_text='merci de ne pas faire de référence cyclique', null=True, on_delete=django.db.models.deletion.CASCADE, to='equipment.EquipmentCategory'),
),
]

View file

@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-08 14:40
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0006_auto_20180808_1354'),
]
operations = [
migrations.CreateModel(
name='EquipmentAttribute',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200, unique=True, verbose_name='nom')),
],
options={
'verbose_name': 'attribut',
'verbose_name_plural': 'attributs',
},
),
migrations.CreateModel(
name='EquipmentAttributeValue',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('value', models.CharField(max_length=200, verbose_name='valeur')),
('attribute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='equipment.EquipmentAttribute')),
('equipment', models.ForeignKey(help_text='Matériel concerné par le defaut', on_delete=django.db.models.deletion.CASCADE, related_name='attributes', to='equipment.Equipment')),
],
options={
'verbose_name': 'attribut de matériel',
'verbose_name_plural': 'attributs de matériel',
},
),
]

View file

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-08 14:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0007_equipmentattribute_equipmentattributevalue'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='equipment.EquipmentCategory'),
),
]

View file

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-09 12:00
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('equipment', '0008_auto_20180808_1454'),
]
operations = [
migrations.AddField(
model_name='equipment',
name='added_at',
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2018, 8, 9, 12, 0, 50, 140250, tzinfo=utc), verbose_name='ajouté le'),
preserve_default=False,
),
migrations.AddField(
model_name='equipment',
name='modified_at',
field=models.DateTimeField(auto_now=True, verbose_name='dernière modification'),
),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-09 12:11
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('equipment', '0009_auto_20180809_1200'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='stock',
field=models.PositiveSmallIntegerField(verbose_name='quantité totale'),
),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-09 14:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('equipment', '0010_auto_20180809_1211'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='description',
field=models.TextField(blank=True, verbose_name='description'),
),
]

View file

@ -1,61 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-20 11:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0011_auto_20180809_1405'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='equipment.EquipmentCategory', verbose_name='catégorie'),
),
migrations.AlterField(
model_name='equipment',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.Group', verbose_name='propriétaire'),
),
migrations.AlterField(
model_name='equipmentattributevalue',
name='attribute',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='equipment.EquipmentAttribute', verbose_name='attribut'),
),
migrations.AlterField(
model_name='equipmentattributevalue',
name='equipment',
field=models.ForeignKey(help_text='Matériel concerné par le defaut', on_delete=django.db.models.deletion.CASCADE, related_name='attributes', to='equipment.Equipment', verbose_name='matériel'),
),
migrations.AlterField(
model_name='equipmentattribution',
name='equipment',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='equipment.Equipment', verbose_name='matériel'),
),
migrations.AlterField(
model_name='equipmentcategory',
name='parent',
field=models.ForeignKey(blank=True, default=None, help_text='merci de ne pas faire de référence cyclique', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='equipment.EquipmentCategory', verbose_name='parent'),
),
migrations.AlterField(
model_name='equipmentdefault',
name='equipment',
field=models.ForeignKey(help_text='Matériel concerné par le defaut', on_delete=django.db.models.deletion.CASCADE, related_name='remarks', to='equipment.Equipment', verbose_name='matériel'),
),
migrations.AlterField(
model_name='equipmentlost',
name='equipment',
field=models.ForeignKey(help_text='Matériel concerné par la perte', on_delete=django.db.models.deletion.CASCADE, related_name='losts', to='equipment.Equipment', verbose_name='matériel'),
),
migrations.AlterField(
model_name='equipmentrevision',
name='equipment',
field=models.ForeignKey(help_text='Matériel concerné par les révisions', on_delete=django.db.models.deletion.CASCADE, related_name='revisions', to='equipment.Equipment', verbose_name='matériel'),
),
]

View file

@ -1,20 +0,0 @@
# -*- 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

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-26 22:05
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0013_auto_20180826_1949'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='auth.Group', verbose_name='propriétaire'),
),
migrations.AlterField(
model_name='equipmentcategory',
name='parent',
field=models.ForeignKey(blank=True, default=None, help_text='merci de ne pas faire de référence cyclique', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='equipment.EquipmentCategory', verbose_name='parent'),
),
]

View file

@ -1,26 +0,0 @@
# Generated by Django 2.1.5 on 2019-03-18 11:45
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('equipment', '0014_auto_20180827_0005'),
]
operations = [
migrations.CreateModel(
name='EquipmentStorage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200, verbose_name='nom')),
],
),
migrations.AddField(
model_name='equipment',
name='storage',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='equipment.EquipmentStorage', verbose_name='stockage'),
),
]

View file

@ -1,17 +0,0 @@
# Generated by Django 2.1.5 on 2019-03-18 11:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('equipment', '0015_auto_20190318_1245'),
]
operations = [
migrations.AlterModelOptions(
name='equipmentstorage',
options={'verbose_name': 'stockage', 'verbose_name_plural': 'stockages'},
),
]

View file

@ -1,24 +1,37 @@
from django.db import models
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Group
from event.models import Activity, EventSpecificMixin
from django.db.models import Q
from .fields import IdField
from taggit.managers import TaggableManager
from datetime import date
class EquipmentStorage(models.Model):
class EquipmentOwner(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
)
class Meta:
verbose_name = _("stockage")
verbose_name_plural = _("stockages")
verbose_name = _("propriétaire de matériel")
verbose_name_plural = _("propriétaires de matériel")
def __str__(self):
return self.name
class EquipmentPole(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
)
class Meta:
verbose_name = _("catégorie")
verbose_name_plural = _("catégories")
def __str__(self):
return self.name
@ -29,169 +42,38 @@ class EquipmentCategory(models.Model):
_("nom"),
max_length=200,
)
parent = models.ForeignKey(
'self',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
related_name="children",
help_text=_("merci de ne pas faire de référence cyclique"),
verbose_name=_("parent"),
)
def has_parent(self, cat):
current = self
for k in range(100):
if current is None:
return False
if current == cat:
return True
current = current.parent
def full_name(self):
current = self
res = ""
for k in range(100):
res = "/{current}{old}".format(
current=current.name,
old=res)
if current.parent is None:
break
current = current.parent
return res
full_name.short_description = _("Chemin complet")
full_name_p = property(full_name)
class Meta:
verbose_name = _("catégories")
verbose_name_plural = _("catégories")
verbose_name = _("pôle")
verbose_name_plural = _("pôles")
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if self.pk:
done = False
current = self
while not done:
if current.parent == self:
self.parent = None
done = True
elif current.parent is None:
done = True
current = current.parent
return super().save(*args, **kwargs)
class EquipmentQuerySet(models.QuerySet):
def in_category(self, cat):
filtre = Q(id__lt=0)
childs_id = [c.id for c in EquipmentCategory.objects.all()
if c.has_parent(cat)]
for pk in childs_id:
filtre |= Q(category__id=pk)
return self.filter(filtre)
class Equipment(EventSpecificMixin, models.Model):
name = models.CharField(
_("nom du matériel"),
max_length=200,
)
stock = models.PositiveSmallIntegerField(_("quantité totale"))
description = models.TextField(
_("description"),
blank=True,
)
stock = models.PositiveSmallIntegerField(_("quantité disponible"))
description = models.TextField(_("description"))
activities = models.ManyToManyField(
Activity,
related_name="equipment",
through="EquipmentAttribution",
)
owner = models.ForeignKey(
Group,
verbose_name=_("propriétaire"),
EquipmentOwner,
blank=True,
null=True,
on_delete=models.SET_NULL,
)
pole = models.ForeignKey(
EquipmentPole,
)
category = models.ForeignKey(
EquipmentCategory,
verbose_name=_("catégorie"),
on_delete=models.PROTECT,
)
storage = models.ForeignKey(
EquipmentStorage,
blank=True,
null=True,
default=None,
verbose_name=_("stockage"),
on_delete=models.PROTECT,
)
added_at = models.DateTimeField(
_("ajouté le"),
auto_now_add=True,
)
modified_at = models.DateTimeField(
_("dernière modification"),
auto_now=True,
)
objects = EquipmentQuerySet.as_manager()
def is_in_category(self, cat):
current = self.category
for k in range(100):
if current is None:
return False
if current == cat:
return True
current = current.parent
def ids_aviable(self):
if self.stock is None:
return []
res = list(map(lambda x: x+1, range(self.stock)))
for lost in self.losts.all():
res = [x
for x in res
if x not in lost.ids]
# TODO cassé
# TODO utilisés
return res
def ids_lost(self):
res = []
for lost in self.losts.all():
res = res + [x
for x in lost.ids
if x not in res]
return res
def stock_aviable(self):
aviable = self.ids_aviable()
return len(aviable)
def stock_lost(self):
return len(self.ids_lost())
def full_category(self):
return self.category.full_name()
full_category.short_description = _("Chemin complet")
ids_aviable.short_description = _("disponibles")
ids_lost.short_description = _("perdus")
stock_aviable.short_description = _("quantité disponible")
stock_lost.short_description = _("quantité perdue")
full_category_p = property(full_category)
ids_aviable_p = property(ids_aviable)
ids_lost_p = property(ids_lost)
stock_aviable_p = property(stock_aviable)
stock_lost_p = property(stock_lost)
class Meta:
verbose_name = _("matériel")
@ -201,63 +83,11 @@ class Equipment(EventSpecificMixin, models.Model):
return self.name
class EquipmentAttribute(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
unique=True,
)
class Meta:
verbose_name = _("attribut")
verbose_name_plural = _("attributs")
def __str__(self):
return self.name
class EquipmentAttributeValue(models.Model):
equipment = models.ForeignKey(
Equipment,
on_delete=models.CASCADE,
related_name="attributes",
verbose_name=_("matériel"),
help_text=_("Matériel concerné par le defaut"),
)
attribute = models.ForeignKey(
EquipmentAttribute,
verbose_name=_("attribut"),
on_delete=models.CASCADE,
)
value = models.CharField(
_("valeur"),
max_length=200,
)
class Meta:
verbose_name = _("attribut de matériel")
verbose_name_plural = _("attributs de matériel")
def __str__(self):
return "{attr}={value}".format(attr=self.attribute.name,
value=self.value)
class EquipmentAttribution(models.Model):
equipment = models.ForeignKey(
Equipment,
verbose_name=_("matériel"),
on_delete=models.CASCADE,
)
activity = models.ForeignKey(
Activity,
on_delete=models.CASCADE,
)
equipment = models.ForeignKey(Equipment)
activity = models.ForeignKey(Activity)
amount = models.BigIntegerField(_("quantité attribuée"))
remarks = models.TextField(
_("remarques concernant l'attribution"),
blank=True,
)
remarks = models.TextField(_("remarques concernant l'attribution"))
class Meta:
verbose_name = _("attribution de matériel")
@ -265,54 +95,36 @@ class EquipmentAttribution(models.Model):
def __str__(self):
return "%s (%d) -> %s" % (self.equipment.name,
self.amount,
self.amout,
self.activity.get_herited('title'))
def save(self, *args, **kwargs):
if (self.equipment.event
and self.equipment.event != self.activity.event):
if self.equipment.event and self.equipment.event != self.activity.event:
raise ValidationError
super(EquipmentAttribution, self).save(*args, **kwargs)
class EquipmentDefault(models.Model):
remark = models.TextField(_("remarque sur le défaut"))
class EquipmentRemark(models.Model):
remark = models.TextField(_("remarque sur le matériel"))
equipment = models.ForeignKey(
Equipment,
verbose_name=_("matériel"),
on_delete=models.CASCADE,
related_name="remarks",
help_text=_("Matériel concerné par le defaut"),
help_text=_("Matériel concerné par la remarque"),
)
ids = IdField()
is_unusable = models.BooleanField(_("inutilisable"))
send_repare = models.BooleanField(_("à envoyer réparareur"))
is_broken = models.BooleanField()
is_lost = models.BooleanField()
class Meta:
verbose_name = _("defaut matériel")
verbose_name_plural = _("défauts sur le matériel")
verbose_name = _("remarque sur matériel")
verbose_name_plural = _("remarques sur le matériel")
def __str__(self):
return "%s : %s" % (self.equipment.name,
self.remark)
class EquipmentLost(models.Model):
lost_at = models.DateField(
_("perdu le"),
default=date.today,
)
equipment = models.ForeignKey(
Equipment,
verbose_name=_("matériel"),
on_delete=models.CASCADE,
related_name="losts",
help_text=_("Matériel concerné par la perte"),
)
ids = IdField()
class EquipmentRevision(models.Model):
date = models.DateField(
_("date"),
@ -320,8 +132,6 @@ class EquipmentRevision(models.Model):
)
equipment = models.ForeignKey(
Equipment,
verbose_name=_("matériel"),
on_delete=models.CASCADE,
related_name="revisions",
help_text=_("Matériel concerné par les révisions"),
)

View file

@ -1,109 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Group
from django.db.models import Q
from django.http.request import QueryDict
import django_filters
from django_filters.widgets import LinkWidget
from django_tables2.utils import A
import django_tables2 as tables
from .models import Equipment, EquipmentCategory
class EquipmentFilter(django_filters.FilterSet):
owner = django_filters.ModelChoiceFilter(
field_name='owner',
queryset=Group.objects.all(),
widget=LinkWidget(),
)
category = django_filters.ModelChoiceFilter(
field_name='category',
queryset=EquipmentCategory.objects.all(),
widget=LinkWidget(),
method='filter_category',
)
def filter_category(self, queryset, name, value):
return queryset.in_category(value)
def get_categories(self, qs):
"""
rend les catégories qui servent à filtrer les Equipments de qs
ie les catégories des equipments et tous leurs parents
"""
filtre = Q(id__lt=0)
for eq in qs:
current = eq.category
for k in range(100):
if current is None:
break
filtre |= Q(id=current.id)
current = current.parent
return EquipmentCategory.objects.filter(filtre)
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
# On que les requêtes vides rendent quelque chose
if data is None:
data = QueryDict('category&owner')
super().__init__(data=data, queryset=queryset,
request=request, prefix=prefix)
if self.queryset is not None:
for filter_ in self.filters.values():
if filter_.queryset.model == Group:
own_ids = [eq.owner.id for eq in self.queryset
if eq.owner is not None]
filtre = Q(id__lt=0)
for own_id in own_ids:
filtre |= Q(id=own_id)
filter_.queryset = Group.objects.filter(filtre)
if filter_.queryset.model == EquipmentCategory:
filter_.queryset = self.get_categories(self.queryset)
class Meta:
model = Equipment
fields = ['category', 'owner']
class AbstractEquipmentTable(tables.Table):
stock_aviable_p = tables.Column(
accessor=A('stock_aviable_p'),
orderable=False, # TODO le rendre ordorable
verbose_name=_("Quantité disponible"),
)
full_category_p = tables.Column(
accessor=A('full_category_p'),
order_by=('category'),
verbose_name=_("Catégorie"),
)
name = tables.LinkColumn(
'equipment:detail',
args=[A('pk')],
verbose_name=_("Matériel"),
)
admin = tables.LinkColumn(
'admin:equipment_equipment_change',
attrs={
'a': {'class': 'glyphicon glyphicon-cog'}
},
text="",
orderable=False,
args=[A('pk')],
verbose_name=_(""),
)
def before_render(self, request):
if (request.user.is_staff and
request.user.has_perm('equipment_change_equipment')):
self.columns.show('admin')
else:
self.columns.hide('admin')
class EquipmentTable(AbstractEquipmentTable):
class Meta:
model = Equipment
template_name = 'equipment/tables/bootstrap-responsive.html'
fields = ['name', 'stock', 'owner', ]
sequence = ['admin', 'name', 'stock', 'stock_aviable_p',
'full_category_p', 'owner', ]

View file

@ -1,13 +0,0 @@
{% extends "shared/base.html" %}
{% load i18n staticfiles %}
{% block title %}{% trans "Matériel" %}{% endblock %}
{% block content %}
<h2>{{ equipment.name }}<a class="pull-right glyphicon glyphicon-cog" href="{% url 'admin:equipment_equipment_change' equipment.id %}"></a></h2>
{% endblock %}
{% block aside %}
Coucou :)
{% endblock %}

View file

@ -1,50 +0,0 @@
{% extends "shared/base.html" %}
{% load i18n staticfiles %}
{% block title %}{% trans "Matériel" %}{% endblock %}
{% block content %}
<h1 class="equipment">{% trans "Inventaire" %}</h1>
<div class="module-list">
<a href="{% url 'equipment:list' %}" class="module equipment">
<span class="glyphicon glyphicon-list-alt"></span>
{% trans "Tout le matériel" %}
</a>
<a href="#TODO" class="module equipment">
<span class="glyphicon glyphicon-list-alt"></span>
{% trans "Disponible" %}
</a>
</div>
<h2 class="staff">{% trans "Liste par Propriétaire" %}</h2>
<div class="module-list">
{% for owner in owners %}
<a href="{% url 'equipment:list_by_owner' owner.id %}" class="module staff">
<span class="glyphicon glyphicon-user"></span>
{{ owner.name }}
</a>
{% endfor %}
</div>
<h2 class="equipment">{% trans "Liste par Catégorie" %}</h2>
<div class="tree">
<ul>
{% for node in root_cat %}
{% include "equipment/tree_cat.html" %}
{% endfor %}
</ul>
</div>
{% endblock %}
{% block aside %}
<div class="heading">
{{ nb_type }} <span class="sub">{% trans "référence" %}{{ nb_type|pluralize}}</span>
</div>
<div class="heading separator">
{{ stock }} <span class="sub">{% trans "item" %}{{ stock|pluralize}}</span>
</div>
<div class="heading inverted small">
{{ categories.count }} <span class="sub">{% trans "catégorie" %}{{ categories.count|pluralize}}</span>
</div>
<div class="heading inverted small ">
{{ owners.count }} <span class="sub">{% trans "propriéaire" %}{{ owners.count|pluralize}}</span>
</div>
{% endblock %}

View file

@ -1,30 +0,0 @@
{% extends "shared/base.html" %}
{% load render_table from django_tables2 %}
{% load bootstrap3 %}
{% load i18n staticfiles %}
{% block title %}{% trans "Matériel" %}{% endblock %}
{% block content %}
<h1 class="equipment">Inventaire</h1>
{% if subtitle %}
<h2 class="equipment">{{ subtitle }}</h2>
{% endif %}
{% render_table table %}
{% endblock %}
{% block aside %}
<div class="heading">
{{ nb_type }} <span class="sub">{% trans "référence" %}{{ nb_type|pluralize}}</span>
</div>
<div class="heading separator">
{{ stock }} <span class="sub">{% trans "item" %}{{ stock|pluralize}}</span>
</div>
{% if filter %}
<div class="text inverted">
<form id="filter_form" action="" method="get" class="form form-inline">
{% bootstrap_form filter.form layout='horizontal' size='lg' %}
</form>
</div>
{% endif %}
{% endblock %}

View file

@ -1,16 +0,0 @@
{% extends 'equipment/tables/bootstrap.html' %}
{% block table-wrapper %}
<div class="table-container table-responsive">
{% block table %}
{{ block.super }}
{% endblock table %}
{% if table.page and table.paginator.num_pages > 1 %}
{% block pagination %}
{{ block.super }}
{% endblock pagination %}
{% endif %}
</div>
{% endblock table-wrapper %}

View file

@ -1,103 +0,0 @@
{% load django_tables2 %}
{% load i18n %}
{% block table-wrapper %}
<div class="table-container">
{% block table %}
<table {% render_attrs table.attrs class="table table-striped" %}>
{% block table.thead %}
{% if table.show_header %}
<thead>
<tr>
{% for column in table.columns %}
<th {{ column.attrs.th.as_html }}>
{% if column.orderable %}
<a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header }}</a>
{% else %}
{{ column.header }}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
{% endif %}
{% endblock table.thead %}
{% block table.tbody %}
<tbody>
{% for row in table.paginated_rows %}
{% block table.tbody.row %}
<tr {{ row.attrs.as_html }}>
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
</tbody>
{% endblock table.tbody %}
{% block table.tfoot %}
{% if table.has_footer %}
<tfoot>
<tr>
{% for column in table.columns %}
<td {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
{% endfor %}
</tr>
</tfoot>
{% endif %}
{% endblock table.tfoot %}
</table>
{% endblock table %}
{% if table.page and table.paginator.num_pages > 1 %}
{% block pagination %}
<nav aria-label="Table navigation">
<ul class="pagination">
{% if table.page.has_previous %}
{% block pagination.previous %}
<li class="previous">
<a href="{% querystring table.prefixed_page_field=table.page.previous_page_number %}">
<span aria-hidden="true">&laquo;</span>
{% trans 'previous' %}
</a>
</li>
{% endblock pagination.previous %}
{% endif %}
{% if table.page.has_previous or table.page.has_next %}
{% block pagination.range %}
{% for p in table.page|table_page_range:table.paginator %}
<li {% if p == table.page.number %}class="active"{% endif %}>
{% if p == '...' %}
<a href="#">{{ p }}</a>
{% else %}
<a href="{% querystring table.prefixed_page_field=p %}">
{{ p }}
</a>
{% endif %}
</li>
{% endfor %}
{% endblock pagination.range %}
{% endif %}
{% if table.page.has_next %}
{% block pagination.next %}
<li class="next">
<a href="{% querystring table.prefixed_page_field=table.page.next_page_number %}">
{% trans 'next' %}
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% endblock pagination.next %}
{% endif %}
</ul>
</nav>
{% endblock pagination %}
{% endif %}
</div>
{% endblock table-wrapper %}

View file

@ -1,11 +0,0 @@
<li> <a href="{% url "equipment:list_by_category" node.id %}"><span class="category_node">{{node.name}}</span></a>
{%if node.children %}
<ul>
{%for ch in node.children.all %}
{%with node=ch template_name="equipment/tree_cat.html" %}
{%include template_name%}
{%endwith%}
{%endfor%}
</ul>
{%endif%}
</li>

View file

@ -1,11 +0,0 @@
from django.conf.urls import url
from .views import EquipmentList, EquipmentView, EquipmentListByCategory, EquipmentListByOwner, EquipmentHome
app_name = 'equipment'
urlpatterns = [
url(r'^$', EquipmentHome.as_view(), name='home'),
url(r'^all/$', EquipmentList.as_view(), name='list'),
url(r'^(?P<pk>[0-9]+)/$', EquipmentView.as_view(), name='detail'),
url(r'^c/(?P<pk>[0-9]+)/$', EquipmentListByCategory.as_view(), name='list_by_category'),
url(r'^o/(?P<pk>[0-9]+)/$', EquipmentListByOwner.as_view(), name='list_by_owner'),
]

View file

@ -1,97 +0,0 @@
from .models import Equipment, EquipmentCategory
from django.contrib.auth.models import Group
from django.db.models import Sum
from django.views.generic import DetailView, ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from django_filters.views import FilterView
from django_tables2.views import SingleTableMixin
from .tables import EquipmentTable, EquipmentFilter
class EquipmentHome(LoginRequiredMixin, ListView):
template_name = 'equipment/home.html'
context_object_name = 'categories'
model = EquipmentCategory
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# TODO remplacer par les vrais owners
context['owners'] = Group.objects.all()
categories = (EquipmentCategory.objects.order_by('name')
.prefetch_related('children'))
context['root_cat'] = categories.filter(parent=None)
queryset = Equipment.objects.all()
context['stock'] = queryset.aggregate(Sum('stock'))['stock__sum']
context['nb_type'] = queryset.count()
return context
class EquipmentListAbstract(LoginRequiredMixin, SingleTableMixin,FilterView):
table_class = EquipmentTable
filterset_class = EquipmentFilter
template_name = 'equipment/list.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['stock'] = self.queryset.aggregate(Sum('stock'))['stock__sum']
context['nb_type'] = self.queryset.count()
return context
class EquipmentList(EquipmentListAbstract):
def get_queryset(self):
self.queryset = Equipment.objects.all()
return self.queryset
class EquipmentListByCategory(EquipmentListAbstract):
def get_category(self):
try:
pk = self.kwargs.get('pk')
except KeyError:
raise AttributeError(
"View %s must be called with an object "
"pk in the URLconf." % self.__class__.__name__
)
return EquipmentCategory.objects.get(id=pk)
def get_queryset(self):
cat = self.get_category()
self.queryset = Equipment.objects.all().in_category(cat)
return self.queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
cat = self.get_category()
context['subtitle'] = "Dans {cat}".format(cat=cat.full_name())
return context
class EquipmentListByOwner(EquipmentListAbstract):
def get_owner(self):
try:
pk = self.kwargs.get('pk')
except KeyError:
raise AttributeError(
"View %s must be called with an object "
"pk in the URLconf." % self.__class__.__name__
)
return Group.objects.get(id=pk)
def get_queryset(self):
owner = self.get_owner()
self.queryset = Equipment.objects.filter(owner=owner)
return self.queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
owner = self.get_owner()
context['subtitle'] = "Matériel de {owner}".format(owner=owner)
return context
class EquipmentView(LoginRequiredMixin, DetailView):
model = Equipment
template_name = 'equipment/detail.html'

View file

@ -2,6 +2,6 @@ import os
from channels.asgi import get_channel_layer
if "DJANGO_SETTINGS_MODULE" not in os.environ:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "poulpe.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evenementiel.settings")
channel_layer = get_channel_layer()

View file

@ -10,7 +10,7 @@ We also load the secrets in this file.
import os
from . import secret
from django.urls import reverse_lazy
from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
@ -27,7 +27,6 @@ def import_secret(name):
SECRET_KEY = import_secret("SECRET_KEY")
ADMINS = import_secret("ADMINS")
SERVER_EMAIL = import_secret("SERVER_EMAIL")
DBNAME = import_secret("DBNAME")
DBUSER = import_secret("DBUSER")
@ -47,8 +46,7 @@ BASE_DIR = os.path.dirname(
INSTALLED_APPS = [
# 'shared.apps.CustomAdminConfig',
'django.contrib.admin',
'shared.apps.CustomAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
@ -57,13 +55,10 @@ INSTALLED_APPS = [
'django.contrib.sites',
# 'channels',
# 'rest_framework',
'rest_framework',
'bootstrapform',
'widget_tweaks',
'taggit',
'django_tables2',
'django_filters',
'bootstrap3',
'allauth_ens',
'allauth',
@ -71,8 +66,9 @@ INSTALLED_APPS = [
'allauth.socialaccount',
'allauth_cas',
'allauth_ens.providers.clipper',
# 'api',
'api',
'communication',
'equipment',
'event',
@ -80,13 +76,13 @@ INSTALLED_APPS = [
'users',
]
MIDDLEWARE = [
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
@ -99,7 +95,7 @@ REST_FRAMEWORK = {
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
}
ROOT_URLCONF = 'poulpe.urls'
ROOT_URLCONF = 'evenementiel.urls'
STATIC_URL = "/static/"
MEDIA_URL = "/media/"
@ -147,7 +143,7 @@ DATABASES = {
# port=REDIS_PORT, db=REDIS_DB)
# )],
# },
# "ROUTING": "poulpe.routing.channel_routing",
# "ROUTING": "evenementiel.routing.channel_routing",
# }
# }
@ -166,9 +162,9 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'fr-fr'
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Paris'
TIME_ZONE = 'UTC'
USE_I18N = True
@ -184,17 +180,16 @@ AUTHENTICATION_BACKENDS = (
SITE_ID = 1
CAS_SERVER_URL = "https://cas.eleves.ens.fr/" # SPI CAS
CAS_SERVER_URL = "https://cas.eleves.ens.fr/" #SPI CAS
CAS_VERIFY_URL = "https://cas.eleves.ens.fr/"
CAS_VERSION = "2"
CAS_IGNORE_REFERER = True
CAS_LOGIN_MSG = None
CAS_REDIRECT_URL = reverse_lazy('shared:home')
CAS_EMAIL_FORMAT = "%s@clipper.ens.fr"
CAS_FORCE_CHANGE_USERNAME_CASE = "lower"
CAS_VERSION = 'CAS_2_SAML_1_0'
LOGIN_URL = reverse_lazy('account_login')
LOGOUT_URL = reverse_lazy('account_logout')
LOGIN_URL = reverse_lazy('users:login')
LOGOUT_URL = reverse_lazy('users:logout')
LOGIN_REDIRECT_URL = reverse_lazy('shared:home')
ACCOUNT_HOME_URL = reverse_lazy('shared:home')
ACCOUNT_DETAILS_URL = reverse_lazy('shared:home')
@ -214,7 +209,7 @@ SOCIALACCOUNT_PROVIDERS = {
}
ACCOUNT_ADAPTER = 'shared.allauth_adapter.AccountAdapter'
#SOCIALACCOUNT_ADAPTER='allauth_ens.adapter.LongTermClipperAccountAdapter'
SOCIALACCOUNT_ADAPTER= 'shared.allauth_adapter.SocialAccountAdapter'
ACCOUNT_ADAPTER = 'shared.allauth_adapter.AccountAdapter'
SOCIALACCOUNT_ADAPTER = 'shared.allauth_adapter.SocialAccountAdapter'

View file

@ -11,12 +11,10 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
DEBUG = True
# Add some debugging tools
INSTALLED_APPS += ["debug_toolbar", ] # NOQA
MIDDLEWARE = (
[
"debug_toolbar.middleware.DebugToolbarMiddleware",
]
+ MIDDLEWARE # NOQA
INSTALLED_APPS += ["debug_toolbar", "debug_panel"] # NOQA
MIDDLEWARE_CLASSES = (
["debug_panel.middleware.DebugPanelMiddleware"]
+ MIDDLEWARE_CLASSES # NOQA
)

View file

@ -18,6 +18,6 @@ DATABASES = {
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgiref.inmemory.ChannelLayer",
"ROUTING": "poulpe.routing.channel_routing",
"ROUTING": "evenementiel.routing.channel_routing",
},
}

View file

@ -8,17 +8,18 @@ from django.contrib import admin
#from django_cas_ng import views as django_cas_views
from allauth_ens.views import capture_login, capture_logout
from shared.admin import admin_site
urlpatterns = [
url(r'^admin/login/$', capture_login),
url(r'^admin/logout/$', capture_logout),
url(r'^compte/', include('allauth.urls')),
# Admin
url(r'^admin/', admin.site.urls),
url(r'^admin/', admin_site.urls),
# Apps
url(r'^equipment/', include('equipment.urls')),
url(r'^event/', include('event.urls')),
#url(r'^user/', include('users.urls')),
url(r'^user/', include('users.urls')),
# REST
url(r'^api/', include('api.urls')),
# Reste

View file

@ -1,5 +1,5 @@
"""
WSGI config for GestionEvenementiel project.
WSGI config for evenementiel project.
It exposes the WSGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "poulpe.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evenementiel.settings")
application = get_wsgi_application()

View file

@ -1,97 +1,3 @@
from django.contrib import admin
from .models import Event, Place, ActivityTag, Activity, ActivityTemplate # TODO add me
from equipment.models import EquipmentAttribution
class EquipmentAttributionExtraInline(admin.TabularInline):
autocomplete_fields = ['equipment', ]
model = EquipmentAttribution
extra = 0
classes = ['collapse']
class EventAdmin(admin.ModelAdmin):
list_display = ['title', 'slug', 'beginning_date', 'ending_date']
readonly_fields = ['created_by', 'created_at', ]
ordering = ['title', 'beginning_date', 'ending_date', ]
search_fields = ['title', 'decription', ]
list_filter = ['beginning_date', 'ending_date', ]
date_hierarchy = 'beginning_date'
class PlaceAdmin(admin.ModelAdmin):
list_display = ['name', 'event', ]
ordering = ['name', 'event', ]
search_fields = ['name', ]
list_filter = ['event', ]
class ActivityTagAdmin(admin.ModelAdmin):
list_display = ['name', 'event', 'is_public', ]
ordering = ['name', 'event', 'is_public', ]
search_fields = ['name', ]
list_filter = ['event', 'is_public', ]
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', ]
list_filter = ['event', 'is_public', 'has_perm', 'tags', ]
filter_horizontal = ['tags', 'places', ]
fieldsets = (
('Identifiant', {
'fields': ('name', ),
}),
('Général', {
'fields': ('event', 'title', 'is_public', 'places', ),
'description': "Tous ces champs sont héritables (Sauf Évènement)",
}),
('Permanences', {
'fields': ('has_perm', ('min_perm', 'max_perm', ), ),
'classes': ('collapse',),
'description': "Tous ces champs sont héritables",
}),
('Descriptions', {
'fields': ('description', 'tags', 'remarks', ),
'classes': ('collapse',),
'description': "Tous ces champs sont héritables",
}),
)
class ActivityAdmin(admin.ModelAdmin):
save_as = 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', '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', ), 'staff', ),
'classes': ('wide',),
'description': "Tous ces champs sont héritables (sauf les gens en perm)",
}),
('Descriptions', {
'fields': ('description', 'tags', 'remarks', ),
'classes': ('collapse',),
'description': "Tous ces champs sont héritables",
}),
)
admin.site.register(Event, EventAdmin)
admin.site.register(Place, PlaceAdmin)
admin.site.register(ActivityTag, ActivityTagAdmin)
admin.site.register(ActivityTemplate, ActivityTemplateAdmin)
admin.site.register(Activity, ActivityAdmin)
# Register your models here.

View file

@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-20 15:29
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('event', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='activitytemplate',
name='name',
field=models.CharField(default='change_me!', help_text='Ne sera pas affiché', max_length=200, verbose_name='Nom du template'),
preserve_default=False,
),
migrations.AlterField(
model_name='activity',
name='event',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
),
migrations.AlterField(
model_name='activitytemplate',
name='event',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
),
]

View file

@ -1,5 +1,5 @@
from django.contrib.auth import get_user_model
from django.core.exceptions import FieldDoesNotExist, FieldError, ValidationError
from django.core.exceptions import FieldDoesNotExist, FieldError
from django.db import models
from django.utils.translation import ugettext_lazy as _
@ -123,6 +123,7 @@ class AbstractActivityTemplate(SubscriptionMixin, models.Model):
Event,
verbose_name=_("évènement"),
on_delete=models.CASCADE,
editable=False,
)
is_public = models.NullBooleanField(
_("est public"),
@ -166,34 +167,12 @@ class AbstractActivityTemplate(SubscriptionMixin, models.Model):
class ActivityTemplate(AbstractActivityTemplate):
name = models.CharField(
_("Nom du template"),
max_length=200,
help_text=_("Ne sera pas affiché"),
)
class Meta:
verbose_name = _("template activité")
verbose_name_plural = _("templates activité")
def __str__(self):
return self.name
def clean(self):
errors = []
# On clean les nombre de permanents
if not self.has_perm:
self.max_perm = None
self.min_perm = None
else:
if self.min_perm > self.max_perm:
errors.append(ValidationError(
_("Nombres de permanents incompatibles"),
code='wrong-nb-perm',
))
if errors != []:
raise ValidationError(errors)
return self.title
class Activity(AbstractActivityTemplate):
@ -214,86 +193,6 @@ class Activity(AbstractActivityTemplate):
beginning = models.DateTimeField(_("heure de début"))
end = models.DateTimeField(_("heure de fin"))
def clean(self):
errors = []
# On clean les nombre de permanents
if not self.get_herited('has_perm'):
self.max_perm = None
self.min_perm = None
else:
if self.get_herited('min_perm') > self.get_herited('max_perm'):
errors.append(ValidationError(
_("Nombres de permanents incompatibles"),
code='wrong-nb-perm',
))
# On valide l'héritage
for f in self._meta.get_fields():
try:
# On réccupère le field du parent
attrname = f.name
tpl_field = ActivityTemplate._meta.get_field(attrname)
# Peut-être que ce n'est pas un field
# concerné par l'héritage
except FieldDoesNotExist:
continue
# Y'a certains champs dont on se moque
if attrname in ['id', 'staff', 'tags', ]:
continue
# C'est plus compliqué que ça pour les nb_perm
if attrname in ['max_perm', 'min_perm', ]:
if not self.get_herited('has_perm'):
continue
# On a un Many to Many, on lit différement
if tpl_field.many_to_many:
pass
# # On a pas spécifié
# if not value.exists():
# # On a pas de parent
# if self.parent is None:
# errors.append(ValidationError(
# _("N'hérite pas d'un template, spécifier le champs : %(attr)s"),
# code='bad-overriding',
# params={'attr': f.verbose_name},
# ))
# else:
# pvalue = getattr(self.parent, attrname)
# # On a un parent qui ne dit rien
# if not pvalue.exists():
# errors.append(ValidationError(
# _("Champs non précisé chez le parent, spécifier : %(attr)s"),
# code='bad-overriding',
# params={'attr': f.verbose_name},
# ))
else:
value = getattr(self, attrname)
# On a pas spécifié
if value is None:
# On a pas de parent
if self.parent is None:
errors.append(ValidationError(
_("N'hérite pas d'un template, spécifier le champs : %(attr)s"),
code='bad-overriding',
params={'attr': f.verbose_name},
))
else:
pvalue = getattr(self.parent, attrname)
# On a un parent qui ne dit rien
if pvalue is None:
errors.append(ValidationError(
_("Champs non précisé chez le parent, spécifier : %(attr)s"),
code='bad-overriding',
params={'attr': f.verbose_name},
))
if errors != []:
raise ValidationError(errors)
def get_herited(self, attrname):
try:
tpl_field = ActivityTemplate._meta.get_field(attrname)
@ -308,9 +207,9 @@ class Activity(AbstractActivityTemplate):
if tpl_field.many_to_many:
if value.exists():
return value
elif self.parent is not None:
else:
return getattr(self.parent, attrname)
elif value is None and self.parent is not None:
elif value is None:
return getattr(self.parent, attrname)
else:
return value
@ -320,4 +219,4 @@ class Activity(AbstractActivityTemplate):
verbose_name_plural = _("activités")
def __str__(self):
return self.get_herited('title')
return self.get_herited('title')

View file

@ -1,373 +0,0 @@
/* Calendar */
#cal-container {
width: 100%;
height: 100%;
padding: 0;
min-height: 80vh;
display: block;
position: relative;
line-height: 100%;
}
#cal-container,
#cal-container * {
box-sizing: border-box;
}
/* Time slots */
#cal-container .cal-time-slot-container {
display: grid;
grid-template-rows: 30px auto;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100% + 30px + 10px);
padding: 0;
z-index: 10;
}
#cal-container .cal-time-slot {
border-right: 1px solid #EEE;
background-color: #FAFAFA;
}
#cal-container .cal-time-slot:nth-child(even) {
background-color: #F4F4F4;
}
#cal-container .cal-time-slot:last-child {
border-right: 0;
}
#cal-container .cal-time-slot-hour {
padding: 0 0 0 calc(100% - 1.4rem + 7px);
background-color: #F9F9F9;/* #3D3D3D; */
border-bottom: 1px solid #AAA;
color: #333;
font-size: 1.4rem;
line-height: 30px;
vertical-align: middle;
}
#cal-container .cal-time-slot-hour:nth-child(even) {
background-color: #FCFCFC;/* #464646; */
}
#cal-container .cal-time-slot-hour:first-child {
color: transparent;
border-right: 0;
}
#cal-container .cal-time-slot-hour.cal-last-hour {
padding: 0;
color: transparent;
}
#cal-container .cal-time-slot.cal-last-hour,
#cal-container .cal-time-slot-hour.cal-last-hour {
border-right: 1px solid #AAA;
}
#cal-container .cal-time-slot.cal-first-hour,
#cal-container .cal-time-slot-hour.cal-first-hour {
border-left: 1px solid #AAA;
}
/* Events */
#cal-container .cal-event-container {
display: grid;
/* grid-template-columns: repeat(24, 1fr); */
/* grid-template-rows: repeat(12, auto); */
position: absolute;
top: 40px;
left: 0;
width: 100%;
height: 100%;
padding: 0;
z-index: 100;
}
#cal-container .cal-event {
position: relative;
height: 80px;
margin: 2px 0;
/* padding: 5px; */
/* background-color: #EFEFEF; */
border-radius: 3px;
/* border: 1px solid #CCC; */
border-width: 1px;
border-style: solid;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* z-index: 500; */
transition: 50ms ease-in;
}
#cal-container .cal-event:hover {
/* background-color: #FEDDDD; */
}
#cal-container .cal-event > * {
display: none;
margin: 5px;
}
#cal-container .cal-event > .cal-event-name,
#cal-container .cal-event > .cal-event-location,
#cal-container .cal-event > .cal-event-perm-count {
display: block;
}
#cal-container .cal-event > .cal-event-name {
font-weight: bold;
}
#cal-container .cal-event > .cal-event-location {
font-style: italic;
}
#cal-container .cal-event > .cal-event-perm-count {
position: absolute;
bottom: 0;
right: 0;
}
#cal-container .cal-event:not(.cal-event-subscribed) > .cal-event-perm-count.cal-perms-missing {
width: calc(100% - 10px);
right: auto;
margin: 5px;
padding: 5px;
background-color: #FFF;
border: 2px solid #E44;
color: #E44;
font-weight: bold;
border-radius: 3px;
overflow: hidden;
}
#cal-container .cal-event.cal-event-subscribed {
border-width: 3px;
border-color: #000;
}
#cal-container .cal-event.cal-event-subscribed::after {
content: "✔";
position: absolute;
left: 0;
bottom: 0;
width: 16px;
height: 16px;
padding: 1px;
color: #fff;
background-color: #000;
border-top-right-radius: 3px;
}
/* Event details popup */
#cal-container .cal-event-details {
position: absolute;
min-height: 100px;
/* min-width: 40%; */
max-width: 80%;
padding: 20px;
background-color: #333;
color: #FFF;
border-radius: 4px;
box-shadow: 0 15px 50px rgba(0, 0, 0, 0.6);
z-index: 1000;
}
#cal-container .cal-event-details:after {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-bottom-color: #333;
border-width: 20px;
margin-left: -20px;
}
#cal-container .cal-event-details.above-event:after {
top: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-top-color: #333;
border-width: 20px;
margin-left: -20px;
}
#cal-container .cal-event-details * {
z-index: 1000;
}
#cal-container .cal-event-details .cal-detail-close-button {
width: 35px;
height: 35px;
position: absolute;
top: 10px;
right: 10px;
margin: 0;
padding: 5px;
background: transparent;
border: none;
border-radius: 50%;
font-size: 1.6rem;
color: #BBB;
transition: 100ms ease-out;
}
#cal-container .cal-event-details .cal-detail-close-button:hover {
background-color: #484848;
color: #EFEFEF;
}
#cal-container .cal-event-details a,
#cal-container .cal-event-details a:hover {
color: #FFF;
text-decoration: none;
}
#cal-container .cal-event-details .cal-detail-name > h3 {
margin: 0 0 25px 26px;
padding: 10px;
border-radius: 4px;
color: #FFF;
font-size: 2.5rem;
text-transform: uppercase;
text-align: center;
}
#cal-container .cal-event-details .cal-detail-name > h3::after {
content: "";
display: inline-block;
width: 16px;
height: 16px;
margin: 0 0 0 10px;
vertical-align: middle;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA90lEQVQoz2WRsS6DURiGn/yaaNqBySpGicFg6iJcAYuuNBaJpJEg6gLcADFIdWR0BZZKS4SBRTe3YFf/Y/j/c3LUe4Zz3vd78+U734uUJ7Ptg7k68NDpoIdyU9V3TzzwRdXt1HCq9pwR510W616oZ8Gwoe6KWFN1ScStogui3sRJ9uxYLd/n6hTuaCy3XHfNWuR6hM+OojBQdSXyJ0cZizwSsMo3kEc+ZCEjxZgxE8j4oBFZhRww8gaff4fEL3UuGfK4uG5L4VLVfvrNCrDJHfd0gSrXQB2AJvu0+Cm8HbXnbGw9seqwWH2z65Wv/8MKcfdVHaZx/wKtOg5kifzQhwAAAABJRU5ErkJggg==);
opacity: 0.6;
}
#cal-container .cal-event-details .cal-detail-name:hover > h3 {
margin-right: 26px;
margin-bottom: 10px;
background-color: #484848;
color: #FFF;
}
#cal-container .cal-event-details .cal-detail-name:hover > h3::after {
content: "Cliquez pour afficher les détails.";
display: block;
width: auto;
height: 15px;
padding: 2px 0 0 0;
font-size: 1.2rem;
background-image: none;
color: #DDD;
}
#cal-container .cal-event-details .cal-detail-name:hover + .cal-detail-close-button {
opacity: 0;
}
#cal-container .cal-event-details table {
margin: 0 auto;
font-size: 1.8rem;
}
#cal-container .cal-event-details td.cal-detail-label {
padding: 0 10px 10px 0;
font-weight: bold;
text-align: right;
}
#cal-container .cal-event-details td.cal-detail-value {
padding: 0 0 10px 10px;
text-align: left;
}
#cal-container .cal-event-details .cal-detail-perm-area {
margin: 10px 0;
padding: 10px;
background-color: #DFDFDF;
color: #333;
text-align: center;
border-radius: 4px;
}
#cal-container .cal-event-details .cal-detail-perm-title {
display: block;
margin: 0 0 10px 0;
}
#cal-container .cal-event-details .cal-detail-perm-area .cal-detail-perm-count {
margin: 0 10px 0 0;
font-size: 2.5rem;
vertical-align: middle;
}
#cal-container .cal-event-details .cal-detail-perm-area .cal-detail-perm-count.cal-perms-missing {
color: #E44;
}
#cal-container .cal-event-details .cal-detail-perm-area .cal-detail-perm-count.cal-perms-full {
color: #393;
}
#cal-container .cal-event-details .cal-detail-perm-area .cal-detail-perm-subscription-switch {
margin: 0 0 0 10px;
padding: 10px;
font-size: 1.8rem;
vertical-align: middle;
}
#cal-container .cal-event-details .cal-detail-perm-area .cal-detail-perm-nb-missing-perms {
margin: 20px 0 0 0;
padding: 5px;
background-color: #FFF;
border-radius: 4px;
text-align: center;
font-size: 1.5rem;
color: #E44;
font-weight: bold;
}
#cal-container .cal-event-details .cal-detail-description {
margin: 20px 0 20px 0;
color: #DDD;
font-size: 1.8rem;
font-style: italic;
text-align: justify;
line-height: 120%;
}
#cal-container .cal-event-details .cal-detail-tag {
display: inline-block;
margin: 5px;
padding: 5px;
border: 1px solid #DDD;
}

View file

@ -1,108 +0,0 @@
/* Tipso Bubble Styles */
.tipso_bubble, .tipso_bubble > .tipso_arrow{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.tipso_bubble {
position: absolute;
text-align: center;
border-radius: 6px;
z-index: 9999;
}
.tipso_style{
/* cursor: help; */
border-bottom: 1px dotted;
}
.tipso_title {
padding: 3px 0;
border-radius: 6px 6px 0 0;
font-weight: 700;
}
.tipso_content {
word-wrap: break-word;
padding: 0.5em;
}
/* Tipso Bubble size classes - Similar to Foundation's syntax*/
.tipso_bubble.tiny {
font-size: 0.6rem;
}
.tipso_bubble.small {
font-size: 0.8rem;
}
.tipso_bubble.default {
font-size: 1rem;
}
.tipso_bubble.large {
font-size: 1.2rem;
width: 100%;
}
.tipso_bubble.cal_small {
font-size: 1.6rem;
}
/* Tipso Bubble Div */
.tipso_bubble > .tipso_arrow{
position: absolute;
width: 0; height: 0;
border: 8px solid;
pointer-events: none;
}
.tipso_bubble.top > .tipso_arrow {
border-top-color: #000;
border-right-color: transparent;
border-left-color: transparent;
border-bottom-color: transparent;
top: 100%;
left: 50%;
margin-left: -8px;
}
.tipso_bubble.bottom > .tipso_arrow {
border-bottom-color: #000;
border-right-color: transparent;
border-left-color: transparent;
border-top-color: transparent;
bottom: 100%;
left: 50%;
margin-left: -8px;
}
.tipso_bubble.left > .tipso_arrow {
border-left-color: #000;
border-top-color: transparent;
border-bottom-color: transparent;
border-right-color: transparent;
top: 50%;
left: 100%;
margin-top: -8px;
}
.tipso_bubble.right > .tipso_arrow {
border-right-color: #000;
border-top-color: transparent;
border-bottom-color: transparent;
border-left-color: transparent;
top: 50%;
right: 100%;
margin-top: -8px;
}
.tipso_bubble .top_right_corner,
.tipso_bubble.top_right_corner {
border-bottom-left-radius: 0;
}
.tipso_bubble .bottom_right_corner,
.tipso_bubble.bottom_right_corner {
border-top-left-radius: 0;
}
.tipso_bubble .top_left_corner,
.tipso_bubble.top_left_corner {
border-bottom-right-radius: 0;
}
.tipso_bubble .bottom_left_corner,
.tipso_bubble.bottom_left_corner {
border-top-right-radius: 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,18 +0,0 @@
$(function(){
function initEnrolment(elt) {
elt = $(elt);
elt.find("form.enrolment").on("submit", function() {
elt.addClass("sending-request");
var form = this;
var url = form.action + "?ajax";
$.post(url, $(form).serialize(), function(data) {
elt.html(data);
elt.removeClass("sending-request");
initEnrolment(elt);
});
return false;
});
}
$.each($(".activity-summary"), function(i, item) { initEnrolment(item) });
});

View file

@ -1,84 +0,0 @@
// Interval graph coloring algorithm, by Twal
class IntervalColoration {
constructor (intervals) {
this.intervals = intervals;
this.n = this.intervals.length;
this.computeInterferenceGraph();
this.computePEO();
this.computeColoration();
}
computeInterferenceGraph() {
this.adj = new Array(this.n);
for (let i = 0; i < this.n; ++i) {
this.adj[i] = [];
}
for (let i = 0; i < this.n; ++i) {
for (let j = 0; j < i; ++j) {
let inti = this.intervals[i];
let intj = this.intervals[j];
if (inti[0] < intj[1] && intj[0] < inti[1]) {
this.adj[i].push(j);
this.adj[j].push(i);
}
}
}
}
//Perfect elimination order using Maximum Cardinality Search
//Runs in O(n^2), could be optimized in O(n log n)
computePEO() {
let marked = new Array(this.n);
let nbMarkedNeighbor = new Array(this.n);
this.perm = new Array(this.n);
for (let i = 0; i < this.n; ++i) {
marked[i] = false;
nbMarkedNeighbor[i] = 0;
}
for (let k = this.n-1; k >= 0; --k) {
let maxi = -1;
for (let i = 0; i < this.n; ++i) {
if (!marked[i] && (maxi == -1 || nbMarkedNeighbor[i] >= nbMarkedNeighbor[maxi])) {
maxi = i;
}
}
for (let i = 0; i < this.adj[maxi].length; ++i) {
nbMarkedNeighbor[this.adj[maxi][i]] += 1;
}
this.perm[maxi] = k;
marked[maxi] = true;
}
// console.log(this.perm);
}
computeColoration() {
this.colors = new Array(this.n);
let isColorUsed = new Array(this.n);
for (let i = 0; i < this.n; ++i) {
this.colors[i] = -1;
isColorUsed[i] = false;
}
for (let i = 0; i < this.n; ++i) {
let ind = this.perm[i];
for (let j = 0; j < this.adj[ind].length; ++j) {
let neigh = this.adj[ind][j];
if (this.colors[neigh] >= 0) {
isColorUsed[this.colors[neigh]] = true;
}
}
for (let j = 0; j < this.n; ++j) {
if (!isColorUsed[j]) {
this.colors[ind] = j;
break;
}
}
for (let j = 0; j < this.adj[ind].length; ++j) {
let neigh = this.adj[ind][j];
if (this.colors[neigh] >= 0) {
isColorUsed[this.colors[neigh]] = false;
}
}
}
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,52 +0,0 @@
{% 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 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

@ -1,79 +0,0 @@
{% 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>
{% with activity|get_herited:'places' as places %}
{% if places.all %}
<span>{{ places.all |join:", "}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
{% endwith %}
</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>
{% with activity|get_herited:'tags' as tags %}
{% if tags.all %}
<span>{{ tags.all |join:", "}}</span>
{% else %}
<span>&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;</span>
{% endif %}
{% endwith %}
</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">
{% enrol_btn activity request.user %}
</div>
</div>
</div>
{% endif %}
{% endwith %}

View file

@ -1,116 +0,0 @@
{% extends "shared/fluid.html" %}
{% load i18n staticfiles event_tags %}
{% block extra_css %}
{{ block.super }}
<link rel="stylesheet" href="{% static "css/tipso.css" %}">
<link rel="stylesheet" href="{% static "css/calendar.css" %}">
<style>
#cal-toggle-unsubscribed-events-display {
display: block;
position: fixed;
bottom: 30px;
left: 30px;
border-bottom: 2px solid rgb(150, 50, 50);
font-size: 1.6rem;
font-weight: bold;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4),
0 1px 1px rgba(150, 50, 50, 0.7);
text-shadow: 0 0 7px rgb(150, 50, 50);
z-index: 5000;
}
</style>
{% endblock %}
{% block extra_js %}
{{ block.super }}
<script type="text/javascript" src="{% static "js/tipso.min.js" %}"></script>
<script type="text/javascript" src="{% static "js/interval_coloration.js" %}"></script>
<script type="text/javascript" src="{% static "js/calendar.js" %}"></script>
<script type="text/javascript">
$(document).ready(() => {
let calendar = new Calendar({
startDate: new Date(2018, 10, 30, 8),
endDate: new Date(2018, 11, 2, 6),
eventDetailURLFormat: "https://cof.ens.fr/poulpe/event/activity/999999",
subscriptionURLFormat: "{% url "event:enrol_activity" 999999 %}?ajax=json",
csrfToken: $(".planning [name=csrfmiddlewaretoken]").val(),
groupEventsByLocation: true
});
// TODO: move this elsewhere
// Button to switch between:
// - displaying all events (default);
// - only displaying events for which the current user is enroled.
// Create the button
let toggleUnsubscribedEventDisplayButton = $("<button>")
.attr("type", "button")
.attr("id", "cal-toggle-unsubscribed-events-display")
.addClass("btn btn-primary")
.appendTo(calendar.containerNode);
// Set/update its label
function updateToggleButtonLabel () {
if (calendar.onlyDisplaySubscribedEvents) {
toggleUnsubscribedEventDisplayButton.html("Afficher toutes les activités");
}
else {
toggleUnsubscribedEventDisplayButton.html("Afficher seulement mes permanences");
}
}
updateToggleButtonLabel();
// Switch between display modes on click
toggleUnsubscribedEventDisplayButton.on("click", () => {
calendar.toggleEventsNotSubscribedByUser();
updateToggleButtonLabel();
});
// DEBUG: js console helpers, to be removed
console.log(calendar);
window["cal"] = calendar;
});
</script>
{% endblock %}
{% block content %}
<div class="planning">
{% csrf_token %}
{% regroup activities by beginning|date:"Y-m-d" as days_list %}
<div class="content fluid" id="cal-container">
{% for day in days_list %}
{% for activity in day.list %}
<div class="cal-event">
<span class="cal-event-id">{{ activity.id }}</span>
<span class="cal-event-name">{{ activity|get_herited:'title' }}</span>
<span class="cal-event-start-date">{{ activity.beginning | date:"j/m/Y H:i" }}</span>
<span class="cal-event-end-date">{{ activity.end | date:"j/m/Y H:i" }}</span>
{% with activity|get_herited:'places' as places %}
<span class="cal-event-location">{{ places.all | join:", " }}</span>
{% endwith %}
<span class="cal-event-description">{{ activity.description }}</span>
<span class="cal-event-url">{% url "event:activity" activity.id %}</span>
{% if activity|get_herited:'has_perm' %}
<span class="cal-event-has-perms">1</span>
<span class="cal-event-min-nb-perms">{{ activity|get_herited:'min_perm' }}</span>
<span class="cal-event-max-nb-perms">{{ activity|get_herited:'max_perm' }}</span>
<span class="cal-event-nb-perms">{{ activity.staff.count }}</span>
<span class="cal-event-subscribed">{% is_enrolled activity request.user %}</span>
{% endif %}
{% with activity|get_herited:'tags' as tags %}
{% for tag in tags.all %}
<span class="cal-event-tag">{{ tag.name }}</span>
{% endfor %}
{% endwith %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endblock %}

View file

@ -1,101 +0,0 @@
{% extends "shared/base.html" %}
{% load i18n staticfiles event_tags %}
{% block title %}{% trans "Évènement" %}{% endblock %}
{% block extra_js %}
{{ block.super }}
<script type="text/javascript" src="{% static "js/enrol_event.js" %}"></script>
{% 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>
<a href="{% url "event:calendar" event.slug %}" class="module">
Calendrier
</a>
{% if staffuser %}
<a href="{% url "event:event" event.slug %}" class="module">
Toutes les activités
</a>
{% else %}
<a href="{% url "event:event-staff" event.slug user.username %}" class="module">
Mes perms
</a>
{% endif %}
</div>
{% if staffuser %}
<h2>Perms de {{ staffuser.first_name }} {{ staffuser.last_name }}</h2>
{% else %}
<h2>Planning</h2>
{% endif %}
<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>
<div class="activity-summary">
{% include "event/activity_summary.html" with activity=activity %}
</div>
</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

@ -1,6 +0,0 @@
{% load i18n %}
<form method="POST" action="{% url "event:enrol_activity" activity.pk %}" class="enrolment {{ enrolled|yesno:"enrolled,unenrolled" }}">
{% csrf_token %}
<input type="hidden" name="goal" value="{{ enrolled|yesno:"unenrol,enrol" }}" />
{{ enrolled|yesno:_("Inscrit,") }} <input type="submit" value="{{ enrolled|yesno:_("Se désinscrire,S'inscrire") }}" class="btn btn-warning"/>
</form>

View file

@ -1,21 +0,0 @@
from django import template
register = template.Library()
@register.filter()
def get_herited(activity, attrname):
return activity.get_herited(attrname)
@register.inclusion_tag("event/tags/enrol_btn.html")
def enrol_btn(activity, user):
return {
"enrolled": activity.staff.filter(id=user.id).exists(),
"activity": activity,
}
@register.simple_tag
def is_enrolled(activity, user):
user_is_enrolled = activity.staff.filter(id=user.id).exists()
return "1" if user_is_enrolled else "0"

View file

@ -1,14 +1,7 @@
from django.conf.urls import url
from event.views import Index, EventView, EventViewStaff, ActivityView, EnrolActivityView, EventCalendar
from event.views import Index
app_name = 'event'
urlpatterns = [
# url(r'^$', Index.as_view(), name='index'),
url(r'^(?P<slug>[-\w]+)/$', EventView.as_view(), name='event'),
url(r'^(?P<slug>[-\w]+)/s/(?P<username>[-\w]+)/$', EventViewStaff.as_view(), name='event-staff'),
url(r'^(?P<slug>[-\w]+)/calendar/$', EventCalendar.as_view(), name='calendar'),
url(r'^activity/(?P<pk>[0-9]+)/$', ActivityView.as_view(),
name='activity'),
url(r'^activity/(?P<pk>[0-9]+)/enrol/$',
EnrolActivityView.as_view(), name="enrol_activity"),
url(r'^$', Index.as_view(), name='index'),
]

View file

@ -1,97 +1,5 @@
from django.views.generic import TemplateView, DetailView, View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404, render
from django.http import JsonResponse, HttpResponseRedirect
from django.urls import reverse
from .models import Event, Activity
from equipment.models import EquipmentAttribution
User = get_user_model()
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = "event/index.html"
class EventCalendar(LoginRequiredMixin, DetailView):
model = Event
template_name = 'event/calendar.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 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 EventViewStaff(LoginRequiredMixin, DetailView):
model = Event
template_name = 'event/event.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = User.objects.get(username=self.kwargs['username'])
event = self.object
context['staffuser'] = user
context['activities'] = (user.in_perm_activities
.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
class EnrolActivityView(LoginRequiredMixin, View):
http_method_names = ['post']
def post(self, request, pk, *args, **kwargs):
activity = get_object_or_404(Activity, id=pk)
action = request.POST.get("goal", None)
success = True
if action == "enrol":
activity.staff.add(request.user)
elif action == "unenrol":
activity.staff.remove(request.user)
else:
success = False
if "ajax" in request.GET:
if request.GET["ajax"] == "json":
enrols = activity.staff
return JsonResponse({
"enrolled": enrols.filter(id=request.user.id).exists(),
"number": enrols.count(),
})
return render(request, "event/activity_summary.html",
{"activity": activity})
return HttpResponseRedirect(reverse("event:activity", kwargs={"pk":pk}))

View file

@ -3,7 +3,7 @@ import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "poulpe.settings.devlocal")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evenementiel.settings.devlocal")
from django.core.management import execute_from_command_line

View file

View file

@ -10,7 +10,7 @@ DBPASSWD="4KZt3nGPLVeWSvtBZPsd9jdssdJMds78"
REDIS_PASSWD="dummy"
# It is used in quite a few places
SETTINGS="poulpe.settings.dev"
SETTINGS="evenementiel.settings.dev"
# Fills a "templated file" with the information specified in the variables above
# e.g. every occurrence of {{DBUSER}} in the file will be replaced by the value
@ -90,9 +90,9 @@ redis-cli -a $REDIS_PASSWD CONFIG REWRITE
cd /vagrant
# Setup the secrets
sudo -H -u vagrant cp poulpe/settings/secret_example.py \
poulpe/settings/secret.py
fill_template poulpe/settings/secret.py
sudo -H -u vagrant cp evenementiel/settings/secret_example.py \
evenementiel/settings/secret.py
fill_template evenementiel/settings/secret.py
# Run the usual django admin commands
function venv_python {

View file

@ -10,7 +10,7 @@ TimeoutSec=300
WorkingDirectory=/vagrant
Environment="DJANGO_SETTINGS_MODULE={{SETTINGS}}"
ExecStart=/home/vagrant/venv/bin/daphne -u /srv/GE/GE.sock \
poulpe.asgi:channel_layer
evenementiel.asgi:channel_layer
[Install]
WantedBy=multi-user.target

View file

@ -1,3 +1,4 @@
-r requirements.txt
django-debug-toolbar
django-debug-panel
ipython

View file

@ -1,14 +1,16 @@
asgi-redis==1.3.0
asgiref==1.1.1
django-bootstrap3==10.0.1
channels==1.1.5
Django==2.1
django-tables2==2.0.0a2
django-filter==2.0.0
git+https://git.eleves.ens.fr/klub-dev-ens/django-allauth-ens.git@1.1.3
django-bootstrap-form==3.4
Django==1.11.11
django-allauth==0.36.0
django-allauth-cas==1.0.0b2
#git+https://git.eleves.ens.fr/cof-geek/django-allauth-ens@6e77b31e0dfed7659776d
git+https://git.eleves.ens.fr/cof-geek/django-allauth-ens@30a072b7db1fc2d4652284227a3e7e876b14c915
django-bootstrap-form==3.2.1
drf-nested-routers==0.90.0
django-notifications==0.1.dev0
django-contrib-comments==1.8.0
django-taggit==0.22.2
Pillow==5.0.0
python-cas==1.2.0

View file

@ -28,7 +28,9 @@ class CustomAdminSite(AdminSite):
return super().index(request, extra_context)
# admin.site = CustomAdminSite(name='admin')
admin_site = CustomAdminSite(name='admin')
admin_site.register(User, UserAdmin)
admin_site.register(Group, GroupAdmin)
admin_site.register(Site, SiteAdmin)
admin.site.register(User, UserAdmin)
# admin.site.register(Group, GroupAdmin)
# admin.site.register(Site, SiteAdmin)

View file

@ -2,9 +2,9 @@ from django.apps import AppConfig
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'myproject.admin.CustomAdminSite'
class SharedConfig(AppConfig):
name = 'shared'
class CustomAdminConfig(AdminConfig):
default_site = 'shared.admin.CustomAdminSite'

View file

@ -11,7 +11,6 @@ class EventSpecificMixin(models.Model):
verbose_name=_("évènement"),
help_text=_("Si spécifié, l'instance du modèle"
"est spécifique à l'évènement en question"),
on_delete=models.CASCADE,
blank=True,
null=True
)

View file

@ -1,25 +0,0 @@
require 'compass/import-once/activate'
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass

View file

@ -1,114 +0,0 @@
//@import "compass/css3";
//Variables here:
//(alongside with commented suggestions)
$foreground-color:#b85b3f;//black;
$background-color:#e8e3c7;//white
$shadow-color:#ba9186;//$foreground-color;
$distance:8px;
$cut-distance:3px;//$distance/4;
$strips-size:6px; //10px
$strips-ratio:50%;//70%
$strips-angle:45deg;//90deg;
//cray stuff yo. be sure to try (if you please)
$animate:false;//true
$fixed:false;//true
body{
font-family: 'Open Sans Condensed', sans-serif;
font-size:85pt;
background-color:$background-color;
text-align:center;
line-height:1.2em;
padding-top:70px;
}
.dashed-shadow{
position:relative;
top:$distance;
left:$distance;
display:inline-block;
color:$shadow-color;
}
.dashed-shadow:before{
content:" ";
display:block;
position:absolute;
$bleeding-horizontal:10px;
$bleeding-vertical:0px;
top:-$bleeding-vertical - $distance;
left:-$bleeding-vertical - $distance;
bottom:-$bleeding-horizontal + $distance;
right:-$bleeding-horizontal + $distance;
z-index:1;
$color:$background-color;
$size:$strips-ratio/2;
$halfSize:$size/2;
$p1:$halfSize;
$p2:50%-$halfSize;
$p3:50%+$halfSize;
$p4:100%-$halfSize;
$transparent:transparentize($color,1);
@include background-image(linear-gradient($strips-angle,$color $p1, $transparent $p1, $transparent $p2,$color $p2, $color $p3, $transparent $p3, $transparent $p4, $color $p4));
background-size:$strips-size $strips-size;
@if($animate){
animation:dash-animation 30s infinite linear;
}
@if($fixed){
background-attachment:fixed;
}
}
.dashed-shadow:hover:before{
animation:dash-animation 30s infinite linear;
}
.dashed-shadow:after{
z-index:2;
content:attr(data-text);
position:absolute;
left:-$distance;
top:-$distance;
color:$foreground-color;
text-shadow:$cut-distance $cut-distance $background-color;
}
//fancy stuff - just useless fluff, don't mind from here onwards
.hello{
font-family:'Cookie',cursive;
font-size:140pt;
}
.sorta-block{
font-size:50pt;
line-height:1.1em;
@include transform(skew(0,-5deg));
z-index:3;
position:relative;
margin-top:20px;
margin-bottom:10px;
}
.sorta{
border-top:4px solid $foreground-color;
border-bottom:4px solid $foreground-color;
text-transform:uppercase;
z-index:3;
//position:relative;
//display:block;
//width:300px;
font-style:italic;
}
.hipsterish{
font-family: 'Sancreek', cursive;
font-size:70pt;
}
.dashed-shadow-text{
font-size:140pt;
line-height:0.7em;
//left:-10px;
}
.shadow{
font-size:120pt;
line-height:0.8em;
}

View file

@ -1,18 +0,0 @@
// main: global.scss
#filter_form {
.form-group {
.col-md-3, .col-md-9 {
float: none;
}
ul.form-control {
padding-left: 15px;
list-style: none;
height: auto;
a.selected {
text-decoration: underline;
color: darken($main_soft_color, 40%);
}
}
}
}

View file

@ -1,122 +0,0 @@
// main: global.scss
@mixin active {
&:active,
&.active {
@content;
}
}
@mixin hover-focus {
&:focus,
&.focus,
&:hover {
@content;
}
}
@mixin disabled {
&.disabled,
&[disabled],
fieldset[disabled] & {
@content;
}
}
@mixin dropdown-open {
.open > &.dropdown-toggle { @content }
}
@mixin btn-special {
/**
* This mixin applies content if the button is in at least one of the
* following states:
*
* - hovered,
* - focused,
* - actived,
* - is responsible of an opened dropdown.
*
* Where possible, state is checked from class attribute and
* :pseudo-classes.
*
* ## Bootstrap compatibility
*
* If content defines 'color', 'background-color' and 'border', it is safe
* to use this mixin with Bootstrap buttons as it will overrides all
* Bootstrap color defaults of the previous cases.
* To be precise, this covers all special important-like cases of the
* Bootstrap mixin 'button-variant' (except the 'disabled' case).
*
*/
@include hover-focus { @content }
@include active {
@content;
@include hover-focus { @content }
}
@include dropdown-open {
@content;
@include hover-focus { @content }
}
}
@mixin button-variant-2modes($color, $background-base, $background-special, $border) {
/**
* This mixins allows defining color-related properties of buttons.
*
* It sets the following properties:
* color: $color, except for disabled-like buttons.
* border-color: $border.
* background-color: Depending on button state:
* - Default, disabled:
* $background-base
* - Hovered, focused, actived, responsible of an opened dropdown:
* (one is sufficent)
* $background-special
*
* ## Bootstrap compatibility
*
* This mixin can be used to replace colors behaviors of Bootstrap buttons.
* Indeed, this mixin aims to replace each definition done by the
* 'button-variant' Bootstrap mixin.
*
*/
color: $color;
background-color: $background-base;
border-color: $border;
@include btn-special {
color: $color;
background-color: $background-special;
border-color: $border;
}
@include disabled {
@include hover-focus {
background-color: $background-base;
border-color: $border;
}
}
.badge {
color: $background-base;
background-color: $color;
}
}
.btn-primary {
@include button-variant-2modes($btn-font-color, $btn-bg-base, $btn-bg-special, $btn-border);
}
form#filter_form {
.form-group {
padding-right:20px;
}
ul.form-control {
background-color: transparent;
border: none;
box-shadow: none;
}
}

View file

@ -1,91 +0,0 @@
// main: global.scss
.strong-banner {
padding-top : 20px;
padding-bottom : 10px ;
background-color : $header-background;
color: $header-color;
}
.navbar-inverse {
background-color : $header-background;
background-color : transparent ;
border-style : none ;
.navbar-nav {
& > .open > a,
& > .open > a:focus,
& > .open > a:hover {
color: #fff;
background-color: $header-second-backgroud;
}
}
}
.navbar-collapse {
border-top: 0px solid transparent ;
padding : 0px ;
/* only < 768px*/
background-color : $header-second-backgroud;
padding-left: 25px;
margin-left: -15px;
margin-right: -15px;
@media (min-width: 768px) {
background-color : transparent;
padding-left: 0px;
margin-left: 0px;
margin-right: 0px;
}
}
.navbar-nav {
width: 100%;
@media (min-width: 768px) {
float : right ;
width: auto;
}
}
.navbar-inverse {
/* BRAND */
.navbar-brand {
&,
&:hover,
&:focus {
color: white;
font-family: $font_brand;
font-size: xx-large;
border-bottom: 5px solid $underline-brand;
}
}
/* ICONE */
.navbar-toggle {
&,
&:hover,
&:focus {
background-color: $second_bold_color;
border-color: $second_bold_color;
}
.icon-bar {
background-color: $second_white_color;
}
}
/* LINKS */
.navbar-nav {
& > li > a {
&,
&:hover,
&:focus {
font-family: $font_nav;
font-size: large;
color: $second_bold_color;
background: transparent;
@media (min-width: 768px) {
color: $second_white_color;
}
}
}
}
}

View file

@ -1,38 +0,0 @@
// main: global.scss
.tree {
font-size:large;
ul, li {
position: relative;
}
ul {
list-style: none;
padding-left: 32px;
}
li::before,
li::after {
content: "";
position: absolute;
left: -12px;
}
li::before {
border-top: 3px solid $second_soft_color;
top: 9px;
width: 8px;
height: 0;
}
li::after {
border-left: 3px solid $second_soft_color;
height: 100%;
width: 0px;
top: 2px;
}
ul > li:last-child::after {
height: 8px;
}
.category_node {
}
}

View file

@ -1,99 +0,0 @@
// main: global.scss
$main_c7: #375362;
$main_c6: #4F778C;
$main_c5: #5D8CA6;
$main_c3: #BDD2DE;
$main_c1: #F0FAFF;
$neutral_c2 : #F2EDDC;
$neutral_c1: #FFFBEF;
$activity_c8: #4FADB8;
$activity_c7: #5ED1DC;
$activity_c3: #CAE4E7;
$event_c8: #3488A6;
$event_c7: #3999BA;
$event_c3: #AAD5E2;
$todo_c8: #F19F5D;
$todo_c7: #FF9C4D;
$todo_c3: #FFDEBC;
$equipment_c8: #E75571;
$equipment_c7: #FF5C79;
$equipment_c3: #FECAD6;
$staff_c8: #3BAD89;
$staff_c7: #42C2A2;
$staff_c3: #A9E1D7;
/* LEGACY COLORS*/
$main_bold_color: #FF6969;
$main_soft_color: #FF9191;
$main_white_color: #FFEBEB;
$second_bold_color: #FFB363;
$second_soft_color: #FFC282;
$second_white_color: #FFF5EB;
$third_bold_color: #48B0C7;
$third_soft_color: #8FD4E3;
$third_white_color: #DCEAED;
/* COLORS */
/* Header */
$header-background: $main_c7;
$header-second-backgroud: $main_c5;
$header-color: white;
$underline-brand: $equipment_c7;
/* Général */
$html-background: $neutral_c1;
$content-background: $neutral_c1;
$content-border: $main_c7;
$aside-background: $main_c7;
$aside-inverted-background: $main_c5;
$title_border: $main_c7;
/* Le reste */
$btn-font-color: white;
$btn-bg-base: $main_bold_color;
$btn-bg-special: $main_soft_color;
$btn-border: $main_bold_color;
$yes_color: #55C487;
$no_color: #E36268;
$dunno_color: #5599C4;
/* Titres */
$h1_background: $main_c6;
$h2_background: $main_c3;
$h3_background: $main_c1;
$h1_background_activity: $activity_c8;
$h2_background_activity: $activity_c7;
$h3_background_activity: $main_c1;
$h1_background_event: $event_c8;
$h2_background_event: $event_c7;
$h3_background_event: $main_c1;
$h1_background_todo: $todo_c8;
$h2_background_todo: $todo_c7;
$h3_background_todo: $main_c1;
$h1_background_equipment: $equipment_c8;
$h2_background_equipment: $equipment_c7;
$h3_background_equipment: $main_c1;
$h1_background_staff: $staff_c8;
$h2_background_staff: $staff_c7;
$h3_background_staff: $main_c1;
/* FONTS */
$font_brand:'Lily Script One', cursive;
$font_nav:'Work Sans', cursive;
$font_bold:'Capriola', sans-serif;
$font_normal:'Saira Semi Condensed', sans-serif;

View file

@ -1,4 +1,3 @@
// main: global.scss
@mixin active {
&:active,
&.active {
@ -109,14 +108,3 @@
@include button-variant-2modes($btn-font-color, $btn-bg-base, $btn-bg-special, $btn-border);
}
form#filter_form {
.form-group {
padding-right:20px;
}
ul.form-control {
background-color: transparent;
border: none;
box-shadow: none;
}
}

View file

@ -1 +0,0 @@
global.min.css

View file

@ -0,0 +1,237 @@
@charset "UTF-8";
/*NE PAS MODIFIER LE FICHIER .CSS, MAIS PLUTÔT LE
FICHIER .SCSS */
/* COLORS */
/* FONTS */
.message-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1; }
.message-success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6; }
.message-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc; }
.message-error {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1; }
.alert {
margin-bottom: 0; }
/* BANNER */
.strong-banner {
padding-top: 20px;
padding-bottom: 10px;
background-color: #FF6969;
color: #FFB363; }
.navbar-inverse {
background-color: #FF6969;
background-color: transparent;
border-style: none; }
.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:focus, .navbar-inverse .navbar-nav > .open > a:hover {
color: #fff;
background-color: #FF9191; }
.navbar-collapse {
border-top: 0px solid transparent;
padding: 0px;
/* only < 768px*/
background-color: #FF9191;
padding-left: 25px;
margin-left: -15px;
margin-right: -15px; }
@media (min-width: 768px) {
.navbar-collapse {
background-color: transparent;
padding-left: 0px;
margin-left: 0px;
margin-right: 0px; } }
.navbar-nav {
width: 100%; }
@media (min-width: 768px) {
.navbar-nav {
float: right;
width: auto; } }
.navbar-inverse {
/* BRAND */
/* ICONE */
/* LINKS */ }
.navbar-inverse .navbar-brand, .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus {
color: white;
font-family: "Lily Script One", cursive;
font-size: xx-large;
border-bottom: 5px solid #FFC282; }
.navbar-inverse .navbar-toggle, .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus {
background-color: #FFB363;
border-color: #FFB363; }
.navbar-inverse .navbar-toggle .icon-bar {
background-color: #FFF5EB; }
.navbar-inverse .navbar-nav > li > a, .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
font-family: "Work Sans", cursive;
font-size: large;
color: #FFB363;
background: transparent; }
@media (min-width: 768px) {
.navbar-inverse .navbar-nav > li > a, .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
color: #FFF5EB; } }
.btn-primary {
/**
* This mixins allows defining color-related properties of buttons.
*
* It sets the following properties:
* color: $color, except for disabled-like buttons.
* border-color: $border.
* background-color: Depending on button state:
* - Default, disabled:
* $background-base
* - Hovered, focused, actived, responsible of an opened dropdown:
* (one is sufficent)
* $background-special
*
* ## Bootstrap compatibility
*
* This mixin can be used to replace colors behaviors of Bootstrap buttons.
* Indeed, this mixin aims to replace each definition done by the
* 'button-variant' Bootstrap mixin.
*
*/
color: white;
background-color: #FF6969;
border-color: #FF6969;
/**
* This mixin applies content if the button is in at least one of the
* following states:
*
* - hovered,
* - focused,
* - actived,
* - is responsible of an opened dropdown.
*
* Where possible, state is checked from class attribute and
* :pseudo-classes.
*
* ## Bootstrap compatibility
*
* If content defines 'color', 'background-color' and 'border', it is safe
* to use this mixin with Bootstrap buttons as it will overrides all
* Bootstrap color defaults of the previous cases.
* To be precise, this covers all special important-like cases of the
* Bootstrap mixin 'button-variant' (except the 'disabled' case).
*
*/ }
.btn-primary:focus, .btn-primary.focus, .btn-primary:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969; }
.btn-primary:active, .btn-primary.active {
color: white;
background-color: #FF9191;
border-color: #FF6969; }
.btn-primary:active:focus, .btn-primary:active.focus, .btn-primary:active:hover, .btn-primary.active:focus, .btn-primary.active.focus, .btn-primary.active:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969; }
.open > .btn-primary.dropdown-toggle {
color: white;
background-color: #FF9191;
border-color: #FF6969; }
.open > .btn-primary.dropdown-toggle:focus, .open > .btn-primary.dropdown-toggle.focus, .open > .btn-primary.dropdown-toggle:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969; }
.btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:hover {
background-color: #FF6969;
border-color: #FF6969; }
.btn-primary .badge {
color: #FF6969;
background-color: white; }
/* MISE EN FORME GÉNÉRALE */
html {
height: 100%;
background-color: #FFF5EB; }
body {
font-family: "Saira Semi Condensed", sans-serif;
font-size: medium; }
#principal {
background-color: #FFF5EB; }
/*MAIN*/
main {
background-color: white;
margin-top: 0px;
padding: 15px; }
main a {
color: #FF6969; }
main a:hover, main a:active, main a:focus {
color: #FF6969; }
main h1 {
border-bottom: 7px solid #FFB363;
padding-bottom: 5px;
font-family: "Saira", sans-serif;
font-weight: 600; }
main h2 {
border-bottom: 2px solid #FF6969;
color: #FF6969;
padding-bottom: 5px;
font-family: "Saira", sans-serif;
font-weight: 600; }
/*ASIDE*/
aside {
background-color: #FFC282;
color: white;
margin-top: 0px;
padding: 15px; }
aside a {
color: #FF9191; }
aside a:hover, aside a:active, aside a:focus {
color: #FF9191; }
aside code {
color: white;
background-color: #FFB363; }
@media (min-width: 768px) {
main {
margin-top: 20px; }
aside {
margin-top: 20px; } }
hr {
border-top: 1px solid #FFB363; }
span.vsep {
padding-left: 5px;
padding-right: 5px; }
div.tag-list {
margin-top: 20px; }
code {
font-size: small; }
/* COULD BE USERFULL LATER
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
*/
/*# sourceMappingURL=global.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,17 +1,14 @@
/*NE PAS MODIFIER LE FICHIER .CSS, MAIS PLUTÔT LE
FICHIER .SCSS */
@import '_variables';
@import '_messages';
@import '_header';
@import '_forms';
@import '_tree';
@import '_filters';
//@import '_dashed-shadows';
@import 'variables';
@import 'messages';
@import 'header';
@import 'forms';
/* MISE EN FORME GÉNÉRALE */
html {
height : 100% ;
background-color: $html-background;
background-color: $second_white_color;
}
body {
@ -20,112 +17,15 @@ body {
}
#principal {
background-color: $html-background;
background-color: $second_white_color;
}
/*MAIN*/
main {
background-color:$content-background;
border-width: 2px;
border-color: $content-border;
border-style: none;
border-collapse: collapse;
display: table-cell;
background-color:white;
margin-top:0px;
padding: 0px;
padding: 15px;
.fuid, h1, h2, h3 {
margin-left: -15px;
margin-right: -15px;
margin-top: 0px;
margin-bottom: 0px;
}
h1, h2, h3 {
margin-top: -2px;
margin-bottom: -2px;
margin-left: -17px;
margin-right: -17px;
color: white;
padding-left: 15px;
padding-right: 15px;
}
h1 {
font-family: $font_bold;
font-weight: 600;
padding-bottom: 10px;
padding-top: 15px;
background-color: $h1_background;
&.activity {
background-color: $h1_background_activity;
}
&.event {
background-color: $h1_background_event;
}
&.todo {
background-color: $h1_background_todo;
}
&.equipment {
background-color: $h1_background_equipment;
}
&.staff {
background-color: $h1_background_staff;
}
}
h2, h3 {
border-bottom : 2px solid $main_c5;
padding-bottom : 5px ;
padding-top: 10px;
font-family: $font_bold;
font-weight: 600;
font-size: x-large;
background-color: $h2_background;
&.activity {
background-color: $h2_background_activity;
border-color: $activity_c8;
}
&.event {
background-color: $h2_background_event;
border-color: $event_c8;
}
&.todo {
background-color: $h2_background_todo;
border-color: $todo_c8;
}
&.equipment {
background-color: $h2_background_equipment;
border-color: $equipment_c8;
}
&.staff {
background-color: $h2_background_staff;
border-color: $staff_c8;
}
}
h3 {
background-color: $h3_background;
color: $main_c6;
&.activity {
background-color: $h3_background_activity;
color: $activity_c7;
}
&.event {
background-color: $h3_background_event;
color: $event_c7;
}
&.todo {
background-color: $h3_background_todo;
color: $todo_c7;
}
&.equipment {
background-color: $h3_background_equipment;
color: $equipment_c7;
}
&.staff {
background-color: $h3_background_staff;
color: $staff_c7;
}
}
a {
color: $main_bold_color;
@ -135,18 +35,27 @@ main {
color : $main_bold_color;
}
}
.text {
padding: 15px;
h1 {
border-bottom : 7px solid $second_bold_color;
padding-bottom : 5px ;
font-family: $font_bold;
font-weight: 600;
}
h2 {
border-bottom : 2px solid $main_bold_color;
color: $main_bold_color;
padding-bottom : 5px ;
font-family: $font_bold;
font-weight: 600;
}
}
/*ASIDE*/
aside {
background-color:$aside-background;
background-color:$second_soft_color;
color: white;
margin-top: 0px;
padding: 0px!important;
margin-top:0px;
padding: 15px;
a {
color: $main_soft_color;
@ -157,58 +66,15 @@ aside {
color : $main_soft_color;
}
}
code {
color: $main_c7;
background-color: $main_c3;
}
.heading {
padding: 8px 15px;
font-size: 32px;
line-height: 1.3;
text-align:center;
&.inverted {
background-color:$second_white_color;
color:black;
}
&.small {
font-size: 25px;
.sub {
font-size: 0.7em;
font-weight: normal;
}
}
.sub {
font-size: 0.7em;
font-weight: normal;
}
&.separator {
border-bottom-color: $main_soft_color;
border-bottom-style: solid;
}
}
.text {
padding: 15px;
&.inverted {
background-color:$second_white_color;
color:black;
}
color: white;
background-color: $second_bold_color;
}
}
@media (min-width: 768px) {
main {
margin-top:20px;
border-style: dashed;
}
aside {
margin-top:20px;
@ -232,185 +98,12 @@ div.tag-list {
code {
font-size: small;
}
/* COULD BE USERFULL LATER
.module-list {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
align-items: stretch;
flex-wrap: wrap;
}
a.module {
padding: 20px 40px;
margin: 5px;
border-bottom-style: solid;
font-size: large;
display: block;
border-bottom-color: $main_c7;
background-color: $main_c3;
color: $main_c7;
&.activity {
border-bottom-color: $activity_c8;
background-color: $activity_c3;
color: $activity_c8;
}
&.event {
border-bottom-color: $event_c8;
background-color: $event_c3;
color: $event_c8;
}
&.todo {
border-bottom-color: $todo_c8;
background-color: $todo_c3;
color: $todo_c8;
}
&.equipment {
border-bottom-color: $equipment_c8;
background-color: $equipment_c3;
color: $equipment_c8;
}
&.staff {
border-bottom-color: $staff_c8;
background-color: $staff_c3;
color: $staff_c8;
}
&:hover,
&:active,
&:focus {
text-decoration: none;
color: $main_c1;
background-color: $main_c7;
&.activity {
background-color: $activity_c7;
}
&.event {
background-color: $event_c7;
}
&.equipment {
background-color: $equipment_c7;
}
&.todo {
background-color: $todo_c7;
}
&.staff {
background-color: $staff_c7;
}
}
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
&: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;
}
}
.sending-request {
position: relative;
&:after {
content: "Chargement...";
position: absolute;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.8;
color: #777;
text-align: center;
box-sizing: border-box;
z-index: 5;
top: 0;
left: 0;
padding: 8%;
}
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
*/

View file

@ -1,14 +1,15 @@
// main: global.scss
/* BANNER */
.strong-banner {
padding-top : 20px;
padding-bottom : 10px ;
background-color : $header-background;
color: $header-color;
background-color : $main_bold_color;
color: $second_bold_color;
}
.navbar-inverse {
background-color : $header-background;
background-color : $main_bold_color;
background-color : transparent ;
border-style : none ;
.navbar-nav {
@ -16,7 +17,7 @@
& > .open > a:focus,
& > .open > a:hover {
color: #fff;
background-color: $header-second-backgroud;
background-color: $main_soft_color;
}
}
}
@ -26,7 +27,7 @@
padding : 0px ;
/* only < 768px*/
background-color : $header-second-backgroud;
background-color : $main_soft_color;
padding-left: 25px;
margin-left: -15px;
margin-right: -15px;
@ -83,7 +84,7 @@
color: $second_bold_color;
background: transparent;
@media (min-width: 768px) {
color: $second_white_color;
color: $second_white_color;
}
}
}

View file

@ -1,4 +1,3 @@
// main: global.scss
.message-info {
color : #31708f;
background-color: #d9edf7;

View file

@ -0,0 +1,20 @@
/* COLORS */
$main_bold_color: #FF6969;
$main_soft_color: #FF9191;
$main_white_color: #FFEBEB;
$second_bold_color: #FFB363;
$second_soft_color: #FFC282;
$second_white_color: #FFF5EB;
$btn-font-color: white;
$btn-bg-base: $main_bold_color;
$btn-bg-special: $main_soft_color;
$btn-border: $main_bold_color;
$underline-brand: $second_soft_color;
/* FONTS */
$font_brand:'Lily Script One', cursive;
$font_nav:'Work Sans', cursive;
$font_bold:'Saira', sans-serif;
$font_normal:'Saira Semi Condensed', sans-serif;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 197 KiB

View file

@ -1,36 +0,0 @@
/* Backbone models for the API */
"use strict";
var GE_API = new Object();
GE_API.rootUrl = "/api/";
GE_API.Event = Backbone.Model.extend({
rootUrl: GE_API.rootUrl + "event/",
});
GE_API.Events = Backbone.Collection.extend({
model: GE_API.Event,
url: GE_API.rootUrl + "event/"
});
GE_API.Place = Backbone.Model.extend({
rootUrl: function() {
if (this.get("event")) {
return GE_API.rootUrl + "event/" + this.get("event").id + "/place/";
} else {
return GE_API.rootUrl + "place/";
}
}
});
GE_API.Places = Backbone.Collection.extend({
url: function() {
if (this.event) {
return GE_API.rootUrl + "event/" + this.event + "/place/";
} else {
return GE_API.rootUrl + "place/";
}
}
});
GE_API.Places = Backbone.Collection.

File diff suppressed because it is too large Load diff

View file

@ -1,19 +0,0 @@
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

@ -1,763 +0,0 @@
@charset "UTF-8";
/*NE PAS MODIFIER LE FICHIER .CSS, MAIS PLUTÔT LE
FICHIER .SCSS */
/* LEGACY COLORS*/
/* COLORS */
/* Header */
/* Général */
/* Le reste */
/* Titres */
/* FONTS */
/* line 2, ../sass/_messages.scss */
.message-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
/* line 7, ../sass/_messages.scss */
.message-success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
/* line 12, ../sass/_messages.scss */
.message-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
/* line 17, ../sass/_messages.scss */
.message-error {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
/* line 22, ../sass/_messages.scss */
.alert {
margin-bottom: 0;
}
/* line 2, ../sass/_header.scss */
.strong-banner {
padding-top: 20px;
padding-bottom: 10px;
background-color: #375362;
color: white;
}
/* line 10, ../sass/_header.scss */
.navbar-inverse {
background-color: #375362;
background-color: transparent;
border-style: none;
}
/* line 15, ../sass/_header.scss */
.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:focus, .navbar-inverse .navbar-nav > .open > a:hover {
color: #fff;
background-color: #5D8CA6;
}
/* line 24, ../sass/_header.scss */
.navbar-collapse {
border-top: 0px solid transparent;
padding: 0px;
/* only < 768px*/
background-color: #5D8CA6;
padding-left: 25px;
margin-left: -15px;
margin-right: -15px;
}
@media (min-width: 768px) {
/* line 24, ../sass/_header.scss */
.navbar-collapse {
background-color: transparent;
padding-left: 0px;
margin-left: 0px;
margin-right: 0px;
}
}
/* line 43, ../sass/_header.scss */
.navbar-nav {
width: 100%;
}
@media (min-width: 768px) {
/* line 43, ../sass/_header.scss */
.navbar-nav {
float: right;
width: auto;
}
}
/* line 51, ../sass/_header.scss */
.navbar-inverse {
/* BRAND */
/* ICONE */
/* LINKS */
}
/* line 54, ../sass/_header.scss */
.navbar-inverse .navbar-brand, .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus {
color: white;
font-family: "Lily Script One", cursive;
font-size: xx-large;
border-bottom: 5px solid #FF5C79;
}
/* line 65, ../sass/_header.scss */
.navbar-inverse .navbar-toggle, .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus {
background-color: #FFB363;
border-color: #FFB363;
}
/* line 71, ../sass/_header.scss */
.navbar-inverse .navbar-toggle .icon-bar {
background-color: #FFF5EB;
}
/* line 78, ../sass/_header.scss */
.navbar-inverse .navbar-nav > li > a, .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
font-family: "Work Sans", cursive;
font-size: large;
color: #FFB363;
background: transparent;
}
@media (min-width: 768px) {
/* line 78, ../sass/_header.scss */
.navbar-inverse .navbar-nav > li > a, .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
color: #FFF5EB;
}
}
/* line 108, ../sass/_forms.scss */
.btn-primary {
/**
* This mixins allows defining color-related properties of buttons.
*
* It sets the following properties:
* color: $color, except for disabled-like buttons.
* border-color: $border.
* background-color: Depending on button state:
* - Default, disabled:
* $background-base
* - Hovered, focused, actived, responsible of an opened dropdown:
* (one is sufficent)
* $background-special
*
* ## Bootstrap compatibility
*
* This mixin can be used to replace colors behaviors of Bootstrap buttons.
* Indeed, this mixin aims to replace each definition done by the
* 'button-variant' Bootstrap mixin.
*
*/
color: white;
background-color: #FF6969;
border-color: #FF6969;
/**
* This mixin applies content if the button is in at least one of the
* following states:
*
* - hovered,
* - focused,
* - actived,
* - is responsible of an opened dropdown.
*
* Where possible, state is checked from class attribute and
* :pseudo-classes.
*
* ## Bootstrap compatibility
*
* If content defines 'color', 'background-color' and 'border', it is safe
* to use this mixin with Bootstrap buttons as it will overrides all
* Bootstrap color defaults of the previous cases.
* To be precise, this covers all special important-like cases of the
* Bootstrap mixin 'button-variant' (except the 'disabled' case).
*
*/
}
/* line 10, ../sass/_forms.scss */
.btn-primary:focus, .btn-primary.focus, .btn-primary:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969;
}
/* line 3, ../sass/_forms.scss */
.btn-primary:active, .btn-primary.active {
color: white;
background-color: #FF9191;
border-color: #FF6969;
}
/* line 10, ../sass/_forms.scss */
.btn-primary:active:focus, .btn-primary:active.focus, .btn-primary:active:hover, .btn-primary.active:focus, .btn-primary.active.focus, .btn-primary.active:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969;
}
/* line 26, ../sass/_forms.scss */
.open > .btn-primary.dropdown-toggle {
color: white;
background-color: #FF9191;
border-color: #FF6969;
}
/* line 10, ../sass/_forms.scss */
.open > .btn-primary.dropdown-toggle:focus, .open > .btn-primary.dropdown-toggle.focus, .open > .btn-primary.dropdown-toggle:hover {
color: white;
background-color: #FF9191;
border-color: #FF6969;
}
/* line 10, ../sass/_forms.scss */
.btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:hover {
background-color: #FF6969;
border-color: #FF6969;
}
/* line 102, ../sass/_forms.scss */
.btn-primary .badge {
color: #FF6969;
background-color: white;
}
/* line 113, ../sass/_forms.scss */
form#filter_form .form-group {
padding-right: 20px;
}
/* line 117, ../sass/_forms.scss */
form#filter_form ul.form-control {
background-color: transparent;
border: none;
box-shadow: none;
}
/* line 2, ../sass/_tree.scss */
.tree {
font-size: large;
}
/* line 4, ../sass/_tree.scss */
.tree ul, .tree li {
position: relative;
}
/* line 8, ../sass/_tree.scss */
.tree ul {
list-style: none;
padding-left: 32px;
}
/* line 13, ../sass/_tree.scss */
.tree li::before,
.tree li::after {
content: "";
position: absolute;
left: -12px;
}
/* line 19, ../sass/_tree.scss */
.tree li::before {
border-top: 3px solid #FFC282;
top: 9px;
width: 8px;
height: 0;
}
/* line 25, ../sass/_tree.scss */
.tree li::after {
border-left: 3px solid #FFC282;
height: 100%;
width: 0px;
top: 2px;
}
/* line 31, ../sass/_tree.scss */
.tree ul > li:last-child::after {
height: 8px;
}
/* line 4, ../sass/_filters.scss */
#filter_form .form-group .col-md-3, #filter_form .form-group .col-md-9 {
float: none;
}
/* line 7, ../sass/_filters.scss */
#filter_form .form-group ul.form-control {
padding-left: 15px;
list-style: none;
height: auto;
}
/* line 12, ../sass/_filters.scss */
#filter_form .form-group ul.form-control a.selected {
text-decoration: underline;
color: #c40000;
}
/* line 18, ../sass/_dashed-shadows.scss */
.dashed-shadow {
position: relative;
top: 8px;
left: 8px;
display: inline-block;
color: #ba9186;
}
/* line 25, ../sass/_dashed-shadows.scss */
.dashed-shadow:before {
content: " ";
display: block;
position: absolute;
top: -8px;
left: -8px;
bottom: -2px;
right: -2px;
z-index: 1;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjEuMCIgeDI9IjEuMCIgeTI9IjAuMCI+PHN0b3Agb2Zmc2V0PSIxMi41JSIgc3RvcC1jb2xvcj0iI2U4ZTNjNyIvPjxzdG9wIG9mZnNldD0iMTIuNSUiIHN0b3AtY29sb3I9IiNlOGUzYzciIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSIzNy41JSIgc3RvcC1jb2xvcj0iI2U4ZTNjNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjM3LjUlIiBzdG9wLWNvbG9yPSIjZThlM2M3Ii8+PHN0b3Agb2Zmc2V0PSI2Mi41JSIgc3RvcC1jb2xvcj0iI2U4ZTNjNyIvPjxzdG9wIG9mZnNldD0iNjIuNSUiIHN0b3AtY29sb3I9IiNlOGUzYzciIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI4Ny41JSIgc3RvcC1jb2xvcj0iI2U4ZTNjNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9Ijg3LjUlIiBzdG9wLWNvbG9yPSIjZThlM2M3Ii8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
background-size: 100%;
background-image: -moz-linear-gradient(45deg, #e8e3c7 12.5%, rgba(232, 227, 199, 0) 12.5%, rgba(232, 227, 199, 0) 37.5%, #e8e3c7 37.5%, #e8e3c7 62.5%, rgba(232, 227, 199, 0) 62.5%, rgba(232, 227, 199, 0) 87.5%, #e8e3c7 87.5%);
background-image: -webkit-linear-gradient(45deg, #e8e3c7 12.5%, rgba(232, 227, 199, 0) 12.5%, rgba(232, 227, 199, 0) 37.5%, #e8e3c7 37.5%, #e8e3c7 62.5%, rgba(232, 227, 199, 0) 62.5%, rgba(232, 227, 199, 0) 87.5%, #e8e3c7 87.5%);
background-image: linear-gradient(45deg, #e8e3c7 12.5%, rgba(232, 227, 199, 0) 12.5%, rgba(232, 227, 199, 0) 37.5%, #e8e3c7 37.5%, #e8e3c7 62.5%, rgba(232, 227, 199, 0) 62.5%, rgba(232, 227, 199, 0) 87.5%, #e8e3c7 87.5%);
background-size: 6px 6px;
}
/* line 54, ../sass/_dashed-shadows.scss */
.dashed-shadow:hover:before {
animation: dash-animation 30s infinite linear;
}
/* line 58, ../sass/_dashed-shadows.scss */
.dashed-shadow:after {
z-index: 2;
content: attr(data-text);
position: absolute;
left: -8px;
top: -8px;
color: #b85b3f;
text-shadow: 3px 3px #e8e3c7;
}
/* MISE EN FORME GÉNÉRALE */
/* line 12, ../sass/global.scss */
html {
height: 100%;
background-color: #FFFBEF;
}
/* line 17, ../sass/global.scss */
body {
font-family: "Saira Semi Condensed", sans-serif;
font-size: medium;
}
/* line 22, ../sass/global.scss */
#principal {
background-color: #FFFBEF;
}
/*MAIN*/
/* line 27, ../sass/global.scss */
main {
background-color: #FFFBEF;
border-width: 2px;
border-color: #375362;
border-style: none;
border-collapse: collapse;
display: table-cell;
margin-top: 0px;
padding: 0px;
}
/* line 37, ../sass/global.scss */
main .fuid, main h1, main h2, main h3 {
margin-left: -15px;
margin-right: -15px;
margin-top: 0px;
margin-bottom: 0px;
}
/* line 43, ../sass/global.scss */
main h1, main h2, main h3 {
margin-top: -2px;
margin-bottom: -2px;
margin-left: -17px;
margin-right: -17px;
color: white;
padding-left: 15px;
padding-right: 15px;
}
/* line 52, ../sass/global.scss */
main h1 {
font-family: "Capriola", sans-serif;
font-weight: 600;
padding-bottom: 10px;
padding-top: 15px;
background-color: #4F778C;
}
/* line 59, ../sass/global.scss */
main h1.activity {
background-color: #4FADB8;
}
/* line 62, ../sass/global.scss */
main h1.event {
background-color: #3488A6;
}
/* line 65, ../sass/global.scss */
main h1.todo {
background-color: #F19F5D;
}
/* line 68, ../sass/global.scss */
main h1.equipment {
background-color: #E75571;
}
/* line 71, ../sass/global.scss */
main h1.staff {
background-color: #3BAD89;
}
/* line 75, ../sass/global.scss */
main h2, main h3 {
border-bottom: 2px solid #5D8CA6;
padding-bottom: 5px;
padding-top: 10px;
font-family: "Capriola", sans-serif;
font-weight: 600;
font-size: x-large;
background-color: #BDD2DE;
}
/* line 84, ../sass/global.scss */
main h2.activity, main h3.activity {
background-color: #5ED1DC;
border-color: #4FADB8;
}
/* line 88, ../sass/global.scss */
main h2.event, main h3.event {
background-color: #3999BA;
border-color: #3488A6;
}
/* line 92, ../sass/global.scss */
main h2.todo, main h3.todo {
background-color: #FF9C4D;
border-color: #F19F5D;
}
/* line 96, ../sass/global.scss */
main h2.equipment, main h3.equipment {
background-color: #FF5C79;
border-color: #E75571;
}
/* line 100, ../sass/global.scss */
main h2.staff, main h3.staff {
background-color: #42C2A2;
border-color: #3BAD89;
}
/* line 105, ../sass/global.scss */
main h3 {
background-color: #F0FAFF;
color: #4F778C;
}
/* line 108, ../sass/global.scss */
main h3.activity {
background-color: #F0FAFF;
color: #5ED1DC;
}
/* line 112, ../sass/global.scss */
main h3.event {
background-color: #F0FAFF;
color: #3999BA;
}
/* line 116, ../sass/global.scss */
main h3.todo {
background-color: #F0FAFF;
color: #FF9C4D;
}
/* line 120, ../sass/global.scss */
main h3.equipment {
background-color: #F0FAFF;
color: #FF5C79;
}
/* line 124, ../sass/global.scss */
main h3.staff {
background-color: #F0FAFF;
color: #42C2A2;
}
/* line 129, ../sass/global.scss */
main a {
color: #FF6969;
}
/* line 132, ../sass/global.scss */
main a:hover, main a:active, main a:focus {
color: #FF6969;
}
/* line 139, ../sass/global.scss */
main .text {
padding: 15px;
}
/*ASIDE*/
/* line 145, ../sass/global.scss */
aside {
background-color: #375362;
color: white;
margin-top: 0px;
padding: 0px !important;
}
/* line 151, ../sass/global.scss */
aside a {
color: #FF9191;
}
/* line 154, ../sass/global.scss */
aside a:hover, aside a:active, aside a:focus {
color: #FF9191;
}
/* line 161, ../sass/global.scss */
aside code {
color: #375362;
background-color: #BDD2DE;
}
/* line 166, ../sass/global.scss */
aside .heading {
padding: 8px 15px;
font-size: 32px;
line-height: 1.3;
text-align: center;
}
/* line 172, ../sass/global.scss */
aside .heading.inverted {
background-color: #FFF5EB;
color: black;
}
/* line 177, ../sass/global.scss */
aside .heading.small {
font-size: 25px;
}
/* line 180, ../sass/global.scss */
aside .heading.small .sub {
font-size: 0.7em;
font-weight: normal;
}
/* line 186, ../sass/global.scss */
aside .heading .sub {
font-size: 0.7em;
font-weight: normal;
}
/* line 191, ../sass/global.scss */
aside .heading.separator {
border-bottom-color: #FF9191;
border-bottom-style: solid;
}
/* line 197, ../sass/global.scss */
aside .text {
padding: 15px;
}
/* line 200, ../sass/global.scss */
aside .text.inverted {
background-color: #FFF5EB;
color: black;
}
@media (min-width: 768px) {
/* line 209, ../sass/global.scss */
main {
margin-top: 20px;
border-style: dashed;
}
/* line 213, ../sass/global.scss */
aside {
margin-top: 20px;
}
}
/* line 218, ../sass/global.scss */
hr {
border-top: 1px solid #FFB363;
}
/* line 223, ../sass/global.scss */
span.vsep {
padding-left: 5px;
padding-right: 5px;
}
/* line 228, ../sass/global.scss */
div.tag-list {
margin-top: 20px;
}
/* line 232, ../sass/global.scss */
code {
font-size: small;
}
/* line 236, ../sass/global.scss */
.module-list {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
align-items: stretch;
flex-wrap: wrap;
}
/* line 244, ../sass/global.scss */
a.module {
padding: 20px 40px;
margin: 5px;
border-bottom-style: solid;
font-size: large;
display: block;
border-bottom-color: #375362;
background-color: #BDD2DE;
color: #375362;
}
/* line 256, ../sass/global.scss */
a.module.activity {
border-bottom-color: #4FADB8;
background-color: #CAE4E7;
color: #4FADB8;
}
/* line 262, ../sass/global.scss */
a.module.event {
border-bottom-color: #3488A6;
background-color: #AAD5E2;
color: #3488A6;
}
/* line 268, ../sass/global.scss */
a.module.todo {
border-bottom-color: #F19F5D;
background-color: #FFDEBC;
color: #F19F5D;
}
/* line 274, ../sass/global.scss */
a.module.equipment {
border-bottom-color: #E75571;
background-color: #FECAD6;
color: #E75571;
}
/* line 280, ../sass/global.scss */
a.module.staff {
border-bottom-color: #3BAD89;
background-color: #A9E1D7;
color: #3BAD89;
}
/* line 286, ../sass/global.scss */
a.module:hover, a.module:active, a.module:focus {
text-decoration: none;
color: #F0FAFF;
background-color: #375362;
}
/* line 293, ../sass/global.scss */
a.module:hover.activity, a.module:active.activity, a.module:focus.activity {
background-color: #5ED1DC;
}
/* line 296, ../sass/global.scss */
a.module:hover.event, a.module:active.event, a.module:focus.event {
background-color: #3999BA;
}
/* line 299, ../sass/global.scss */
a.module:hover.equipment, a.module:active.equipment, a.module:focus.equipment {
background-color: #FF5C79;
}
/* line 302, ../sass/global.scss */
a.module:hover.todo, a.module:active.todo, a.module:focus.todo {
background-color: #FF9C4D;
}
/* line 305, ../sass/global.scss */
a.module:hover.staff, a.module:active.staff, a.module:focus.staff {
background-color: #42C2A2;
}
/* line 311, ../sass/global.scss */
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
/* line 322, ../sass/global.scss */
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
/* line 330, ../sass/global.scss */
.collapsible:hover {
background-color: #555;
}
/* line 334, ../sass/global.scss */
.collapsible h3 {
margin-top: 0px;
margin-bottom: 0px;
display: inline-block;
}
/* line 341, ../sass/global.scss */
.active {
background-color: #555;
}
/* line 344, ../sass/global.scss */
.active:after {
content: "\2212";
}
/* line 348, ../sass/global.scss */
.content {
padding: 8px 18px;
display: none;
background-color: #f1f1f1;
}
/* line 353, ../sass/global.scss */
.content.fluid {
padding: 0px 0px;
background-color: transparent;
}
/* line 358, ../sass/global.scss */
.content h4 {
font-size: x-large;
font-weight: bold;
display: inline-block;
margin: 0px 0px;
}
/* line 367, ../sass/global.scss */
.planning .activity {
padding: 8px 18px;
padding-top: 8px;
padding-bottom: 12px;
border-left: none;
border-right: 6px solid #FF9191;
}
/* line 375, ../sass/global.scss */
.planning .activity.inverted {
border-left: 6px solid #FF9191;
border-right: none;
}
/* line 380, ../sass/global.scss */
.planning .activity .activity-title {
font-size: large;
}
/* line 387, ../sass/global.scss */
.glyphicon.yes {
color: #55C487 !important;
}
/* line 390, ../sass/global.scss */
.glyphicon.no {
color: #E36268 !important;
}
/* line 393, ../sass/global.scss */
.glyphicon.dunno {
color: #5599C4 !important;
}
/* line 398, ../sass/global.scss */
.sending-request {
position: relative;
}
/* line 401, ../sass/global.scss */
.sending-request:after {
content: "Chargement...";
position: absolute;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.8;
color: #777;
text-align: center;
box-sizing: border-box;
z-index: 5;
top: 0;
left: 0;
padding: 8%;
}

View file

@ -1,416 +0,0 @@
/*NE PAS MODIFIER LE FICHIER .CSS, MAIS PLUTÔT LE
FICHIER .SCSS */
@import '_variables';
@import '_messages';
@import '_header';
@import '_forms';
@import '_tree';
@import '_filters';
//i@import '_dashed-shadows';
/* MISE EN FORME GÉNÉRALE */
html {
height : 100% ;
background-color: $html-background;
}
body {
font-family: $font_normal;
font-size: medium;
}
#principal {
background-color: $html-background;
}
/*MAIN*/
main {
background-color:$content-background;
border-width: 2px;
border-color: $content-border;
border-style: none;
border-collapse: collapse;
display: table-cell;
margin-top:0px;
padding: 0px;
.fuid, h1, h2, h3 {
margin-left: -15px;
margin-right: -15px;
margin-top: 0px;
margin-bottom: 0px;
}
h1, h2, h3 {
margin-top: -2px;
margin-bottom: -2px;
margin-left: -17px;
margin-right: -17px;
color: white;
padding-left: 15px;
padding-right: 15px;
}
h1 {
font-family: $font_bold;
font-weight: 600;
padding-bottom: 10px;
padding-top: 15px;
background-color: $h1_background;
&.activity {
background-color: $h1_background_activity;
}
&.event {
background-color: $h1_background_event;
}
&.todo {
background-color: $h1_background_todo;
}
&.equipment {
background-color: $h1_background_equipment;
}
&.staff {
background-color: $h1_background_staff;
}
}
h2, h3 {
border-bottom : 2px solid $main_c5;
padding-bottom : 5px ;
padding-top: 10px;
font-family: $font_bold;
font-weight: 600;
font-size: x-large;
background-color: $h2_background;
&.activity {
background-color: $h2_background_activity;
border-color: $activity_c8;
}
&.event {
background-color: $h2_background_event;
border-color: $event_c8;
}
&.todo {
background-color: $h2_background_todo;
border-color: $todo_c8;
}
&.equipment {
background-color: $h2_background_equipment;
border-color: $equipment_c8;
}
&.staff {
background-color: $h2_background_staff;
border-color: $staff_c8;
}
}
h3 {
background-color: $h3_background;
color: $main_c6;
&.activity {
background-color: $h3_background_activity;
color: $activity_c7;
}
&.event {
background-color: $h3_background_event;
color: $event_c7;
}
&.todo {
background-color: $h3_background_todo;
color: $todo_c7;
}
&.equipment {
background-color: $h3_background_equipment;
color: $equipment_c7;
}
&.staff {
background-color: $h3_background_staff;
color: $staff_c7;
}
}
a {
color: $main_bold_color;
&:hover,
&:active,
&:focus {
color : $main_bold_color;
}
}
.text {
padding: 15px;
}
}
/*ASIDE*/
aside {
background-color:$aside-background;
color: white;
margin-top: 0px;
padding: 0px!important;
a {
color: $main_soft_color;
&:hover,
&:active,
&:focus {
color : $main_soft_color;
}
}
code {
color: $main_c7;
background-color: $main_c3;
}
.heading {
padding: 8px 15px;
font-size: 32px;
line-height: 1.3;
text-align:center;
&.inverted {
background-color:$second_white_color;
color:black;
}
&.small {
font-size: 25px;
.sub {
font-size: 0.7em;
font-weight: normal;
}
}
.sub {
font-size: 0.7em;
font-weight: normal;
}
&.separator {
border-bottom-color: $main_soft_color;
border-bottom-style: solid;
}
}
.text {
padding: 15px;
&.inverted {
background-color:$second_white_color;
color:black;
}
}
}
@media (min-width: 768px) {
main {
margin-top:20px;
border-style: dashed;
}
aside {
margin-top:20px;
}
}
hr {
border-top : 1px solid $second_bold_color ;
}
span.vsep {
padding-left: 5px;
padding-right: 5px;
}
div.tag-list {
margin-top: 20px;
}
code {
font-size: small;
}
.module-list {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
align-items: stretch;
flex-wrap: wrap;
}
a.module {
padding: 20px 40px;
margin: 5px;
border-bottom-style: solid;
font-size: large;
display: block;
border-bottom-color: $main_c7;
background-color: $main_c3;
color: $main_c7;
&.activity {
border-bottom-color: $activity_c8;
background-color: $activity_c3;
color: $activity_c8;
}
&.event {
border-bottom-color: $event_c8;
background-color: $event_c3;
color: $event_c8;
}
&.todo {
border-bottom-color: $todo_c8;
background-color: $todo_c3;
color: $todo_c8;
}
&.equipment {
border-bottom-color: $equipment_c8;
background-color: $equipment_c3;
color: $equipment_c8;
}
&.staff {
border-bottom-color: $staff_c8;
background-color: $staff_c3;
color: $staff_c8;
}
&:hover,
&:active,
&:focus {
text-decoration: none;
color: $main_c1;
background-color: $main_c7;
&.activity {
background-color: $activity_c7;
}
&.event {
background-color: $event_c7;
}
&.equipment {
background-color: $equipment_c7;
}
&.todo {
background-color: $todo_c7;
}
&.staff {
background-color: $staff_c7;
}
}
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
&: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;
}
}
.sending-request {
position: relative;
&:after {
content: "Chargement...";
position: absolute;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.8;
color: #777;
text-align: center;
box-sizing: border-box;
z-index: 5;
top: 0;
left: 0;
padding: 8%;
}
}

View file

@ -1,5 +0,0 @@
/* Welcome to Compass. Use this file to write IE specific override styles.
* Import this file using the following HTML or equivalent:
* <!--[if IE]>
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
* <![endif]--> */

View file

@ -1,3 +0,0 @@
/* Welcome to Compass. Use this file to define print styles.
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */

View file

@ -1,68 +0,0 @@
/* Welcome to Compass.
* In this file you should write your main styles. (or centralize your imports)
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
/* line 5, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
}
/* line 22, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html {
line-height: 1;
}
/* line 24, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
/* line 26, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* line 28, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
/* line 30, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
/* line 103, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
/* line 32, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
/* line 116, ../../../../../.gem/ruby/2.5.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}

View file

@ -1,66 +0,0 @@
@import "compass/css3";
//Variables here:
//(alongside with commented suggestions)
$foreground-color:#b85b3f;//black;
$background-color:#e8e3c7;//white
$shadow-color:#ba9186;//$foreground-color;
$distance:8px;
$cut-distance:3px;//$distance/4;
$strips-size:6px; //10px
$strips-ratio:50%;//70%
$strips-angle:45deg;//90deg;
//cray stuff yo. be sure to try (if you please)
$animate:false;//true
$fixed:false;//true
.dashed-shadow{
position:relative;
top:$distance;
left:$distance;
display:inline-block;
color:$shadow-color;
}
.dashed-shadow:before{
content:" ";
display:block;
position:absolute;
$bleeding-horizontal:10px;
$bleeding-vertical:0px;
top:-$bleeding-vertical - $distance;
left:-$bleeding-vertical - $distance;
bottom:-$bleeding-horizontal + $distance;
right:-$bleeding-horizontal + $distance;
z-index:1;
$color:$background-color;
$size:$strips-ratio/2;
$halfSize:$size/2;
$p1:$halfSize;
$p2:50%-$halfSize;
$p3:50%+$halfSize;
$p4:100%-$halfSize;
$transparent:transparentize($color,1);
@include background-image(linear-gradient($strips-angle,$color $p1, $transparent $p1, $transparent $p2,$color $p2, $color $p3, $transparent $p3, $transparent $p4, $color $p4));
background-size:$strips-size $strips-size;
@if($animate){
animation:dash-animation 30s infinite linear;
}
@if($fixed){
background-attachment:fixed;
}
}
.dashed-shadow:hover:before{
animation:dash-animation 30s infinite linear;
}
.dashed-shadow:after{
z-index:2;
content:attr(data-text);
position:absolute;
left:-$distance;
top:-$distance;
color:$foreground-color;
text-shadow:$cut-distance $cut-distance $background-color;
}

View file

@ -1,18 +0,0 @@
// main: global.scss
#filter_form {
.form-group {
.col-md-3, .col-md-9 {
float: none;
}
ul.form-control {
padding-left: 15px;
list-style: none;
height: auto;
a.selected {
text-decoration: underline;
color: darken($main_soft_color, 40%);
}
}
}
}

View file

@ -1,24 +0,0 @@
// main: global.scss
.message-info {
color : #31708f;
background-color: #d9edf7;
border-color : #bce8f1;
}
.message-success {
color : #3c763d;
background-color: #dff0d8;
border-color : #d6e9c6;
}
.message-warning {
color : #8a6d3b;
background-color: #fcf8e3;
border-color : #faebcc;
}
.message-error {
color : #a94442;
background-color: #f2dede;
border-color : #ebccd1;
}
.alert {
margin-bottom: 0;
}

View file

@ -1,38 +0,0 @@
// main: global.scss
.tree {
font-size:large;
ul, li {
position: relative;
}
ul {
list-style: none;
padding-left: 32px;
}
li::before,
li::after {
content: "";
position: absolute;
left: -12px;
}
li::before {
border-top: 3px solid $second_soft_color;
top: 9px;
width: 8px;
height: 0;
}
li::after {
border-left: 3px solid $second_soft_color;
height: 100%;
width: 0px;
top: 2px;
}
ul > li:last-child::after {
height: 8px;
}
.category_node {
}
}

View file

@ -1,99 +0,0 @@
// main: global.scss
$main_c7: #375362;
$main_c6: #4F778C;
$main_c5: #5D8CA6;
$main_c3: #BDD2DE;
$main_c1: #F0FAFF;
$neutral_c2 : #F2EDDC;
$neutral_c1: #FFFBEF;
$activity_c8: #4FADB8;
$activity_c7: #5ED1DC;
$activity_c3: #CAE4E7;
$event_c8: #3488A6;
$event_c7: #3999BA;
$event_c3: #AAD5E2;
$todo_c8: #F19F5D;
$todo_c7: #FF9C4D;
$todo_c3: #FFDEBC;
$equipment_c8: #E75571;
$equipment_c7: #FF5C79;
$equipment_c3: #FECAD6;
$staff_c8: #3BAD89;
$staff_c7: #42C2A2;
$staff_c3: #A9E1D7;
/* LEGACY COLORS*/
$main_bold_color: #FF6969;
$main_soft_color: #FF9191;
$main_white_color: #FFEBEB;
$second_bold_color: #FFB363;
$second_soft_color: #FFC282;
$second_white_color: #FFF5EB;
$third_bold_color: #48B0C7;
$third_soft_color: #8FD4E3;
$third_white_color: #DCEAED;
/* COLORS */
/* Header */
$header-background: $main_c7;
$header-second-backgroud: $main_c5;
$header-color: white;
$underline-brand: $equipment_c7;
/* Général */
$html-background: $neutral_c1;
$content-background: $neutral_c1;
$content-border: $main_c7;
$aside-background: $main_c7;
$aside-inverted-background: $main_c5;
$title_border: $main_c7;
/* Le reste */
$btn-font-color: white;
$btn-bg-base: $main_bold_color;
$btn-bg-special: $main_soft_color;
$btn-border: $main_bold_color;
$yes_color: #55C487;
$no_color: #E36268;
$dunno_color: #5599C4;
/* Titres */
$h1_background: $main_c6;
$h2_background: $main_c3;
$h3_background: $main_c1;
$h1_background_activity: $activity_c8;
$h2_background_activity: $activity_c7;
$h3_background_activity: $main_c1;
$h1_background_event: $event_c8;
$h2_background_event: $event_c7;
$h3_background_event: $main_c1;
$h1_background_todo: $todo_c8;
$h2_background_todo: $todo_c7;
$h3_background_todo: $main_c1;
$h1_background_equipment: $equipment_c8;
$h2_background_equipment: $equipment_c7;
$h3_background_equipment: $main_c1;
$h1_background_staff: $staff_c8;
$h2_background_staff: $staff_c7;
$h3_background_staff: $main_c1;
/* FONTS */
$font_brand:'Lily Script One', cursive;
$font_nav:'Work Sans', cursive;
$font_bold:'Capriola', sans-serif;
$font_normal:'Saira Semi Condensed', sans-serif;

View file

@ -1,416 +0,0 @@
/*NE PAS MODIFIER LE FICHIER .CSS, MAIS PLUTÔT LE
FICHIER .SCSS */
@import '_variables';
@import '_messages';
@import '_header';
@import '_forms';
@import '_tree';
@import '_filters';
@import '_dashed-shadows';
/* MISE EN FORME GÉNÉRALE */
html {
height : 100% ;
background-color: $html-background;
}
body {
font-family: $font_normal;
font-size: medium;
}
#principal {
background-color: $html-background;
}
/*MAIN*/
main {
background-color:$content-background;
border-width: 2px;
border-color: $content-border;
border-style: none;
border-collapse: collapse;
display: table-cell;
margin-top:0px;
padding: 0px;
.fuid, h1, h2, h3 {
margin-left: -15px;
margin-right: -15px;
margin-top: 0px;
margin-bottom: 0px;
}
h1, h2, h3 {
margin-top: -2px;
margin-bottom: -2px;
margin-left: -17px;
margin-right: -17px;
color: white;
padding-left: 15px;
padding-right: 15px;
}
h1 {
font-family: $font_bold;
font-weight: 600;
padding-bottom: 10px;
padding-top: 15px;
background-color: $h1_background;
&.activity {
background-color: $h1_background_activity;
}
&.event {
background-color: $h1_background_event;
}
&.todo {
background-color: $h1_background_todo;
}
&.equipment {
background-color: $h1_background_equipment;
}
&.staff {
background-color: $h1_background_staff;
}
}
h2, h3 {
border-bottom : 2px solid $main_c5;
padding-bottom : 5px ;
padding-top: 10px;
font-family: $font_bold;
font-weight: 600;
font-size: x-large;
background-color: $h2_background;
&.activity {
background-color: $h2_background_activity;
border-color: $activity_c8;
}
&.event {
background-color: $h2_background_event;
border-color: $event_c8;
}
&.todo {
background-color: $h2_background_todo;
border-color: $todo_c8;
}
&.equipment {
background-color: $h2_background_equipment;
border-color: $equipment_c8;
}
&.staff {
background-color: $h2_background_staff;
border-color: $staff_c8;
}
}
h3 {
background-color: $h3_background;
color: $main_c6;
&.activity {
background-color: $h3_background_activity;
color: $activity_c7;
}
&.event {
background-color: $h3_background_event;
color: $event_c7;
}
&.todo {
background-color: $h3_background_todo;
color: $todo_c7;
}
&.equipment {
background-color: $h3_background_equipment;
color: $equipment_c7;
}
&.staff {
background-color: $h3_background_staff;
color: $staff_c7;
}
}
a {
color: $main_bold_color;
&:hover,
&:active,
&:focus {
color : $main_bold_color;
}
}
.text {
padding: 15px;
}
}
/*ASIDE*/
aside {
background-color:$aside-background;
color: white;
margin-top: 0px;
padding: 0px!important;
a {
color: $main_soft_color;
&:hover,
&:active,
&:focus {
color : $main_soft_color;
}
}
code {
color: $main_c7;
background-color: $main_c3;
}
.heading {
padding: 8px 15px;
font-size: 32px;
line-height: 1.3;
text-align:center;
&.inverted {
background-color:$second_white_color;
color:black;
}
&.small {
font-size: 25px;
.sub {
font-size: 0.7em;
font-weight: normal;
}
}
.sub {
font-size: 0.7em;
font-weight: normal;
}
&.separator {
border-bottom-color: $main_soft_color;
border-bottom-style: solid;
}
}
.text {
padding: 15px;
&.inverted {
background-color:$second_white_color;
color:black;
}
}
}
@media (min-width: 768px) {
main {
margin-top:20px;
border-style: dashed;
}
aside {
margin-top:20px;
}
}
hr {
border-top : 1px solid $second_bold_color ;
}
span.vsep {
padding-left: 5px;
padding-right: 5px;
}
div.tag-list {
margin-top: 20px;
}
code {
font-size: small;
}
.module-list {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
align-items: stretch;
flex-wrap: wrap;
}
a.module {
padding: 20px 40px;
margin: 5px;
border-bottom-style: solid;
font-size: large;
display: block;
border-bottom-color: $main_c7;
background-color: $main_c3;
color: $main_c7;
&.activity {
border-bottom-color: $activity_c8;
background-color: $activity_c3;
color: $activity_c8;
}
&.event {
border-bottom-color: $event_c8;
background-color: $event_c3;
color: $event_c8;
}
&.todo {
border-bottom-color: $todo_c8;
background-color: $todo_c3;
color: $todo_c8;
}
&.equipment {
border-bottom-color: $equipment_c8;
background-color: $equipment_c3;
color: $equipment_c8;
}
&.staff {
border-bottom-color: $staff_c8;
background-color: $staff_c3;
color: $staff_c8;
}
&:hover,
&:active,
&:focus {
text-decoration: none;
color: $main_c1;
background-color: $main_c7;
&.activity {
background-color: $activity_c7;
}
&.event {
background-color: $event_c7;
}
&.equipment {
background-color: $equipment_c7;
}
&.todo {
background-color: $todo_c7;
}
&.staff {
background-color: $staff_c7;
}
}
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
&: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;
}
}
.sending-request {
position: relative;
&:after {
content: "Chargement...";
position: absolute;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.8;
color: #777;
text-align: center;
box-sizing: border-box;
z-index: 5;
top: 0;
left: 0;
padding: 8%;
}
}

View file

@ -1,5 +0,0 @@
/* Welcome to Compass. Use this file to write IE specific override styles.
* Import this file using the following HTML or equivalent:
* <!--[if IE]>
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
* <![endif]--> */

View file

@ -1,3 +0,0 @@
/* Welcome to Compass. Use this file to define print styles.
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */

View file

@ -1,6 +0,0 @@
/* Welcome to Compass.
* In this file you should write your main styles. (or centralize your imports)
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
@import "compass/reset";

Some files were not shown because too many files have changed in this diff Show more