✨(backend) allow masking documents from the list view
Once users have visited a document to which they have access, they can't remove it from their list view anymore. Several users reported that this is annoying because a document that gets a lot of updates keeps popping up at the top of their list view. They want to be able to mask the document in a click. We propose to add a "masked documents" section in the left side bar where the masked documents can still be found.
This commit is contained in:
@@ -60,6 +60,9 @@ class ListDocumentFilter(DocumentFilter):
|
||||
is_creator_me = django_filters.BooleanFilter(
|
||||
method="filter_is_creator_me", label=_("Creator is me")
|
||||
)
|
||||
is_masked = django_filters.BooleanFilter(
|
||||
method="filter_is_masked", label=_("Masked")
|
||||
)
|
||||
is_favorite = django_filters.BooleanFilter(
|
||||
method="filter_is_favorite", label=_("Favorite")
|
||||
)
|
||||
@@ -106,3 +109,22 @@ class ListDocumentFilter(DocumentFilter):
|
||||
return queryset
|
||||
|
||||
return queryset.filter(is_favorite=bool(value))
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def filter_is_masked(self, queryset, name, value):
|
||||
"""
|
||||
Filter documents based on whether they are masked by the current user.
|
||||
|
||||
Example:
|
||||
- /api/v1.0/documents/?is_masked=true
|
||||
→ Filters documents marked as masked by the logged-in user
|
||||
- /api/v1.0/documents/?is_masked=false
|
||||
→ Filters documents not marked as masked by the logged-in user
|
||||
"""
|
||||
user = self.request.user
|
||||
|
||||
if not user.is_authenticated:
|
||||
return queryset
|
||||
|
||||
queryset_method = queryset.filter if bool(value) else queryset.exclude
|
||||
return queryset_method(link_traces__user=user, link_traces__is_masked=True)
|
||||
|
||||
@@ -455,9 +455,8 @@ class DocumentViewSet(
|
||||
|
||||
# Annotate favorite status and filter if applicable as late as possible
|
||||
queryset = queryset.annotate_is_favorite(user)
|
||||
queryset = filterset.filters["is_favorite"].filter(
|
||||
queryset, filter_data["is_favorite"]
|
||||
)
|
||||
for field in ["is_favorite", "is_masked"]:
|
||||
queryset = filterset.filters[field].filter(queryset, filter_data[field])
|
||||
|
||||
# Apply ordering only now that everything is filtered and annotated
|
||||
queryset = filters.OrderingFilter().filter_queryset(
|
||||
@@ -1109,15 +1108,50 @@ class DocumentViewSet(
|
||||
document=document, user=user
|
||||
).delete()
|
||||
if deleted:
|
||||
return drf.response.Response(
|
||||
{"detail": "Document unmarked as favorite"},
|
||||
status=drf.status.HTTP_204_NO_CONTENT,
|
||||
)
|
||||
return drf.response.Response(status=drf.status.HTTP_204_NO_CONTENT)
|
||||
return drf.response.Response(
|
||||
{"detail": "Document was already not marked as favorite"},
|
||||
status=drf.status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["post", "delete"], url_path="mask")
|
||||
def mask(self, request, *args, **kwargs):
|
||||
"""Mask or unmask the document for the logged-in user based on the HTTP method."""
|
||||
# Check permissions first
|
||||
document = self.get_object()
|
||||
user = request.user
|
||||
|
||||
try:
|
||||
link_trace = models.LinkTrace.objects.get(document=document, user=user)
|
||||
except models.LinkTrace.DoesNotExist:
|
||||
return drf.response.Response(
|
||||
{"detail": "User never accessed this document before."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
if request.method == "POST":
|
||||
if link_trace.is_masked:
|
||||
return drf.response.Response(
|
||||
{"detail": "Document was already masked"},
|
||||
status=drf.status.HTTP_200_OK,
|
||||
)
|
||||
link_trace.is_masked = True
|
||||
link_trace.save(update_fields=["is_masked"])
|
||||
return drf.response.Response(
|
||||
{"detail": "Document was masked"},
|
||||
status=drf.status.HTTP_201_CREATED,
|
||||
)
|
||||
|
||||
# Handle DELETE method to unmask document
|
||||
if not link_trace.is_masked:
|
||||
return drf.response.Response(
|
||||
{"detail": "Document was already not masked"},
|
||||
status=drf.status.HTTP_200_OK,
|
||||
)
|
||||
link_trace.is_masked = False
|
||||
link_trace.save(update_fields=["is_masked"])
|
||||
return drf.response.Response(status=drf.status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["post"], url_path="attachment-upload")
|
||||
def attachment_upload(self, request, *args, **kwargs):
|
||||
"""Upload a file related to a given document"""
|
||||
|
||||
Reference in New Issue
Block a user