diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py
index e796e714b0..88d691797e 100644
--- a/InvenTree/part/api.py
+++ b/InvenTree/part/api.py
@@ -328,6 +328,22 @@ class PartDetail(generics.RetrieveUpdateDestroyAPIView):
message = f'Part \'{part.name}\' (pk = {part.pk}) is active: cannot delete'
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED, data=message)
+ def update(self, request, *args, **kwargs):
+ """
+ Custom update functionality for Part instance.
+
+ - If the 'starred' field is provided, update the 'starred' status against current user
+ """
+
+ if 'starred' in request.data:
+ starred = str2bool(request.data.get('starred', None))
+
+ self.get_object().setStarred(request.user, starred)
+
+ response = super().update(request, *args, **kwargs)
+
+ return response
+
class PartList(generics.ListCreateAPIView):
""" API endpoint for accessing a list of Part objects
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 31dc821117..b06469699b 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -1056,6 +1056,23 @@ class Part(MPTTModel):
except PartStar.DoesNotExist:
return False
+ def setStarred(self, user, starred):
+ """
+ Set the "starred" status of this Part for the given user
+ """
+
+ if not user:
+ return
+
+ # Do not duplicate efforts
+ if self.isStarredBy(user) == starred:
+ return
+
+ if starred:
+ PartStar.objects.create(part=self, user=user)
+ else:
+ PartStar.objects.filter(part=self, user=user).delete()
+
def need_to_restock(self):
""" Return True if this part needs to be restocked
(either by purchasing or building).
diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html
index be6986ccd3..cc211aec1a 100644
--- a/InvenTree/part/templates/part/part_base.html
+++ b/InvenTree/part/templates/part/part_base.html
@@ -248,8 +248,7 @@
$("#toggle-starred").click(function() {
toggleStar({
part: {{ part.id }},
- user: {{ user.id }},
- button: '#part-star-icon'
+ button: '#part-star-icon',
});
});
diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html
index bff711d1b2..2120d0ccfb 100644
--- a/InvenTree/templates/base.html
+++ b/InvenTree/templates/base.html
@@ -50,8 +50,11 @@
-{% block css %}
-{% endblock %}
+
{% block head %}
{% endblock %}
diff --git a/InvenTree/templates/js/part.js b/InvenTree/templates/js/part.js
index 9c21034b28..9f770f452e 100644
--- a/InvenTree/templates/js/part.js
+++ b/InvenTree/templates/js/part.js
@@ -14,50 +14,30 @@ function toggleStar(options) {
* - user: pk of the user
*/
- var url = '/api/part/star/';
+ var url = `/api/part/${options.part}/`;
- inventreeGet(
- url,
- {
- part: options.part,
- user: options.user,
- },
- {
- success: function(response) {
- if (response.length == 0) {
- // Zero length response = star does not exist
- // So let's add one!
- inventreePut(
- url,
- {
- part: options.part,
- user: options.user,
- },
- {
- method: 'POST',
- success: function(response, status) {
- $(options.button).addClass('icon-yellow');
- },
+ inventreeGet(url, {}, {
+ success: function(response) {
+ var starred = response.starred;
+
+ inventreePut(
+ url,
+ {
+ starred: !starred,
+ },
+ {
+ method: 'PATCH',
+ success: function(response) {
+ if (response.starred) {
+ $(options.button).addClass('icon-yellow');
+ } else {
+ $(options.button).removeClass('icon-yellow');
}
- );
- } else {
- var pk = response[0].pk;
- // There IS a star (delete it!)
- inventreePut(
- url + pk + "/",
- {
- },
- {
- method: 'DELETE',
- success: function(response, status) {
- $(options.button).removeClass('icon-yellow');
- },
- }
- );
+ }
}
- },
+ );
}
- );
+ });
}