Projet

Général

Profil

0001-review-backoffice-homepage-and-announce-management-1.patch

Serghei Mihai (congés, retour 15/05), 11 septembre 2016 20:01

Télécharger (14,9 ko)

Voir les différences:

Subject: [PATCH] review backoffice homepage and announce management (#12908)

 corbo/manage_urls.py                       |   7 +-
 corbo/models.py                            |   6 ++
 corbo/static/css/corbo.css                 |  59 +++++++++----
 corbo/templates/corbo/category_detail.html |  44 ++++++++++
 corbo/templates/corbo/manage.html          | 133 ++++++++---------------------
 corbo/views.py                             |  60 ++++++-------
 6 files changed, 167 insertions(+), 142 deletions(-)
 create mode 100644 corbo/templates/corbo/category_detail.html
corbo/manage_urls.py
1 1
from django.conf.urls import patterns, include, url
2 2

  
3 3
from .views import add_announce, edit_announce, delete_announce, \
4
    add_category, edit_category, delete_category, manage, menu_json
4
    add_category, edit_category, view_category, delete_category, manage, \
5
    add_announce_for_category, menu_json
5 6

  
6 7
urlpatterns = patterns('',
7 8
            url(r'^$', manage, name='manage'),
......
10 11
                name='edit_announce'),
11 12
            url(r'^announce/delete/(?P<pk>\d+)$', delete_announce,
12 13
                name='delete_announce'),
14
            url(r'^category/(?P<pk>\d+)/$', view_category,
15
                name='view_category'),
16
            url(r'^category/(?P<pk>\d+)/announce/$', add_announce_for_category,
17
                name='add_announce_for_category'),
13 18
            url(r'^category/add$', add_category,
14 19
                name='add_category'),
15 20
            url(r'^category/edit/(?P<pk>\d+)$', edit_category,
corbo/models.py
31 31
    def __unicode__(self):
32 32
        return self.name
33 33

  
34
    def get_announces_number(self):
35
        return self.announce_set.all().count()
36

  
37
    def get_subscriptions_number(self):
38
        return self.subscription_set.all().count()
39

  
34 40

  
35 41
class Announce(models.Model):
36 42
    category  = models.ForeignKey('Category', verbose_name=_('category'))
corbo/static/css/corbo.css
9 9

  
10 10
a:link, a:visited, a:hover {
11 11
    text-decoration: none;
12
    color: #000;
13 12
}
14 13

  
15 14
header h1 {
......
154 153
#management ul li {
155 154
    padding: 5px;
156 155
    border: 1px solid #aaa;
157
    background: #eee;
158
    margin:2px 0;
159
    border-radius: .3em;
160 156
    position: relative;
161 157
}
162 158

  
......
164 160
    margin: .4em 0;
165 161
}
166 162

  
167
.title {
168
    font-size: .9em;
169
    font-weight: bold;
170
}
171

  
172 163
.preview {
173 164
    padding-left: 10px;
174 165
    font-size: .8em;
......
181 172
    right: 5px;
182 173
}
183 174

  
175
ul.objects-list.single-links li .actions a {
176
    color: #999;
177
    display: inline;
178
    padding: 0;
179
}
180

  
181
.actions a:hover {
182
    color: #333;
183
}
184

  
184 185
.status {
185 186
    position: absolute;
186 187
    padding: 2px;
......
200 201

  
201 202
.status .icon {
202 203
    color: #888;
204
    font-size: 0.9em;
203 205
}
204 206

  
205 207
.status .published:before {
......
220 222
}
221 223

  
222 224
#management .datetime {
223
    width: 15%;
224
    float: right;
225
    margin-right: 35px;
225
    position: absolute;
226
    top: 3px;
227
    right: 0;
228
    width: 25%;
226 229
}
227 230

  
228 231
.empty {
......
295 298
    clear: both;
296 299
}
297 300

  
298
.subscriptions_number {
299
    font-size: 0.8em;
301
.categories-listing {
302
    -webkit-column-width: 13em;
303
    -moz-column-width: 13em;
304
    column-width: 13em;
305
}
306

  
307
.categories-listing div.category {
308
    border-radius: 0.3em;
309
    display: table;
310
    min-width: 10em;
311
    position: relative;
312
    padding:6px;
313
    margin-bottom: 10px;
314
    background:#f6f6f6;
315
    color:#505050;
316
    border: 1px solid #e4e4e4;
317
}
318

  
319
div.title {
320
    line-height:1.5em;
321
}
322

  
323
div.category .creation_date, div.category .infos {
324
    font-size: 0.7em;
325
}
326

  
327
.category .infos {
328
    margin: 5px 0 0 0;
300 329
    float: right;
301
}
330
}
corbo/templates/corbo/category_detail.html
1
{% extends 'corbo/manage.html' %}
2
{% load i18n %}
3

  
4
{% block appbar %}
5
<h2>{% trans "Category:" %} {{ object.name }}</h2>
6
<a href="{% url 'delete_category' object.id %}" rel="popup">{% trans 'Delete' %}</a>
7
<a href="{% url 'edit_category' object.id %}" rel="popup">{% trans 'Rename' %}</a>
8
<a href="{% url 'add_announce_for_category' pk=object.pk %}" rel='popup'>{% trans 'New announce' %}</a>
9
{% endblock %}
10

  
11
{% block content %}
12
<div id="management">
13
<ul class='objects-list single-links'>
14
{% for announce in announces %}
15
<li>
16
  <div class="status">
17
    {% if announce.is_published %}
18
    <span class="icon published" title="{% trans "published" %}"></span>
19
    {% endif %}
20
    {% if not announce.is_published %}
21
    {% if announce.is_expired %}
22
    <span class="icon expired" title="{% trans "expired" %}"></span>
23
    {% else %}
24
    <span class="icon unpublished" title="{% trans "not published yet" %}"></span>
25
    {% endif %}
26
    {% endif %}
27
  </div>  
28
  <a href="{% url 'edit_announce' announce.id %}" rel='popup'>{{ announce.title }}</a>
29
  <div class="datetime">
30
    {% blocktrans with mtime=announce.mtime|date:'DATETIME_FORMAT' %}
31
    Modified on {{ mtime }}
32
    {% endblocktrans %}
33
  </div>
34
  <div class="actions">
35
    <span><a class="icon delete" href="{% url 'delete_announce' announce.id %}" rel="popup"></a></span>
36
  </div>
37
</li>
38
{% empty %}
39
<div class="empty">
40
  {% trans "No announces yet." %}
41
</div>
42
{% endfor %}
43
</ul>
44
{% endblock %}
corbo/templates/corbo/manage.html
1 1
{% extends 'corbo/base.html' %}
2
{% load i18n static %}
2
{% load i18n %}
3 3
{% block page-title %}
4 4
{{ block.super }} :: {% trans "Management" %}
5 5
{% endblock %}
6 6

  
7

  
7
{% block appbar %}
8
<h2>{% trans "Categories" %}</h2>
9
<a href="{% url 'add_category' %}" rel='popup'>{% trans 'New category' %}</a>
10
<a href="{% url 'add_announce' %}" rel='popup'>{% trans 'New announce' %}</a>
11
{% endblock %}
8 12

  
9 13
{% block content %}
10
<div class="categories">
11
  <span class="title">{% trans "Category:" %}</span>
12
  <select>
13
    <option value=''>{% trans "All" %}</option>
14
    {% for category in categories %}
15
    <option value='{{ category.id }}'{% if category_id == category.id %} selected{% endif %}>{{ category }}</option>
16
    {% endfor %}
17
  </select>
18
  <span>
19
    {% if category_id %}
20
    <a class="icon edit" href="{% url "edit_category" category_id %}" rel="popup" title="{% trans "edit category" %}"></a>
21
    <a class="icon delete" href="{% url "delete_category" category_id %}" rel="popup" title="{% trans "delete category" %}"></a>
22
    {% endif %}
23
    <a class="icon add" href="{% url "add_category" %}" rel="popup" title="{% trans "add category" %}"></a></span>
24
</div>
25 14
<div id="management">
26
  <h4>{% trans "Announces" %}</h4>
27
  <span><a class="icon add" href="{% url "add_announce" %}">{% trans "add announce" %}</a></span>
28
  <div>
29
    <span class="subscriptions_number">
30
    {% blocktrans count n=subscriptions_number %}
31
    {{ n }} subscription
32
    {% plural %}
33
    {{ n }} subscriptions
34
    {% endblocktrans %}
35
    </span>
36
  </div>
37
  <div class="clear"></div>
38
<ul>
39
{% for obj in object_list %}
40
<li class='{% cycle 'bluesky' '' %}'>
41
  <div class="status">
42
    {% if obj.is_published %}
43
    <span class="icon published" title="{% trans "published" %}"></span>
44
    {% endif %}
45
    {% if not obj.is_published %}
46
    {% if obj.is_expired %}
47
    <span class="icon expired" title="{% trans "expired" %}"></span>
48
    {% else %}
49
    <span class="icon unpublished" title="{% trans "not published yet" %}"></span>
50
    {% endif %}
51
    {% endif %}
52
  </div>
53
  <div class="preview datetime">
54
    {% blocktrans with mtime=obj.mtime|date:'DATETIME_FORMAT' %}
55
    Modified on {{ mtime }}
56
    {% endblocktrans %}
57
  </div>
58
  <div class="actions">
59
    <span><a class="icon edit" href="{% url 'edit_announce' obj.id %}"></a></span>
60
    <span><a class="icon delete" href="{% url 'delete_announce' obj.id %}" rel="popup"></a></span>
61
  </div>
62
  <div class="announce">
63
    <div class="title">{{ obj.title }}</div>
64
    <div class="preview">{{ obj.text|safe|truncatechars_html:128 }}</div>
65
  </div>
66
</li>
67
{% empty %}
68
<div class="empty">
69
  {% trans "No announces matching this category" %}
70
</div>
71
{% endfor %}
72
</ul>
73

  
74
{% if is_paginated %}
75
<ul class="pagination">
76
  {% if page_obj.has_previous %}
77
  <li class="prev">
78
    <a href="?{% if category_id %}category={{ category_id}}&{% endif %}page={{ page_obj.previous_page_number }}" class="icon"></a>
79
  </li>
80
  {% endif %}
81
  <li class="current">
82
    page {{ page_obj.number }} of {{ paginator.num_pages }}
83
  </li>
84
  {% if page_obj.has_next %}
85
  <li class="next">
86
    <a href="?{% if category_id %}category={{ category_id}}&{% endif %}page={{ page_obj.next_page_number }}" class="icon"></a>
87
  </li>
88
  {% endif %}
89
</ul>
90
{% endif %}
15
  <ul class='objects-list single-links'>
16
    {% for obj in object_list %}
17
    <li class='category'>
18
        <a href="{% url 'view_category' pk=obj.id %}">{{ obj.name }} /
19
        {% blocktrans with creation_date=obj.ctime|date:"SHORT_DATETIME_FORMAT" %}
20
        created on {{ creation_date }}
21
          {% endblocktrans %} /
22
          {% blocktrans count announces_number=obj.get_announces_number %}
23
          {{ announces_number }} announce
24
          {% plural %}
25
          {{ announces_number }} announces
26
          {% endblocktrans %} /
27
          {% blocktrans count subscriptions_number=obj.get_subscriptions_number %}
28
          {{ subscriptions_number }} subscription
29
          {% plural %}
30
          {{ subscriptions_number }} subscriptions
31
          {% endblocktrans %}
32
        </a>
33
      <div class="actions">
34
        <a class="icon edit" href="{% url 'edit_category' obj.id %}" rel="popup"></a>
35
        <a class="icon delete" href="{% url 'delete_category' obj.id %}" rel="popup"></a>
36
      </div>
37
    </li>
38
    {% empty %}
39
    <div class="empty">
40
      {% trans "No categories yet." %}
41
    </div>
42
    {% endfor %}
43
  </ul>
91 44
</div>
92
{% endblock %}
93

  
94
{% block page-end %}
95
<script type="text/javascript">
96
  $(function() {
97
    $('div.categories select').on('change', function() {
98
        var category = $(this).val();
99
        if (category)
100
            window.location.replace('{% url "manage" %}?category=' + category);
101
        else
102
            window.location.replace({% url "manage" %});
103
    })
104
})
105
</script>
106
{% endblock %}
45
  {% endblock %}
corbo/views.py
6 6
from django.core import signing
7 7
from django.core.urlresolvers import reverse
8 8
from django.views.generic import CreateView, UpdateView, DeleteView, \
9
                                 ListView, TemplateView, RedirectView
9
                                 ListView, TemplateView, RedirectView, \
10
                                 DetailView
10 11
from django.contrib.syndication.views import Feed
11 12
from django.shortcuts import resolve_url
12 13
from django.utils.encoding import force_text
......
54 55
    template_name = 'corbo/announce_form.html'
55 56

  
56 57
    def get_success_url(self):
57
        """
58
        redirect to the category page of the new created announce
59
        """
60
        return reverse('manage') + '?' + urlencode({'category': self.object.category.id})
58
        return reverse('view_category', kwargs={'pk': self.object.category.pk})
61 59

  
62 60
add_announce = AnnounceCreateView.as_view()
63 61

  
62

  
63
class AnnounceForCategoryCreateView(AnnounceCreateView):
64

  
65
    def get_initial(self):
66
        initial = super(AnnounceForCategoryCreateView, self).get_initial()
67
        initial['category'] = models.Category.objects.get(pk=self.kwargs['pk'])
68
        return initial
69

  
70
add_announce_for_category = AnnounceForCategoryCreateView.as_view()
71

  
72

  
64 73
class AnnounceEditView(UpdateView):
65 74
    model = models.Announce
66 75
    form_class = AnnounceForm
67 76

  
68 77
    def get_success_url(self):
69
        return reverse('manage') + '?' + urlencode({'category': self.object.category.id})
78
        return reverse('view_category', kwargs={'pk': self.object.category.pk})
70 79

  
71 80
edit_announce = AnnounceEditView.as_view()
72 81

  
......
92 101

  
93 102
add_category = CategoryCreateView.as_view()
94 103

  
104

  
95 105
class CategoryEditView(UpdateView):
96 106
    form_class = CategoryForm
97 107
    model = models.Category
98 108

  
99 109
    def get_success_url(self):
100
        return self.request.META['HTTP_REFERER'] or \
101
            reverse('manage') + '?' + urlencode({'category': self.object.id})
110
        return reverse('view_category', kwargs={'pk': self.object.pk})
102 111

  
103 112
edit_category = CategoryEditView.as_view()
104 113

  
114

  
115
class CategoryView(DetailView):
116
    model = models.Category
117

  
118
    def get_context_data(self, **kwargs):
119
        context = super(CategoryView, self).get_context_data(**kwargs)
120
        context['announces'] = self.object.announce_set.all()
121
        return context
122

  
123
view_category = CategoryView.as_view()
124

  
125

  
105 126
class CategoryDeleteView(DeleteView):
106 127
    model = models.Category
107 128

  
......
135 156

  
136 157

  
137 158
class ManageView(ListView):
138
    paginate_by = settings.ANNOUNCES_PER_PAGE
139 159
    template_name = 'corbo/manage.html'
140
    model = models.Announce
141

  
142
    def get_queryset(self):
143
        queryset = super(ManageView, self).get_queryset()
144
        if self.request.GET.get('category'):
145
            queryset = queryset.filter(category__id=self.request.GET['category'])
146
        return queryset
147

  
148
    def get_context_data(self, **kwargs):
149
        context = super(ManageView, self).get_context_data(**kwargs)
150
        context['categories'] = models.Category.objects.all().order_by('-ctime')
151
        context['subscriptions_number'] = models.Subscription.objects.count()
152
        if self.request.GET.get('category'):
153
            try:
154
                context['category_id'] = int(self.request.GET['category'])
155
                cat = models.Category.objects.get(pk=context['category_id'])
156
                context['subscriptions_number'] = cat.subscription_set.count()
157
            except (ValueError, models.Category.DoesNotExist):
158
                pass
159
        return context
160
    model = models.Category
160 161

  
161 162
manage = ManageView.as_view()
162 163

  
164

  
163 165
class Atom1Feed(DjangoAtom1Feed):
164 166
    def root_attributes(self):
165 167
        attrs = super(Atom1Feed, self).root_attributes()
166
-