rozszerzone uprawnienia
This commit is contained in:
@@ -1,179 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Zarządzanie dostępem do list{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
|
||||
<h2 class="mb-2">🔐{% if list_id %} Zarządzanie dostępem listy #{{ list_id }}{% else %} Zarządzanie dostępem do list {% endif %}</h2>
|
||||
<div>
|
||||
{% if list_id %}
|
||||
<a href="{{ url_for('admin_lists_access') }}" class="btn btn-outline-light me-2">Powrót do wszystkich list</a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('admin_panel') }}" class="btn btn-outline-secondary">← Powrót do panelu</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-dark text-white mb-5">
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="save_changes">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark align-middle sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Nazwa listy</th>
|
||||
<th scope="col">Właściciel</th>
|
||||
<th scope="col">Utworzono</th>
|
||||
<th scope="col">Statusy</th>
|
||||
<th scope="col">Udostępnianie</th>
|
||||
<th scope="col">Uprawnienia</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for l in lists %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ l.id }}
|
||||
<input type="hidden" name="visible_ids" value="{{ l.id }}">
|
||||
</td>
|
||||
|
||||
<td class="fw-bold align-middle">
|
||||
<a href="{{ url_for('view_list', list_id=l.id) }}" class="text-white">{{ l.title }}</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if l.owner %}
|
||||
👤 {{ l.owner.username }} ({{ l.owner.id }})
|
||||
{% else %}-{% endif %}
|
||||
</td>
|
||||
|
||||
<td>{{ l.created_at.strftime('%Y-%m-%d %H:%M') if l.created_at else '-' }}</td>
|
||||
|
||||
<td style="min-width: 220px;">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="pub_{{ l.id }}"
|
||||
name="is_public_{{ l.id }}" {% if l.is_public %}checked{% endif %}>
|
||||
<label class="form-check-label" for="pub_{{ l.id }}">🌐 Publiczna</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="tmp_{{ l.id }}"
|
||||
name="is_temporary_{{ l.id }}" {% if l.is_temporary %}checked{% endif %}>
|
||||
<label class="form-check-label" for="tmp_{{ l.id }}">⏳ Tymczasowa</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="arc_{{ l.id }}"
|
||||
name="is_archived_{{ l.id }}" {% if l.is_archived %}checked{% endif %}>
|
||||
<label class="form-check-label" for="arc_{{ l.id }}">📦 Archiwalna</label>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td style="min-width: 220px;">
|
||||
{% if l.share_token %}
|
||||
{% set share_url = url_for('shared_list', token=l.share_token, _external=True) %}
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<div class="flex-grow-1 text-truncate mono" title="{{ share_url }}">
|
||||
{{ share_url }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-info small">
|
||||
{% if l.is_public %}Lista widoczna publicznie{% else %}Lista dostępna przez
|
||||
link/uprawnienia{%
|
||||
endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-warning small">Brak tokenu</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td style="min-width: 320px;">
|
||||
<ul class="list-group list-group-flush mb-2">
|
||||
{% for u in permitted_by_list.get(l.id, []) %}
|
||||
<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" class="m-0"
|
||||
onsubmit="return confirm('Odebrać dostęp @{{ u.username }}?');">
|
||||
<input type="hidden" name="action" value="revoke">
|
||||
<input type="hidden" name="target_list_id" value="{{ l.id }}">
|
||||
<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 %}
|
||||
{% if permitted_by_list.get(l.id, [])|length == 0 %}
|
||||
<li class="list-group-item bg-dark text-white border-secondary">
|
||||
<div class="text-warning small">Brak dodanych uprawnień.</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<!-- Nadawanie dostępu -->
|
||||
<form method="post" class="m-0">
|
||||
<input type="hidden" name="action" value="grant">
|
||||
<input type="hidden" name="target_list_id" value="{{ l.id }}">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" name="grant_username"
|
||||
class="form-control bg-dark text-white border-secondary"
|
||||
placeholder="nazwa użytkownika">
|
||||
<button type="submit" class="btn btn-outline-light">➕ Dodaj</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if lists|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-4">Brak list do wyświetlenia</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<button type="submit" class="btn btn-sm btn-outline-light">💾 Zapisz zmiany</button>
|
||||
</div>
|
||||
</form>
|
||||
</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">
|
||||
<label for="per_page" class="me-2">🔢 Pozycji na stronę:</label>
|
||||
<select id="per_page" name="per_page" class="form-select form-select-sm me-2"
|
||||
onchange="this.form.page.value = 1; this.form.submit();">
|
||||
<option value="25" {% if per_page==25 %}selected{% endif %}>25</option>
|
||||
<option value="50" {% if per_page==50 %}selected{% endif %}>50</option>
|
||||
<option value="100" {% if per_page==100 %}selected{% endif %}>100</option>
|
||||
</select>
|
||||
<input type="hidden" name="page" value="{{ page }}">
|
||||
</form>
|
||||
|
||||
<nav aria-label="Nawigacja stron">
|
||||
<ul class="pagination pagination-dark mb-0">
|
||||
<li class="page-item {% if page <= 1 %}disabled{% endif %}">
|
||||
<a class="page-link"
|
||||
href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ page - 1 }}">«</a>
|
||||
</li>
|
||||
{% for p in range(1, total_pages + 1) %}
|
||||
<li class="page-item {% if p == page %}active{% endif %}">
|
||||
<a class="page-link" href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ p }}">{{ p }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="page-item {% if page >= total_pages %}disabled{% endif %}">
|
||||
<a class="page-link"
|
||||
href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ page + 1 }}">»</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
220
templates/admin/lists_access.html
Normal file
220
templates/admin/lists_access.html
Normal file
@@ -0,0 +1,220 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Zarządzanie dostępem do list{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap mb-3">
|
||||
<h2 class="mb-2">🔐{% if list_id %} Zarządzanie dostępem listy #{{ list_id }}{% else %} Zarządzanie dostępem do list
|
||||
{% endif %}</h2>
|
||||
<div class="d-flex gap-2">
|
||||
{% if list_id %}
|
||||
<a href="{{ url_for('admin_lists_access') }}" class="btn btn-outline-light">Powrót do wszystkich list</a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('admin_panel') }}" class="btn btn-outline-secondary">← Powrót do panelu</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- STICKY ACTION BAR -->
|
||||
<div id="bulkBar" class="position-sticky top-0 z-3 mb-3" style="backdrop-filter: blur(6px);">
|
||||
<div class="card bg-dark border-secondary shadow-sm">
|
||||
<div class="card-body py-2 d-flex flex-wrap align-items-center gap-3">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<input id="selectAll" class="form-check-input" type="checkbox" />
|
||||
<label for="selectAll" class="form-check-label">Zaznacz wszystko</label>
|
||||
</div>
|
||||
|
||||
<div class="vr text-secondary"></div>
|
||||
|
||||
<div class="flex-grow-1 d-flex align-items-center gap-2">
|
||||
<input id="listFilter" class="form-control form-control-sm bg-dark text-white border-secondary"
|
||||
placeholder="Szukaj po tytule/ID/właścicielu…" aria-label="Filtruj listy">
|
||||
<span class="text-secondary small ms-1" id="filterCount">—</span>
|
||||
</div>
|
||||
|
||||
<div class="vr text-secondary d-none d-md-block"></div>
|
||||
|
||||
<!-- BULK GRANT -->
|
||||
<div class="flex-grow-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<input id="bulkUsersInput" class="form-control bg-dark text-white border-secondary"
|
||||
placeholder="Podaj użytkowników (po przecinku lub enterach)" list="userHints">
|
||||
<button id="bulkAddBtn" class="btn btn-outline-light" type="button">➕ Nadaj dostęp</button>
|
||||
</div>
|
||||
<div id="bulkTokens" class="d-flex flex-wrap gap-2 mt-2"></div>
|
||||
</div>
|
||||
|
||||
<div class="vr text-secondary d-none d-md-block"></div>
|
||||
|
||||
<!-- ZAPISZ – ten sam poziom co reszta -->
|
||||
<div class="d-flex align-items-center gap-2 flex-shrink-0">
|
||||
<button form="statusForm" type="submit" class="btn btn-sm btn-outline-light">
|
||||
💾 Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- HINTS -->
|
||||
<datalist id="userHints"></datalist>
|
||||
|
||||
<div class="card bg-dark text-white mb-5">
|
||||
<div class="card-body">
|
||||
<form id="statusForm" method="post">
|
||||
<input type="hidden" name="action" value="save_changes">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark align-middle" id="listsTable">
|
||||
<thead class="align-middle">
|
||||
<tr>
|
||||
<th scope="col" style="width:36px;"></th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Nazwa listy</th>
|
||||
<th scope="col">Właściciel</th>
|
||||
<th scope="col">Utworzono</th>
|
||||
<th scope="col">Statusy</th>
|
||||
<th scope="col">Udostępnianie</th>
|
||||
<th scope="col" style="min-width: 340px;">Uprawnienia</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for l in lists %}
|
||||
<tr data-id="{{ l.id }}" data-title="{{ l.title|lower }}"
|
||||
data-owner="{{ (l.owner.username if l.owner else '-')|lower }}">
|
||||
<td>
|
||||
<input class="row-check form-check-input" type="checkbox" data-list-id="{{ l.id }}">
|
||||
<input type="hidden" name="visible_ids" value="{{ l.id }}">
|
||||
</td>
|
||||
|
||||
<td class="text-nowrap">#{{ l.id }}</td>
|
||||
|
||||
<td class="fw-bold align-middle">
|
||||
<a href="{{ url_for('view_list', list_id=l.id) }}" class="text-white text-decoration-none">{{ l.title
|
||||
}}</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if l.owner %}
|
||||
👤 <span class="owner-username" data-username="{{ l.owner.username }}">@{{ l.owner.username }}</span>
|
||||
({{ l.owner.id }})
|
||||
{% else %}-{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="text-nowrap">{{ l.created_at.strftime('%Y-%m-%d %H:%M') if l.created_at else '-' }}</td>
|
||||
|
||||
<td style="min-width: 230px;">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="pub_{{ l.id }}" name="is_public_{{ l.id }}" {% if
|
||||
l.is_public %}checked{% endif %}>
|
||||
<label class="form-check-label" for="pub_{{ l.id }}">🌐 Publiczna</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="tmp_{{ l.id }}" name="is_temporary_{{ l.id }}" {%
|
||||
if l.is_temporary %}checked{% endif %}>
|
||||
<label class="form-check-label" for="tmp_{{ l.id }}">⏳ Tymczasowa</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="arc_{{ l.id }}" name="is_archived_{{ l.id }}" {%
|
||||
if l.is_archived %}checked{% endif %}>
|
||||
<label class="form-check-label" for="arc_{{ l.id }}">📦 Archiwalna</label>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td style="min-width: 260px;">
|
||||
{% if l.share_token %}
|
||||
{% set share_url = url_for('shared_list', token=l.share_token, _external=True) %}
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<div class="flex-grow-1 text-truncate mono small" title="{{ share_url }}">{{ share_url }}</div>
|
||||
<button class="btn btn-sm btn-outline-secondary copy-share" type="button" data-url="{{ share_url }}"
|
||||
aria-label="Kopiuj link">📋</button>
|
||||
</div>
|
||||
<div class="text-info small mt-1">
|
||||
{% if l.is_public %}Lista widoczna publicznie{% else %}Dostęp przez link / uprawnienia{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-warning small">Brak tokenu</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="access-editor" data-list-id="{{ l.id }}">
|
||||
<!-- Tokeny z uprawnieniami -->
|
||||
<div class="d-flex flex-wrap gap-2 mb-2 tokens">
|
||||
{% for u in permitted_by_list.get(l.id, []) %}
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary rounded-pill token"
|
||||
data-user-id="{{ u.id }}" data-username="{{ u.username }}" title="Kliknij, aby odebrać dostęp">
|
||||
@{{ u.username }} <span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% if permitted_by_list.get(l.id, [])|length == 0 %}
|
||||
<span class="text-warning small no-perms">Brak dodanych uprawnień.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Dodawanie (wiele na raz) -->
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text"
|
||||
class="form-control form-control-sm bg-dark text-white border-secondary access-input"
|
||||
placeholder="Dodaj @użytkownika (wiele: przecinki/enter)" list="userHints"
|
||||
aria-label="Dodaj użytkowników">
|
||||
<button type="button" class="btn btn-sm btn-outline-light access-add">➕ Dodaj</button>
|
||||
</div>
|
||||
<div class="text-secondary small mt-1">Kliknij token, aby odebrać dostęp.</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if lists|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="8" class="text-center py-4">Brak list do wyświetlenia</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 d-flex justify-content-end">
|
||||
<button type="submit" class="btn btn-sm btn-outline-light">💾 Zapisz zmiany statusów</button>
|
||||
</div>
|
||||
</form>
|
||||
</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">
|
||||
<label for="per_page" class="me-2">🔢 Pozycji na stronę:</label>
|
||||
<select id="per_page" name="per_page" class="form-select form-select-sm me-2"
|
||||
onchange="this.form.page.value = 1; this.form.submit();">
|
||||
<option value="25" {% if per_page==25 %}selected{% endif %}>25</option>
|
||||
<option value="50" {% if per_page==50 %}selected{% endif %}>50</option>
|
||||
<option value="100" {% if per_page==100 %}selected{% endif %}>100</option>
|
||||
</select>
|
||||
<input type="hidden" name="page" value="{{ page }}">
|
||||
</form>
|
||||
|
||||
<nav aria-label="Nawigacja stron">
|
||||
<ul class="pagination pagination-dark mb-0">
|
||||
<li class="page-item {% if page <= 1 %}disabled{% endif %}">
|
||||
<a class="page-link" href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ page - 1 }}">«</a>
|
||||
</li>
|
||||
{% for p in range(1, total_pages + 1) %}
|
||||
<li class="page-item {% if p == page %}active{% endif %}">
|
||||
<a class="page-link" href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ p }}">{{ p }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="page-item {% if page >= total_pages %}disabled{% endif %}">
|
||||
<a class="page-link" href="?{{ query_string }}{% if query_string %}&{% endif %}page={{ page + 1 }}">»</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='lists_access.js') }}?v={{ APP_VERSION }}"></script>
|
||||
|
||||
{% endblock %}
|
@@ -95,67 +95,33 @@
|
||||
</div>
|
||||
|
||||
<!-- DOSTĘP DO LISTY -->
|
||||
<div class="card bg-secondary bg-opacity-10 text-white mb-5">
|
||||
<div class="card-body">
|
||||
<h5 class="mb-3">🔐 Dostęp do listy</h5>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">👥 Użytkownicy z dostępem</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>
|
||||
<div class="access-editor border rounded p-2 bg-dark" data-post-url="{{ request.path }}"
|
||||
data-suggest-url="{{ url_for('edit_my_list_suggestions', list_id=list.id) }}" data-next="{{ request.path }}"
|
||||
data-list-id="{{ list.id }}">
|
||||
|
||||
{% 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>
|
||||
{% 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>
|
||||
<input type="hidden" name="action" value="grant">
|
||||
<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>
|
||||
<!-- Tokeny uprawnionych -->
|
||||
<div class="tokens d-flex flex-wrap gap-2 mb-2">
|
||||
{% for u in permitted_users %}
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary rounded-pill token" data-user-id="{{ u.id }}"
|
||||
data-username="{{ u.username }}" title="Kliknij, aby odebrać dostęp">
|
||||
@{{ u.username }} <span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% if not permitted_users or permitted_users|length == 0 %}
|
||||
<span class="no-perms text-warning small">Brak dodanych uprawnień.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Dodawanie (wiele: przecinki/enter) + prywatne podpowiedzi -->
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="access-input form-control form-control-sm bg-dark text-white border-secondary"
|
||||
placeholder="Dodaj @użytkownika (wiele: przecinki/enter)" aria-label="Dodaj użytkowników">
|
||||
<button type="button" class="access-add btn btn-sm btn-outline-light">➕ Dodaj</button>
|
||||
</div>
|
||||
<div class="text-secondary small mt-1">Kliknij token, aby odebrać dostęp.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -282,4 +248,5 @@
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='user_receipt_crop.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='receipt_crop_logic.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='select.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='access_users.js') }}?v={{ APP_VERSION }}"></script>
|
||||
{% endblock %}
|
@@ -244,31 +244,48 @@
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content bg-dark text-white">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="grantAccessModalLabel">Nadaj dostęp użytkownikowi</h5>
|
||||
<h5 class="modal-title" id="grantAccessModalLabel">Nadaj dostęp użytkownikom</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Zamknij"></button>
|
||||
</div>
|
||||
<form method="post" action="{{ url_for('list_settings', list_id=list.id) }}" class="m-0">
|
||||
<div class="modal-body">
|
||||
<label for="grant_username" class="form-label">👥 Login użytkownika</label>
|
||||
<input type="text" name="grant_username" id="grant_username"
|
||||
class="form-control bg-dark text-white border-secondary rounded" placeholder="np. marek" required>
|
||||
|
||||
<input type="hidden" name="action" value="grant_access">
|
||||
<input type="hidden" name="next" value="{{ url_for('view_list', list_id=list.id) }}">
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="access-editor border rounded p-2 bg-dark"
|
||||
data-post-url="{{ url_for('list_settings', list_id=list.id) }}"
|
||||
data-suggest-url="{{ url_for('edit_my_list_suggestions', list_id=list.id) }}"
|
||||
data-next="{{ url_for('view_list', list_id=list.id) }}" data-list-id="{{ list.id }}"
|
||||
data-grant-action="grant_access" data-revoke-field="revoke_user_id">
|
||||
|
||||
<div class="modal-footer justify-content-end">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-sm btn-outline-light" data-bs-dismiss="modal">❌ Anuluj</button>
|
||||
<button type="submit" class="btn btn-sm btn-outline-light">💾 Zapisz</button>
|
||||
<!-- Tokeny aktualnie uprawnionych -->
|
||||
<div class="tokens d-flex flex-wrap gap-2 mb-2">
|
||||
{% for u in permitted_users %}
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary rounded-pill token" data-user-id="{{ u.id }}"
|
||||
data-username="{{ u.username }}" title="Kliknij, aby odebrać dostęp">
|
||||
@{{ u.username }} <span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% if not permitted_users or permitted_users|length == 0 %}
|
||||
<span class="no-perms text-warning small">Brak dodanych uprawnień.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Dodawanie wielu na raz + podpowiedzi prywatne -->
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="access-input form-control form-control-sm bg-dark text-white border-secondary"
|
||||
placeholder="Dodaj @użytkownika (wiele: przecinki/enter)" aria-label="Dodaj użytkowników">
|
||||
<button type="button" class="access-add btn btn-sm btn-outline-light">➕ Dodaj</button>
|
||||
</div>
|
||||
<div class="text-secondary small mt-1">Kliknij token, aby odebrać dostęp.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer justify-content-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-light" data-bs-dismiss="modal">Zamknij</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade" id="massAddModal" tabindex="-1" aria-labelledby="massAddModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content bg-dark text-white">
|
||||
@@ -285,7 +302,7 @@
|
||||
<ul id="mass-add-list" class="list-group"></ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-light btn-sm" data-bs-dismiss="modal">Zamknij</button>
|
||||
<button type="button" class="btn btn-outline-light btn-sm w-100" data-bs-dismiss="modal">Zamknij</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -302,7 +319,7 @@
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='mass_add.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='receipt_upload.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='sort_mode.js') }}?v={{ APP_VERSION }}"></script>
|
||||
|
||||
<script src="{{ url_for('static_bp.serve_js', filename='access_users.js') }}?v={{ APP_VERSION }}"></script>
|
||||
<script>
|
||||
setupList({{ list.id }}, '{{ current_user.username if current_user.is_authenticated else 'Gość' }}');
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user