Revision 91cb6fb6 snf-astakos-app/astakos/im/tables.py

b/snf-astakos-app/astakos/im/tables.py
1
import django_tables2 as tables
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
2 33

  
3 34
from django.utils.translation import ugettext as _
35
from django.utils.safestring import mark_safe
36
from django.template import Context, Template
37
from django.template.loader import render_to_string
38

  
4 39
from django_tables2 import A
40
import django_tables2 as tables
41

  
5 42
from astakos.im.models import *
6
from django.utils.safestring import mark_safe
7 43

  
8 44
DEFAULT_DATE_FORMAT = "d/m/Y"
9 45

  
......
18 54
     -1: _('Unregistered'),
19 55
}
20 56

  
57
# Helper columns
58
class RichLinkColumn(tables.TemplateColumn):
59

  
60
    method = 'POST'
61

  
62
    confirm_prompt = _('Yes')
63
    cancel_prompt = _('No')
64
    confirm = True
65

  
66
    prompt = _('Confirm action ?')
67

  
68
    action_tpl = None
69
    action = _('Action')
70
    extra_context = lambda record, table, column: {}
71

  
72
    url = None
73
    url_args = ()
74
    resolve_func = None
75

  
76
    def __init__(self, *args, **kwargs):
77
        kwargs['template_name'] = kwargs.get('template_name',
78
                                             'im/table_rich_link_column.html')
79
        for attr in ['method', 'confirm_prompt',
80
                     'cancel_prompt', 'prompt', 'url',
81
                     'url_args', 'action', 'confirm',
82
                     'resolve_func', 'extra_context']:
83
            setattr(self, attr, kwargs.pop(attr, getattr(self, attr)))
84

  
85
        super(RichLinkColumn, self).__init__(*args, **kwargs)
86

  
87
    def render(self, record, table, value, bound_column, **kwargs):
88
        # If the table is being rendered using `render_table`, it hackily
89
        # attaches the context to the table as a gift to `TemplateColumn`. If
90
        # the table is being rendered via `Table.as_html`, this won't exist.
91
        context = getattr(table, 'context', Context())
92
        context.update(self.get_template_context(record, table, value,
93
                                                 bound_column, **kwargs))
94
        try:
95
            if self.template_code:
96
                return Template(self.template_code).render(context)
97
            else:
98
                return render_to_string(self.template_name, context)
99
        finally:
100
            context.pop()
101

  
102
    def get_confirm(self, record, table):
103
        if callable(self.confirm):
104
            return self.confirm(record, table)
105
        return self.confirm
106

  
107
    def resolved_url(self, record, table):
108
        if callable(self.url):
109
            return self.url(record, table)
110

  
111
        if not self.url:
112
            return '#'
113

  
114
        args = list(self.url_args)
115
        for index, arg in enumerate(args):
116
            if isinstance(arg, A):
117
                args[index] = arg.resolve(record)
118
        return reverse(self.url, args=args)
119

  
120
    def get_action(self, record, table):
121
        if callable(self.action):
122
            return self.action(record, table)
123
        return self.action
124

  
125
    def get_prompt(self, record, table):
126
        if callable(self.prompt):
127
            return self.prompt(record, table)
128
        return self.prompt
129

  
130
    def get_template_context(self, record, table, value, bound_column, **kwargs):
131
        context = {'default': bound_column.default,
132
                   'record': record,
133
                   'value': value,
134
                   'col': self,
135
                   'url': self.resolved_url(record, table),
136
                   'prompt': self.get_prompt(record, table),
137
                   'action': self.get_action(record, table),
138
                   'confirm': self.get_confirm(record, table)
139
                  }
140

  
141
        if self.extra_context:
142
            context.update(self.extra_context(record, table, self))
143

  
144
        return context
145

  
146

  
147
def action_extra_context(project, table, self):
148
    user = table.user
149
    url, action, confirm, prompt = '', '', True, ''
150
    append_url = ''
151

  
152
    if user.owns_project(project):
153
        url = 'astakos.im.views.project_update'
154
        action = _('Update')
155
        confirm = False
156
        prompt = ''
157
    elif user.is_project_member(project):
158
        url = 'astakos.im.views.project_leave'
159
        action = _('- Leave')
160
        confirm = True
161
        prompt = _('Are you sure you want to leave from the project ?')
162
    else:
163
        url = 'astakos.im.views.project_join'
164
        action = _('+ Join')
165
        confirm = True
166
        prompt = _('Are you sure you want to join this project ?')
167

  
168
    return {'action': action, 'confirm': confirm,
169
            'url': reverse(url, args=(project.pk, )) + append_url,
170
            'prompt': prompt}
171

  
172

  
173
# Table classes
21 174
class UserProjectApplicationsTable(tables.Table):
22 175

  
23 176
    def __init__(self, *args, **kwargs):
......
39 192
                                  sortable=False)
40 193
    membership_status = tables.Column(verbose_name=_("My status"), empty_values=(),
41 194
                                      orderable=False)
195
    project_action = RichLinkColumn(verbose_name=_('Action'),
196
                                    extra_context=action_extra_context,
197
                                    sortable=False)
42 198

  
43 199

  
44 200
    def render_membership_status(self, *args, **kwargs):
45
        return MEMBER_STATUS_DISPLAY.get(kwargs.get('record').member_status(self.user))
201
        return MEMBER_STATUS_DISPLAY.get(kwargs.get('record').user_status(self.user))
46 202

  
47 203
    class Meta:
48 204
        model = ProjectApplication

Also available in: Unified diff