tables.py 23.4 KB
Newer Older
1
2
# coding: utf-8
from flask import Markup, url_for, request
Robin Sonnabend's avatar
Robin Sonnabend committed
3
from models.database import Protocol, ProtocolType, DefaultTOP, TOP, Todo, Decision, Meta, DefaultMeta
Robin Sonnabend's avatar
Robin Sonnabend committed
4
from shared import date_filter, datetime_filter, date_filter_short, current_user, check_login 
5

6
7
import config

8
class Table:
Robin Sonnabend's avatar
Robin Sonnabend committed
9
    def __init__(self, title, values, newlink=None, newtext=None):
10
11
12
        self.title = title
        self.values = values
        self.newlink = newlink
Robin Sonnabend's avatar
Robin Sonnabend committed
13
        self.newtext = newtext or "Neu"
14
15
16
17

    def rows(self):
        return [row for row in [self.row(value) for value in self.values] if row is not None]

18
19
20
    def classes(self):
        return [None for header in self.headers()]

21
22
23
24
25
26
27
    @staticmethod
    def link(target, text, confirm=None):
        confirmation = ""
        if confirm:
            confirmation = " onclick=\"return confirm('{}');\"".format(confirm)
        return Markup("<a href=\"{}\"{}>{}</a>".format(target, confirmation, text))

marco's avatar
marco committed
28
29
30
31
32
33
    @staticmethod
    def button(target, icon, style, confirm=None):
        confirmation = ""
        if confirm:
            confirmation = " onclick=\"return confirm('{}');\"".format(confirm)
        return Markup(
marco's avatar
marco committed
34
                '''<a href="{target}" class="btn btn-{style}" {confirmation}>
marco's avatar
marco committed
35
                        <span class="glyphicon glyphicon-{icon}"></span>
marco's avatar
marco committed
36
                   </a>'''.format(target=target, style=style, confirmation=confirmation, icon=icon))
marco's avatar
marco committed
37
    
38
39
40
41
42
43
    @staticmethod
    def mail(target):
        return Markup("<a href=\"mailto:{}\">{}</a>".format(target, target))

    @staticmethod
    def bool(value):
Robin Sonnabend's avatar
Robin Sonnabend committed
44
        return "Ja" if value else "Nein"
45
46
47

    @staticmethod
    def concat(values):
Robin Sonnabend's avatar
Robin Sonnabend committed
48
        return Markup(", ".join(values))
49
50
51
52
53
54
55
        #if len(values) <= 1:
        #    return "".join(values)
        #else:
        #    return "{} and {}".format(", ".join(values[:-1]), values[-1])
            

class SingleValueTable:
Robin Sonnabend's avatar
Robin Sonnabend committed
56
    def __init__(self, title, value, newlink=None, newtext=None):
57
58
59
        self.title = title
        self.value = value
        self.newlink = newlink if newlink else None
Robin Sonnabend's avatar
Robin Sonnabend committed
60
        self.newtext = newtext or "Ändern"
61
62
63
64
65

    def rows(self):
        return [self.row()]

class ProtocolsTable(Table):
Robin Sonnabend's avatar
Robin Sonnabend committed
66
    def __init__(self, protocols, search_results=None):
Robin Sonnabend's avatar
Robin Sonnabend committed
67
        super().__init__("Protokolle", protocols, newlink=url_for("new_protocol"))
Robin Sonnabend's avatar
Robin Sonnabend committed
68
        self.search_results = search_results
69
70

    def headers(self):
Administrator's avatar
Administrator committed
71
        user = current_user()
marco's avatar
marco committed
72
        result = ["Sitzung", "Sitzung", "Datum"]
marco's avatar
marco committed
73
74
        state_part = ["Status", "Status",""]
        search_part = ["Suchergebnis",""]
Robin Sonnabend's avatar
Robin Sonnabend committed
75
76
77
78
        if self.search_results is None:
            result.extend(state_part)
        else:
            result.extend(search_part)
Robin Sonnabend's avatar
Robin Sonnabend committed
79
        return result
80

81
    def classes(self):
marco's avatar
marco committed
82
83
84
85
        if self.search_results is None:
            result = ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "hidden-sm hidden-md hidden-lg", "hidden-xs", ""]
        else:
            result = ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "", "hidden-xs","hidden-xs"]
86
87
        return result

88
    def row(self, protocol):
Robin Sonnabend's avatar
Robin Sonnabend committed
89
        user = current_user()
90
        protocol_link = url_for("show_protocol", protocol_id=protocol.id)
Robin Sonnabend's avatar
Robin Sonnabend committed
91
        result = [
92
93
            Markup("<br>").join([Table.link(protocol_link, protocol.protocoltype.name), date_filter(protocol.date)]),
            Table.link(protocol_link, protocol.protocoltype.name),
Robin Sonnabend's avatar
Robin Sonnabend committed
94
            date_filter(protocol.date),
95
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
96
        if self.search_results is None:
marco's avatar
marco committed
97
98
            result.append(Markup('<span class="glyphicon glyphicon-{state}"></span>'.format(state=protocol.get_state_glyph())))
            result.append(Markup('<span class="glyphicon glyphicon-{glyph}"></span> {state}'.format(state=protocol.get_state_name(),glyph=protocol.get_state_glyph())))
Robin Sonnabend's avatar
Robin Sonnabend committed
99
100
        elif protocol in self.search_results:
            result.append(Markup(self.search_results[protocol]))
marco's avatar
marco committed
101
            result.append(Markup('<span class="glyphicon glyphicon-{state}"></span>'.format(state=protocol.get_state_glyph())))
marco's avatar
marco committed
102
        
marco's avatar
marco committed
103
        login_part1=""
marco's avatar
marco committed
104
        login_part2=""
marco's avatar
marco committed
105
106
107
        if protocol.has_public_view_right(user):
            user_right = protocol.has_private_view_right(user)
            document = protocol.get_compiled_document(user_right)
Robin Sonnabend's avatar
Robin Sonnabend committed
108
109
110
            if document is not None:
                login_part1 = Table.button(
                    url_for("download_document", document_id=document.id),
marco's avatar
marco committed
111
                    icon="download", style="success")
marco's avatar
marco committed
112

Robin Sonnabend's avatar
Robin Sonnabend committed
113
114
115
116
117
118
119
120
121
122
        if protocol.protocoltype.has_admin_right(user):
            login_part2 = Table.button(
                url_for("delete_protocol", protocol_id=protocol.id),
                icon="trash",
                style="danger",
                confirm="Bist du dir sicher, dass du das Protokoll {} löschen möchtest?")

        result.append(Markup(
            '<div class="btn-group btn-group-xs"> {} </div>'.format(
                "".join((login_part1, login_part2)))))
marco's avatar
marco committed
123

Robin Sonnabend's avatar
Robin Sonnabend committed
124
        return result
125

Robin Sonnabend's avatar
Robin Sonnabend committed
126
127
128
129
130
class ProtocolTypesTable(Table):
    def __init__(self, types):
        super().__init__("Protokolltypen", types, newlink=url_for("new_type"))

    def headers(self):
131
132
133
134
135
136
137
138
139
140
        return [
            "Typ", "Protokoll",
            "Typ", "Name", "Neuestes Protokoll", ""
        ]

    def classes(self):
        return [
            "hidden-sm hidden-md hidden-lg", "hidden-sm hidden-md hidden-lg",
            "hidden-xs", "hidden-xs", "hidden-xs", "hidden-xs"
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
141
142

    def row(self, protocoltype):
Robin Sonnabend's avatar
Robin Sonnabend committed
143
144
        protocol = protocoltype.get_latest_protocol()
        user = current_user()
145
        has_private_view_right = protocoltype.has_private_view_right(user)
Robin Sonnabend's avatar
Robin Sonnabend committed
146
        has_modify_right = protocoltype.has_modify_right(user)
147
        protocoltype_link = url_for("show_type", protocoltype_id=protocoltype.id)
148
149
        protocol_link = (url_for("show_protocol", protocol_id=protocol.id)
            if protocol is not None else "")
150
        new_protocol_link = url_for("new_protocol", protocoltype_id=protocoltype.id)
151
        mobile_name = "{} ({})".format(protocoltype.name, protocoltype.short_name)
152
153
        mobile_links = []
        if protocol is not None:
154
            mobile_links.append(Table.link(protocol_link, protocol.get_short_identifier()))
155
156
157
158
159
160
161
162
        if has_modify_right:
            mobile_links.append(Table.link(new_protocol_link, "Neues Protokoll"))
        mobile_part = [
            Table.link(protocoltype_link, mobile_name) if has_private_view_right else mobile_name,
            Markup("<br>".join(mobile_links))
        ]
        desktop_part = [
            Table.link(protocoltype_link, protocoltype.short_name) if has_private_view_right else protocoltype.short_name,
Robin Sonnabend's avatar
Robin Sonnabend committed
163
            protocoltype.name,
164
            Table.link(protocol_link, protocol.get_short_identifier()) if protocol is not None else "Noch kein Protokoll",
165
            Table.link(new_protocol_link, "Neues Protokoll") if has_modify_right else ""
Robin Sonnabend's avatar
Robin Sonnabend committed
166
            "" # TODO: add link for modify, delete
Robin Sonnabend's avatar
Robin Sonnabend committed
167
        ]
168
        return mobile_part + desktop_part
Robin Sonnabend's avatar
Robin Sonnabend committed
169
170
171

class ProtocolTypeTable(SingleValueTable):
    def __init__(self, protocoltype):
Robin Sonnabend's avatar
Robin Sonnabend committed
172
        super().__init__(protocoltype.name, protocoltype, newlink=url_for("edit_type", protocoltype_id=protocoltype.id))
Robin Sonnabend's avatar
Robin Sonnabend committed
173
174

    def headers(self):
175
        general_headers = ["Name", "Abkürzung", "Organisation", "Beginn",
Robin Sonnabend's avatar
Robin Sonnabend committed
176
            "Öffentlich", "Verwaltungsgruppe", "Bearbeitungsgruppe", "Interne Gruppe",
177
            "Öffentliche Gruppe"]
178
179
180
        etherpad_headers = ["Nicht-reproduzierbare Etherpadlinks"]
        if not config.ETHERPAD_ACTIVE:
            etherpad_headers = []
181
182
183
184
185
        mail_headers = ["Interner Verteiler", "Öffentlicher Verteiler"]
        if not config.MAIL_ACTIVE:
            mail_headers = []
        printing_headers = ["Drucker"] if config.PRINTING_ACTIVE else []
        wiki_headers = ["Wiki"]
Robin Sonnabend's avatar
Robin Sonnabend committed
186
        if self.value.use_wiki:
187
188
189
            wiki_headers.append("Wiki-Kategorie")
        if not config.WIKI_ACTIVE:
            wiki_headers = []
Robin Sonnabend's avatar
Robin Sonnabend committed
190
191
192
        calendar_headers = ["Kalender"]
        if not config.CALENDAR_ACTIVE:
            calendar_headers = []
193
        network_headers = ["Netzwerke einschränken", "Erlaubte Netzwerke"]
194
        action_headers = ["Aktion"]
Robin Sonnabend's avatar
Robin Sonnabend committed
195
        feed_headers = []
196
        latex_template_headers = ["LaTeX Vorlage"] if getattr(config, "LATEX_TEMPLATES", None) is not None else []
Robin Sonnabend's avatar
Robin Sonnabend committed
197
198
199
        if self.value.has_public_anonymous_view_right():
            feed_headers = [Markup("<img height=\"18px\" src=\"{}\" /> Feed".format(
                url_for("static", filename="images/feed-icon.svg")))]
200
201
        return (general_headers + etherpad_headers + mail_headers
            + printing_headers + wiki_headers + calendar_headers
202
            + network_headers + latex_template_headers + feed_headers + action_headers)
Robin Sonnabend's avatar
Robin Sonnabend committed
203
204

    def row(self):
205
        user = current_user()
206
        general_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
207
208
209
            self.value.name,
            self.value.short_name,
            self.value.organization,
Robin Sonnabend's avatar
Robin Sonnabend committed
210
            self.value.usual_time.strftime("%H:%M") if self.value.usual_time is not None else "", # todo: remove if, this field is required
Robin Sonnabend's avatar
Robin Sonnabend committed
211
            Table.bool(self.value.is_public),
Robin Sonnabend's avatar
Robin Sonnabend committed
212
            self.value.publish_group,
213
            self.value.modify_group,
Robin Sonnabend's avatar
Robin Sonnabend committed
214
215
            self.value.private_group,
            self.value.public_group,
216
        ]
217
218
219
220
        etherpad_part = [
            Table.bool(self.value.non_reproducible_pad_links)
        ]
        if not config.ETHERPAD_ACTIVE:
221
            etherpad_part = []
222
        mail_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
223
            self.value.private_mail,
Robin Sonnabend's avatar
Robin Sonnabend committed
224
            self.value.public_mail,
225
226
227
228
229
230
231
        ]
        if not config.MAIL_ACTIVE:
            mail_part = []
        printing_part = [self.value.printer]
        if not config.PRINTING_ACTIVE:
            printing_part = []
        wiki_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
232
            (Table.bool(self.value.use_wiki) + ((", " + ("Öffentlich" if self.value.wiki_only_public else "Intern")) if self.value.use_wiki else ""))
Robin Sonnabend's avatar
Robin Sonnabend committed
233
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
234
        if self.value.use_wiki:
235
236
237
            wiki_part.append(self.value.wiki_category)
        if not config.WIKI_ACTIVE:
            wiki_part = []
Robin Sonnabend's avatar
Robin Sonnabend committed
238
239
240
        calendar_part = [self.value.calendar if self.value.calendar is not None else ""]
        if not config.CALENDAR_ACTIVE:
            calendar_part = []
241
242
243
244
245
        network_part = [Table.bool(self.value.restrict_networks)]
        if self.value.allowed_networks is not None:
            network_part.append(", ".join(map(str.strip, self.value.allowed_networks.split(","))))
        else:
            network_part.append("")
246
247
248
249
250
        _latex_templates = getattr(config, "LATEX_TEMPLATES", None)
        if _latex_templates is not None:
            latex_template_part = [_latex_templates[self.value.latex_template]['name'] if self.value.latex_template is not (None or "") else "Standardvorlage"]
        else:
            latex_template_part = []
Robin Sonnabend's avatar
Robin Sonnabend committed
251
252
253
254
255
256
257
258
259
260
261
        feed_part = []
        if self.value.has_public_anonymous_view_right():
            feed_part = [Markup(", ".join([
                Table.link(url_for("feed_protocols_rss",
                    protocoltype_id=self.value.id), "Protokolle (RSS)"),
                Table.link(url_for("feed_protocols_atom",
                    protocoltype_id=self.value.id), "Protokolle (Atom)"),
                Table.link(url_for("feed_appointments_rss",
                    protocoltype_id=self.value.id), "Sitzungen (RSS)"),
                Table.link(url_for("feed_appointments_atom",
                    protocoltype_id=self.value.id), "Sitzungen (Atom)"),
Robin Sonnabend's avatar
Robin Sonnabend committed
262
263
                Table.link(url_for("feed_appointments_ical",
                    protocoltype_id=self.value.id), "Sitzungen (iCal)"),
Robin Sonnabend's avatar
Robin Sonnabend committed
264
            ]))]
Robin Sonnabend's avatar
Robin Sonnabend committed
265
        action_part = [Table.link(url_for("delete_type", protocoltype_id=self.value.id), "Löschen", confirm="Bist du dir sicher, dass du den Protokolltype {} löschen möchtest?".format(self.value.name))]
266
267
        if not self.value.has_admin_right(user):
            action_part = [""]
268
        return (general_part + etherpad_part + mail_part + printing_part
269
            + wiki_part +  calendar_part + network_part + latex_template_part + feed_part
Robin Sonnabend's avatar
Robin Sonnabend committed
270
            + action_part)
Robin Sonnabend's avatar
Robin Sonnabend committed
271
272
273

class DefaultTOPsTable(Table):
    def __init__(self, tops, protocoltype=None):
Robin Sonnabend's avatar
Robin Sonnabend committed
274
        super().__init__("Standard-TOPs", tops, newlink=url_for("new_default_top", protocoltype_id=protocoltype.id) if protocoltype is not None else None)
Robin Sonnabend's avatar
Robin Sonnabend committed
275
276
277
278
279
280
281
282
283
284
        self.protocoltype = protocoltype

    def headers(self):
        return ["TOP", "Sortierung", ""]

    def row(self, top):
        return [
            top.name,
            top.number,
            Table.concat([
285
286
                Table.link(url_for("move_default_top", defaulttop_id=top.id, diff=1), "Runter"),
                Table.link(url_for("move_default_top", defaulttop_id=top.id, diff=-1), "Hoch"),
Robin Sonnabend's avatar
Robin Sonnabend committed
287
                Table.link(url_for("edit_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id), "Ändern"),
288
                Table.link(url_for("delete_default_top", defaulttop_id=top.id), "Löschen", confirm="Bist du dir sicher, dass du den Standard-TOP {} löschen willst?".format(top.name))
Robin Sonnabend's avatar
Robin Sonnabend committed
289
290
            ])
        ]
291
292
293

class MeetingRemindersTable(Table):
    def __init__(self, reminders, protocoltype=None):
Robin Sonnabend's avatar
Robin Sonnabend committed
294
        super().__init__("Einladungsmails", reminders, newlink=url_for("new_reminder", protocoltype_id=protocoltype.id) if protocoltype is not None else None)
295
296
297
        self.protocoltype = protocoltype

    def headers(self):
Robin Sonnabend's avatar
Robin Sonnabend committed
298
        return ["Zeit", "Einladen", "Zusätzlicher Mailinhalt", ""]
299
300

    def row(self, reminder):
301
302
        user = current_user()
        general_part = [
303
304
            "{} Tage".format(reminder.days_before),
            self.get_send_summary(reminder),
305
            reminder.additional_text or ""
306
        ]
307
        action_links = [
308
309
            Table.link(url_for("edit_reminder", meetingreminder_id=reminder.id), "Ändern"),
            Table.link(url_for("delete_reminder", meetingreminder_id=reminder.id), "Löschen", confirm="Bist du dir sicher, dass du die Einladungsmail {} Tage vor der Sitzung löschen willst?".format(reminder.days_before))
310
311
312
        ]
        action_part = [Table.concat(action_links)]
        return general_part + action_part
313
314
315
316
317
318
319
320

    def get_send_summary(self, reminder):
        parts = []
        if reminder.send_public:
            parts.append("Öffentlich")
        if reminder.send_private:
            parts.append("Intern")
        return " und ".join(parts)
Robin Sonnabend's avatar
Robin Sonnabend committed
321
322
323
324
325
326

class ErrorsTable(Table):
    def __init__(self, errors):
        super().__init__("Fehler", errors)

    def headers(self):
Robin Sonnabend's avatar
Robin Sonnabend committed
327
        return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt", "Beschreibung", ""]
Robin Sonnabend's avatar
Robin Sonnabend committed
328

329
    def classes(self):
330
        return [None, None, None, None, "hidden-xs", "hidden-xs"]
331

Robin Sonnabend's avatar
Robin Sonnabend committed
332
333
    def row(self, error):
        return [
334
            Table.link(url_for("show_protocol", protocol_id=error.protocol.id), error.protocol.get_short_identifier()),
Robin Sonnabend's avatar
Robin Sonnabend committed
335
336
            error.action,
            Table.link(url_for("show_error", error_id=error.id), error.name),
Robin Sonnabend's avatar
Robin Sonnabend committed
337
            datetime_filter(error.datetime),
Robin Sonnabend's avatar
Robin Sonnabend committed
338
            error.get_short_description(),
Robin Sonnabend's avatar
Robin Sonnabend committed
339
            Table.link(url_for("delete_error", error_id=error.id, next=request.path), "Löschen", confirm="Bist du dir sicher, dass du den Fehler löschen möchtest?")
Robin Sonnabend's avatar
Robin Sonnabend committed
340
341
342
343
344
345
346
        ]

class ErrorTable(SingleValueTable):
    def __init__(self, error):
        super().__init__(error.action, error)

    def headers(self):
347
        return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt"]
Robin Sonnabend's avatar
Robin Sonnabend committed
348
349
350

    def row(self):
        return [
351
            Table.link(url_for("show_protocol", protocol_id=self.value.protocol.id), self.value.protocol.get_short_identifier()),
Robin Sonnabend's avatar
Robin Sonnabend committed
352
353
            self.value.action,
            self.value.name,
354
            datetime_filter(self.value.datetime)
Robin Sonnabend's avatar
Robin Sonnabend committed
355
356
357
358
        ]

class TodosTable(Table):
    def __init__(self, todos):
Robin Sonnabend's avatar
Robin Sonnabend committed
359
        super().__init__("Todos", todos, newlink=url_for("new_todo"))
Robin Sonnabend's avatar
Robin Sonnabend committed
360
361

    def headers(self):
362
363
364
365
        return ["Todo", "ID", "Status", "Sitzung", "Name", "Aufgabe", ""]

    def classes(self):
        return ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "hidden-xs", "hidden-xs", None, "hidden-xs"]
Robin Sonnabend's avatar
Robin Sonnabend committed
366
367

    def row(self, todo):
Robin Sonnabend's avatar
Robin Sonnabend committed
368
        user = current_user()
Robin Sonnabend's avatar
Robin Sonnabend committed
369
        protocol = todo.get_first_protocol()
370
371
372
373
        mobile_parts = [Table.link(url_for("show_todo", todo_id=todo.id), todo.get_state())]
        if protocol is not None:
            mobile_parts.append(Table.link(url_for("show_protocol", protocol_id=protocol.id), todo.protocoltype.short_name))
        mobile_parts.append(todo.who)
Robin Sonnabend's avatar
Robin Sonnabend committed
374
        row = [
375
            Markup("<br>").join(mobile_parts),
Robin Sonnabend's avatar
Robin Sonnabend committed
376
            Table.link(url_for("show_todo", todo_id=todo.id), todo.get_id()),
Robin Sonnabend's avatar
Robin Sonnabend committed
377
            todo.get_state(),
378
            Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier())
Robin Sonnabend's avatar
Robin Sonnabend committed
379
                if protocol is not None
380
                else Table.link(url_for("list_protocols", protocoltype_id=todo.protocoltype.id), todo.protocoltype.short_name),
Robin Sonnabend's avatar
Robin Sonnabend committed
381
            todo.who,
Robin Sonnabend's avatar
Robin Sonnabend committed
382
            todo.description,
Robin Sonnabend's avatar
Robin Sonnabend committed
383
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
384
        if todo.protocoltype.has_modify_right(user):
385
386
387
388
            row.append(Table.concat([
                Table.link(url_for("edit_todo", todo_id=todo.id), "Ändern"),
                Table.link(url_for("delete_todo", todo_id=todo.id), "Löschen")
            ]))
Robin Sonnabend's avatar
Robin Sonnabend committed
389
390
391
392
393
394
395
396
397
        else:
            row.append("")
        return row

class TodoTable(SingleValueTable):
    def __init__(self, todo):
        super().__init__("Todo", todo)

    def headers(self):
398
        return ["ID", "Status", "Sitzung", "Name", "Aufgabe", ""]
Robin Sonnabend's avatar
Robin Sonnabend committed
399
400
401
402
403
404
405

    def row(self):
        user = current_user()
        protocol = self.value.get_first_protocol()
        row = [
            self.value.get_id(),
            self.value.get_state_plain(),
406
            Table.concat([
407
                Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier())
408
409
                    for protocol in self.value.protocols
            ]),
Robin Sonnabend's avatar
Robin Sonnabend committed
410
            self.value.who,
411
            self.value.description
Robin Sonnabend's avatar
Robin Sonnabend committed
412
413
414
415
416
417
418
419
420
        ]
        if self.value.protocoltype.has_modify_right(user):
            row.append(Table.concat([
                Table.link(url_for("edit_todo", todo_id=self.value.id), "Ändern"),
                Table.link(url_for("delete_todo", todo_id=self.value.id), "Löschen", confirm="Bist du dir sicher, dass du das Todo löschen willst?")
            ]))
        else:
            row.append("")
        return row
421

Robin Sonnabend's avatar
Robin Sonnabend committed
422
423
424
class DecisionsTable(Table):
    def __init__(self, decisions):
        super().__init__("Beschlüsse", decisions)
425
426
        self.category_present = len([
            decision for decision in decisions
427
            if len(decision.categories) > 0
428
        ]) > 0
Robin Sonnabend's avatar
Robin Sonnabend committed
429
430

    def headers(self):
431
432
433
434
435
436
        content_part = ["Sitzung", "Beschluss"]
        category_part = ["Kategorie"]
        if not self.category_present:
            category_part = []
        action_part = [""]
        return content_part + category_part + action_part
Robin Sonnabend's avatar
Robin Sonnabend committed
437
438

    def row(self, decision):
Robin Sonnabend's avatar
Robin Sonnabend committed
439
        user = current_user()
440
        content_part = [
441
            Table.link(url_for("show_protocol", protocol_id=decision.protocol.id), decision.protocol.get_short_identifier()),
442
443
            decision.content
        ]
444
        category_part = [decision.get_categories_str()]
445
446
447
        if not self.category_present:
            category_part = []
        action_part = [
448
            Table.link(url_for("print_decision", decisiondocument_id=decision.document.id), "Drucken")
Robin Sonnabend's avatar
Robin Sonnabend committed
449
450
451
452
                if config.PRINTING_ACTIVE
                and decision.protocol.protocoltype.has_modify_right(user)
                and decision.document is not None 
                else ""
Robin Sonnabend's avatar
Robin Sonnabend committed
453
        ]
454
        return content_part + category_part + action_part
Robin Sonnabend's avatar
Robin Sonnabend committed
455

456
class DocumentsTable(Table):
457
    def __init__(self, documents, protocol):
458
        super().__init__("Anhang", documents)
459
        self.protocol = protocol
460
461

    def headers(self):
462
463
464
465
466
467
468
        user = current_user()
        general_headers = ["ID", "Name"]
        visibility_headers = []
        if self.protocol.has_private_view_right(user):
            visibility_headers = ["Sichtbarkeit"]
        action_headers=[""]
        return general_headers + visibility_headers + action_headers
469

470
    def classes(self):
471
472
473
474
475
476
477
        user = current_user()
        general_part = [None, None]
        visibility_part = []
        if self.protocol.has_private_view_right(user):
            visibility_part = [None]
        action_part = ["hidden-xs"]
        return general_part + visibility_part + action_part
478

479
    def row(self, document):
Robin Sonnabend's avatar
Robin Sonnabend committed
480
        user = current_user()
481
        links = []
Robin Sonnabend's avatar
Robin Sonnabend committed
482
483
        if document.protocol.has_modify_right(user):
            links.append(Table.link(url_for("edit_document", document_id=document.id), "Bearbeiten"))
484
        if config.PRINTING_ACTIVE and document.protocol.has_modify_right(user):
485
            links.append(Table.link(url_for("print_document", document_id=document.id), "Drucken"))
486
487
        if document.protocol.protocoltype.has_admin_right(user):
            links.append(Table.link(url_for("delete_document", document_id=document.id), "Löschen", confirm="Bist du dir sicher, dass du das Dokument {} löschen willst?".format(document.name)))
488
        general_part = [
489
490
491
            document.id,
            Table.link(url_for("download_document", document_id=document.id), document.name),
        ]
492
493
494
495
496
        visibility_part = []
        if document.protocol.has_private_view_right(user):
            visibility_part = ["Intern" if document.is_private else "Öffentlich"]
        action_part = [Table.concat(links)]
        return general_part + visibility_part + action_part
Robin Sonnabend's avatar
Robin Sonnabend committed
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

class TodoMailsTable(Table):
    def __init__(self, todomails):
        super().__init__("Todo-Mail-Zuordnungen", todomails, url_for("new_todomail"))

    def headers(self):
        return ["Name", "Mail", ""]

    def row(self, todomail):
        return [
            todomail.name,
            todomail.mail,
            Table.concat([
                Table.link(url_for("edit_todomail", todomail_id=todomail.id), "Ändern"),
                Table.link(url_for("delete_todomail", todomail_id=todomail.id), "Löschen", confirm="Bist du dir sicher, dass du die Todomailzuordnung {} zu {} löschen willst?".format(todomail.name, todomail.mail))
            ])
        ]

Robin Sonnabend's avatar
Robin Sonnabend committed
515
516
517
518
519
class DefaultMetasTable(Table):
    def __init__(self, metas, protocoltype):
        super().__init__(
            "Metadatenfelder",
            metas,
Robin Sonnabend's avatar
Robin Sonnabend committed
520
            url_for("new_defaultmeta", protocoltype_id=protocoltype.id)
Robin Sonnabend's avatar
Robin Sonnabend committed
521
522
523
        )

    def headers(self):
524
        return ["Name", "Key", "Standardwert", "Intern", "Vorher", ""]
Robin Sonnabend's avatar
Robin Sonnabend committed
525
526

    def row(self, meta):
527
528
        user = current_user()
        general_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
529
530
            meta.name,
            meta.key,
531
532
533
            meta.value,
            Table.bool(meta.internal),
            Table.bool(meta.prior)
Robin Sonnabend's avatar
Robin Sonnabend committed
534
        ]
535
        links = [
Robin Sonnabend's avatar
Robin Sonnabend committed
536
            Table.link(url_for("edit_defaultmeta", defaultmeta_id=meta.id), "Ändern"),
537
            Table.link(url_for("delete_defaultmeta", defaultmeta_id=meta.id), "Löschen", confirm="Bist du dir sicher, dass du das Metadatenfeld {} löschen willst?".format(meta.name))
538
539
540
541
        ]
        link_part = [Table.concat(links)]
        return general_part + link_part

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
class DecisionCategoriesTable(Table):
    def __init__(self, categories, protocoltype):
        super().__init__(
            "Beschlusskategorien",
            categories, 
            url_for("new_decisioncategory", protocoltype_id=protocoltype.id)
        )

    def headers(self):
        return ["Name", ""]

    def row(self, category):
        user = current_user()
        general_part = [category.name]
        action_part = [
            Table.concat([
                Table.link(url_for("edit_decisioncategory", decisioncategory_id=category.id), "Ändern"),
                Table.link(url_for("delete_decisioncategory", decisioncategory_id=category.id), "Löschen", confirm="Bist du dir sicher, dass du die Beschlusskategorie {} löschen willst?".format(category.name))
            ])
        ]
        return general_part + action_part