Revision 9b32e2fb

b/snf-astakos-app/astakos/im/models.py
1125 1125
        """
1126 1126
        Return projects accessed by specified user.
1127 1127
        """
1128
        return self.filter(Q(owner=user) | Q(applicant=user) | \
1129
                        Q(project__projectmembership__person=user)).order_by('pk').distinct()
1128
        participates_fitlers = Q(owner=user) | Q(applicant=user) | \
1129
                               Q(project__projectmembership__person=user)
1130
        state_filters = (Q(state=ProjectApplication.PENDING) & \
1131
                        Q(precursor_application__isnull=True)) | \
1132
                        Q(state=ProjectApplication.APPROVED)
1133
        return self.filter(participates_fitlers & state_filters).order_by('issue_date').distinct()
1130 1134

  
1131 1135
    def search_by_name(self, *search_strings):
1132 1136
        q = Q()
......
1252 1256
        except ProjectApplication.DoesNotExist:
1253 1257
            return
1254 1258

  
1259
    def followers(self):
1260
        current = self
1261
        try:
1262
            while current.projectapplication:
1263
                yield current.follower
1264
                current = current.follower
1265
        except:
1266
            pass
1267

  
1268
    def last_follower(self):
1269
        try:
1270
            return list(self.followers())[-1]
1271
        except IndexError:
1272
            return None
1273

  
1255 1274
    def submit(self, resource_policies, applicant, comments,
1256 1275
               precursor_application=None):
1257 1276

  
b/snf-astakos-app/astakos/im/static/im/css/modules.css
557 557
    -webkit-transition: width 1s, color 0.2s; /* Safari and Chrome */
558 558
    -o-transition: width 1s, color 0.2s; /* Opera */
559 559
}
560

  
561
i.tiny { font-size: 0.8em; color: #999;}
b/snf-astakos-app/astakos/im/tables.py
37 37
from django.utils.safestring import mark_safe
38 38
from django.template import Context, Template
39 39
from django.template.loader import render_to_string
40
from django.core.exceptions import PermissionDenied
40 41

  
41 42
from django_tables2 import A
42 43
import django_tables2 as tables
43 44

  
44 45
from astakos.im.models import *
45 46
from astakos.im.templatetags.filters import truncatename
47
from astakos.im.functions import do_join_project_checks
46 48

  
47 49
DEFAULT_DATE_FORMAT = "d/m/Y"
48 50

  
49 51

  
50
MEMBER_STATUS_DISPLAY = {
51
    100: _('Owner'),
52
      0: _('Requested'),
53
      1: _('Pending'),
54
      2: _('Accepted'),
55
      3: _('Removing'),
56
      4: _('Removed'),
57
     -1: _('Unregistered'),
58
}
59

  
60
class TruncatedLinkColumn(tables.LinkColumn):
52
class LinkColumn(tables.LinkColumn):
61 53

  
62 54
    def __init__(self, *args, **kwargs):
63
        self.truncate_chars = kwargs.pop('truncate_chars', 10)
64
        super(TruncatedLinkColumn, self).__init__(*args, **kwargs)
65

  
55
        self.coerce = kwargs.pop('coerce', None)
56
        self.append = kwargs.pop('append', None)
57
        super(LinkColumn, self).__init__(*args, **kwargs)
58

  
59
    def render(self, value, record, bound_column):
60
        link = super(LinkColumn, self).render(value, record, bound_column)
61
        extra = ''
62
        if self.append:
63
            if callable(self.append):
64
                extra = self.append(record, bound_column)
65
            else:
66
                extra = self.append
67
        return mark_safe(link + extra)
66 68

  
67 69
    def render_link(self, uri, text, attrs=None):
68
        text = truncatename(text, self.truncate_chars)
69
        return super(TruncatedLinkColumn, self).render_link(uri, text, attrs)
70
        if self.coerce:
71
            text = self.coerce(text)
72
        return super(LinkColumn, self).render_link(uri, text, attrs)
70 73

  
71 74

  
72 75
# Helper columns
......
226 229
        super(UserTable, self).__init__(*args, **kwargs)
227 230

  
228 231

  
232
def project_name_append(record, column):
233
    try:
234
        if record.projectapplication and column.table.user.owns_project(record):
235
            if record.state == ProjectApplication.APPROVED:
236
                return mark_safe("<br /><i class='tiny'>%s</i>" % _('modifications pending'))
237
            else:
238
                return u''
239
        else:
240
            return u''
241
    except:
242
        return u''
243

  
229 244
# Table classes
230 245
class UserProjectApplicationsTable(UserTable):
231 246
    caption = _('My projects')
232 247

  
233
    name = TruncatedLinkColumn('astakos.im.views.project_detail',
234
                                                truncate_chars=25,
235
                                                args=(A('pk'),))
236
    issue_date = tables.DateColumn(format=DEFAULT_DATE_FORMAT)
248
    name = LinkColumn('astakos.im.views.project_detail',
249
                      coerce=lambda x: truncatename(x, 25),
250
                      append=project_name_append,
251
                      args=(A('pk'),))
252
    issue_date = tables.DateColumn(verbose_name=_('Applied at'), format=DEFAULT_DATE_FORMAT)
237 253
    start_date = tables.DateColumn(format=DEFAULT_DATE_FORMAT)
238
    end_date = tables.DateColumn(format=DEFAULT_DATE_FORMAT)
239
    members_count = tables.Column(verbose_name=_("Enrolled"), default=0,
254
    end_date = tables.DateColumn(verbose_name=_('Expires at'), format=DEFAULT_DATE_FORMAT)
255
    members_count = tables.Column(verbose_name=_("Members"), default=0,
240 256
                                  sortable=False)
241 257
    membership_status = tables.Column(verbose_name=_("Status"), empty_values=(),
242 258
                                      sortable=False)
......
246 262

  
247 263

  
248 264
    def render_membership_status(self, record, *args, **kwargs):
249
        status = record.user_status(self.user)
250
        if status == 100:
251
            return record.state
265
        if self.user.owns_project(record):
266
            return record.state_display()
252 267
        else:
253
            return MEMBER_STATUS_DISPLAY.get(status, 'Unknown')
268
            status = record.user_status(self.user)
269
            return record.user_status_display(self.user)
254 270

  
255 271
    class Meta:
256 272
        model = ProjectApplication
257
        fields = ('name', 'membership_status', 'issue_date', 'start_date','end_date', 'members_count')
273
        fields = ('name', 'membership_status', 'issue_date', 'end_date', 'members_count')
258 274
        attrs = {'id': 'projects-list', 'class': 'my-projects alt-style'}
259 275
        template = "im/table_render.html"
260 276
        empty_text = _('No projects')
261 277

  
278
class ProjectModificationApplicationsTable(UserProjectApplicationsTable):
279
    name = LinkColumn('astakos.im.views.project_detail',
280
                      verbose_name=_('Action'),
281
                      coerce= lambda x: 'review',
282
                      args=(A('pk'),))
283
    class Meta:
284
        attrs = {'id': 'projects-list', 'class': 'my-projects alt-style'}
285
        fields = ('issue_date', 'membership_status')
286
        exclude = ('start_date', 'end_date', 'members_count', 'project_action')
262 287

  
263 288
def member_action_extra_context(membership, table, col):
264 289

  
b/snf-astakos-app/astakos/im/templates/im/projects/project_detail.html
109 109
		 	<dd>{% if object.limit_on_members_number%}{{object.limit_on_members_number}}{% else %}&nbsp;{% endif %}</dd>
110 110
		 	<dt>Member join policy</dt>
111 111
            <dd>
112
                {{ join_policies|lookup:object.member_join_policy }}
112
                {{ join_policies|lookup:object.member_join_policy|title }}
113 113
            </dd>
114 114
		 	<dt>Member leave policy</dt>
115 115
            <dd>
116
                {{ leave_policies|lookup:object.member_leave_policy }}
116
                {{ leave_policies|lookup:object.member_leave_policy|title }}
117 117
            </dd>
118 118
		 </dl>
119 119
	 </div>
......
170 170
            </form>
171 171
        </div>
172 172
        {% endif %}
173
        {% comment %}
174
        {% if modifications_table %}
175
         <div class="full-dotted">
176
             <h3>MODIFICATION REQUESTS</h3>
177
             {% render_table modifications_table %}
178
         </div>
179
         {% endif %}
180
         {% endcomment %}
173 181
    {% endif %}
174 182
    <div class="full-dotted">
175 183
        <p>
b/snf-astakos-app/astakos/im/views.py
1136 1136
                                                          prefix="members_")
1137 1137
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(members_table)
1138 1138

  
1139
    modifications_table = None
1140
    if application.follower:
1141
        following_applications = list(application.followers())
1142
        following_applications.reverse()
1143
        modifications_table = \
1144
            tables.ProjectModificationApplicationsTable(following_applications,
1145
                                                       user=request.user,
1146
                                                       prefix="modifications_")
1147

  
1139 1148
    return object_detail(
1140 1149
        request,
1141 1150
        queryset=ProjectApplication.objects.select_related(),

Also available in: Unified diff