Revision 04febd09
b/snf-astakos-app/.settings/org.eclipse.core.resources.prefs | ||
---|---|---|
1 |
#Mon Sep 10 11:32:44 EEST 2012
|
|
1 |
#Thu Sep 27 13:01:48 EEST 2012
|
|
2 | 2 |
eclipse.preferences.version=1 |
3 |
encoding//astakos/im/migrations/0010_auto__add_field_astakosuser_activation_sent__chg_field_service_url.py=utf-8 |
|
4 |
encoding//astakos/im/migrations/0011_set_old_activation_sent.py=utf-8 |
|
3 | 5 |
encoding//astakos/im/migrations/0017_populate_resource_data.py=utf-8 |
6 |
encoding//astakos/im/migrations/0023_populate_resource_data.py=utf-8 |
b/snf-astakos-app/astakos/im/forms.py | ||
---|---|---|
607 | 607 |
('expiration_date', 'Expiration Date'), |
608 | 608 |
('approved_members_num', 'Participants'), |
609 | 609 |
('is_enabled', 'Status'), |
610 |
('moderation_enabled', 'Moderation') |
|
610 |
('moderation_enabled', 'Moderation'), |
|
611 |
('membership_status','Enrollment Status') |
|
611 | 612 |
), |
612 | 613 |
required=False) |
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
187 | 187 |
|
188 | 188 |
@property |
189 | 189 |
def members(self): |
190 |
return [m.person for m in self.membership_set.all()] |
|
190 |
l = [] |
|
191 |
for m in self.membership_set.all(): |
|
192 |
m.person.is_approved = m.is_approved |
|
193 |
l.append(m.person) |
|
194 |
return l |
|
191 | 195 |
|
192 | 196 |
@property |
193 | 197 |
def approved_members(self): |
b/snf-astakos-app/astakos/im/static/im/css/forms.css | ||
---|---|---|
152 | 152 |
form.link-like { display:inline-block; margin:0 5px; float:right;} |
153 | 153 |
form.link-like input[type="submit"] { margin:0; padding:0 5px; background:transparent; color:#F89A1C; cursor:pointer; height:auto; } |
154 | 154 |
form.link-like input[type="submit"]:hover { text-decoration:underline; } |
155 |
form.link-like.alone { float:none; margin:0;} |
|
156 |
form.link-like.alone .form-row { margin:0; } |
|
157 |
form.link-like.alone input[type="submit"] { padding:0; } |
|
155 | 158 |
.projects form.withlabels .checkbox-widget { margin-top:5px; } |
156 | 159 |
.projects form .with-checkbox { margin:20px 0; } |
157 | 160 |
.projects form .with-checkbox label { padding-top:7px; } |
b/snf-astakos-app/astakos/im/templates/im/astakosgroup_detail.html | ||
---|---|---|
91 | 91 |
</div> |
92 | 92 |
<div class="full-dotted"> |
93 | 93 |
{% if object.members %} |
94 |
<form method="GET" class="minimal" action=""> |
|
95 |
<div class="form-row"> |
|
96 |
<select name="sorting" onchange="this.form.submit();"> |
|
97 |
<option value="">Sort by</option> |
|
98 |
<option value="email" {% if sorting == 'email' %}selected{% endif %}>User Id</option> |
|
99 |
<option value="realname" {% if sorting == 'realname' %}selected{% endif %}>Name</option> |
|
100 |
<option value="is_approved" {% if sorting == 'is_approved' %}selected{% endif %}>Status</option> |
|
101 |
</select> |
|
102 |
<input type="hidden" name="q" value="{{q}}"/> |
|
103 |
</div> |
|
104 |
</form> |
|
94 | 105 |
<table class="alt-style"> |
95 | 106 |
<caption>MEMBERS:</caption> |
96 | 107 |
<thead> |
... | ... | |
101 | 112 |
</tr> |
102 | 113 |
</thead> |
103 | 114 |
<tbody> |
104 |
{% for m in object.membership_set.all %}
|
|
115 |
{% for p in members.object_list %}
|
|
105 | 116 |
<tr> |
106 |
<td>{{m.person.email}}</td>
|
|
107 |
<td>{{m.person.realname}}</td>
|
|
108 |
{% if m.person in m.group.owner.all %}
|
|
117 |
<td>{{p.email}}</td>
|
|
118 |
<td>{{p.realname}}</td>
|
|
119 |
{% if p in object.owner.all %}
|
|
109 | 120 |
<td>Owner</td> |
110 | 121 |
{% else %} |
111 |
{% if m.is_approved %}
|
|
122 |
{% if p.is_approved %}
|
|
112 | 123 |
<td>Approved</td> |
113 | 124 |
{% else %} |
114 | 125 |
<td>Pending |
115 |
{% if user in m.group.owner.all %}
|
|
126 |
{% if user in object.owner.all %}
|
|
116 | 127 |
<a href="{% url approve_member m.group.id m.person.id %}">Accept</a> |
117 | 128 |
<a href="{% url disapprove_member m.group.id m.person.id %}">Reject</a> |
118 | 129 |
{% endif %} |
... | ... | |
123 | 134 |
{% endfor %} |
124 | 135 |
</tbody> |
125 | 136 |
</table> |
137 |
<div class="pagination"> |
|
138 |
<p class="next-prev"> |
|
139 |
{% if members.has_previous %} |
|
140 |
<a href="?page={{ members.previous_page_number }}{% if sorting %}&sorting={{sorting}}{% endif %}">previous</a> |
|
141 |
{% endif %} |
|
142 |
{% if members.has_next %} |
|
143 |
<a href="?page={{ members.next_page_number }}{% if sorting %}&sorting={{sorting}}{% endif %}">next</a> |
|
144 |
{% endif %} |
|
145 |
</p> |
|
146 |
<p class="nums"> |
|
147 |
<span class="current"> |
|
148 |
Page {{ members.number }} of {{ members.paginator.num_pages }} |
|
149 |
</span> |
|
150 |
</p> |
|
151 |
</div> |
|
126 | 152 |
{% else %} |
127 | 153 |
<p>No members yet!</p> |
128 | 154 |
{% endif %} |
b/snf-astakos-app/astakos/im/templates/im/astakosgroup_list.html | ||
---|---|---|
55 | 55 |
<option value="expiration_date" {% if sorting == 'expiration_date' %}selected{% endif %}>Expiration Date</option> |
56 | 56 |
<option value="approved_members_num" {% if sorting == 'approved_members_num' %}selected{% endif %}>Participants</option> |
57 | 57 |
</select> |
58 |
<input type="hidden" name="q" value="{{q}}"/> |
|
58 | 59 |
</div> |
59 | 60 |
</form> |
60 | 61 |
<table class="alt-style complex"> |
... | ... | |
131 | 132 |
<div class="pagination"> |
132 | 133 |
<p class="next-prev"> |
133 | 134 |
{% if page_obj.has_previous %} |
134 |
<a href="?page={{ page_obj.previous_page_number }}{% if q %}&q={{q}}{% endif %}">previous</a> |
|
135 |
<a href="?page={{ page_obj.previous_page_number }}{% if q %}&q={{q}}{% endif %}{% if sorting %}&sorting={{sorting}}{% endif %}">previous</a>
|
|
135 | 136 |
{% endif %} |
136 | 137 |
{% if page_obj.has_next %} |
137 |
<a href="?page={{ page_obj.next_page_number }}{% if q %}&q={{q}}{% endif %}">next</a> |
|
138 |
<a href="?page={{ page_obj.next_page_number }}{% if q %}&q={{q}}{% endif %}{% if sorting %}&sorting={{sorting}}{% endif %}">next</a>
|
|
138 | 139 |
{% endif %} |
139 | 140 |
</p> |
140 | 141 |
<p class="nums"> |
... | ... | |
156 | 157 |
<option value="expiration_date" {% if own_sorting == 'expiration_date' %}selected{% endif %}>Expiration Date</option> |
157 | 158 |
<option value="approved_members_num" {% if own_sorting == 'approved_members_num' %}selected{% endif %}>Participants</option> |
158 | 159 |
<option value="is_enabled" {% if own_sorting == 'is_enabled' %}selected{% endif %}>Status</option> |
159 |
<option value="moderation_enabled" {% if own_sorting == 'moderation_enabled' %}selected{% endif %}>Moderation</option>
|
|
160 |
<option value="moderation_enabled" {% if own_sorting == 'moderation_enabled' %}selected{% endif %}>Moderation</option> |
|
160 | 161 |
</select> |
161 | 162 |
</div> |
162 | 163 |
</form> |
... | ... | |
230 | 231 |
<option value="issue_date" {% if other_sorting == 'issue_date' %}selected{% endif %}>Issue date</option> |
231 | 232 |
<option value="expiration_date" {% if other_sorting == 'expiration_date' %}selected{% endif %}>Expiration Date</option> |
232 | 233 |
<option value="approved_members_num" {% if other_sorting == 'approved_members_num' %}selected{% endif %}>Participants</option> |
234 |
<option value="membership_status" {% if other_sorting == 'membership_status' %}selected{% endif %}>Enrollment Status</option> |
|
233 | 235 |
|
234 | 236 |
</select> |
235 | 237 |
</div> |
... | ... | |
264 | 266 |
<td>{{ o.approved_members_num }}</td> |
265 | 267 |
|
266 | 268 |
<td> |
267 |
{% if o.membership_approval_date %} |
|
269 |
{{ o.membership_status }} |
|
270 |
{% if o.membership_status == 'Registered' %} |
|
268 | 271 |
|
269 |
Registered |
|
270 | 272 |
<form action="{% url group_leave o.id %}" method="post" class="link-like">{% csrf_token %} |
271 | 273 |
<input type="submit" value="LEAVE GROUP" /> |
272 | 274 |
</form> |
273 | 275 |
|
274 | 276 |
|
275 |
{% else %} |
|
276 |
Pending |
|
277 | 277 |
{% endif %} |
278 | 278 |
</td> |
279 | 279 |
<td><a href="#" class="more-info" title="more info"> </a></td> |
b/snf-astakos-app/astakos/im/views.py | ||
---|---|---|
47 | 47 |
from django.db.models import Q |
48 | 48 |
from django.db.utils import IntegrityError |
49 | 49 |
from django.forms.fields import URLField |
50 |
from django.db.models.fields import DateTimeField |
|
50 | 51 |
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \ |
51 | 52 |
HttpResponseRedirect, HttpResponseBadRequest, Http404 |
52 | 53 |
from django.shortcuts import redirect |
... | ... | |
731 | 732 |
(SELECT COUNT(*) FROM im_membership |
732 | 733 |
WHERE group_id = im_astakosgroup.group_ptr_id |
733 | 734 |
AND date_joined IS NOT NULL) AS approved_members_num, |
734 |
(SELECT date_joined FROM im_membership |
|
735 |
WHERE group_id = im_astakosgroup.group_ptr_id |
|
736 |
AND person_id = %s) AS membership_approval_date |
|
735 |
(SELECT CASE WHEN( |
|
736 |
SELECT date_joined FROM im_membership |
|
737 |
WHERE group_id = im_astakosgroup.group_ptr_id |
|
738 |
AND person_id = %s) IS NULL |
|
739 |
THEN 'Pending' ELSE 'Registered' END) AS membership_status |
|
737 | 740 |
FROM im_astakosgroup |
738 | 741 |
INNER JOIN im_membership ON ( |
739 | 742 |
im_astakosgroup.group_ptr_id = im_membership.group_id) |
... | ... | |
758 | 761 |
if sorting: |
759 | 762 |
sort_form = AstakosGroupSortForm({'sort_by': sorting}) |
760 | 763 |
if sort_form.is_valid(): |
761 |
l.sort(key=lambda i: getattr(i, sorting)) |
|
764 |
sort_field = q._model_fields.get(sorting) |
|
765 |
default = datetime.utcfromtimestamp(0) if isinstance(sort_field, DateTimeField) else '' |
|
766 |
l.sort(key=lambda i: getattr(i, sorting) if getattr(i, sorting) else default ) |
|
762 | 767 |
globals()['%s_sorting' % k] = sorting |
763 | 768 |
paginator = Paginator(l, PAGINATE_BY) |
764 | 769 |
|
... | ... | |
791 | 796 |
except AstakosGroup.DoesNotExist: |
792 | 797 |
return HttpResponseBadRequest(_('Invalid group.')) |
793 | 798 |
form = AstakosGroupUpdateForm(instance=group) |
794 |
search_form = AddGroupMembersForm() |
|
799 |
add_members_form = AddGroupMembersForm() |
|
800 |
|
|
801 |
# build members |
|
802 |
page = request.GET.get('page', 1) |
|
803 |
sorting = request.GET.get('sorting') |
|
804 |
if sorting: |
|
805 |
group.members.sort(key=lambda i: getattr(i, sorting)) |
|
806 |
paginator = Paginator(group.members, PAGINATE_BY) |
|
807 |
|
|
808 |
try: |
|
809 |
page_number = int(page) |
|
810 |
except ValueError: |
|
811 |
if page == 'last': |
|
812 |
page_number = paginator.num_pages |
|
813 |
else: |
|
814 |
# Page is not 'last', nor can it be converted to an int. |
|
815 |
raise Http404 |
|
816 |
try: |
|
817 |
members_page = globals()['page'] = paginator.page(page_number) |
|
818 |
except InvalidPage: |
|
819 |
raise Http404 |
|
795 | 820 |
return object_detail(request, |
796 | 821 |
AstakosGroup.objects.all(), |
797 | 822 |
object_id=group_id, |
798 | 823 |
extra_context={'quota': group.quota, |
799 | 824 |
'form': form, |
800 |
'search_form': search_form} |
|
825 |
'search_form': add_members_form, |
|
826 |
'members': members_page, |
|
827 |
'sorting': sorting} |
|
801 | 828 |
) |
802 | 829 |
|
803 | 830 |
|
... | ... | |
825 | 852 |
@login_required |
826 | 853 |
def group_search(request, extra_context=None, **kwargs): |
827 | 854 |
q = request.GET.get('q') |
855 |
sorting = request.GET.get('sorting') |
|
828 | 856 |
if request.method == 'GET': |
829 | 857 |
form = AstakosGroupSearchForm({'q': q} if q else None) |
830 | 858 |
else: |
... | ... | |
852 | 880 |
WHERE group_id = im_astakosgroup.group_ptr_id |
853 | 881 |
AND person_id = %s) |
854 | 882 |
THEN 1 ELSE 0 END""" % request.user.id}) |
883 |
if sorting: |
|
884 |
# TODO check sorting value |
|
885 |
queryset = queryset.order_by(sorting) |
|
855 | 886 |
else: |
856 | 887 |
queryset = AstakosGroup.objects.none() |
857 | 888 |
return object_list( |
... | ... | |
862 | 893 |
template_name='im/astakosgroup_list.html', |
863 | 894 |
extra_context=dict(form=form, |
864 | 895 |
is_search=True, |
865 |
q=q)) |
|
896 |
q=q, |
|
897 |
sorting=sorting)) |
|
866 | 898 |
|
867 | 899 |
@signed_terms_required |
868 | 900 |
@login_required |
... | ... | |
886 | 918 |
WHERE group_id = im_astakosgroup.group_ptr_id |
887 | 919 |
AND person_id = %s) |
888 | 920 |
THEN 1 ELSE 0 END""" % request.user.id}) |
921 |
sorting = request.GET.get('sorting') |
|
922 |
if sorting: |
|
923 |
# TODO check sorting value |
|
924 |
q = q.order_by(sorting) |
|
889 | 925 |
return object_list( |
890 | 926 |
request, |
891 | 927 |
q, |
... | ... | |
893 | 929 |
page=request.GET.get('page') or 1, |
894 | 930 |
template_name='im/astakosgroup_list.html', |
895 | 931 |
extra_context=dict(form=AstakosGroupSearchForm(), |
896 |
is_search=True)) |
|
932 |
is_search=True, |
|
933 |
sorting=sorting)) |
|
897 | 934 |
|
898 | 935 |
|
899 | 936 |
@signed_terms_required |
Also available in: Unified diff