Edició de llistes (afegir i esborrar llistes)

This commit is contained in:
marc
2025-12-21 17:30:19 +01:00
parent fdcda1b566
commit c0624d1e56
10 changed files with 101 additions and 19 deletions

View File

@@ -24,3 +24,13 @@ def page(request: Request, logged_in: auth.LoggedIn):
@router.get("/api/content/llistes") @router.get("/api/content/llistes")
def content(request: Request, logged_in: auth.LoggedIn): def content(request: Request, logged_in: auth.LoggedIn):
return llistes.llistes_pagina(request, logged_in) return llistes.llistes_pagina(request, logged_in)
@router.post("/api/llistes/editor/")
def insert_row(request: Request, _: auth.RequireLogin):
return llistes.llistes_editor_insert_row(request)
@router.delete("/api/llistes/{playlist_id}")
def delete_playlist(playlist_id: int, _: auth.RequireLogin):
return llistes.llistes_editor_delete_row(playlist_id)

View File

@@ -1147,10 +1147,6 @@ video {
transition-duration: 200ms; transition-duration: 200ms;
} }
.hover\:underline:hover {
text-decoration-line: underline;
}
.focus\:outline-none:focus { .focus\:outline-none:focus {
outline: 2px solid transparent; outline: 2px solid transparent;
outline-offset: 2px; outline-offset: 2px;

View File

@@ -1,16 +1,26 @@
{% include "fragments/menu.html" %} {% include "fragments/menu.html" %}
<div class="p-12 text-center"> <div class="p-12 text-center">
<h3 class="text-3xl text-beige p-4">Llistes de Repertori</h3> <h3 class="text-3xl text-beige p-4">Llistes de Repertori</h3>
{% if logged_in %}
<button title="Afegeix una llista"
class="text-beige m-2"
hx-post="/api/llistes/editor/"
hx-target="#{{ playlist_list_id }}"
hx-swap="afterbegin transition:true">
<i class="fa fa-plus" aria-hidden="true"></i>
Afegeix una llista
</button>
{% endif %}
<div id="{{ playlist_list_id }}"
class="flex flex-col items-center">
{% if playlists %} {% if playlists %}
<div class="flex flex-col items-center">
{% for playlist in playlists %} {% for playlist in playlists %}
{% include "fragments/llistes/playlist_entry.html" %} {% include "fragments/llistes/playlist_entry.html" %}
{% endfor %} {% endfor %}
</div>
{% else %} {% else %}
<div class="text-center py-8"> <div class="text-center py-8">
<p class="text-beige/70">No hi ha llistes disponibles.</p> <p class="text-beige/70">No hi ha llistes disponibles.</p>
</div> </div>
{% endif %} {% endif %}
</div>
</div> </div>

View File

@@ -1,7 +1,8 @@
<div class=" <div class="
border rounded border-beige border rounded border-beige
p-2 m-2 w-full max-w-xl p-2 m-2 w-full max-w-xl
"> relative"
id="playlist-entry-{{ playlist.id }}">
<div class="flex justify-between items-start"> <div class="flex justify-between items-start">
<div class="flex-1"> <div class="flex-1">
<p class="text-xl text-white"> <p class="text-xl text-white">
@@ -9,15 +10,22 @@
{% if playlist.name %} {% if playlist.name %}
{{ playlist.name }} {{ playlist.name }}
{% else %} {% else %}
Llista de temes #{{ playlist.id }} Llista de temes
{% endif %} {% endif %}
</a> </a>
</p> </p>
</div> </div>
{% if logged_in %} {% if logged_in %}
<div class="ml-2"> <div class="ml-auto">
{% include "fragments/llista/visibility.html" %} {% include "fragments/llistes/playlist_visibility.html" %}
<button title="Esborra la llista"
class="text-beige mx-1"
hx-delete="/api/llistes/{{ playlist.id }}"
hx-target="#playlist-entry-{{ playlist.id }}"
hx-swap="outerHTML swap:0.5s">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -0,0 +1,15 @@
{% if not playlist.hidden %}
<button title="Llista visible (amaga-la)"
class="text-beige mx-2"
hx-put="/api/llista/{{ playlist.id }}/invisible"
hx-swap="outerHTML">
<i class="fa fa-eye" aria-hidden="true"></i>
</button>
{% else %}
<button title="Llista invisible (mostra-la)"
class="text-beige mx-2"
hx-put="/api/llista/{{ playlist.id }}/visible"
hx-swap="outerHTML">
<i class="fa fa-eye-slash" aria-hidden="true"></i>
</button>
{% endif %}

View File

@@ -73,19 +73,26 @@ def get_playlist_name(playlist_id: int, con: Connection | None = None) -> str |
def get_all_playlists(logged_in: bool = False, con: Connection | None = None) -> Iterator[model.Playlist]: def get_all_playlists(logged_in: bool = False, con: Connection | None = None) -> Iterator[model.Playlist]:
if logged_in: if logged_in:
# Show all playlists for logged in users # Show all playlists for logged in users, except session-associated ones
query = """ query = """
SELECT id, name, hidden SELECT id, name, hidden
FROM playlists FROM playlists
ORDER BY id ASC WHERE id NOT IN (
SELECT DISTINCT playlist_id
FROM session_playlists
)
ORDER BY id DESC
""" """
else: else:
# Show only visible playlists for non-logged in users # Show only visible playlists for non-logged in users, except session-associated ones
query = """ query = """
SELECT id, name, hidden SELECT id, name, hidden
FROM playlists FROM playlists
WHERE hidden = 0 WHERE hidden = 0 AND id NOT IN (
ORDER BY id ASC SELECT DISTINCT playlist_id
FROM session_playlists
)
ORDER BY id DESC
""" """
with get_connection(con) as con: with get_connection(con) as con:

View File

@@ -1,9 +1,11 @@
from fastapi import Request
from folkugat_web.model import playlists as playlists_model
from folkugat_web.model.pagines import Pages from folkugat_web.model.pagines import Pages
from folkugat_web.services import playlists as playlists_service from folkugat_web.services import playlists as playlists_service
from folkugat_web.templates import templates from folkugat_web.templates import templates
def llistes_pagina(request, logged_in): def llistes_pagina(request: Request, logged_in: bool):
playlists = playlists_service.get_all_playlists(logged_in=logged_in) playlists = playlists_service.get_all_playlists(logged_in=logged_in)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/llistes/pagina.html", "fragments/llistes/pagina.html",
@@ -13,5 +15,28 @@ def llistes_pagina(request, logged_in):
"playlists": playlists, "playlists": playlists,
"Pages": Pages, "Pages": Pages,
"menu_selected_id": Pages.Llistes, "menu_selected_id": Pages.Llistes,
"playlist_list_id": "playlist-list",
} }
) )
def llistes_editor_insert_row(request: Request):
new_playlist = playlists_service.create_playlist(name=playlists_model.DEFAULT_PLAYLIST_NAME)
return llistes_editor_row(request, new_playlist)
def llistes_editor_row(request: Request, playlist: playlists_model.Playlist):
return templates.TemplateResponse(
"fragments/llistes/playlist_entry.html",
{
"request": request,
"playlist": playlist,
"logged_in": True,
}
)
def llistes_editor_delete_row(playlist_id: int):
playlists_service.delete_playlist(playlist_id)
from fastapi.responses import HTMLResponse
return HTMLResponse()

View File

@@ -6,6 +6,8 @@ from typing import Self
from folkugat_web.model.temes import Tema from folkugat_web.model.temes import Tema
from folkugat_web.utils import groupby from folkugat_web.utils import groupby
DEFAULT_PLAYLIST_NAME = "Llista de temes"
class PlaylistType(enum.Enum): class PlaylistType(enum.Enum):
SESSION_SETLIST = "session_setlist" SESSION_SETLIST = "session_setlist"

View File

@@ -233,3 +233,12 @@ def set_visibility(playlist_id: int, hidden: bool) -> playlists.Playlist:
# Return updated playlist # Return updated playlist
return dataclasses.replace(playlist, hidden=hidden) return dataclasses.replace(playlist, hidden=hidden)
def create_playlist(name: str | None = None) -> playlists.Playlist:
playlist_id = write.create_playlist(name=name)
return get_playlist(playlist_id=playlist_id)
def delete_playlist(playlist_id: int):
write.delete_playlist(playlist_id=playlist_id)