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;
|
||||
|
@ -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,7 +370,7 @@ footer .footer-left {
|
|||
}
|
||||
}
|
||||
|
||||
.project-actions > .delete,
|
||||
.project-actions>form>.delete,
|
||||
.project-actions>.edit,
|
||||
.project-actions>.show {
|
||||
font-size: 0px;
|
||||
|
@ -363,8 +382,9 @@ 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 {
|
||||
|
@ -488,39 +508,51 @@ tr:hover .extra-info {
|
|||
.row-fluid>[class*="span"]:not([class*="offset"]):first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.row-fluid>.offset12 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset11 {
|
||||
margin-left: 93.5%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset10 {
|
||||
margin-left: 85%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset9 {
|
||||
margin-left: 76.5%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset8 {
|
||||
margin-left: 68%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset7 {
|
||||
margin-left: 59.5%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset6 {
|
||||
margin-left: 51%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset5 {
|
||||
margin-left: 42.5%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset4 {
|
||||
margin-left: 34%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset3 {
|
||||
margin-left: 25.5%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset2 {
|
||||
margin-left: 17%;
|
||||
}
|
||||
|
||||
.row-fluid>.offset1 {
|
||||
margin-left: 8.5%;
|
||||
}
|
||||
|
@ -528,21 +560,26 @@ tr:hover .extra-info {
|
|||
.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 {
|
||||
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,6 +607,7 @@ footer .icon svg {
|
|||
.icon.icon-red {
|
||||
fill: #dc3545;
|
||||
}
|
||||
|
||||
.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,10 +2,22 @@
|
|||
{% 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>
|
||||
<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>
|
||||
|
@ -14,9 +26,16 @@
|
|||
<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>
|
||||
<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 %}
|
||||
|
|
|
@ -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