Revision 5550bcfb
b/snf-astakos-app/astakos/im/forms.py | ||
---|---|---|
765 | 765 |
|
766 | 766 |
class ProjectSearchForm(forms.Form): |
767 | 767 |
q = forms.CharField(max_length=200, label='Search project', required=False) |
768 |
|
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
1350 | 1350 |
SyncedState = make_synced(prefix='sync', name='SyncedState') |
1351 | 1351 |
|
1352 | 1352 |
|
1353 |
class ProjectApplicationManager(models.Manager): |
|
1354 |
|
|
1355 |
def user_projects(self, user): |
|
1356 |
""" |
|
1357 |
Return projects accessed by specified user. |
|
1358 |
""" |
|
1359 |
return self.filter(Q(owner=user) | Q(applicant=user) | \ |
|
1360 |
Q(project__in=user.projectmembership_set.filter())) |
|
1361 |
|
|
1353 | 1362 |
class ProjectApplication(models.Model): |
1354 | 1363 |
PENDING, APPROVED, REPLACED, UNKNOWN = 'Pending', 'Approved', 'Replaced', 'Unknown' |
1355 | 1364 |
applicant = models.ForeignKey( |
... | ... | |
1388 | 1397 |
comments = models.TextField(null=True, blank=True) |
1389 | 1398 |
issue_date = models.DateTimeField() |
1390 | 1399 |
|
1400 |
objects = ProjectApplicationManager() |
|
1401 |
|
|
1391 | 1402 |
def add_resource_policy(self, service, resource, uplimit): |
1392 | 1403 |
"""Raises ObjectDoesNotExist, IntegrityError""" |
1393 | 1404 |
q = self.projectresourcegrant_set |
1394 | 1405 |
resource = Resource.objects.get(service__name=service, name=resource) |
1395 | 1406 |
q.create(resource=resource, member_capacity=uplimit) |
1396 | 1407 |
|
1397 |
|
|
1408 |
def member_status(self, user): |
|
1409 |
if user == self.owner: |
|
1410 |
status = 100 |
|
1411 |
else: |
|
1412 |
try: |
|
1413 |
membership = self.project.projectmembership_set.get(person=user) |
|
1414 |
status = membership.state |
|
1415 |
except Project.DoesNotExist: |
|
1416 |
status = -1 |
|
1417 |
|
|
1418 |
return status |
|
1419 |
|
|
1420 |
def members_count(self): |
|
1421 |
return self.project.approved_memberships.count() |
|
1422 |
|
|
1398 | 1423 |
@property |
1399 | 1424 |
def grants(self): |
1400 | 1425 |
return self.projectresourcegrant_set.values('member_capacity', 'resource__name', 'resource__service__name') |
1401 |
|
|
1426 |
|
|
1402 | 1427 |
@property |
1403 | 1428 |
def resource_policies(self): |
1404 | 1429 |
return self.projectresourcegrant_set.all() |
b/snf-astakos-app/astakos/im/synnefo_settings.py | ||
---|---|---|
43 | 43 |
'django.contrib.contenttypes', |
44 | 44 |
'django.contrib.sessions', |
45 | 45 |
'django.contrib.messages', |
46 |
'django_tables2', |
|
46 | 47 |
# 'debug_toolbar', |
47 | 48 |
] |
48 | 49 |
|
b/snf-astakos-app/astakos/im/tables.py | ||
---|---|---|
1 |
import django_tables2 as tables |
|
2 |
|
|
3 |
from django.utils.translation import ugettext as _ |
|
4 |
from django_tables2 import A |
|
5 |
from astakos.im.models import * |
|
6 |
|
|
7 |
DEFAULT_DATE_FORMAT = "d/m/Y" |
|
8 |
|
|
9 |
|
|
10 |
MEMBER_STATUS_DISPLAY = { |
|
11 |
100: _('Owner'), |
|
12 |
0: _('Requested'), |
|
13 |
1: _('Pending'), |
|
14 |
2: _('Accepted'), |
|
15 |
3: _('Removing'), |
|
16 |
4: _('Removed'), |
|
17 |
-1: _('Unregistered'), |
|
18 |
} |
|
19 |
|
|
20 |
class UserProjectApplicationsTable(tables.Table): |
|
21 |
|
|
22 |
def __init__(self, *args, **kwargs): |
|
23 |
self.user = None |
|
24 |
|
|
25 |
if 'request' in kwargs and kwargs.get('request').user: |
|
26 |
self.user = kwargs.get('request').user |
|
27 |
|
|
28 |
if 'user' in kwargs: |
|
29 |
self.user = kwargs.pop('user') |
|
30 |
|
|
31 |
super(UserProjectApplicationsTable, self).__init__(*args, **kwargs) |
|
32 |
|
|
33 |
|
|
34 |
name = tables.LinkColumn('astakos.im.views.project_detail', args=(A('pk'),)) |
|
35 |
issue_date = tables.DateColumn(format=DEFAULT_DATE_FORMAT) |
|
36 |
start_date = tables.DateColumn(format=DEFAULT_DATE_FORMAT) |
|
37 |
state = tables.Column(verbose_name="Status") |
|
38 |
members_count = tables.Column(verbose_name="Enrolled", default=0) |
|
39 |
membership_status = tables.Column(verbose_name="My status", empty_values=(), |
|
40 |
orderable=False) |
|
41 |
|
|
42 |
def render_membership_status(self, *args, **kwargs): |
|
43 |
return MEMBER_STATUS_DISPLAY.get(kwargs.get('record').member_status(self.user)) |
|
44 |
|
|
45 |
class Meta: |
|
46 |
model = ProjectApplication |
|
47 |
fields = ('name', 'membership_status', 'issue_date', 'start_date', |
|
48 |
'state', 'members_count') |
|
49 |
|
b/snf-astakos-app/astakos/im/target/google.py | ||
---|---|---|
179 | 179 |
# authenticate user |
180 | 180 |
response = prepare_response(request, |
181 | 181 |
user, |
182 |
userid, |
|
183 | 182 |
request.GET.get('next'), |
184 | 183 |
'renew' in request.GET) |
185 | 184 |
messages.success(request, _(astakos_messages.LOGIN_SUCCESS)) |
b/snf-astakos-app/astakos/im/templates/im/projects/project_list.html | ||
---|---|---|
2 | 2 |
|
3 | 3 |
{% load astakos_tags %} |
4 | 4 |
{% load filters %} |
5 |
{% load django_tables2 %} |
|
5 | 6 |
|
6 | 7 |
{% block page.body %} |
7 | 8 |
<div class="maincol {% block innerpage.class %}{% endblock %}"> |
8 | 9 |
<div class="projects"> |
9 | 10 |
<h2>PROJECTS</h2> |
10 | 11 |
{% if form %} |
11 |
<p>Search for existing Projects and join the ones you like. Please search by Project name. </p> |
|
12 |
<form action="{% url project_search %}" method="post" class="withlabels signup submit-inline">{% csrf_token %} |
|
13 |
{% include "im/form_render.html" %} |
|
14 |
<div class="form-row submit"> |
|
15 |
<input type="submit" class="submit altcol" value="SEARCH" /> |
|
16 |
{% if q %}<a href="{% url project_search %}">clear</a>{% endif %} |
|
17 |
</div> |
|
18 |
</form> |
|
12 |
{% include "im/projects_list.html" %} |
|
19 | 13 |
{% else %} |
20 |
|
|
21 |
<div class="two-cols clearfix"> |
|
22 |
<div class="rt"> |
|
23 |
|
|
24 |
</div> |
|
25 |
<div class="lt"> |
|
26 |
<p>~okeanos gives the opportunity to Greek Academic or Research Organizations/Institutions/Faculty to run their own projects remotely on virtual infrastructure. Simple, fast and with minimal to no cost at all.</p> |
|
27 |
<p><a href="{% url how_it_works %}" style="font-size:1.154em;">How it works ></a></p> |
|
28 |
</div> |
|
14 |
{% include "im/projects_index.html" %} |
|
29 | 15 |
</div> |
30 |
|
|
31 |
|
|
32 |
<div class="widjets"> |
|
33 |
<!--<a href="#" class="widjet-x" title="remove boxes">X</a>--> |
|
34 |
<ul class="clearfix"> |
|
35 |
<li class="create"> |
|
36 |
<div> |
|
37 |
<div class="wrap"> |
|
38 |
|
|
39 |
<p class="centered"><a href="{% url project_add %}"><img alt="THINK ABOUT IT" src="/static/im/images/create.png"></a></p> |
|
40 |
<p class="txt">Create a new Project in seconds. Specify how many members it will have, which and how many virtual resources it will provide to its members. Describe its purpose. Submit your request and if accepted, you and your colleagues are ready to deploy!<br><br> </p> |
|
41 |
<p><a href="{% url project_add %}">create a project ></a></p> |
|
42 |
</div> |
|
43 |
</div> |
|
44 |
</li> |
|
45 |
<li class="join"> |
|
46 |
<div> |
|
47 |
<div class="wrap"> |
|
48 |
<p class="centered"><a href="{% url project_search %}"><img alt="THINK ABOUT IT" src="/static/im/images/join.png"></a></p> |
|
49 |
<p class="txt">Become a member of an existing Project and instantly gain access to the resources it has to offer you. Search for open Projects and join for free. Contact the closed Projects administrators, if you think they will accept you. In two words: try to Join now. </p> |
|
50 |
|
|
51 |
<p><a href="{% url project_search %}">join a project ></a></p> |
|
52 |
</div> |
|
53 |
</div> |
|
54 |
</li> |
|
55 |
</ul> |
|
56 |
</div> |
|
57 |
|
|
58 | 16 |
{% endif %} |
59 |
{% with page_obj.object_list as object_list %} |
|
60 |
<!-- Search project --> |
|
61 |
{% if is_search %} |
|
62 |
|
|
63 |
{% if object_list %} |
|
64 |
<div> |
|
65 |
<table class="alt-style complex" id="searchResults"> |
|
66 |
<caption> |
|
67 |
{% if q %}SEARCH RESULTS{% else %}ALL PROJECTS{% endif %} |
|
68 |
</caption> |
|
69 |
<thead> |
|
70 |
<tr> |
|
71 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'name' %}-name{% else %}name{% endif %}#searchResults">Name</a></th> |
|
72 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'issue_date' %}-issue_date{% else %}issue_date{% endif %}#searchResults">Issue Date</a></th> |
|
73 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'start_date' %}-start_date{% else %}start_date{% endif %}#searchResults">Start Date</a></th> |
|
74 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'end_date' %}-end_date{% else %}end_date{% endif %}#searchResults">End Date</a></th> |
|
75 |
<th><a href="#searchResults">Enrolled</a></th> |
|
76 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'state' %}-state{% else %}state{% endif %}#searchResults">Status</a></th> |
|
77 |
<th> </th> |
|
78 |
<th><a href="#searchResults">Membership Status</a></th> |
|
79 |
<th> </th> |
|
80 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'member_join_policy__description' %}-member_join_policy__description{% else %}member_join_policy__description{%endif%}#searchResults">Member Join Policy</a></th> |
|
81 |
<th><a href="?{% if q %}q={{q}}&{% endif %}sorting={% if sorting == 'member_leave_policy__description' %}-member_leave_policy__description{% else %}member_leave_policy__description{%endif%}#searchResults">Member Leave Policy</a></th> |
|
82 |
<!-- <th> </th>--> |
|
83 |
</tr> |
|
84 |
</thead> |
|
85 |
<tbody> |
|
86 |
{% for o in object_list %} |
|
87 |
{% with o.project.members.all as members %} |
|
88 |
{% with o.project.approved_members as approved_members%} |
|
89 |
<tr class="{% cycle 'tr1' 'tr2' %}"> |
|
90 |
<td><a href="{% url project_detail o.id %}" title="visit project page">{{o.name|truncatename}}</a></td> |
|
91 |
<!--td>{{o.kindname|capfirst}}</td--> |
|
92 |
<td>{{o.issue_date|date:"d/m/Y"}}</td> |
|
93 |
<td>{{o.start_date|date:"d/m/Y"}}</td> |
|
94 |
<td>{{o.end_date|date:"d/m/Y"}}</td> |
|
95 |
<td>{{approved_members|length}}</td> |
|
96 |
<td> |
|
97 |
{{o.state}} |
|
98 |
</td> |
|
99 |
<td>{% if o.state != 'Replaced' %}<a href="{% url project_update o.id %}">Update</a>{% endif %}</td> |
|
100 |
<td> |
|
101 |
<div class="msg-wrap"> |
|
102 |
{% if user == o.owner %} |
|
103 |
Owner |
|
104 |
{% else %} |
|
105 |
{% if not user in members %} |
|
106 |
Not member |
|
107 |
{% else %} |
|
108 |
{% if user in approved_members %} |
|
109 |
Registered |
|
110 |
{% else %} |
|
111 |
Activation pending |
|
112 |
{% endif %} |
|
113 |
{% endif %} |
|
114 |
{% endif %} |
|
115 |
</div> |
|
116 |
</td> |
|
117 |
<td> |
|
118 |
<div class="msg-wrap"> |
|
119 |
|
|
120 |
{% if user in members %} |
|
121 |
{% if user in approved_members %} |
|
122 |
{% if not user == o.owner %} |
|
123 |
<form action="{% url project_leave o.id %}?next={{request.path}}" method="post" class="link-like">{% csrf_token %} |
|
124 |
<input type="submit" value="x leave group" class="leave"/> |
|
125 |
</form> |
|
126 |
<div class="dialog"> |
|
127 |
Are you sure you what to leave this project?<br> |
|
128 |
Name: <a href="{% url project_detail o.id %}" title="visit group page">{{o.name}}</a><br> |
|
129 |
{% if o.description %}Description:{{o.description|truncatewords:30}}{% endif %}<br><br> |
|
130 |
<a href="#" class="yes submit">Yes</a> <a href="#" class="no submit">No</a> |
|
131 |
</div> |
|
132 |
{% else %} |
|
133 |
|
|
134 |
{% endif %} |
|
135 |
{% else %} |
|
136 |
|
|
137 |
{% endif %} |
|
138 |
{% else %} |
|
139 |
{% if o.project.is_alive and not user == o.owner %} |
|
140 |
<form action="{% url project_join o.id %}?next={{request.path}}" method="post" class="link-like">{% csrf_token %} |
|
141 |
<input type="submit" value="+ join group" class="join_group join" /> |
|
142 |
</form> |
|
143 |
<div class="dialog"> |
|
144 |
Are you sure you what to join this project?<br> |
|
145 |
Name: <a href="{% url project_detail o.id %}" title="visit group page">{{o.name}}</a><br> |
|
146 |
{% if o.description %}Description:{{o.description|truncatewords:30}}{% endif %}<br><br> |
|
147 |
|
|
148 |
<a href="#" class="yes submit">Yes</a> <a href="#" class="no submit">No</a> |
|
149 |
</div> |
|
150 |
{% endif %} |
|
151 |
{% endif %} |
|
152 |
</div> |
|
153 |
</td> |
|
154 |
<td class="centered">{{o.member_join_policy}}</td> |
|
155 |
<td class="centered">{{o.member_leave_policy}}</td> |
|
156 |
<!--td><a href="#" class="more-info" title="more info">+ more info</a></td--> |
|
157 |
</tr> |
|
158 |
<tr class="{% cycle 'tmore1' 'tmore2' %}" style="display:none"> |
|
159 |
<td colspan="11" class="info-td"> |
|
160 |
<div> |
|
161 |
<p>{{o.desc}}</p> |
|
162 |
<p>{% if o.homepage%} |
|
163 |
Project's home page: <a target="_blank" href="{{ o.homepage }}">{{ o.homepage }}</a> |
|
164 |
|
|
165 |
{% endif %} |
|
166 |
</p> |
|
167 |
</div> |
|
168 |
</td> |
|
169 |
</tr> |
|
170 |
{% endwith %} |
|
171 |
{% endwith %} |
|
172 |
{% endfor %} |
|
173 |
</tbody> |
|
174 |
</table> |
|
175 |
|
|
176 |
</div> |
|
177 |
|
|
178 |
|
|
179 |
<div class="pagination"> |
|
180 |
<p class="next-prev"> |
|
181 |
{% if page_obj.has_previous %} |
|
182 |
<a href="?page={{ page_obj.previous_page_number }}{% if q %}&q={{q}}{% endif %}{% if sorting %}&sorting={{sorting}}{% endif %}">< previous</a> |
|
183 |
{% else %} |
|
184 |
<a href="javascript:void()" class="disabled">< previous</a> |
|
185 |
{% endif %} |
|
186 |
{% if page_obj.has_next %} |
|
187 |
<a href="?page={{ page_obj.next_page_number }}{% if q %}&q={{q}}{% endif %}{% if sorting %}&sorting={{sorting}}{% endif %}">next ></a> |
|
188 |
{% else %} |
|
189 |
<a href="javascript:void()" class="disabled">next ></a> |
|
190 |
{% endif %} |
|
191 |
</p> |
|
192 |
<p class="nums"> |
|
193 |
<span class="current"> |
|
194 |
Page {{ page_obj.number }} of {{ paginator.num_pages }} |
|
195 |
</span> |
|
196 |
</p> |
|
197 |
</div> |
|
198 |
|
|
199 |
{% endif %} |
|
200 |
|
|
201 |
<!-- Group listing --> |
|
202 |
{% else %} |
|
203 |
{% if not form %} |
|
204 |
|
|
205 |
{% if page_obj.object_list %} |
|
206 |
<div> |
|
207 |
|
|
208 |
<table class="alt-style complex" id="allGroups"> |
|
209 |
<caption>MY PROJECTS</caption> |
|
210 |
<thead> |
|
211 |
<tr> |
|
212 |
<th><a href="?sorting={% if sorting == 'name' %}-name{% else %}name{% endif %}#allGroups">Name</a></th> |
|
213 |
<th><a href="?sorting={% if sorting == 'issue_date' %}-issue_date{% else %}issue_date{% endif %}#allGroups">Issue Date</a></th> |
|
214 |
<th><a href="?sorting={% if sorting == 'start_date' %}-start_date{% else %}start_date{% endif %}#allGroups">Start Date</a></th> |
|
215 |
<th><a href="?sorting={% if sorting == 'end_date' %}-end_date{% else %}end_date{% endif %}#allGroups">End Date</a></th> |
|
216 |
<th><a href="#allGroups">Enrolled</a></th> |
|
217 |
<th><a href="?sorting={% if sorting == 'state' %}-state{% else %}state{% endif %}#allGroups">Status</a></th> |
|
218 |
<th> </th> |
|
219 |
<th><a href="#allGroups">Membership Status</a></th> |
|
220 |
<th> </th> |
|
221 |
<th><a href="?sorting={% if sorting == 'member_join_policy__description' %}-member_join_policy__description{% else %}member_join_policy__description{% endif %}#allGroups">Member Join Policy</a></th> |
|
222 |
<th><a href="?sorting={% if sorting == 'member_leave_policy__description' %}-member_leave_policy__description{% else %}member_leave_policy__description{% endif %}#allGroups">Member Leave Policy</a></th> |
|
223 |
<!-- <th> </th>--> |
|
224 |
</tr> |
|
225 |
</thead> |
|
226 |
<tbody> |
|
227 |
{% for o in object_list %} |
|
228 |
{% with o.project.members.all as members %} |
|
229 |
{% with o.project.approved_members as approved_members %} |
|
230 |
<tr class="{% cycle 'tr1' 'tr2' %}"> |
|
231 |
<td><a href="{% url project_detail o.id %}" title="visit group page">{{o.name|truncatename }}</a></td> |
|
232 |
<td>{{o.issue_date|date:"d/m/Y"}}</td> |
|
233 |
<td>{{o.start_date|date:"d/m/Y"}}</td> |
|
234 |
<td>{{o.end_date|date:"d/m/Y"}}</td> |
|
235 |
<td>{{approved_members|length}}</td> |
|
236 |
<td> |
|
237 |
{{o.state}} |
|
238 |
</td> |
|
239 |
<td>{% if o.state != 'Replaced' %}<a href="{% url project_update o.id %}">Update</a>{% endif %}</td> |
|
240 |
<td> |
|
241 |
|
|
242 |
{% if user == o.owner %} |
|
243 |
Owner |
|
244 |
{% else %} |
|
245 |
{% if not user in members %} |
|
246 |
Not member |
|
247 |
{% else %} |
|
248 |
{% if user in approved_members %} |
|
249 |
Registered |
|
250 |
{% else %} |
|
251 |
Activation pending |
|
252 |
{% endif %} |
|
253 |
{% endif %} |
|
254 |
{% endif %} |
|
255 |
|
|
256 |
</td> |
|
257 |
<td> |
|
258 |
<div class="msg-wrap"> |
|
259 |
|
|
260 |
{% if user in members %} |
|
261 |
{% if user in approved_members %} |
|
262 |
{% if not user == o.owner %} |
|
263 |
<form action="{% url project_leave o.id %}?next={{request.path}}" method="post" class="link-like">{% csrf_token %} |
|
264 |
<input type="submit" value="x leave group" class="leave"/> |
|
265 |
</form> |
|
266 |
<div class="dialog"> |
|
267 |
Are you sure you what to leave this project?<br> |
|
268 |
Name: <a href="{% url project_detail o.id %}" title="visit group page">{{o.name}}</a><br> |
|
269 |
{% if o.description %}Description:{{o.description|truncatewords:30}}{% endif %}<br><br> |
|
270 |
<a href="#" class="yes submit">Yes</a> <a href="#" class="no submit">No</a> |
|
271 |
</div> |
|
272 |
{% else %} |
|
273 |
|
|
274 |
{% endif %} |
|
275 |
{% else %} |
|
276 |
|
|
277 |
{% endif %} |
|
278 |
{% else %} |
|
279 |
{% if o.project.is_alive and not user == o.owner %} |
|
280 |
<form action="{% url project_join o.id %}?next={{request.path}}" method="post" class="link-like">{% csrf_token %} |
|
281 |
<input type="submit" value="+ join group" class="join_group join" /> |
|
282 |
</form> |
|
283 |
<div class="dialog"> |
|
284 |
Are you sure you what to join this project?<br> |
|
285 |
Name: <a href="{% url project_detail o.id %}" title="visit group page">{{o.name}}</a><br> |
|
286 |
{% if o.description %}Description:{{o.description|truncatewords:30}}{% endif %}<br><br> |
|
287 |
|
|
288 |
<a href="#" class="yes submit">Yes</a> <a href="#" class="no submit">No</a> |
|
289 |
</div> |
|
290 |
{% endif %} |
|
291 |
{% endif %} |
|
292 |
</div> |
|
293 |
</td> |
|
294 |
<td class="centered" >{{o.member_join_policy}}</td> |
|
295 |
<td class="centered">{{o.member_leave_policy}}</td> |
|
296 |
<!-- <td><a href="#" class="more-info" title="more info">+ more info </a></td>--> |
|
297 |
</tr> |
|
298 |
<tr class="{% cycle 'tmore1' 'tmore2' %}" style="display:none"> |
|
299 |
<td colspan="11" class="info-td"> |
|
300 |
<div> |
|
301 |
<p>{{o.description}}</p> |
|
302 |
<p>{% if o.homepage%} |
|
303 |
Project's home page: <a href="{{ o.homepage }}">{{ o.homepage }}</a> |
|
304 |
{% endif %} |
|
305 |
</p> |
|
306 |
</div> |
|
307 |
</td> |
|
308 |
</tr> |
|
309 |
{% endwith %} |
|
310 |
{% endwith %} |
|
311 |
{% endfor %} |
|
312 |
</tbody> |
|
313 |
</table> |
|
314 |
</div> |
|
315 |
<div class="pagination"> |
|
316 |
|
|
317 |
<p class="next-prev"> |
|
318 |
{% if page_obj.has_previous %} |
|
319 |
<a href="?page={{ page_obj.previous_page_number }}{% if sorting %}&sorting={{ sorting }}{% endif%}#allGroups">< previous</a> |
|
320 |
{% else %} |
|
321 |
<a href="javascript:void()" class="disabled">< previous</a> |
|
322 |
{% endif %} |
|
323 |
{% if page_obj.has_next %} |
|
324 |
<a href="?page={{ page_obj.next_page_number }}{% if sorting %}&sorting={{ sorting }}{% endif%}#allGroups">next ></a> |
|
325 |
{% else %} |
|
326 |
<a href="javascript:void()" class="disabled">next ></a> |
|
327 |
{% endif %} |
|
328 |
</p> |
|
329 |
<p class="nums"> |
|
330 |
<span class="current"> |
|
331 |
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} |
|
332 |
</span> |
|
333 |
</p> |
|
334 |
</div> |
|
335 |
{% endif %} |
|
336 |
|
|
337 |
{% endif %} |
|
338 |
{% if form %} |
|
339 |
{% if q %} |
|
340 |
<h2>No projects found!</h2> |
|
341 |
{% endif %} |
|
342 |
{% endif %} |
|
343 |
{% endif %} |
|
344 |
{% endwith %} |
|
17 |
{% render_table table %} |
|
345 | 18 |
</div> |
346 | 19 |
</div> |
347 | 20 |
{% endblock %} |
b/snf-astakos-app/astakos/im/templates/im/projects_index.html | ||
---|---|---|
1 |
<div class="two-cols clearfix"> |
|
2 |
<div class="rt"> |
|
3 |
|
|
4 |
</div> |
|
5 |
<div class="lt"> |
|
6 |
<p>~okeanos gives the opportunity to Greek Academic or Research Organizations/Institutions/Faculty to run their own projects remotely on virtual infrastructure. Simple, fast and with minimal to no cost at all.</p> |
|
7 |
<p><a href="{% url how_it_works %}" style="font-size:1.154em;">How it works ></a></p> |
|
8 |
</div> |
|
9 |
</div> |
|
10 |
|
|
11 |
|
|
12 |
<div class="widjets"> |
|
13 |
<!--<a href="#" class="widjet-x" title="remove boxes">X</a>--> |
|
14 |
<ul class="clearfix"> |
|
15 |
<li class="create"> |
|
16 |
<div> |
|
17 |
<div class="wrap"> |
|
18 |
|
|
19 |
<p class="centered"><a href="{% url project_add %}"><img alt="THINK ABOUT IT" src="/static/im/images/create.png"></a></p> |
|
20 |
<p class="txt">Create a new Project in seconds. Specify how many members it will have, which and how many virtual resources it will provide to its members. Describe its purpose. Submit your request and if accepted, you and your colleagues are ready to deploy!<br><br> </p> |
|
21 |
<p><a href="{% url project_add %}">create a project ></a></p> |
|
22 |
</div> |
|
23 |
</div> |
|
24 |
</li> |
|
25 |
<li class="join"> |
|
26 |
<div> |
|
27 |
<div class="wrap"> |
|
28 |
<p class="centered"><a href="{% url project_search %}"><img alt="THINK ABOUT IT" src="/static/im/images/join.png"></a></p> |
|
29 |
<p class="txt">Become a member of an existing Project and instantly gain access to the resources it has to offer you. Search for open Projects and join for free. Contact the closed Projects administrators, if you think they will accept you. In two words: try to Join now. </p> |
|
30 |
|
|
31 |
<p><a href="{% url project_search %}">join a project ></a></p> |
|
32 |
</div> |
|
33 |
</div> |
|
34 |
</li> |
|
35 |
</ul> |
|
36 |
</div> |
b/snf-astakos-app/astakos/im/templates/im/projects_list.html | ||
---|---|---|
1 |
{% extends "im/account_base.html" %} |
|
2 |
|
|
3 |
{% load astakos_tags %} |
|
4 |
{% load filters %} |
|
5 |
{% load django_tables2 %} |
|
6 |
|
|
7 |
{% block page.body %} |
|
8 |
<div class="maincol {% block innerpage.class %}{% endblock %}"> |
|
9 |
<div class="projects"> |
|
10 |
<h2>PROJECTS</h2> |
|
11 |
{% if form %} |
|
12 |
{% include "im/projects_list.html" %} |
|
13 |
{% else %} |
|
14 |
{% include "im/projects_index.html" %} |
|
15 |
</div> |
|
16 |
{% endif %} |
|
17 |
{% render_table table %} |
|
18 |
</div> |
|
19 |
</div> |
|
20 |
{% endblock %} |
b/snf-astakos-app/astakos/im/templates/im/projects_search_form.html | ||
---|---|---|
1 |
<p>Search for existing Projects and join the ones you like. Please search by Project name. </p> |
|
2 |
<form action="{% url project_search %}" method="post" class="withlabels signup submit-inline">{% csrf_token %} |
|
3 |
{% include "im/form_render.html" %} |
|
4 |
<div class="form-row submit"> |
|
5 |
<input type="submit" class="submit altcol" value="SEARCH" /> |
|
6 |
{% if q %}<a href="{% url project_search %}">clear</a>{% endif %} |
|
7 |
</div> |
|
8 |
</form> |
|
9 |
|
b/snf-astakos-app/astakos/im/views.py | ||
---|---|---|
68 | 68 |
import astakos.im.messages as astakos_messages |
69 | 69 |
|
70 | 70 |
from astakos.im.activation_backends import get_backend, SimpleBackend |
71 |
from astakos.im import tables |
|
71 | 72 |
from astakos.im.models import ( |
72 | 73 |
AstakosUser, ApprovalTerms, |
73 | 74 |
EmailChange, GroupKind, |
... | ... | |
1102 | 1103 |
@signed_terms_required |
1103 | 1104 |
@login_required |
1104 | 1105 |
def project_list(request): |
1105 |
q = ProjectApplication.objects.filter(owner=request.user) |
|
1106 |
q |= ProjectApplication.objects.filter(applicant=request.user) |
|
1107 |
q |= ProjectApplication.objects.filter( |
|
1108 |
project__in=request.user.projectmembership_set.values_list('project', flat=True) |
|
1109 |
) |
|
1110 |
q = q.select_related() |
|
1111 |
sorting = 'name' |
|
1112 |
sort_form = ProjectSortForm(request.GET) |
|
1113 |
if sort_form.is_valid(): |
|
1114 |
sorting = sort_form.cleaned_data.get('sorting') |
|
1115 |
q = q.order_by(sorting) |
|
1106 |
projects = ProjectApplication.objects.user_projects(request.user).select_related() |
|
1107 |
table = tables.UserProjectApplicationsTable(projects, user=request.user, prefix="my_projects") |
|
1108 |
table.paginate(page=request.GET.get('my_projectspage', 1), per_page=PAGINATE_BY) |
|
1116 | 1109 |
|
1117 | 1110 |
return object_list( |
1118 | 1111 |
request, |
1119 |
q, |
|
1120 |
paginate_by=PAGINATE_BY, |
|
1121 |
page=request.GET.get('page') or 1, |
|
1112 |
projects, |
|
1122 | 1113 |
template_name='im/projects/project_list.html', |
1123 | 1114 |
extra_context={ |
1124 | 1115 |
'is_search':False, |
1125 |
'sorting':sorting
|
|
1116 |
'table': table,
|
|
1126 | 1117 |
} |
1127 | 1118 |
) |
1128 | 1119 |
|
... | ... | |
1213 | 1204 |
else: |
1214 | 1205 |
transaction.commit() |
1215 | 1206 |
|
1207 |
|
|
1216 | 1208 |
@require_http_methods(["GET", "POST"]) |
1217 | 1209 |
@signed_terms_required |
1218 | 1210 |
@login_required |
1219 | 1211 |
def project_search(request): |
1220 |
q = request.GET.get('q') |
|
1221 |
queryset = ProjectApplication.objects |
|
1212 |
q = request.GET.get('q', '')
|
|
1213 |
queryset = ProjectApplication.objects.filter()
|
|
1222 | 1214 |
|
1223 | 1215 |
if request.method == 'GET': |
1224 | 1216 |
form = ProjectSearchForm() |
... | ... | |
1230 | 1222 |
|
1231 | 1223 |
if form.is_valid(): |
1232 | 1224 |
q = form.cleaned_data['q'].strip() |
1233 |
|
|
1234 | 1225 |
queryset = queryset.filter(~Q(project__last_approval_date__isnull=True)) |
1235 |
|
|
1236 | 1226 |
queryset = queryset.filter(name__contains=q) |
1237 | 1227 |
else: |
1238 | 1228 |
queryset = queryset.none() |
Also available in: Unified diff