mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-30 18:22:38 +02:00
bill list: add placeholder and disable add bill when no members
This commit is contained in:
parent
a467f46372
commit
9c9832704d
6 changed files with 99 additions and 34 deletions
|
@ -157,6 +157,20 @@ body {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-bill {
|
||||||
|
margin-top: 5rem !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
.empty-bill .card {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-bill .hand-holding-heart svg {
|
||||||
|
fill: lightgray;
|
||||||
|
height: 5em;
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
.invites textarea {
|
.invites textarea {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
@ -258,7 +272,6 @@ footer .footer-left {
|
||||||
|
|
||||||
#new-bill {
|
#new-bill {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid text color flickering when it loose focus as the modal appears */
|
/* Avoid text color flickering when it loose focus as the modal appears */
|
||||||
|
@ -295,6 +308,10 @@ footer .footer-left {
|
||||||
background: url("../images/edit.png") no-repeat right;
|
background: url("../images/edit.png") no-repeat right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#bill_table {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.project-actions > .delete,
|
.project-actions > .delete,
|
||||||
.project-actions > .edit {
|
.project-actions > .edit {
|
||||||
font-size: 0px;
|
font-size: 0px;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
1
ihatemoney/static/images/hand-holding-heart.svg
Normal file
1
ihatemoney/static/images/hand-holding-heart.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M275.3 250.5c7 7.4 18.4 7.4 25.5 0l108.9-114.2c31.6-33.2 29.8-88.2-5.6-118.8-30.8-26.7-76.7-21.9-104.9 7.7L288 36.9l-11.1-11.6C248.7-4.4 202.8-9.2 172 17.5c-35.3 30.6-37.2 85.6-5.6 118.8l108.9 114.2zm290 77.6c-11.8-10.7-30.2-10-42.6 0L430.3 402c-11.3 9.1-25.4 14-40 14H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h78.3c15.9 0 30.7-10.9 33.3-26.6 3.3-20-12.1-37.4-31.6-37.4H192c-27 0-53.1 9.3-74.1 26.3L71.4 384H16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h356.8c14.5 0 28.6-4.9 40-14L564 377c15.2-12.1 16.4-35.3 1.3-48.9z"/></svg>
|
After Width: | Height: | Size: 593 B |
|
@ -129,17 +129,17 @@
|
||||||
<div class="footer-limiter">
|
<div class="footer-limiter">
|
||||||
|
|
||||||
<div class="footer-right">
|
<div class="footer-right">
|
||||||
<a target="_blank" rel="noopener" n data-toggle="tooltip" data-placement="top" title="{{ _('Code') }}" href="https://github.com/spiral-project/ihatemoney">
|
<a target="_blank" rel="noopener" data-toggle="tooltip" data-placement="top" title="{{ _('Code') }}" href="https://github.com/spiral-project/ihatemoney">
|
||||||
<i class="icon git">{{ static_include("images/git.svg") | safe }}</i>
|
<i class="icon git">{{ static_include("images/git.svg") | safe }}</i>
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" rel="noopener" n data-toggle="tooltip" data-placement="top" title="{{ _('Mobile Application') }}" href="https://gitlab.com/eneiluj/moneybuster">
|
<a target="_blank" rel="noopener" data-toggle="tooltip" data-placement="top" title="{{ _('Mobile Application') }}" href="https://gitlab.com/eneiluj/moneybuster">
|
||||||
<i class="icon mobile">{{ static_include("images/mobile-alt.svg") | safe }}</i>
|
<i class="icon mobile">{{ static_include("images/mobile-alt.svg") | safe }}</i>
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" rel="noopener" n data-toggle="tooltip" data-placement="top" title="{{ _('Documentation') }}" href="https://ihatemoney.readthedocs.io/en/latest/">
|
<a target="_blank" rel="noopener" data-toggle="tooltip" data-placement="top" title="{{ _('Documentation') }}" href="https://ihatemoney.readthedocs.io/en/latest/">
|
||||||
<i class="icon book">{{ static_include("images/book.svg") | safe }}</i>
|
<i class="icon book">{{ static_include("images/book.svg") | safe }}</i>
|
||||||
</a>
|
</a>
|
||||||
{% if g.show_admin_dashboard_link %}
|
{% if g.show_admin_dashboard_link %}
|
||||||
<a target="_blank" rel="noopener" n data-toggle="tooltip" data-placement="top" title="{{ _('Administation Dashboard') }}" href="{{ url_for("main.dashboard") }}">
|
<a target="_blank" rel="noopener" data-toggle="tooltip" data-placement="top" title="{{ _('Administation Dashboard') }}" href="{{ url_for("main.dashboard") }}">
|
||||||
<i class="icon admin">{{ static_include("images/cog.svg") | safe }}</i>
|
<i class="icon admin">{{ static_include("images/cog.svg") | safe }}</i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -87,10 +87,12 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a id="new-bill" href="{{ url_for('.add_bill') }}" class="btn btn-primary float-right" data-toggle="modal" data-target="#bill-form">
|
<span id="new-bill" class="float-right" {% if not g.project.members %} data-toggle="tooltip" title="{{_('You should start by adding participants')}}" {% endif %}>
|
||||||
<i class="icon icon-white plus">{{ static_include("images/plus.svg") | safe }}</i>
|
<a href="{{ url_for('.add_bill') }}" class="btn btn-primary float-right {% if not g.project.members %} disabled {% endif %}" data-toggle="modal" data-target="#bill-form">
|
||||||
{{ _("Add a new bill") }}
|
<i class="icon icon-white plus">{{ static_include("images/plus.svg") | safe }}</i>
|
||||||
</a>
|
{{ _("Add a new bill") }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
<div id="bill-form" class="modal fade show" role="dialog">
|
<div id="bill-form" class="modal fade show" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
@ -106,31 +108,50 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if bills.count() > 0 %}
|
{% if bills.count() > 0 %}
|
||||||
<table id="bill_table" class="col table table-striped table-hover table-responsive-sm">
|
<div class="clearfix"></div>
|
||||||
<thead><tr><th>{{ _("When?") }}</th><th>{{ _("Who paid?") }}</<th><th>{{ _("For what?") }}</th><th>{{ _("For whom?") }}</th><th>{{ _("How much?") }}</th><th>{{ _("Actions") }}</th></tr></thead>
|
|
||||||
<tbody>
|
<table id="bill_table" class="col table table-striped table-hover table-responsive-sm">
|
||||||
{% for bill in bills %}
|
<thead><tr><th>{{ _("When?") }}</th><th>{{ _("Who paid?") }}</<th><th>{{ _("For what?") }}</th><th>{{ _("For whom?") }}</th><th>{{ _("How much?") }}</th><th>{{ _("Actions") }}</th></tr></thead>
|
||||||
<tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}">
|
<tbody>
|
||||||
<td>
|
{% for bill in bills %}
|
||||||
<span data-toggle="tooltip" data-placement="top"
|
<tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}">
|
||||||
title="{{ _('Added on %(date)s', date=bill.creation_date if bill.creation_date else bill.date) }}">
|
<td>
|
||||||
{{ bill.date }}
|
<span data-toggle="tooltip" data-placement="top"
|
||||||
</span>
|
title="{{ _('Added on %(date)s', date=bill.creation_date if bill.creation_date else bill.date) }}">
|
||||||
</td>
|
{{ bill.date }}
|
||||||
<td>{{ bill.payer }}</td>
|
</span>
|
||||||
<td>{{ bill.what }}</td>
|
</td>
|
||||||
<td>{{ bill.owers|join(', ', 'name') }} </td>
|
<td>{{ bill.payer }}</td>
|
||||||
<td>{{ "%0.2f"|format(bill.amount) }} ({{ "%0.2f"|format(bill.pay_each()) }} {{ _("each") }})</td>
|
<td>{{ bill.what }}</td>
|
||||||
<td class="bill-actions">
|
<td>{{ bill.owers|join(', ', 'name') }} </td>
|
||||||
<a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
|
<td>{{ "%0.2f"|format(bill.amount) }} ({{ "%0.2f"|format(bill.pay_each()) }} {{ _("each") }})</td>
|
||||||
<a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
|
<td class="bill-actions">
|
||||||
</td>
|
<a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
|
||||||
</tr>
|
<a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
|
||||||
{% endfor %}
|
</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="py-3"></div><p>{{ _("Nothing to list yet. You probably want to") }} <a href="{{ url_for(".add_bill") }}" data-toggle="modal" data-target="#bill-form">{{ _("add a bill") }}</a> ?</p></div>
|
<div class="py-3 d-flex justify-content-center empty-bill">
|
||||||
|
<div class="card d-inline-flex p-2">
|
||||||
|
<div class="card-body text-center text-muted">
|
||||||
|
<i class="icon icon-white hand-holding-heart">{{ static_include("images/hand-holding-heart.svg") | safe }}</i>
|
||||||
|
<h3>{{ _('No bills')}}</h3>
|
||||||
|
<p>
|
||||||
|
{{ _("Nothing to list yet.")}}<br />
|
||||||
|
{{ _("You probably want to") }}
|
||||||
|
{%- if g.project.members %} <a href="{{ url_for('.add_bill') }}" data-toggle="modal" data-target="#bill-form">
|
||||||
|
{{- _("add a bill") -}}
|
||||||
|
</a> ?
|
||||||
|
{% else %} <a href="{{ url_for('.add_member') }}">
|
||||||
|
{{- _('add participants') -}}
|
||||||
|
</a> ?
|
||||||
|
{%- endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -178,7 +178,10 @@ class BudgetTestCase(IhatemoneyTestCase):
|
||||||
self.client.get("/exit")
|
self.client.get("/exit")
|
||||||
# Test that we got a valid token
|
# Test that we got a valid token
|
||||||
resp = self.client.get(url, follow_redirects=True)
|
resp = self.client.get(url, follow_redirects=True)
|
||||||
self.assertIn('You probably want to <a href="/raclette/add"', resp.data.decode('utf-8'))
|
self.assertIn(
|
||||||
|
'You probably want to <a href="/raclette/members/add"',
|
||||||
|
resp.data.decode('utf-8')
|
||||||
|
)
|
||||||
# Test empty and invalid tokens
|
# Test empty and invalid tokens
|
||||||
self.client.get("/exit")
|
self.client.get("/exit")
|
||||||
resp = self.client.get("/authenticate")
|
resp = self.client.get("/authenticate")
|
||||||
|
@ -275,6 +278,29 @@ class BudgetTestCase(IhatemoneyTestCase):
|
||||||
# project removed
|
# project removed
|
||||||
self.assertEqual(len(models.Project.query.all()), 0)
|
self.assertEqual(len(models.Project.query.all()), 0)
|
||||||
|
|
||||||
|
def test_bill_placeholder(self):
|
||||||
|
self.post_project("raclette")
|
||||||
|
self.login("raclette")
|
||||||
|
|
||||||
|
result = self.client.get("/raclette/")
|
||||||
|
|
||||||
|
# Empty bill list and no members, should now propose to add members first
|
||||||
|
self.assertIn(
|
||||||
|
'You probably want to <a href="/raclette/members/add"',
|
||||||
|
result.data.decode('utf-8')
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.client.post("/raclette/members/add",
|
||||||
|
data={'name': 'alexis'})
|
||||||
|
|
||||||
|
result = self.client.get("/raclette/")
|
||||||
|
|
||||||
|
# Empty bill with member, list should now propose to add bills
|
||||||
|
self.assertIn(
|
||||||
|
'You probably want to <a href="/raclette/add"',
|
||||||
|
result.data.decode('utf-8')
|
||||||
|
)
|
||||||
|
|
||||||
def test_membership(self):
|
def test_membership(self):
|
||||||
self.post_project("raclette")
|
self.post_project("raclette")
|
||||||
self.login("raclette")
|
self.login("raclette")
|
||||||
|
|
Loading…
Reference in a new issue