Add delete and edit project actions in the dashboard

The dashboard is deactivated by default and
is only accessible by admins when activated
A new ACTIVATE_DASHBOARD setting is introduced
This commit is contained in:
0livd 2017-06-29 17:55:12 +02:00
parent 62dd103b30
commit d8107d449d
9 changed files with 60 additions and 7 deletions

View file

@ -12,11 +12,14 @@ This document describes changes between each past release.
- **BREAKING CHANGE** Turn the WSGI file into a python module, renamed from budget/ihatemoney.wsgi to budget/wsgi.py. Please update your Apache configuration!
- Changed the recommended gunicorn configuration to use the wsgi module as an entrypoint
- **BREAKING CHANGE** The default value of ``ADMIN_PASSWORD`` has changed. If you have a custom settings file which set ``ADMIN_PASSWORD`` to an empty string (""), the application will use the default admin password until you update your settings.
- **BREAKING CHANGE** Admin privileges are required to access the dashboard
### Added
- Add a new setting to allow public project creation (ALLOW_PUBLIC_PROJECT_CREATION)
- With admin credentials, one can access every project
- Add delete and edit project actions in the dashboard
- Add a new setting to activate the dashboard (ACTIVATE_DASHBOARD)
### Removed

View file

@ -14,3 +14,5 @@ ACTIVATE_DEMO_PROJECT = True
ADMIN_PASSWORD = "pbkdf2:sha256:50000$jc3isZTD$b3be8d04ed5c2c1ac89d5eb777facc94adaee48d473c9620f1e0cb73f3dcfa11"
ALLOW_PUBLIC_PROJECT_CREATION = True
ACTIVATE_DASHBOARD = False

View file

@ -169,6 +169,29 @@ footer{
background: url('../images/edit.png') no-repeat right;
}
.project-actions {
padding-top: 10px;
text-align: center;
}
.project-actions > .delete, .project-actions > .edit {
font-size: 0px;
display: block;
width: 16px;
height: 16px;
margin: 2px;
margin-left: 5px;
float: left;
}
.project-actions > .delete{
background: url('../images/delete.png') no-repeat right;
}
.project-actions > .edit{
background: url('../images/edit.png') no-repeat right;
}
.balance .balance-value{
text-align:right;
}

View file

@ -1,8 +1,8 @@
{% extends "layout.html" %}
{% block content %}
{% if is_dashboard_activated %}
<table id="bill_table" class="table table-striped">
<thead><tr><th>{{ _("Project") }}</th><th>{{ _("Number of members") }}</th><th>{{ _("Number of bills") }}</th><th>{{_("Newest bill")}}</th><th>{{_("Oldest bill")}}</th></tr></thead>
<thead><tr><th>{{ _("Project") }}</th><th>{{ _("Number of members") }}</th><th>{{ _("Number of bills") }}</th><th>{{_("Newest bill")}}</th><th>{{_("Oldest bill")}}</th><th>{{_("Actions")}}</th></tr></thead>
<tbody>{% for project in projects|sort(attribute='name') %}
<tr class="{{ loop.cycle("odd", "even") }}">
<td>{{ project.name }}</td><td>{{ project.members | count }}</td><td>{{ project.get_bills().count() }}</td>
@ -13,9 +13,16 @@
<td></td>
<td></td>
{% endif %}
<td class="project-actions">
<a class="edit" href="{{ url_for(".edit_project", project_id=project.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
<a class="delete" href="{{ url_for(".delete_project", project_id=project.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-danger">{{ _("The Dashboard is currently deactivated.") }}</div>
{% endif %}
{% endblock %}

View file

@ -607,8 +607,16 @@ class BudgetTestCase(TestCase):
self.assertIn("Invalid email address", resp.data.decode('utf-8'))
def test_dashboard(self):
response = self.app.get("/dashboard")
self.assertEqual(response.status_code, 200)
# test that the dashboard is deactivated by default
resp = self.app.post("/admin?goto=%2Fdashboard", data={'admin_password': 'adminpass'},
follow_redirects=True)
self.assertIn('<div class="alert alert-danger">', resp.data.decode('utf-8'))
# test access to the dashboard when it is activated
run.app.config['ACTIVATE_DASHBOARD'] = True
resp = self.app.post("/admin?goto=%2Fdashboard", data={'admin_password': 'adminpass'},
follow_redirects=True)
self.assertIn('<thead><tr><th>Project</th><th>Number of members', resp.data.decode('utf-8'))
def test_settle_page(self):
self.post_project("raclette")

View file

@ -271,6 +271,10 @@ msgstr "Facture la plus récente"
msgid "Oldest bill"
msgstr "Facture la plus ancienne"
#: templates/dashboard.html:25
msgid "The Dashboard is currently deactivated."
msgstr "La page d'administration est actuellement désactivée."
#: templates/edit_project.html:6 templates/list_bills.html:24
msgid "you sure?"
msgstr "c'est sûr ?"

View file

@ -294,7 +294,7 @@ def delete_project():
g.project.remove_project()
flash(_('Project successfully deleted'))
return redirect(url_for(".home"))
return redirect(request.headers.get('Referer') or url_for('.home'))
@main.route("/exit")
@ -507,5 +507,8 @@ def settle_bill():
@main.route("/dashboard")
@requires_admin()
def dashboard():
return render_template("dashboard.html", projects=Project.query.all())
is_dashboard_activated = current_app.config['ACTIVATE_DASHBOARD']
return render_template("dashboard.html", projects=Project.query.all(),
is_dashboard_activated=is_dashboard_activated)

View file

@ -86,12 +86,15 @@ properly.
| ACTIVATE_DEMO_PROJECT | ``True`` | If set to `True`, a demo project will be available on the frontpage. |
+------------------------------+---------------------------+----------------------------------------------------------------------------------------+
| | | Hashed password to access protected endpoints. The default password is ``adminpass``. |
| ADMIN_PASSWORD | ``"pbkdf2:sha256:50.."`` | **This needs to be changed**. |
| | | **This needs to be changed** when you disable public project creation or activate the |
| ADMIN_PASSWORD | ``"pbkdf2:sha256:50.."`` | dashboard. |
| | | To generate the proper password HASH, use ``./budget/manage.py generate_password_hash``|
| | | and copy its output into the value of *ADMIN_PASSWORD*. |
+------------------------------+---------------------------+----------------------------------------------------------------------------------------+
| ALLOW_PUBLIC_PROJECT_CREATION| ``True`` | If set to `True`, everyone can create a project without entering the admin password |
+------------------------------+---------------------------+----------------------------------------------------------------------------------------+
| ACTIVATE_DASHBOARD | ``False`` | If set to `True`, the dashboard will become accessible entering the admin password |
+------------------------------+---------------------------+----------------------------------------------------------------------------------------+
.. _`the SQLAlechemy documentation`: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls