Fix button to remove a user from picture

This commit is contained in:
thomas girod 2024-07-25 17:27:23 +02:00
parent b25805e0a1
commit 215fdce411
6 changed files with 107 additions and 39 deletions

View File

@ -199,12 +199,6 @@
> form { > form {
> p { > p {
box-sizing: border-box; box-sizing: border-box;
> input {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
} }
> .results_on_deck > div { > .results_on_deck > div {
@ -219,12 +213,15 @@
right: 0; right: 0;
} }
} }
input {
> input { min-width: 100%;
width: 100%;
max-width: 100%; max-width: 100%;
box-sizing: border-box; box-sizing: border-box;
} }
button {
font-weight: bold;
}
} }
} }
} }

View File

@ -32,7 +32,6 @@
width: 100%; width: 100%;
} }
// Django moment
> div.mini_profile_link { > div.mini_profile_link {
position: relative; position: relative;
@ -106,7 +105,6 @@
} }
} }
// Django moment
> a.mini_profile_link { > a.mini_profile_link {
display: none; display: none;
} }

View File

@ -1,17 +1,23 @@
from django.conf import settings
from ninja import Query from ninja import Query
from ninja_extra import ControllerBase, api_controller, route from ninja_extra import ControllerBase, api_controller, route
from ninja_extra.exceptions import PermissionDenied from ninja_extra.exceptions import PermissionDenied
from ninja_extra.permissions import IsAuthenticated from ninja_extra.permissions import IsAuthenticated
from pydantic import NonNegativeInt
from core.api_permissions import IsOldSubscriber
from core.models import User from core.models import User
from sas.models import Picture from sas.models import PeoplePictureRelation, Picture
from sas.schemas import PictureFilterSchema, PictureSchema from sas.schemas import (
PictureFilterSchema,
PictureSchema,
)
@api_controller("/sas") @api_controller("/sas/pictures")
class SasController(ControllerBase): class PicturesController(ControllerBase):
@route.get( @route.get(
"/picture", "",
response=list[PictureSchema], response=list[PictureSchema],
permissions=[IsAuthenticated], permissions=[IsAuthenticated],
url_name="pictures", url_name="pictures",
@ -45,3 +51,20 @@ class SasController(ControllerBase):
picture.compressed_url = picture.get_download_compressed_url() picture.compressed_url = picture.get_download_compressed_url()
picture.thumb_url = picture.get_download_thumb_url() picture.thumb_url = picture.get_download_thumb_url()
return pictures return pictures
@api_controller("/sas/relation")
class UsersIdentifiedController(ControllerBase):
@route.delete("/{relation_id}", permissions=[IsOldSubscriber])
def delete_relation(self, relation_id: NonNegativeInt):
relation: PeoplePictureRelation = self.get_object_or_exception(
PeoplePictureRelation, pk=relation_id
)
user = self.context.request.user
if (
relation.user_id != user.id
and not user.is_root
and not user.is_in_group(pk=settings.SITH_GROUP_SAS_ADMIN_ID)
):
raise PermissionDenied
relation.delete()

View File

@ -1,10 +1,10 @@
from datetime import datetime from datetime import datetime
from ninja import FilterSchema, ModelSchema from ninja import FilterSchema, ModelSchema, Schema
from pydantic import Field from pydantic import Field, NonNegativeInt
from core.schemas import SimpleUserSchema from core.schemas import SimpleUserSchema
from sas.models import Picture from sas.models import PeoplePictureRelation, Picture
class PictureFilterSchema(FilterSchema): class PictureFilterSchema(FilterSchema):
@ -23,3 +23,14 @@ class PictureSchema(ModelSchema):
full_size_url: str full_size_url: str
compressed_url: str compressed_url: str
thumb_url: str thumb_url: str
class PictureCreateRelationSchema(Schema):
user_id: NonNegativeInt
picture_id: NonNegativeInt
class CreatedPictureRelationSchema(ModelSchema):
class Meta:
model = PeoplePictureRelation
fields = ["id", "user", "picture"]

View File

@ -4,11 +4,19 @@
<link rel="stylesheet" href="{{ scss('sas/picture.scss') }}"> <link rel="stylesheet" href="{{ scss('sas/picture.scss') }}">
{%- endblock -%} {%- endblock -%}
{%- block additional_js -%}
<script src="{{ static('core/js/alpinejs.min.js') }}" defer></script>
{%- endblock -%}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
{% if picture.get_previous() %} {% if picture.get_previous() %}
<link rel="preload" as="image" href="{{ url("sas:download_compressed", picture_id=picture.get_previous().id) }}"> <link
rel="preload"
as="image"
href="{{ url("sas:download_compressed", picture_id=picture.get_previous().id) }}"
>
{% endif %} {% endif %}
{% if picture.get_next() %} {% if picture.get_next() %}
<link rel="preload" as="image" href="{{ url("sas:download_compressed", picture_id=picture.get_next().id) }}"> <link rel="preload" as="image" href="{{ url("sas:download_compressed", picture_id=picture.get_next().id) }}">
@ -36,7 +44,8 @@
<div class="title"> <div class="title">
<h3>{{ picture.get_display_name() }}</h3> <h3>{{ picture.get_display_name() }}</h3>
<h4>{{ picture.parent.children.filter(id__lte=picture.id).count() }} / {{ picture.parent.children.count() }}</h4> <h4>{{ picture.parent.children.filter(id__lte=picture.id).count() }}
/ {{ picture.parent.children.count() }}</h4>
</div> </div>
<br> <br>
@ -100,7 +109,9 @@
<h5>{% trans %}Tools{% endtrans %}</h5> <h5>{% trans %}Tools{% endtrans %}</h5>
<div> <div>
<div> <div>
<a class="text" href="{{ picture.get_download_url() }}">{% trans %}HD version{% endtrans %}</a> <a class="text" href="{{ picture.get_download_url() }}">
{% trans %}HD version{% endtrans %}
</a>
<br> <br>
<a class="text danger" href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a> <a class="text danger" href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a>
</div> </div>
@ -139,20 +150,18 @@
{{ form.as_p() }} {{ form.as_p() }}
<input type="submit" value="{% trans %}Go{% endtrans %}" /> <input type="submit" value="{% trans %}Go{% endtrans %}" />
</form> </form>
<ul> <ul x-data="user_identification">
{% for r in picture.people.all() %} <template x-for="item in items" :key="item.id">
<li> <li>
<a class="user" href="{{ r.user.get_absolute_url() }}"> <a class="user" :href="item.user.url">
{% if r.user.profile_pict %} <img class="profile-pic" :src="item.user.picture" alt="image de profil"/>
<div class="profile-pic" style="background-image: url('{{ r.user.profile_pict.get_download_url() }}');"></div> <span x-text="item.user.name"></span>
{% endif %}
<span>{{ r.user.get_short_name() }}</span>
</a> </a>
{% if user == r.user or user.can_edit(picture) %} <template x-if="can_be_removed(item)">
<a class="delete" href="?remove_user={{ r.user.id }}">❌</a> <a class="delete clickable" @click="remove(item)">❌</a>
{% endif %} </template>
</li> </li>
{% endfor %} </template>
</ul> </ul>
</div> </div>
</div> </div>
@ -162,6 +171,42 @@
{% block script %} {% block script %}
{{ super() }} {{ super() }}
<script> <script>
document.addEventListener("alpine:init", () => {
Alpine.data("user_identification", () => ({
items: [
{%- for r in picture.people.select_related("user", "user__profile_pict") -%}
{
id: {{ r.id }},
user: {
id: {{ r.user.id }},
name: "{{ r.user.get_short_name()|safe }}",
url: "{{ r.user.get_absolute_url() }}",
{% if r.user.profile_pict %}
picture: "{{ r.user.profile_pict.get_download_url() }}",
{% else %}
picture: "{{ static('core/img/unknown.jpg') }}",
{% endif %}
},
},
{%- endfor -%}
],
can_be_removed(item) {
{# If user is root or sas admin, he has the right, at "compile" time.
If not, he can delete only its own identification. #}
{% if user.is_root or user.is_in_group(pk=settings.SITH_GROUP_SAS_ADMIN_ID) %}
return true;
{% else %}
return item.user.id === {{ user.id }};
{% endif %}
},
async remove(item) {
const res = await fetch(`/api/sas/relation/${item.id}`, {method: "DELETE"});
if (res.ok) {
this.items = this.items.filter((i) => i.id !== item.id)
}
},
}))
});
$(() => { $(() => {
$(document).keydown((e) => { $(document).keydown((e) => {
switch (e.keyCode) { switch (e.keyCode) {

View File

@ -143,12 +143,6 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
self.object.rotate(270) self.object.rotate(270)
if "rotate_left" in request.GET: if "rotate_left" in request.GET:
self.object.rotate(90) self.object.rotate(90)
if "remove_user" in request.GET:
user = get_object_or_404(User, pk=int(request.GET["remove_user"]))
if user.id == request.user.id or request.user.is_in_group(
pk=settings.SITH_GROUP_SAS_ADMIN_ID
):
user.picture.filter(picture=self.object).delete()
if "ask_removal" in request.GET.keys(): if "ask_removal" in request.GET.keys():
self.object.is_moderated = False self.object.is_moderated = False
self.object.asked_for_removal = True self.object.asked_for_removal = True