Add audit button to inventory list view
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Madis Mägi 2024-07-28 13:46:46 +03:00
parent 1e0f81fbb3
commit a60a540408
3 changed files with 60 additions and 3 deletions

View File

@ -1,6 +1,6 @@
import boto3 import boto3
import pymongo import pymongo
from datetime import datetime from datetime import datetime, date, timedelta
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from bson.objectid import ObjectId from bson.objectid import ObjectId
from flask import Blueprint, abort, g, make_response, redirect, render_template, request from flask import Blueprint, abort, g, make_response, redirect, render_template, request
@ -393,13 +393,15 @@ def view_inventory(slug=None):
q = {"type": {"$ne": "token"}} q = {"type": {"$ne": "token"}}
template = "inventory.html" template = "inventory.html"
public_view = False public_view = False
if not read_user(): login_user = read_user()
if not login_user:
q.update({"inventory.public": True}) q.update({"inventory.public": True})
template = "inventory_public.html" template = "inventory_public.html"
public_view = True public_view = True
else: else:
fields.append(("inventory.owner.username", "Owner", str)) fields.append(("inventory.owner.username", "Owner", str))
fields.append(("inventory.user.username", "User", str)) fields.append(("inventory.user.username", "User", str))
can_audit = "k-space:janitors" in login_user["groups"]
if slug and not public_view: if slug and not public_view:
template = "inventory_pick.html" template = "inventory_pick.html"
if request.path.startswith("/m/inventory/clone-with-slug"): if request.path.startswith("/m/inventory/clone-with-slug"):
@ -446,7 +448,29 @@ def view_inventory_audit(item_id):
"inventory.audit.timestamp": datetime.utcnow(), "inventory.audit.timestamp": datetime.utcnow(),
}, },
}) })
return redirect("/m/inventory/%s/view" % item_id) if request.form and request.form.get("noRedirect", False):
return {}
else:
return redirect("/m/inventory/%s/view" % item_id)
@page_inventory.app_template_filter('audit_text')
def render_audit_text(item):
timestamp = item.get('audit', {}).get('timestamp', False)
if timestamp:
return timestamp.date()
else:
return 'Never'
@page_inventory.app_template_filter('audit_color')
def render_audit_color(item):
timestamp = item.get('audit', {}).get('timestamp', False)
today = date.today()
if not timestamp or timestamp.date() < today - timedelta(days=365):
return "red"
elif timestamp.date() < today - timedelta(days=7):
return "orange"
else:
return "green unclickable"
@page_inventory.route("/m/inventory/<item_id>/claim", methods=["POST"]) @page_inventory.route("/m/inventory/<item_id>/claim", methods=["POST"])
@login_required @login_required

View File

@ -60,6 +60,9 @@ body {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
} }
.unclickable {
pointer-events: none;
}
</style> </style>
</head> </head>

View File

@ -12,6 +12,9 @@
<th>Type</th> <th>Type</th>
<th>Owner</th> <th>Owner</th>
<th>User</th> <th>User</th>
{% if can_audit %}
<th>Audit</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -30,6 +33,17 @@
<td>{{ item.type }}</td> <td>{{ item.type }}</td>
<td>{{ item | owner_link}}</td> <td>{{ item | owner_link}}</td>
<td>{{ item | user_link}}</td> <td>{{ item | user_link}}</td>
{% if can_audit %}
<td>
<button
data-item-id="{{ item._id }}"
class="audit-button {{ item.inventory | audit_color }} waves-effect waves-light btn-small"
>
<i class="material-icons left">done</i>{{item.inventory | audit_text}}
</button>
</td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -38,4 +52,20 @@
<a class="waves-effect waves-light btn" href="/m/inventory/add">Add item</a> <a class="waves-effect waves-light btn" href="/m/inventory/add">Add item</a>
</p> </p>
</div> </div>
<script>
$('button.audit-button').on('click', function() {
let button = $(this);
$.ajax({
method: 'POST',
url: "/m/inventory/" + button.data('itemId') + "/audit",
data: { noRedirect: true },
success: function() {
button.unbind('click');
button.removeClass(['orange', 'red', 'waves-effect', 'waves-light']);
button.addClass(['unclickable', 'green']);
button.text('Just now');
}
})
});
</script>
{% endblock %} {% endblock %}