diff --git a/models/database.py b/models/database.py index 561b14c4e61b843ec878c8e1aacd068203c0c03e..f2664d3075e28ca1938a743128c3b23206aa1c23 100644 --- a/models/database.py +++ b/models/database.py @@ -422,3 +422,9 @@ class Error(db.Model): def __repr__(self): return "<Error(id={}, protocol_id={}, action={}, name={}, datetime={})>".format( self.id, self.protocol_id, self.action, self.name, self.datetime) + + def get_short_description(self): + lines = self.description.splitlines() + if len(lines) <= 4: + return "\n".join(lines) + return "\n".join(lines[:2], "…", lines[-2:]) diff --git a/server.py b/server.py index 6584081df16bd055715b4f1c4eaf334b75a5cba1..2ef4e0a96eeeae2c8855fb210528fc6112088a39 100755 --- a/server.py +++ b/server.py @@ -23,7 +23,7 @@ from shared import db, date_filter, datetime_filter, date_filter_long, time_filt from utils import is_past, mail_manager, url_manager, get_first_unused_int, set_etherpad_text, get_etherpad_text, split_terms, optional_int_arg from models.database import ProtocolType, Protocol, DefaultTOP, TOP, Document, Todo, Decision, MeetingReminder, Error from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm, MeetingReminderForm, NewProtocolForm, DocumentUploadForm, KnownProtocolSourceUploadForm, NewProtocolSourceUploadForm, ProtocolForm, TopForm, SearchForm, NewProtocolFileUploadForm, NewTodoForm, TodoForm -from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable, ErrorsTable, TodosTable, DocumentsTable, DecisionsTable, TodoTable +from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable, ErrorsTable, TodosTable, DocumentsTable, DecisionsTable, TodoTable, ErrorTable app = Flask(__name__) app.config.from_object(config) @@ -930,6 +930,43 @@ def print_document(document_id): flash("Das Dokument {} wird gedruckt.".format(document.name), "alert-success") return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id)) +@app.route("/errors/list") +@login_required +def list_errors(): + user = current_user() + errors = [ + error for error in Error.query.all() + if error.protocol.protocoltype.has_private_view_right(user) + ] + errors_table = ErrorsTable(errors) + return render_template("errors-list.html", errros=errors, errors_table=errors_table) + +@app.route("/error/show/<int:error_id>") +@login_required +def show_error(error_id): + user = current_user() + error = Error.query.filter_by(id=error_id).first() + if error is None or not error.protocol.protocoltype.has_modify_right(user): + flash("Invalider Fehler oder fehlende Zugriffsrechte.", "alert-error") + return redirect(request.args.get("next") or url_for("index")) + error_table = ErrorTable(error) + return render_template("error-show.html", error=error, error_table=error_table) + +@app.route("/error/delete/<int:error_id>") +@login_required +def delete_error(error_id): + user = current_user() + error = Error.query.filter_by(id=error_id).first() + if error is None or not error.protocol.protocoltype.has_modify_right(user): + flash("Invalider Fehler oder fehlende Zugriffsrechte.", "alert-error") + return redirect(request.args.get("next") or url_for("index")) + name = error.name + db.session.delete(error) + db.session.commit() + flash("Fehler {} gelöscht.".format(name), "alert-success") + return redirect(request.args.get("next") or url_for("list_errors")) + + @app.route("/login", methods=["GET", "POST"]) def login(): if "auth" in session: diff --git a/templates/error-show.html b/templates/error-show.html new file mode 100644 index 0000000000000000000000000000000000000000..a3d06145c0f33fba844de8c8b0a1bb651f3140d5 --- /dev/null +++ b/templates/error-show.html @@ -0,0 +1,9 @@ +{% extends "layout.html" %} +{% from "macros.html" import render_single_table %} +{% block title %}Fehler{% endblock %} + +{% block content %} +<div class="container"> + {{render_single_table(error_table)}} +</div> +{% endblock %} diff --git a/templates/errors-list.html b/templates/errors-list.html new file mode 100644 index 0000000000000000000000000000000000000000..aaab0b7002841bf5b297cbb7bd05dd8212530112 --- /dev/null +++ b/templates/errors-list.html @@ -0,0 +1,9 @@ +{% extends "layout.html" %} +{% from "macros.html" import render_table %} +{% block title %}Fehler{% endblock %} + +{% block content %} +<div class="container"> + {{render_table(errors_table)}} +</div> +{% endblock %} diff --git a/templates/layout.html b/templates/layout.html index d06902a818950c898ec7631c281d65933e78ca7e..e141b04743902e49572b8cff975b732249c4a338 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -36,6 +36,7 @@ <li><a href="{{url_for("list_decisions")}}">Beschlüsse</a></li> {% if check_login() %} <li><a href="{{url_for("list_types")}}">Typen</a></li> + <li><a href="{{url_for("list_errors")}}">Fehler</a></li> {% endif %} {# todo: add more links #} </ul> diff --git a/views/tables.py b/views/tables.py index 0cc7c3069ceeb9ff504ba664740e751d599eeb07..72c6390db3641ef6aea138f6432440cce928d307 100644 --- a/views/tables.py +++ b/views/tables.py @@ -183,14 +183,32 @@ class ErrorsTable(Table): super().__init__("Fehler", errors) def headers(self): - return ["Protokoll", "Fehler", "Zeitpunkt", "Beschreibung"] + return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt", "Beschreibung", ""] def row(self, error): return [ Table.link(url_for("show_protocol", protocol_id=error.protocol.id), error.protocol.get_identifier()), - error.name, + error.action, + Table.link(url_for("show_error", error_id=error.id), error.name), datetime_filter(error.datetime), - error.description + error.get_short_description(), + Table.link(url_for("delete_error", error_id=error.id), "Löschen", confirm="Bist du dir sicher, dass du den Fehler löschen möchtest?") + ] + +class ErrorTable(SingleValueTable): + def __init__(self, error): + super().__init__(error.action, error) + + def headers(self): + return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt", "Beschreibung"] + + def row(self): + return [ + Table.link(url_for("show_protocol", protocol_id=self.value.protocol.id), self.value.protocol.get_identifier()), + self.value.action, + self.value.name, + datetime_filter(self.value.datetime), + Markup("<pre>{}</pre>".format(self.value.description)) ] class TodosTable(Table):