This commit is contained in:
Mateusz Gruszczyński
2025-09-14 12:41:49 +02:00
parent 554340dd64
commit ec200a3819
5 changed files with 85 additions and 65 deletions

27
app.py
View File

@@ -3518,9 +3518,10 @@ def add_suggestion():
@app.route("/admin/lists-access", methods=["GET", "POST"])
@app.route("/admin/lists-access/<int:list_id>", methods=["GET", "POST"])
@login_required
@admin_required
def admin_lists_access():
def admin_lists_access(list_id=None):
try:
page = int(request.args.get("page", 1))
except ValueError:
@@ -3535,6 +3536,19 @@ def admin_lists_access():
ShoppingList.created_at.desc()
)
if list_id is not None:
target_list = db.session.get(ShoppingList, list_id)
if not target_list:
flash("Lista nie istnieje.", "danger")
return redirect(url_for("admin_lists_access"))
lists = [target_list]
list_ids = [list_id]
pagination = None
else:
pagination = q.paginate(page=page, per_page=per_page, error_out=False)
lists = pagination.items
list_ids = [l.id for l in lists]
if request.method == "POST":
action = request.form.get("action")
target_list_id = request.form.get("target_list_id", type=int)
@@ -3575,9 +3589,9 @@ def admin_lists_access():
if action == "save_changes":
ids = request.form.getlist("visible_ids", type=int)
if ids:
lists = ShoppingList.query.filter(ShoppingList.id.in_(ids)).all()
lists_edit = ShoppingList.query.filter(ShoppingList.id.in_(ids)).all()
posted = request.form
for l in lists:
for l in lists_edit:
l.is_public = posted.get(f"is_public_{l.id}") is not None
l.is_temporary = posted.get(f"is_temporary_{l.id}") is not None
l.is_archived = posted.get(f"is_archived_{l.id}") is not None
@@ -3585,10 +3599,6 @@ def admin_lists_access():
flash("Zapisano zmiany statusów.", "success")
return redirect(request.url)
pagination = q.paginate(page=page, per_page=per_page, error_out=False)
lists = pagination.items
list_ids = [l.id for l in lists]
perms = (
db.session.query(
ListPermission.list_id,
@@ -3613,8 +3623,9 @@ def admin_lists_access():
permitted_by_list=permitted_by_list,
page=page,
per_page=per_page,
total_pages=pagination.pages or 1,
total_pages=pagination.pages if pagination else 1,
query_string=query_string,
list_id=list_id,
)

View File

@@ -139,6 +139,7 @@
</div>
</div>
{% if not list_id %}
<hr>
<div class="d-flex justify-content-between align-items-center mt-4">
<form method="get" class="d-flex align-items-center">
@@ -170,4 +171,6 @@
</ul>
</nav>
</div>
{% endif %}
{% endblock %}

View File

@@ -122,6 +122,11 @@
<div class="mb-4 border-top pt-3 mt-4">
<h5 class="mb-3">🔐 Użytkownicy z dostępem</h5>
<a class="btn btn-outline-warning btn-sm mb-3"
href="{{ url_for('admin_lists_access', list_id=list.id) }}">
⚙️ Edytuj uprawnienia (admin)
</a>
{% if permitted_users %}
<ul class="list-group list-group-flush mb-3">
{% for u in permitted_users %}

View File

@@ -96,65 +96,67 @@
<!-- DOSTĘP DO LISTY -->
<div class="card bg-secondary bg-opacity-10 text-white mb-5">
<h5 class="mb-3">🔐 Dostęp do listy</h5>
<div class="card-body">
<h5 class="mb-3">🔐 Dostęp do listy</h5>
<!-- Link udostępniania -->
<div class="mb-4">
<label class="form-label">🔗 Link udostępniania (wejście przez link daje dostęp; zalogowani dostają
uprawnienia na stałę po kliknięciu w link)</label>
<!-- Link udostępniania -->
<div class="mb-4">
<label class="form-label">🔗 Link udostępniania (wejście przez link daje dostęp; zalogowani dostają
uprawnienia na stałę po kliknięciu w link)</label>
{% if list.share_token %}
<div class="input-group mb-3">
<input type="text" class="form-control bg-dark text-white border-secondary"
readonly value="{{ url_for('shared_list', token=list.share_token, _external=True) }}"
id="sharedListUrl" aria-label="Udostępniony link">
<a class="btn btn-outline-light" href="{{ url_for('shared_list', token=list.share_token) }}" target="_blank"
title="Otwórz">
</a>
</div>
{% else %}
<div class="text-warning small">Brak tokenu udostępniania.</div>
{% endif %}
<div class="text-info small">Ustawienie „🌐 Publiczna” nie jest wymagane dla dostępu z linku.</div>
</div>
<form method="post" class="m-0">
<div class="row g-3 align-items-end mb-4">
<div class="col-md-6">
<label for="grant_username" class="form-label"> Nadaj dostęp użytkownikowi (login)</label>
<input type="text" name="grant_username" id="grant_username"
class="form-control bg-dark text-white border-secondary rounded" placeholder="np. marek">
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-outline-light w-100"> Dodaj</button>
</div>
<!-- opcjonalnie, żeby rozróżnić akcje po stronie serwera -->
<input type="hidden" name="action" value="grant">
<!-- opcjonalnie zachowanie powrotu -->
<input type="hidden" name="next" value="{{ request.path }}">
</div>
</form>
<!-- Lista uprawnionych -->
<div class="mb-3">
<label class="form-label">👥 Użytkownicy z dostępem</label>
{% if permitted_users and permitted_users|length > 0 %}
<ul class="list-group list-group-flush">
{% for u in permitted_users %}
<li class="list-group-item bg-dark text-white d-flex justify-content-between align-items-center border-secondary">
<div>
<span class="fw-semibold">@{{ u.username }}</span>
{% if list.share_token %}
<div class="input-group mb-3">
<input type="text" class="form-control bg-dark text-white border-secondary"
readonly value="{{ url_for('shared_list', token=list.share_token, _external=True) }}"
id="sharedListUrl" aria-label="Udostępniony link">
<a class="btn btn-outline-light" href="{{ url_for('shared_list', token=list.share_token) }}" target="_blank"
title="Otwórz">Otwórz
</a>
</div>
<form method="post" onsubmit="return confirm('Odebrać dostęp użytkownikowi @{{ u.username }}?');">
<input type="hidden" name="revoke_user_id" value="{{ u.id }}">
<button type="submit" class="btn btn-sm btn-outline-danger">🚫 Odbierz</button>
</form>
</li>
{% endfor %}
</ul>
{% else %}<br>
<div class="text-warning small">Brak dodanych uprawnień.</div>
{% endif %}
{% else %}
<div class="text-warning small">Brak tokenu udostępniania.</div>
{% endif %}
<div class="text-info small">Ustawienie „🌐 Publiczna” nie jest wymagane dla dostępu z linku.</div>
</div>
<form method="post" class="m-0">
<div class="row g-3 align-items-end mb-4">
<div class="col-md-6">
<label for="grant_username" class="form-label"> Nadaj dostęp użytkownikowi (login)</label>
<input type="text" name="grant_username" id="grant_username"
class="form-control bg-dark text-white border-secondary rounded" placeholder="np. marek">
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-outline-light w-100"> Dodaj</button>
</div>
<!-- opcjonalnie, żeby rozróżnić akcje po stronie serwera -->
<input type="hidden" name="action" value="grant">
<!-- opcjonalnie zachowanie powrotu -->
<input type="hidden" name="next" value="{{ request.path }}">
</div>
</form>
<!-- Lista uprawnionych -->
<div class="mb-3">
<label class="form-label">👥 Użytkownicy z dostępem</label>
{% if permitted_users and permitted_users|length > 0 %}
<ul class="list-group list-group-flush">
{% for u in permitted_users %}
<li class="list-group-item bg-dark text-white d-flex justify-content-between align-items-center border-secondary">
<div>
<span class="fw-semibold">@{{ u.username }}</span>
</div>
<form method="post" onsubmit="return confirm('Odebrać dostęp użytkownikowi @{{ u.username }}?');">
<input type="hidden" name="revoke_user_id" value="{{ u.id }}">
<button type="submit" class="btn btn-sm btn-outline-danger">🚫 Odbierz uprawnienia</button>
</form>
</li>
{% endfor %}
</ul>
{% else %}<br>
<div class="text-warning small">Brak dodanych uprawnień.</div>
{% endif %}
</div>
</div>
</div>

View File

@@ -63,7 +63,6 @@
Nadaj dostęp
</a>
</div>
</div>
</div>