diff options
| author | Brice Maron <b.maron@whatever-company.com> | 2019-07-29 22:10:58 +0200 |
|---|---|---|
| committer | Alexis Metaireau <alexis@notmyidea.org> | 2019-08-18 21:37:20 +0000 |
| commit | fd49599cc76de69e81f645257845778571d4d964 (patch) | |
| tree | df2e05f35fd1ce1894651e96f59a769917d3b0fb | |
| parent | b5cc1592d6907ea055757a37389c6bfada142ec9 (diff) | |
| download | ihatemoney-mirror-fd49599cc76de69e81f645257845778571d4d964.zip ihatemoney-mirror-fd49599cc76de69e81f645257845778571d4d964.tar.gz ihatemoney-mirror-fd49599cc76de69e81f645257845778571d4d964.tar.bz2 | |
Arrange navbar items by functions
| -rw-r--r-- | ihatemoney/default_settings.py | 1 | ||||
| -rw-r--r-- | ihatemoney/run.py | 10 | ||||
| -rw-r--r-- | ihatemoney/static/css/main.css | 13 | ||||
| -rw-r--r-- | ihatemoney/static/images/globe.svg | 1 | ||||
| -rw-r--r-- | ihatemoney/static/images/glyphicons-halflings-white.png | bin | 4352 -> 0 bytes | |||
| -rw-r--r-- | ihatemoney/static/images/glyphicons-halflings.png | bin | 4352 -> 0 bytes | |||
| -rw-r--r-- | ihatemoney/templates/layout.html | 86 | ||||
| -rw-r--r-- | ihatemoney/utils.py | 14 | ||||
| -rw-r--r-- | ihatemoney/web.py | 7 |
9 files changed, 93 insertions, 39 deletions
diff --git a/ihatemoney/default_settings.py b/ihatemoney/default_settings.py index 6033d0a..82e6a43 100644 --- a/ihatemoney/default_settings.py +++ b/ihatemoney/default_settings.py @@ -8,3 +8,4 @@ ACTIVATE_DEMO_PROJECT = True ADMIN_PASSWORD = "" ALLOW_PUBLIC_PROJECT_CREATION = True ACTIVATE_ADMIN_DASHBOARD = False +SUPPORTED_LANGUAGES = ['en', 'fr', 'nl'] diff --git a/ihatemoney/run.py b/ihatemoney/run.py index e9b3ce1..41598ce 100644 --- a/ihatemoney/run.py +++ b/ihatemoney/run.py @@ -10,7 +10,8 @@ from werkzeug.contrib.fixers import ProxyFix from ihatemoney.api import api from ihatemoney.models import db -from ihatemoney.utils import PrefixedWSGI, minimal_round, IhmJSONEncoder +from ihatemoney.utils import (IhmJSONEncoder, PrefixedWSGI, locale_from_iso, + minimal_round, static_include) from ihatemoney.web import main as web_interface from ihatemoney import default_settings @@ -135,6 +136,8 @@ def create_app(configuration=None, instance_path='/etc/ihatemoney', app.mail = mail # Jinja filters + app.jinja_env.globals['static_include'] = static_include + app.jinja_env.globals['locale_from_iso'] = locale_from_iso app.jinja_env.filters['minimal_round'] = minimal_round # Translations @@ -144,7 +147,10 @@ def create_app(configuration=None, instance_path='/etc/ihatemoney', def get_locale(): # get the lang from the session if defined, fallback on the browser "accept # languages" header. - lang = session.get('lang', request.accept_languages.best_match(['fr', 'en'])) + lang = session.get( + 'lang', + request.accept_languages.best_match(app.config['SUPPORTED_LANGUAGES']) + ) setattr(g, 'lang', lang) return lang diff --git a/ihatemoney/static/css/main.css b/ihatemoney/static/css/main.css index ae056c8..47ede77 100644 --- a/ihatemoney/static/css/main.css +++ b/ihatemoney/static/css/main.css @@ -328,3 +328,16 @@ tr:hover .extra-info { .row-fluid > .offset1 { margin-left: 8.5%; } + +.globe-europe svg { + display: inline-block; + border-bottom: 0.2em solid transparent; + height: 1.2em; + fill: rgba(255,255,255,.5) +} +.navbar-nav .dropdown-toggle:hover .globe-europe svg { + fill: rgba(255,255,255,.75); +} +.navbar-dark .navbar-nav .show > .nav-link svg { + fill: white; +}
\ No newline at end of file diff --git a/ihatemoney/static/images/globe.svg b/ihatemoney/static/images/globe.svg new file mode 100644 index 0000000..5982330 --- /dev/null +++ b/ihatemoney/static/images/globe.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm200 248c0 22.5-3.9 44.2-10.8 64.4h-20.3c-4.3 0-8.4-1.7-11.4-4.8l-32-32.6c-4.5-4.6-4.5-12.1.1-16.7l12.5-12.5v-8.7c0-3-1.2-5.9-3.3-8l-9.4-9.4c-2.1-2.1-5-3.3-8-3.3h-16c-6.2 0-11.3-5.1-11.3-11.3 0-3 1.2-5.9 3.3-8l9.4-9.4c2.1-2.1 5-3.3 8-3.3h32c6.2 0 11.3-5.1 11.3-11.3v-9.4c0-6.2-5.1-11.3-11.3-11.3h-36.7c-8.8 0-16 7.2-16 16v4.5c0 6.9-4.4 13-10.9 15.2l-31.6 10.5c-3.3 1.1-5.5 4.1-5.5 7.6v2.2c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8s-3.6-8-8-8H247c-3 0-5.8 1.7-7.2 4.4l-9.4 18.7c-2.7 5.4-8.2 8.8-14.3 8.8H194c-8.8 0-16-7.2-16-16V199c0-4.2 1.7-8.3 4.7-11.3l20.1-20.1c4.6-4.6 7.2-10.9 7.2-17.5 0-3.4 2.2-6.5 5.5-7.6l40-13.3c1.7-.6 3.2-1.5 4.4-2.7l26.8-26.8c2.1-2.1 3.3-5 3.3-8 0-6.2-5.1-11.3-11.3-11.3H258l-16 16v8c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8v-20c0-2.5 1.2-4.9 3.2-6.4l28.9-21.7c1.9-.1 3.8-.3 5.7-.3C358.3 56 448 145.7 448 256zM130.1 149.1c0-3 1.2-5.9 3.3-8l25.4-25.4c2.1-2.1 5-3.3 8-3.3 6.2 0 11.3 5.1 11.3 11.3v16c0 3-1.2 5.9-3.3 8l-9.4 9.4c-2.1 2.1-5 3.3-8 3.3h-16c-6.2 0-11.3-5.1-11.3-11.3zm128 306.4v-7.1c0-8.8-7.2-16-16-16h-20.2c-10.8 0-26.7-5.3-35.4-11.8l-22.2-16.7c-11.5-8.6-18.2-22.1-18.2-36.4v-23.9c0-16 8.4-30.8 22.1-39l42.9-25.7c7.1-4.2 15.2-6.5 23.4-6.5h31.2c10.9 0 21.4 3.9 29.6 10.9l43.2 37.1h18.3c8.5 0 16.6 3.4 22.6 9.4l17.3 17.3c3.4 3.4 8.1 5.3 12.9 5.3H423c-32.4 58.9-93.8 99.5-164.9 103.1z"/></svg>
\ No newline at end of file diff --git a/ihatemoney/static/images/glyphicons-halflings-white.png b/ihatemoney/static/images/glyphicons-halflings-white.png Binary files differdeleted file mode 100644 index a20760b..0000000 --- a/ihatemoney/static/images/glyphicons-halflings-white.png +++ /dev/null diff --git a/ihatemoney/static/images/glyphicons-halflings.png b/ihatemoney/static/images/glyphicons-halflings.png Binary files differdeleted file mode 100644 index 92d4445..0000000 --- a/ihatemoney/static/images/glyphicons-halflings.png +++ /dev/null diff --git a/ihatemoney/templates/layout.html b/ihatemoney/templates/layout.html index 84e75b4..10bb628 100644 --- a/ihatemoney/templates/layout.html +++ b/ihatemoney/templates/layout.html @@ -28,56 +28,72 @@ </head> <body> <div class="container"> - <nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark"> + <nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-dark"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <h1><a class="navbar-brand" href="{{ url_for("main.home") }}">#! money?</a></h1> - {% if g.project %}<strong class="d-block d-sm-none text-white">{{ g.project.name }}</strong>{% endif %} + {% if g.project %} + <ul class="navbar-nav mr-auto"> + <li class="nav-item dropdown"> + <a href="#" class="nav-link dropdown-toggle" id="navbarProjectsLinks" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <strong class="text-white">{{ g.project.name }}</strong> + <b class="caret"></b> + </a> + <ul class="dropdown-menu" aria-labelledby="navbarProjectsLinks"> + <li><a class="dropdown-item" href="{{ url_for("main.create_project") }}">{{ _("Start a new project") }}</a></li> + + {% if (session['projects'] | length) > 1 %} + <li class="dropdown-divider"></li> + <li class="dropdown-header">{{ _('Other projects :') }}</li> + {% for id, name in session['projects'] %} + {% if id != g.project.id %} + <li><a class="dropdown-item" href="{{ url_for("main.list_bills", project_id=id) }}">{{ _("switch to") }} {{ name }}</a></li> + {% endif %} + {% endfor %} + {% endif %} + </ul> + </li> + </ul> + {% endif %} <div class="collapse navbar-collapse" id="navbarToggler"> <ul class="navbar-nav ml-auto mr-auto"> {% if g.project %} - <li class="nav-item"> - </li> - - {% block navbar %} - <li class="nav-item{% if current_view == 'list_bills' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.list_bills") }}">{{ _("Bills") }}</a></li> - <li class="nav-item{% if current_view == 'settle_bill' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.settle_bill") }}">{{ _("Settle") }}</a></li> - <li class="nav-item{% if current_view == 'statistics' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.statistics") }}">{{ _("Statistics") }}</a></li> - {% endblock %} + {% block navbar %} + <li class="nav-item{% if current_view == 'list_bills' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.list_bills") }}">{{ _("Bills") }}</a></li> + <li class="nav-item{% if current_view == 'settle_bill' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.settle_bill") }}">{{ _("Settle") }}</a></li> + <li class="nav-item{% if current_view == 'statistics' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.statistics") }}">{{ _("Statistics") }}</a></li> + <li class="nav-item{% if current_view == 'edit_project' %} active{% endif %}""><a class="nav-link" href="{{ url_for("main.edit_project") }}">{{ _("Settings") }}</a></li> + {% endblock %} {% endif %} - {% if g.project %} + </ul> + <ul class="navbar-nav ml-auto"> <li class="nav-item dropdown"> - <a href="#" class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - <strong class="d-none d-sm-inline">{{ g.project.name }}</strong> {{ _("options") }} + <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="langMenuButton"> + <i class="globe-europe">{{ static_include("images/globe.svg") | safe }}</i> + {% if g.lang %} + {{ locale_from_iso(g.lang).display_name | capitalize }} + {% else %} + {{ _('Languages') }} + {% endif %} <b class="caret"></b> </a> - <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> - <li><a class="dropdown-item" href="{{ url_for("main.edit_project") }}">{{ _("Project settings") }}</a></li> - <li class="dropdown-divider"></li> - {% for id, name in session['projects'] %} - {% if id != g.project.id %} - <li><a class="dropdown-item" href="{{ url_for("main.list_bills", project_id=id) }}">{{ _("switch to") }} {{ name }}</a></li> - {% endif %} - {% endfor %} - <li><a class="dropdown-item" href="{{ url_for("main.create_project") }}">{{ _("Start a new project") }}</a></li> - {% if g.show_admin_dashboard_link %} - <li class="dropdown-divider"></li> - <li class="nav-item{% if request.url_rule.endpoint == "main.dashboard" %} active{% endif %}"> - <a class="dropdown-item" href="{{ url_for("main.dashboard") }}">{{ _("Dashboard") }}</a> - </li> - {% endif %} - <li class="dropdown-divider"></li> - <li><a class="dropdown-item" href="{{ url_for("main.exit") }}">{{ _("Logout") }}</a></li> - </ul> + <div class="dropdown-menu" aria-labelledby="langMenuButton"> + <h6 class="dropdown-header">{{ _('Languages') }}</h6> + {% for lang in config['SUPPORTED_LANGUAGES'] %} + {% if g.lang != lang %} + <a class="dropdown-item" href="{{ url_for("main.change_lang", lang=lang)}}">{{ locale_from_iso(lang).display_name | capitalize }}</a> + {% endif %} + {% endfor %} + </div> + </li> + {% if (session['projects'] | length) > 0 or session['is_admin'] %} + <li class="nav-item"> + <a class="nav-link" href="{{ url_for("main.exit") }}">{{ _("Logout") }}</a> </li> {% endif %} </ul> - <ul class="navbar-nav secondary-nav"> - <li class="nav-item{% if g.lang == "fr" %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.change_lang", lang="fr") }}">fr</a></li> - <li class="nav-item{% if g.lang == "en" %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.change_lang", lang="en") }}">en</a></li> - </ul> </div> </nav> </div> diff --git a/ihatemoney/utils.py b/ihatemoney/utils.py index 2fac4ef..393667e 100644 --- a/ihatemoney/utils.py +++ b/ihatemoney/utils.py @@ -1,13 +1,15 @@ from __future__ import division import base64 import re +import os import ast import operator from io import BytesIO, StringIO import jinja2 from json import dumps, JSONEncoder -from flask import redirect +from flask import redirect, current_app +from babel import Locale from werkzeug.routing import HTTPException, RoutingException import six from datetime import datetime, timedelta @@ -93,6 +95,16 @@ def minimal_round(*args, **kw): return (res if res != ires else ires) +def static_include(filename): + fullpath = os.path.join(current_app.static_folder, filename) + with open(fullpath, 'r') as f: + return f.read() + + +def locale_from_iso(iso_code): + return Locale(iso_code) + + def list_of_dicts2json(dict_to_convert): """Take a list of dictionnaries and turns it into a json in-memory file diff --git a/ihatemoney/web.py b/ihatemoney/web.py index f6f04af..b70bc5f 100644 --- a/ihatemoney/web.py +++ b/ihatemoney/web.py @@ -343,7 +343,12 @@ def edit_project(): edit_form.name.data = g.project.name edit_form.contact_email.data = g.project.contact_email - return render_template("edit_project.html", edit_form=edit_form, export_form=export_form) + return render_template( + "edit_project.html", + edit_form=edit_form, + export_form=export_form, + current_view="edit_project" + ) @main.route("/<project_id>/delete") |
