mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-28 17:32:38 +02:00
Fix project deletion in the dashboard. Fixes #1094
This was broken due to changes introduced to make project deletion more secure. Rather than doing some complicated if branches, I decided this dashboard stuff is probably better handled with separate routes instead. So I've reintroduced a way to delete the projects without specifying the project code (otherwise it's not possible for admins to do it).
This commit is contained in:
parent
97a0aea2ba
commit
43289b8dd2
3 changed files with 128 additions and 59 deletions
|
@ -14,18 +14,22 @@ body {
|
|||
.navbar-brand span {
|
||||
color: #abe128;
|
||||
}
|
||||
|
||||
.navbar h1 {
|
||||
font-size: 1rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar .secondary-nav {
|
||||
text-align: right;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.secondary-nav .nav-link {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-family: "Lobster", arial, serif;
|
||||
font-size: 1.5rem;
|
||||
|
@ -51,7 +55,8 @@ body {
|
|||
font-size: 2.4em;
|
||||
}
|
||||
|
||||
#header .tryout, #header .showcase {
|
||||
#header .tryout,
|
||||
#header .showcase {
|
||||
color: #fff;
|
||||
background-color: #414141;
|
||||
border-color: #414141;
|
||||
|
@ -59,7 +64,8 @@ body {
|
|||
margin-right: 3px;
|
||||
}
|
||||
|
||||
#header .tryout:hover, #header .showcase:hover {
|
||||
#header .tryout:hover,
|
||||
#header .showcase:hover {
|
||||
background-color: #606060;
|
||||
border-color: #606060;
|
||||
cursor: pointer;
|
||||
|
@ -91,9 +97,11 @@ body {
|
|||
.balance tr td {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.positive {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: red;
|
||||
}
|
||||
|
@ -113,6 +121,7 @@ body {
|
|||
flex: 1 1 auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.identifier {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
@ -143,10 +152,12 @@ body {
|
|||
.home-container {
|
||||
background: linear-gradient(150deg, #abe128 0%, #43ca61 100%);
|
||||
}
|
||||
|
||||
.home {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 3em;
|
||||
}
|
||||
|
||||
#authentication-form legend {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -160,11 +171,13 @@ body {
|
|||
margin-bottom: 20px;
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
@media (max-width: 450px) {
|
||||
.home .card {
|
||||
min-width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Other */
|
||||
|
||||
#bills {
|
||||
|
@ -174,6 +187,7 @@ body {
|
|||
.empty-bill {
|
||||
margin-top: 5rem !important;
|
||||
}
|
||||
|
||||
.empty-bill .card {
|
||||
border: 0;
|
||||
}
|
||||
|
@ -250,12 +264,15 @@ footer .footer-right a {
|
|||
border-radius: 50%;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
|
||||
/** Firefox style fix **/
|
||||
footer .footer-right a {
|
||||
padding-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
footer .footer-right a:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
@ -268,6 +285,7 @@ footer .footer-left {
|
|||
/* If you don't want the footer to be responsive, remove these media queries */
|
||||
|
||||
@media (max-width: 600px) {
|
||||
|
||||
footer .footer-left,
|
||||
footer .footer-right {
|
||||
text-align: center;
|
||||
|
@ -298,9 +316,9 @@ footer .footer-left {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.bill-actions > form > .delete,
|
||||
.bill-actions > .edit,
|
||||
.bill-actions > .show {
|
||||
.bill-actions>form>.delete,
|
||||
.bill-actions>.edit,
|
||||
.bill-actions>.show {
|
||||
font-size: 0px;
|
||||
display: block;
|
||||
width: 16px;
|
||||
|
@ -316,15 +334,15 @@ footer .footer-left {
|
|||
height: calc(100% - 8px);
|
||||
}
|
||||
|
||||
.bill-actions > form > .delete {
|
||||
.bill-actions>form>.delete {
|
||||
background: url("../images/delete.png") no-repeat right;
|
||||
}
|
||||
|
||||
.bill-actions > .edit {
|
||||
.bill-actions>.edit {
|
||||
background: url("../images/edit.png") no-repeat right;
|
||||
}
|
||||
|
||||
.bill-actions > .show {
|
||||
.bill-actions>.show {
|
||||
background: url("../images/show.png") no-repeat right;
|
||||
}
|
||||
|
||||
|
@ -344,6 +362,7 @@ footer .footer-left {
|
|||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.split_bills,
|
||||
#table_overflow.statistics {
|
||||
/* The table is shifted to left, so add the spacer width on the right to match */
|
||||
|
@ -351,9 +370,9 @@ footer .footer-left {
|
|||
}
|
||||
}
|
||||
|
||||
.project-actions > .delete,
|
||||
.project-actions > .edit,
|
||||
.project-actions > .show {
|
||||
.project-actions>form>.delete,
|
||||
.project-actions>.edit,
|
||||
.project-actions>.show {
|
||||
font-size: 0px;
|
||||
display: block;
|
||||
width: 16px;
|
||||
|
@ -363,21 +382,22 @@ footer .footer-left {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.project-actions > .delete {
|
||||
.project-actions>form>.delete {
|
||||
background: url("../images/delete.png") no-repeat right;
|
||||
border: 0px !important;
|
||||
}
|
||||
|
||||
.project-actions > .edit {
|
||||
.project-actions>.edit {
|
||||
background: url("../images/edit.png") no-repeat right;
|
||||
}
|
||||
|
||||
.project-actions > .show {
|
||||
.project-actions>.show {
|
||||
background: url("../images/show.png") no-repeat right;
|
||||
}
|
||||
|
||||
.history_icon > .delete,
|
||||
.history_icon > .add,
|
||||
.history_icon > .edit {
|
||||
.history_icon>.delete,
|
||||
.history_icon>.add,
|
||||
.history_icon>.edit {
|
||||
font-size: 0px;
|
||||
display: block;
|
||||
width: 16px;
|
||||
|
@ -388,15 +408,15 @@ footer .footer-left {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.history_icon > .delete {
|
||||
.history_icon>.delete {
|
||||
background: url("../images/delete.png") no-repeat right;
|
||||
}
|
||||
|
||||
.history_icon > .edit {
|
||||
.history_icon>.edit {
|
||||
background: url("../images/edit.png") no-repeat right;
|
||||
}
|
||||
|
||||
.history_icon > .add {
|
||||
.history_icon>.add {
|
||||
background: url("../images/add.png") no-repeat right;
|
||||
}
|
||||
|
||||
|
@ -461,7 +481,7 @@ tr.payer_line .balance-name {
|
|||
margin-top: 30px;
|
||||
}
|
||||
|
||||
#bill-form > fieldset {
|
||||
#bill-form>fieldset {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
@ -485,64 +505,81 @@ tr:hover .extra-info {
|
|||
|
||||
/* Fluid Offsets for Boostrap */
|
||||
|
||||
.row-fluid > [class*="span"]:not([class*="offset"]):first-child {
|
||||
.row-fluid>[class*="span"]:not([class*="offset"]):first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row-fluid > .offset12 {
|
||||
|
||||
.row-fluid>.offset12 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
.row-fluid > .offset11 {
|
||||
|
||||
.row-fluid>.offset11 {
|
||||
margin-left: 93.5%;
|
||||
}
|
||||
.row-fluid > .offset10 {
|
||||
|
||||
.row-fluid>.offset10 {
|
||||
margin-left: 85%;
|
||||
}
|
||||
.row-fluid > .offset9 {
|
||||
|
||||
.row-fluid>.offset9 {
|
||||
margin-left: 76.5%;
|
||||
}
|
||||
.row-fluid > .offset8 {
|
||||
|
||||
.row-fluid>.offset8 {
|
||||
margin-left: 68%;
|
||||
}
|
||||
.row-fluid > .offset7 {
|
||||
|
||||
.row-fluid>.offset7 {
|
||||
margin-left: 59.5%;
|
||||
}
|
||||
.row-fluid > .offset6 {
|
||||
|
||||
.row-fluid>.offset6 {
|
||||
margin-left: 51%;
|
||||
}
|
||||
.row-fluid > .offset5 {
|
||||
|
||||
.row-fluid>.offset5 {
|
||||
margin-left: 42.5%;
|
||||
}
|
||||
.row-fluid > .offset4 {
|
||||
|
||||
.row-fluid>.offset4 {
|
||||
margin-left: 34%;
|
||||
}
|
||||
.row-fluid > .offset3 {
|
||||
|
||||
.row-fluid>.offset3 {
|
||||
margin-left: 25.5%;
|
||||
}
|
||||
.row-fluid > .offset2 {
|
||||
|
||||
.row-fluid>.offset2 {
|
||||
margin-left: 17%;
|
||||
}
|
||||
.row-fluid > .offset1 {
|
||||
|
||||
.row-fluid>.offset1 {
|
||||
margin-left: 8.5%;
|
||||
}
|
||||
|
||||
.globe-europe svg {
|
||||
fill: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.navbar-nav .dropdown-toggle:hover .globe-europe svg {
|
||||
fill: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
.navbar-dark .navbar-nav .show > .nav-link svg {
|
||||
|
||||
.navbar-dark .navbar-nav .show>.nav-link svg {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.navbar-dark .dropdown-menu {
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.icon svg {
|
||||
display: inline-block;
|
||||
border-bottom: 0.2em solid transparent;
|
||||
height: 1.2em;
|
||||
width: 1.2em; /* protection for IE11 */
|
||||
width: 1.2em;
|
||||
/* protection for IE11 */
|
||||
}
|
||||
|
||||
.icon.high svg {
|
||||
|
@ -558,9 +595,11 @@ tr:hover .extra-info {
|
|||
.icon.before-text svg {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
footer .icon svg {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.icon.icon-white {
|
||||
fill: white;
|
||||
}
|
||||
|
@ -568,7 +607,8 @@ footer .icon svg {
|
|||
.icon.icon-red {
|
||||
fill: #dc3545;
|
||||
}
|
||||
.btn:hover .icon.icon-red {
|
||||
|
||||
.btn:hover .icon.icon-red {
|
||||
fill: white !important;
|
||||
}
|
||||
|
||||
|
@ -592,6 +632,7 @@ footer .icon svg {
|
|||
margin-top: 1em;
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
.edit-project .custom-file {
|
||||
margin-bottom: 2em;
|
||||
}
|
|
@ -2,32 +2,51 @@
|
|||
{% block content %}
|
||||
{% if is_admin_dashboard_activated %}
|
||||
<table id="bill_table" class="table table-striped">
|
||||
<thead><tr><th>{{ _("Project") }}</th><th>{{ _("Number of participants") }}</th><th>{{ _("Number of bills") }}</th><th>{{_("Newest bill")}}</th><th>{{_("Oldest bill")}}</th><th>{{_("Actions")}}</th></tr></thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _("Project") }}</th>
|
||||
<th>{{ _("Number of participants") }}</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>
|
||||
<td><a href="{{ url_for(".list_bills", project_id=project.id) }}" title="{{ project.name }}">{{ project.name }}</a></td><td>{{ project.members | count }}</td><td>{{ project.get_bills_unordered().count() }}</td>
|
||||
{% if project.has_bills() %}
|
||||
<td>{{ project.get_bills().all()[0].date }}</td>
|
||||
<td>{{ project.get_bills().all()[-1].date }}</td>
|
||||
{% else %}
|
||||
<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>
|
||||
<a class="show" href="{{ url_for(".list_bills", project_id=project.id) }}" title="{{ _("show") }}">{{ _('show') }}</a>
|
||||
</td>
|
||||
<td><a href="{{ url_for('.list_bills', project_id=project.id) }}"
|
||||
title="{{ project.name }}">{{project.name}}</a></td>
|
||||
<td>{{ project.members | count }}</td>
|
||||
<td>{{ project.get_bills_unordered().count() }}</td>
|
||||
{% if project.has_bills() %}
|
||||
<td>{{ project.get_bills().all()[0].date }}</td>
|
||||
<td>{{ project.get_bills().all()[-1].date }}</td>
|
||||
{% else %}
|
||||
<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>
|
||||
|
||||
<form id="delete-project" class="form-horizontal" action="{{ url_for('.dashboard_delete_project',
|
||||
project_id=project.id) }}" method="post">
|
||||
|
||||
<button class="delete">{{ _("Delete project") }}</button>
|
||||
</form>
|
||||
<a class="show" href="{{ url_for('.list_bills', project_id=project.id) }}" title="{{ _(" show") }}">{{
|
||||
_('show') }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<script language="JavaScript">
|
||||
$(document).ready(function() {
|
||||
$('#bill_table').DataTable({
|
||||
paging: true
|
||||
});
|
||||
})
|
||||
$(document).ready(function () {
|
||||
$('#bill_table').DataTable({
|
||||
paging: true
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% else %}
|
||||
<div class="alert alert-danger">{{ _("The Dashboard is currently deactivated.") }}</div>
|
||||
|
|
|
@ -888,10 +888,19 @@ def dashboard():
|
|||
return render_template(
|
||||
"dashboard.html",
|
||||
projects=Project.query.all(),
|
||||
delete_project_form=DestructiveActionProjectForm,
|
||||
is_admin_dashboard_activated=is_admin_dashboard_activated,
|
||||
)
|
||||
|
||||
|
||||
@main.route("/dashboard/<project_id>/delete", methods=["POST"])
|
||||
@requires_admin()
|
||||
def dashboard_delete_project():
|
||||
g.project.remove_project()
|
||||
flash(_("Project successfully deleted"))
|
||||
return redirect(request.headers.get("Referer") or url_for(".home"))
|
||||
|
||||
|
||||
@main.route("/favicon.ico")
|
||||
def favicon():
|
||||
return send_from_directory(
|
||||
|
|
Loading…
Reference in a new issue