tables.py 21.9 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
34
35
36
37
38
39
    @staticmethod
    def button(target, icon, style, confirm=None):
        confirmation = ""
        if confirm:
            confirmation = " onclick=\"return confirm('{}');\"".format(confirm)
        return Markup(
                '''<div class="btn-group btn-group-xs">
                    <a href="{target}" class="btn btn-{style}" {confirmation}>
                        <span class="glyphicon glyphicon-{icon}"></span>
                    </a>
                </div>'''.format(target=target, style=style, confirmation=confirmation, icon=icon))
    
40
41
42
43
44
45
    @staticmethod
    def mail(target):
        return Markup("<a href=\"mailto:{}\">{}</a>".format(target, target))

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

    @staticmethod
    def concat(values):
Robin Sonnabend's avatar
Robin Sonnabend committed
50
        return Markup(", ".join(values))
51
52
53
54
55
56
57
        #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
58
    def __init__(self, title, value, newlink=None, newtext=None):
59
60
61
        self.title = title
        self.value = value
        self.newlink = newlink if newlink else None
Robin Sonnabend's avatar
Robin Sonnabend committed
62
        self.newtext = newtext or "Ändern"
63
64
65
66
67

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

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

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

86
87
    def classes(self):
        state_or_search_class = "hidden-xs" if self.search_results is None else None
marco's avatar
marco committed
88
        result = ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", None]
89
        #result.append(state_or_search_class)
marco's avatar
marco committed
90
        login_part = ["hidden-xs"]
91
92
93
94
        if check_login():
            result.extend(login_part)
        return result

95
    def row(self, protocol):
Robin Sonnabend's avatar
Robin Sonnabend committed
96
        user = current_user()
97
        protocol_link = url_for("show_protocol", protocol_id=protocol.id)
Robin Sonnabend's avatar
Robin Sonnabend committed
98
        result = [
99
100
            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
101
            date_filter(protocol.date),
102
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
103
        if self.search_results is None:
marco's avatar
marco committed
104
            state = "pencil" #"Geplant"
105
            if protocol.is_done():
marco's avatar
marco committed
106
                state = "unchecked" #"Fertig"
107
                if protocol.public:
marco's avatar
marco committed
108
109
                    state = "check" #"Veröffentlicht"
            result.append(Markup('<span class="glyphicon glyphicon-{state}">'.format(state=state)))
Robin Sonnabend's avatar
Robin Sonnabend committed
110
111
        elif protocol in self.search_results:
            result.append(Markup(self.search_results[protocol]))
marco's avatar
marco committed
112
        
marco's avatar
marco committed
113
        login_part1=""
marco's avatar
marco committed
114
        login_part2=""
marco's avatar
marco committed
115
        if state !=  "pencil":
Robin Sonnabend's avatar
Robin Sonnabend committed
116
117
118
119
120
            document = protocol.get_compiled_document()
            if document is not None:
                login_part1 = Table.button(
                    url_for("download_document", document_id=document.id),
                    icon="download", style="")
marco's avatar
marco committed
121

Robin Sonnabend's avatar
Robin Sonnabend committed
122
123
124
125
126
127
128
129
130
131
        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
132

Robin Sonnabend's avatar
Robin Sonnabend committed
133
        return result
134

Robin Sonnabend's avatar
Robin Sonnabend committed
135
136
137
138
139
class ProtocolTypesTable(Table):
    def __init__(self, types):
        super().__init__("Protokolltypen", types, newlink=url_for("new_type"))

    def headers(self):
140
141
142
143
144
145
146
147
148
149
        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
150
151

    def row(self, protocoltype):
Robin Sonnabend's avatar
Robin Sonnabend committed
152
153
        protocol = protocoltype.get_latest_protocol()
        user = current_user()
154
        has_private_view_right = protocoltype.has_private_view_right(user)
Robin Sonnabend's avatar
Robin Sonnabend committed
155
        has_modify_right = protocoltype.has_modify_right(user)
156
        protocoltype_link = url_for("show_type", protocoltype_id=protocoltype.id)
157
158
        protocol_link = (url_for("show_protocol", protocol_id=protocol.id)
            if protocol is not None else "")
159
        new_protocol_link = url_for("new_protocol", protocoltype_id=protocoltype.id)
160
        mobile_name = "{} ({})".format(protocoltype.name, protocoltype.short_name)
161
162
        mobile_links = []
        if protocol is not None:
163
            mobile_links.append(Table.link(protocol_link, protocol.get_short_identifier()))
164
165
166
167
168
169
170
171
        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
172
            protocoltype.name,
173
            Table.link(protocol_link, protocol.get_short_identifier()) if protocol is not None else "Noch kein Protokoll",
174
            Table.link(new_protocol_link, "Neues Protokoll") if has_modify_right else ""
Robin Sonnabend's avatar
Robin Sonnabend committed
175
            "" # TODO: add link for modify, delete
Robin Sonnabend's avatar
Robin Sonnabend committed
176
        ]
177
        return mobile_part + desktop_part
Robin Sonnabend's avatar
Robin Sonnabend committed
178
179
180

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

    def headers(self):
184
        general_headers = ["Name", "Abkürzung", "Organisation", "Beginn",
Robin Sonnabend's avatar
Robin Sonnabend committed
185
            "Öffentlich", "Verwaltungsgruppe", "Bearbeitungsgruppe", "Interne Gruppe",
186
            "Öffentliche Gruppe"]
187
188
189
        etherpad_headers = ["Nicht-reproduzierbare Etherpadlinks"]
        if not config.ETHERPAD_ACTIVE:
            etherpad_headers = []
190
191
192
193
194
        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
195
        if self.value.use_wiki:
196
197
198
            wiki_headers.append("Wiki-Kategorie")
        if not config.WIKI_ACTIVE:
            wiki_headers = []
Robin Sonnabend's avatar
Robin Sonnabend committed
199
200
201
        calendar_headers = ["Kalender"]
        if not config.CALENDAR_ACTIVE:
            calendar_headers = []
202
        network_headers = ["Netzwerke einschränken", "Erlaubte Netzwerke"]
203
        action_headers = ["Aktion"]
204
205
206
        return (general_headers + etherpad_headers + mail_headers
            + printing_headers + wiki_headers + calendar_headers
            + network_headers + action_headers)
Robin Sonnabend's avatar
Robin Sonnabend committed
207
208

    def row(self):
209
        user = current_user()
210
        general_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
211
212
213
            self.value.name,
            self.value.short_name,
            self.value.organization,
Robin Sonnabend's avatar
Robin Sonnabend committed
214
            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
215
            Table.bool(self.value.is_public),
Robin Sonnabend's avatar
Robin Sonnabend committed
216
            self.value.publish_group,
217
            self.value.modify_group,
Robin Sonnabend's avatar
Robin Sonnabend committed
218
219
            self.value.private_group,
            self.value.public_group,
220
        ]
221
222
223
224
225
        etherpad_part = [
            Table.bool(self.value.non_reproducible_pad_links)
        ]
        if not config.ETHERPAD_ACTIVE:
            ethernet_part = []
226
        mail_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
227
            self.value.private_mail,
Robin Sonnabend's avatar
Robin Sonnabend committed
228
            self.value.public_mail,
229
230
231
232
233
234
235
        ]
        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
236
            (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
237
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
238
        if self.value.use_wiki:
239
240
241
            wiki_part.append(self.value.wiki_category)
        if not config.WIKI_ACTIVE:
            wiki_part = []
Robin Sonnabend's avatar
Robin Sonnabend committed
242
243
244
        calendar_part = [self.value.calendar if self.value.calendar is not None else ""]
        if not config.CALENDAR_ACTIVE:
            calendar_part = []
245
246
247
248
249
        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("")
Robin Sonnabend's avatar
Robin Sonnabend committed
250
        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))]
251
252
        if not self.value.has_admin_right(user):
            action_part = [""]
253
254
        return (general_part + etherpad_part + mail_part + printing_part
            + wiki_part +  calendar_part + network_part + action_part)
Robin Sonnabend's avatar
Robin Sonnabend committed
255
256
257

class DefaultTOPsTable(Table):
    def __init__(self, tops, protocoltype=None):
Robin Sonnabend's avatar
Robin Sonnabend committed
258
        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
259
260
261
262
263
264
265
266
267
268
        self.protocoltype = protocoltype

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

    def row(self, top):
        return [
            top.name,
            top.number,
            Table.concat([
269
270
                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
271
                Table.link(url_for("edit_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id), "Ändern"),
272
                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
273
274
            ])
        ]
275
276
277

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

    def headers(self):
Robin Sonnabend's avatar
Robin Sonnabend committed
282
        return ["Zeit", "Einladen", "Zusätzlicher Mailinhalt", ""]
283
284

    def row(self, reminder):
285
286
        user = current_user()
        general_part = [
287
288
            "{} Tage".format(reminder.days_before),
            self.get_send_summary(reminder),
289
            reminder.additional_text or ""
290
        ]
291
        action_links = [
292
293
            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))
294
295
296
        ]
        action_part = [Table.concat(action_links)]
        return general_part + action_part
297
298
299
300
301
302
303
304

    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
305
306
307
308
309
310

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

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

313
    def classes(self):
314
        return [None, None, None, None, "hidden-xs", "hidden-xs"]
315

Robin Sonnabend's avatar
Robin Sonnabend committed
316
317
    def row(self, error):
        return [
318
            Table.link(url_for("show_protocol", protocol_id=error.protocol.id), error.protocol.get_short_identifier()),
Robin Sonnabend's avatar
Robin Sonnabend committed
319
320
            error.action,
            Table.link(url_for("show_error", error_id=error.id), error.name),
Robin Sonnabend's avatar
Robin Sonnabend committed
321
            datetime_filter(error.datetime),
Robin Sonnabend's avatar
Robin Sonnabend committed
322
            error.get_short_description(),
Robin Sonnabend's avatar
Robin Sonnabend committed
323
            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
324
325
326
327
328
329
330
        ]

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

    def headers(self):
331
        return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt"]
Robin Sonnabend's avatar
Robin Sonnabend committed
332
333
334

    def row(self):
        return [
335
            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
336
337
            self.value.action,
            self.value.name,
338
            datetime_filter(self.value.datetime)
Robin Sonnabend's avatar
Robin Sonnabend committed
339
340
341
342
        ]

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

    def headers(self):
346
347
348
349
        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
350
351

    def row(self, todo):
Robin Sonnabend's avatar
Robin Sonnabend committed
352
        user = current_user()
Robin Sonnabend's avatar
Robin Sonnabend committed
353
        protocol = todo.get_first_protocol()
354
355
356
357
        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
358
        row = [
359
            Markup("<br>").join(mobile_parts),
Robin Sonnabend's avatar
Robin Sonnabend committed
360
            Table.link(url_for("show_todo", todo_id=todo.id), todo.get_id()),
Robin Sonnabend's avatar
Robin Sonnabend committed
361
            todo.get_state(),
362
            Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier())
Robin Sonnabend's avatar
Robin Sonnabend committed
363
                if protocol is not None
364
                else Table.link(url_for("list_protocols", protocoltype_id=todo.protocoltype.id), todo.protocoltype.short_name),
Robin Sonnabend's avatar
Robin Sonnabend committed
365
            todo.who,
Robin Sonnabend's avatar
Robin Sonnabend committed
366
            todo.description,
Robin Sonnabend's avatar
Robin Sonnabend committed
367
        ]
Robin Sonnabend's avatar
Robin Sonnabend committed
368
        if todo.protocoltype.has_modify_right(user):
369
370
371
372
            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
373
374
375
376
377
378
379
380
381
        else:
            row.append("")
        return row

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

    def headers(self):
382
        return ["ID", "Status", "Sitzung", "Name", "Aufgabe", ""]
Robin Sonnabend's avatar
Robin Sonnabend committed
383
384
385
386
387
388
389

    def row(self):
        user = current_user()
        protocol = self.value.get_first_protocol()
        row = [
            self.value.get_id(),
            self.value.get_state_plain(),
390
            Table.concat([
391
                Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier())
392
393
                    for protocol in self.value.protocols
            ]),
Robin Sonnabend's avatar
Robin Sonnabend committed
394
            self.value.who,
395
            self.value.description
Robin Sonnabend's avatar
Robin Sonnabend committed
396
397
398
399
400
401
402
403
404
        ]
        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
405

Robin Sonnabend's avatar
Robin Sonnabend committed
406
407
408
class DecisionsTable(Table):
    def __init__(self, decisions):
        super().__init__("Beschlüsse", decisions)
409
410
        self.category_present = len([
            decision for decision in decisions
411
            if len(decision.categories) > 0
412
        ]) > 0
Robin Sonnabend's avatar
Robin Sonnabend committed
413
414

    def headers(self):
415
416
417
418
419
420
        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
421
422

    def row(self, decision):
Robin Sonnabend's avatar
Robin Sonnabend committed
423
        user = current_user()
424
        content_part = [
425
            Table.link(url_for("show_protocol", protocol_id=decision.protocol.id), decision.protocol.get_short_identifier()),
426
427
            decision.content
        ]
428
        category_part = [decision.get_categories_str()]
429
430
431
        if not self.category_present:
            category_part = []
        action_part = [
432
            Table.link(url_for("print_decision", decisiondocument_id=decision.document.id), "Drucken")
Robin Sonnabend's avatar
Robin Sonnabend committed
433
434
435
436
                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
437
        ]
438
        return content_part + category_part + action_part
Robin Sonnabend's avatar
Robin Sonnabend committed
439

440
class DocumentsTable(Table):
441
    def __init__(self, documents, protocol):
442
        super().__init__("Anhang", documents)
443
        self.protocol = protocol
444
445

    def headers(self):
446
447
448
449
450
451
452
        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
453

454
    def classes(self):
455
456
457
458
459
460
461
        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
462

463
    def row(self, document):
Robin Sonnabend's avatar
Robin Sonnabend committed
464
        user = current_user()
465
        links = []
Robin Sonnabend's avatar
Robin Sonnabend committed
466
467
        if document.protocol.has_modify_right(user):
            links.append(Table.link(url_for("edit_document", document_id=document.id), "Bearbeiten"))
468
        if config.PRINTING_ACTIVE and document.protocol.has_modify_right(user):
469
            links.append(Table.link(url_for("print_document", document_id=document.id), "Drucken"))
470
471
        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)))
472
        general_part = [
473
474
475
            document.id,
            Table.link(url_for("download_document", document_id=document.id), document.name),
        ]
476
477
478
479
480
        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
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

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
499
500
501
502
503
class DefaultMetasTable(Table):
    def __init__(self, metas, protocoltype):
        super().__init__(
            "Metadatenfelder",
            metas,
Robin Sonnabend's avatar
Robin Sonnabend committed
504
            url_for("new_defaultmeta", protocoltype_id=protocoltype.id)
Robin Sonnabend's avatar
Robin Sonnabend committed
505
506
507
        )

    def headers(self):
508
        return ["Name", "Key", "Standardwert", "Intern", "Vorher", ""]
Robin Sonnabend's avatar
Robin Sonnabend committed
509
510

    def row(self, meta):
511
512
        user = current_user()
        general_part = [
Robin Sonnabend's avatar
Robin Sonnabend committed
513
514
            meta.name,
            meta.key,
515
516
517
            meta.value,
            Table.bool(meta.internal),
            Table.bool(meta.prior)
Robin Sonnabend's avatar
Robin Sonnabend committed
518
        ]
519
        links = [
Robin Sonnabend's avatar
Robin Sonnabend committed
520
            Table.link(url_for("edit_defaultmeta", defaultmeta_id=meta.id), "Ändern"),
521
            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))
522
523
524
525
        ]
        link_part = [Table.concat(links)]
        return general_part + link_part

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
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