diff --git a/migrations/versions/497c76393f9_.py b/migrations/versions/497c76393f9_.py new file mode 100644 index 0000000000000000000000000000000000000000..b9573f06f6e1a8ca04b54cb067d60ebb372b7556 --- /dev/null +++ b/migrations/versions/497c76393f9_.py @@ -0,0 +1,26 @@ +"""empty message + +Revision ID: 497c76393f9 +Revises: c14363cf9b +Create Date: 2015-11-07 21:39:34.419696 + +""" + +# revision identifiers, used by Alembic. +revision = '497c76393f9' +down_revision = 'c14363cf9b' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint('topics_index_key', 'topics', type_='unique') + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.create_unique_constraint('topics_index_key', 'topics', ['index']) + ### end Alembic commands ### diff --git a/migrations/versions/c14363cf9b_.py b/migrations/versions/c14363cf9b_.py new file mode 100644 index 0000000000000000000000000000000000000000..b3469e39b7d0c4f2dc7c887fb5d2a290942cd66d --- /dev/null +++ b/migrations/versions/c14363cf9b_.py @@ -0,0 +1,28 @@ +"""empty message + +Revision ID: c14363cf9b +Revises: 201dda3f23e +Create Date: 2015-11-07 20:59:17.755968 + +""" + +# revision identifiers, used by Alembic. +revision = 'c14363cf9b' +down_revision = '201dda3f23e' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.add_column('topics', sa.Column('index', sa.Integer(), nullable=True)) + op.create_unique_constraint(None, 'topics', ['index']) + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(None, 'topics', type_='unique') + op.drop_column('topics', 'index') + ### end Alembic commands ### diff --git a/models/database.py b/models/database.py index adafb0156d02ec34d186a0c68a03ed658fbd5c21..b3cfe076593c61a97d620d23167e719d49e0cd08 100644 --- a/models/database.py +++ b/models/database.py @@ -45,6 +45,9 @@ class Event(db.Model): def __repr__(self): return "<Event(id={}, name={})>".format(self.id, self.name) + + def sorted_topics(self): + return sorted(self.topics, key=lambda tp: tp.get_index()) class Topic(db.Model): __tablename__ = "topics" @@ -52,19 +55,23 @@ class Topic(db.Model): name = db.Column(db.String, unique=True) mode = db.Column(db.String) event_id = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False) + index = db.Column(db.Integer) + event = relationship("Event", backref=backref("topics",order_by=id)) def __init__(self, name, mode, event_id): self.name = name self.mode = mode self.event_id = event_id + self.index = None def __repr__(self): - return "<Topic(id={}, name='{}', mode='{}', event_id={})>".format( + return "<Topic(id={}, name='{}', mode='{}', event_id={}, index={})>".format( self.id, self.name, self.mode, - self.event_id + self.event_id, + self.index ) def sorted_statements(self): @@ -76,6 +83,20 @@ class Topic(db.Model): else: return statements + def swap_topics(self, other): + other.index, self.index = self.get_index(), other.get_index() + + def get_index(self): + if self.index == None: + return self.id + return self.index + + def get_next_index(self): + topics = self.event.sorted_topics() + i = topics.index(self) + 1 + if i >= len(topics): + i = -1 + return topics[i].id class Speaker(db.Model): __tablename__ = "speakers" diff --git a/modules/admin.py b/modules/admin.py index 539980537433755858d90826450d32ed207b12b3..a18f4e7a82cb1e0ea312985edd5d2bb3b4475073 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -144,7 +144,8 @@ def topic_show(): form = AddStatementForm() form.topic.data = topic.id statements = topic.sorted_statements() - return render_layout("admin_topic_show.html", topic=topic, form=form, statements=statements) + topics = topic.event.sorted_topics() + return render_layout("admin_topic_show.html", topic=topic, form=form, statements=statements, topics=topics) return redirect(url_for(".index")) @@ -160,7 +161,7 @@ def topic_new(): topic = Topic(form.name.data, form.mode.data, form.event_id.data) db.session.add(topic) db.session.commit() - return redirect(url_for(".topic")) + return redirect(url_for(".event", id=topic.event.id)) event_id = request.args.get("event_id", None) if event_id is None: return redirect(url_for(".index")) @@ -203,6 +204,37 @@ def topic(): topics = Topic.query.all() return render_layout("admin_topic_index.html", topics=topics) +@admin.route("/topic/swap/up") +@login_required +@admin_permission.require() +def topic_swap_up(): + topic_id = request.args.get("id", None) + original_id = request.args.get("original", None) + if topic_id is not None: + topic = Topic.query.filter_by(id=topic_id).first() + topics = topic.event.sorted_topics() + index = topics.index(topic) + if index != 0: + topic.swap_topics(topics[index-1]) + db.session.commit() + return redirect(url_for(".topic_show", id=original_id)) + return redirect(url_for(".index")) + +@admin.route("/topic/swap/down") +@login_required +@admin_permission.require() +def topic_swap_down(): + topic_id = request.args.get("id", None) + original_id = request.args.get("original", None) + if topic_id is not None: + topic = Topic.query.filter_by(id=topic_id).first() + topics = topic.event.sorted_topics() + index = topics.index(topic) + if index != len(topics) - 1: + topic.swap_topics(topics[index+1]) + db.session.commit() + return redirect(url_for(".topic_show", id=original_id)) + return redirect(url_for(".index")) @admin.route("/speaker/rename", methods=["GET", "POST"]) @login_required @@ -292,3 +324,4 @@ def statement_undo(): statement.undo() db.session.commit() return redirect(url_for(".topic_show", id=topic_id)) + diff --git a/static/css/style.css b/static/css/style.css index 8cf65d48f6839bd832b7d4504869db9f50c0fbea..e83d82b42755302705c069e2f18a275c962506fc 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -123,3 +123,11 @@ th.rede-medium-text { list-style-type: none; padding-left: 1pc; } + +.rede-list-point-big { + font-weight: bold; +} + +.rede-list-point-normal { + font-weight: normal; +} diff --git a/templates/admin_event_index.html b/templates/admin_event_index.html index 42782b69572b489fd450a322908555366b7eb0ad..d6660b99f9c2930b2a3c78a0cf6d2cb0500d8704 100644 --- a/templates/admin_event_index.html +++ b/templates/admin_event_index.html @@ -7,7 +7,6 @@ <thead> <tr> <th class="mdl-data-table__cell--non-numeric">Name</th> - <th class="mdl-data-table__cell--non-numeric">Mode</th> <th class="mdl-data-table__cell--non-numeric">Edit</th> <th class="mdl-data-table__cell--non-numeric">Delete</th> </tr> diff --git a/templates/admin_topic_show.html b/templates/admin_topic_show.html index fa8b5014699bd8a9c064bee80b7062a4d4039cd1..f25ede63427efe5b00d17ebcba617eb7428baba8 100644 --- a/templates/admin_topic_show.html +++ b/templates/admin_topic_show.html @@ -56,7 +56,32 @@ </li> {% endif %} <li><a href="{{ url_for(".statement_undo") }}" class="rede-href"><i class="material-icons" role="presentation">undo</i> Previous</a></li> + <li><a href="{{ url_for(".topic_show", id=topic.get_next_index()) }}"><i class="material-icons">arrow_forward</i> Next Topic</a></li> </ul> </div> </div> + <div class="mdl-cell mdl-cell--3-col mdl-cell--3-col-tablet mdl-cell--4-col-phone mdl-card mdl-shadow--2dp"> + <div class="mdl-card__title"> + <h4 class="mdl-card__title-text">Topics</h4> + </div> + <table> + {% for t in topics %} + <tr class="{% if t == topic %}rede-list-point-big{% else %}rede-list-point-normal{% endif %}"> + <td> + {% if t != topics[0] %} + <a href="{{ url_for(".topic_swap_up", id=t.id, original=topic.id) }}"><i class="material-icons">keyboard_arrow_up</i></a> + {% endif %} + </td> + <td> + {{ t.name }} + </td> + <td> + {% if t != topics[-1] %} + <a href="{{ url_for(".topic_swap_down", id=t.id, original=topic.id) }}"><i class="material-icons">keyboard_arrow_down</i></a> + {% endif %} + </td> + <tr> + {% endfor %} + </table> + </div> {% endblock %}