Group directory view
authorArthur Darcet <arthur.darcet@m4x.org>
Sat, 2 Feb 2013 18:57:19 +0000 (19:57 +0100)
committerArthur Darcet <arthur.darcet@m4x.org>
Sat, 2 Feb 2013 18:57:39 +0000 (19:57 +0100)
xnet/accounts/decorators.py
xnet/accounts/models.py
xnet/accounts/urls.py
xnet/accounts/views.py
xnet/site/static/css/groups.css [deleted file]
xnet/templates/groups/base.html
xnet/templates/groups/directory.html [new file with mode: 0644]
xnet/templates/groups/home.html
xnet/templates/groups/index.html

index 4496b10..825df8d 100644 (file)
@@ -1,4 +1,4 @@
-from functools import wraps
+import functools
 
 from django.http import HttpResponseForbidden
 from django.shortcuts import get_object_or_404
@@ -6,16 +6,21 @@ from django.shortcuts import get_object_or_404
 from .models import XGroup, Membership
 
 
-def group_required(view_func, level=Membership.LEVEL_MEMBER):
-    @wraps(view_func)
-    def _wrapped_view_func(request, group_id, *args, **kwargs):
-        group = get_object_or_404(XGroup, pk=group_id)
-        if request.user.memberships.filter(
-            xgroup=group,
-            level__gte=level,
-            state='enabled',
-        ).exists():
-            return view_func(request, group, *args, **kwargs)
-        else:
-            return HttpResponseForbidden()
-    return _wrapped_view_func
+class group_required(object):
+    def __init__(self, level=Membership.LEVEL_MEMBER):
+        self.level = level
+
+    def __call__(self, view_func):
+        @functools.wraps(view_func)
+        def wrapped_view_func(request, group_id, *args, **kwargs):
+            group = get_object_or_404(XGroup, pk=group_id)
+            membership = request.user.memberships.filter(
+                xgroup=group,
+                level__gte=self.level,
+                state='enabled',
+            )
+            if membership.exists():
+                return view_func(request, group, *args, membership=membership[0], **kwargs)
+            else:
+                return HttpResponseForbidden()
+        return wrapped_view_func
index 6308429..bba15c5 100644 (file)
@@ -63,8 +63,8 @@ class XGroup(models.Model):
     dns = models.CharField(max_length=128, verbose_name=u"dns domain", blank=True)
 
     web = models.CharField(max_length=255, verbose_name=u"website", blank=True)
-    #contact = models.ForeignKey('')
-    description = models.TextField()
+    #contact = models.ForeignKey('Account')
+    description = models.TextField(blank=True)
     logo = ImageField(upload_to='logos', null=True, blank=True)
 
     class Meta:
index 772093c..5f4b864 100644 (file)
@@ -5,4 +5,6 @@ urlpatterns = patterns(
     'xnet.accounts.views',
     url(r'^$', 'index', name='group-list'),
     url(r'^home/([0-9]+)$', 'home', name='group-home'),
+    url(r'^directory/([0-9]+)$', 'directory', name='group-directory'),
+    url(r'^([a-zA-Z0-9]+)/delete/([a-zA-Z0-9\.]+)$', 'membership_delete', name='membership-delete'),
 )
index e525b86..aab40ea 100644 (file)
@@ -1,11 +1,35 @@
 from django.contrib import messages
 from django.shortcuts import get_object_or_404, render
 
-from xnet.accounts.models import XGroup
+from xnet.accounts.decorators import group_required
+from xnet.accounts.models import XGroup, Membership
 
 
 def index(request):
-    return render(request, 'groups/index.html', {'groups': XGroup.objects.order_by('kind')})
+    return render(request, 'groups/index.html', {
+        'groups': XGroup.objects.order_by('kind'),
+        'sidebar': 'list',
+    })
 
 def home(request, pk):
-    return render(request, 'groups/home.html', {'group': get_object_or_404(XGroup, pk=pk)})
+    return render(request, 'groups/home.html', {
+        'group': get_object_or_404(XGroup, pk=pk),
+        'sidebar': 'home',
+    })
+
+@group_required()
+def directory(request, group, membership=None):
+    print(group.memberships.filter(state='enabled').order_by('level'))
+    return render(request, 'groups/directory.html', {
+        'group': group,
+        'memberships': group.memberships. \
+            filter(state='enabled'). \
+            select_related(). \
+            order_by('level'),
+        'is_admin': membership.level == Membership.LEVEL_ADMIN,
+        'sidebar': 'directory',
+    })
+
+@group_required(level=Membership.LEVEL_ADMIN)
+def membership_delete(request, group, to_delete):
+    pass
diff --git a/xnet/site/static/css/groups.css b/xnet/site/static/css/groups.css
deleted file mode 100644 (file)
index db2d9a7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.group_list {
-    float: left;
-    border: solid 1px black;
-    border-radius: 5px;
-    background-color: white;
-    margin: 1%;
-    width: 22%;
-}
-.group_list h3 {
-    margin: 0 10px 0 10px;
-    font-size: medium;
-}
-.group_list li {
-    list-style: none;
-}
-
-.group-desc .logo {
-    float: right;
-    margin: 0;
-}
-.group-desc p {
-    float: left;
-    clear: left;
-}
index 793fd09..eb9eeab 100644 (file)
@@ -1,7 +1,21 @@
 {% extends "base.html" %}
 {% load static %}
 
-{% block css %}
-    {{ block.super }}
-    <link href="{% static 'css/groups.css' %}" rel="stylesheet">
+{% block sidebar %}
+<ul class="nav nav-tabs nav-stacked">
+    <li {% if sidebar == 'list' %}class="active"{% endif %}>
+        <a href="{% url 'accounts:group-list' %}">Tous les groupes</a>
+    </li>
+</ul>
+{% if group %}
+    <h3>{{ group }}</h3>
+    <ul class="nav nav-tabs nav-stacked">
+        <li {% if sidebar == 'home' %}class="active"{% endif %}>
+            <a href="{% url 'accounts:group-home' group.pk %}">Fiche</a>
+        </li>
+        <li {% if sidebar == 'directory' %}class="active"{% endif %}>
+            <a href="{% url 'accounts:group-directory' group.pk %}">Annuaire</a>
+        </li>
+    </ul>
+{% endif %}
 {% endblock %}
diff --git a/xnet/templates/groups/directory.html b/xnet/templates/groups/directory.html
new file mode 100644 (file)
index 0000000..d362961
--- /dev/null
@@ -0,0 +1,62 @@
+{% extends "groups/base.html" %}
+{% load static %}
+
+{% block content %}
+<div class="group-dirctory">
+    <h1>{{ group.name }}</h1>
+    {% if is_admin %}
+    <form>
+        <div class="input-prepend input-append">
+            <span class="add-on"><i class="icon-envelope"></i></span>
+            <input type="text" class="input-xlarge" type="email" required placeholder="Email">
+            <div class="btn-group">
+                <button class="btn" tabindex="-1">Ajouter</button>
+                <button class="btn dropdown-toggle" data-toggle="dropdown" tabindex="-1">
+                    <span class="caret"></span>
+                </button>
+                <ul class="dropdown-menu">
+                    <li><a href="#">Action</a></li>
+                    <li><a href="#">Another action</a></li>
+                    <li><a href="#">Something else here</a></li>
+                    <li class="divider"></li>
+                    <li><a href="#">Separated link</a></li>
+                </ul>
+            </div>
+        </div>
+    </form>
+    {% endif %}
+    <table class="table table-striped" id="directory">
+        <thead>
+            <tr>
+                <th>Nom</th>
+                <th>Promo</th>
+                <th>Contact</th>
+                <th filter="false"></th>
+            </tr>
+        </thead>
+        <tbody>
+        {% for memb in memberships %}
+            <tr>
+                <td>
+                    <span {% if memb.is_admin %}class="admin"{% endif %}>
+                        {{ memb.xuser }}
+                    </span>
+                </td>
+                <td>PROMO</td>
+                <td>
+                    <a href="mailto:{{ memb.email }}">
+                        <i class="icon-envelope"></i>
+                    </a>
+                    {% if is_admin %}
+                        <i class="icon-pencil"></i>
+                        <a href="{% url 'accounts:membership-delete' group.short memb.xuser.username %}">
+                            <i class="icon-trash"></i>
+                         </a>
+                    {% endif %}
+                </td>
+            </tr>
+        {% endfor %}
+        </tbody>
+    </table>
+</div>
+{% endblock %}
index d15a214..5876512 100644 (file)
@@ -1,14 +1,16 @@
 {% extends "groups/base.html" %}
-{% block js %}
-    <script type="text/javascript">
-    </script>
-{% endblock %}
 
 {% block content %}
 <div class="group-desc">
     <h1>{{ group.name }}</h1>
-    {% if group.logo %}<img class="logo" src="{{ group.logo.url_70x70 }}" />{% endif %}
-    {% if group.web %}<p><span>Web</span> : <a href="{{ group.web }}">{{ group.web }}</a></p>{% endif %}
-    {% if group.description %}<p>{{ group.description }}</p>{% endif %}
+    {% if group.logo %}<img class="pull-right" src="{{ group.logo.url_70x70 }}" />{% endif %}
+    <div class="pull-left">
+        {% if group.web %}
+            <p><span>Web</span> : <a href="{{ group.web }}">{{ group.web }}</a></p>
+        {% endif %}
+        {% if group.description %}
+            <p class="pull-left">{{ group.description }}</p>
+        {% endif %}
+    </div>
 </div>
 {% endblock %}
index 3d47d7f..9d3cd59 100644 (file)
 {% block content %}
 {% regroup groups by get_kind_display as group_list %}
 {% for group in group_list %}
-<div class="group_list" id="{{ group.grouper }}_type">
-    <h3>{{ group.grouper }}</h3>
-    <input type="text" class="search-field" data-target="{{ group.grouper }}_type" />
-    <ul>
+<div class="span3 well" id="{{ group.grouper }}_type">
+    <h5>{{ group.grouper }}</h5>
+    <input type="text" class="search-field input-block-level" data-target="{{ group.grouper }}_type" />
+    <ul class="unstyled">
         {% for item in group.list %}
           <li><a href="{% url 'accounts:group-home' item.pk %}">{{ item }}</a></li>
         {% endfor %}