fix: hide council editing controls from read-only viewers
This commit is contained in:
1 parent
508aae4f8a
commit
3fb174899d
10 files changed
+26
-26
No files matched your search
@@ -8,8 +8,7 @@
|
||||
if (names.includes(previous)) branch.value = previous;
|
||||
});
|
||||
const dialog = document.querySelector('[data-council-dialog]');
|
||||
if (!dialog) return;
|
||||
const form = dialog.querySelector('[data-edit-form]');
|
||||
const form = dialog?.querySelector('[data-edit-form]');
|
||||
const autoSpecialties = form?.querySelector('[data-specialty-auto]');
|
||||
const specialtyCheckboxes = form ? Array.from(form.querySelectorAll('[name="specialty_codes"]')) : [];
|
||||
autoSpecialties?.addEventListener('change', () => {
|
||||
@@ -149,6 +148,7 @@
|
||||
}, true);
|
||||
window.addEventListener('resize', repositionTooltips);
|
||||
|
||||
if (!dialog) return;
|
||||
dialog.querySelectorAll('[data-edit-close]').forEach(button => {
|
||||
button.addEventListener('click', () => { if (!saving) dialog.close(); });
|
||||
});
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
{% if candidate.ambiguous %}<p class="council__hint">Есть сотрудники с одинаковым ФИО. Публикации из данных ВШЭ не присвоены автоматически; показаны записи из личного кабинета этого сотрудника.</p>{% endif %}
|
||||
<ol class="council__articles">
|
||||
{% for article in candidate.articles %}
|
||||
<li class="council__article" tabindex="0" data-council-article aria-label="{{ article.title }}. Нажмите, чтобы показать редактирование">
|
||||
<li class="council__article"{% if can_edit %} tabindex="0" data-council-article aria-label="{{ article.title }}. Нажмите, чтобы показать редактирование"{% endif %}>
|
||||
{% if can_edit %}
|
||||
{% set employee_id = candidate.employee_id %}
|
||||
{% include "council_edit_button.html" %}
|
||||
{% endif %}
|
||||
<div class="council__article-heading">
|
||||
<strong>{{ article.title }}</strong>
|
||||
<span>{{ article.year or 'Год не указан' }}{% set field = 'year' %}{% set label = 'год публикации' %}{% include 'council_warning.html' %}</span>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% if can_edit %}
|
||||
<dialog class="columns-modal" data-council-dialog aria-labelledby="article-edit-title">
|
||||
<div class="columns-modal__panel">
|
||||
<div class="columns-modal__header">
|
||||
<h3 class="columns-modal__title" id="article-edit-title">Редактирование статьи</h3>
|
||||
<button class="button button--ghost" type="button" data-edit-close aria-label="Закрыть редактирование">✕</button>
|
||||
</div>
|
||||
{% if can_edit %}
|
||||
<form class="council-editor" data-edit-form>
|
||||
<label class="directory__field" for="article-edit-name">Название статьи
|
||||
<textarea class="directory__input" id="article-edit-name" name="title" required maxlength="2000" rows="3"></textarea>
|
||||
@@ -37,9 +37,6 @@
|
||||
</div>
|
||||
</form>
|
||||
<datalist id="council-journals">{% for name in journal_names|default([]) %}<option value="{{ name }}">{% endfor %}</datalist>
|
||||
{% else %}
|
||||
<p>Для редактирования статей и квартилей войдите в систему.</p>
|
||||
<a class="button" href="/admin/login">Войти в систему</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</dialog>
|
||||
{% endif %}
|
||||
@@ -18,11 +18,10 @@
|
||||
<div class="council__message" role="alert"><h3>Не удалось загрузить публикации</h3><p>Попробуйте ещё раз позже.</p><a class="admin__link" href="{{ request.url.path }}?{{ request.url.query }}">Повторить загрузку</a></div>
|
||||
{% else %}
|
||||
<p class="council__hint" role="status">Найдено статей: {{ matched }}{% if matched %} · Показаны {{ offset + 1 }}–{{ [offset + limit, matched]|min }}{% endif %}</p>
|
||||
{% if not can_edit %}<p class="council__hint">Просмотр доступен без входа. Для сохранения изменений <a class="admin__link" href="/admin/login">войдите в систему</a>.</p>{% endif %}
|
||||
<ol class="council__articles council__articles--editor" start="{{ offset + 1 }}">
|
||||
{% for article in articles %}
|
||||
<li class="council__article" tabindex="0" data-council-article aria-label="{{ article.title }}. Нажмите, чтобы показать редактирование">
|
||||
{% set employee_id = article.employee_id %}{% include "council_edit_button.html" %}
|
||||
<li class="council__article"{% if can_edit %} tabindex="0" data-council-article aria-label="{{ article.title }}. Нажмите, чтобы показать редактирование"{% endif %}>
|
||||
{% if can_edit %}{% set employee_id = article.employee_id %}{% include "council_edit_button.html" %}{% endif %}
|
||||
<p class="council__hint">{{ article.employee_name }}</p>
|
||||
<div class="council__article-heading"><strong>{{ article.title }}</strong><span>{{ article.year or 'Год не указан' }}{% set field = 'year' %}{% set label = 'год публикации' %}{% include 'council_warning.html' %}</span></div>
|
||||
<p class="council__hint">{{ article.display_type }}{% set field = 'type' %}{% set label = 'тип материала' %}{% include 'council_warning.html' %}</p>
|
||||
|
||||
+3
-3
@@ -1,3 +1,3 @@
|
||||
APP_VERSION = "2.0.0"
|
||||
FRONTEND_VERSION = "2.0.0"
|
||||
BACKEND_VERSION = "2.0.0"
|
||||
APP_VERSION = "2.0.1"
|
||||
FRONTEND_VERSION = "2.0.1"
|
||||
BACKEND_VERSION = "2.0.1"
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "miem-workers"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
description = "MIEM employees parser, admin API, and web admin"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
@@ -66,16 +66,11 @@ def main():
|
||||
page.on('pageerror', lambda error: errors.append(str(error)))
|
||||
page.goto('http://miem.test/admin/council')
|
||||
page.locator('.council__candidate-summary').click()
|
||||
expect(page.locator('.council__article strong')).to_have_text('Исследование передачи данных')
|
||||
expect(page.locator('[data-council-edit]')).to_have_count(0)
|
||||
expect(page.locator('[data-council-dialog]')).to_have_count(0)
|
||||
article = page.locator('[data-council-article]')
|
||||
pencil = article.locator('[data-council-edit]')
|
||||
expect(pencil).to_be_hidden()
|
||||
article.locator('strong').click()
|
||||
expect(pencil).to_be_visible()
|
||||
pencil.click()
|
||||
expect(page.get_by_role('dialog')).to_be_visible()
|
||||
expect(page.get_by_role('link', name='Войти в систему', exact=True)).to_be_visible()
|
||||
page.keyboard.press('Escape')
|
||||
expect(pencil).to_be_focused()
|
||||
client.cookies.set(SESSION_COOKIE, sign_session('admin', settings))
|
||||
page.reload()
|
||||
page.locator('.council__candidate-summary').click()
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ def test_health_returns_versions():
|
||||
response = TestClient(app).get("/api/health")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json()["backend_version"] == "2.0.0"
|
||||
assert response.json()["backend_version"] == "2.0.1"
|
||||
|
||||
|
||||
def test_api_employees_and_stats_require_admin_session():
|
||||
|
||||
@@ -230,7 +230,7 @@ def test_public_page_data_minimization_and_safe_links(db_session, export):
|
||||
assert "javascript:" not in fragment.text and "private@example.org" not in fragment.text
|
||||
assert "javascript:" not in response.text and "private@example.org" not in response.text
|
||||
assert "/admin/employees/" not in response.text and "/admin/logout" not in response.text
|
||||
assert "Backend 2.0.0 · Frontend 2.0.0" in response.text
|
||||
assert "Backend 2.0.1 · Frontend 2.0.1" in response.text
|
||||
assert "Вход в систему" in response.text
|
||||
assert client.get("/admin/directory", follow_redirects=False).status_code in (302, 303, 401, 403)
|
||||
assert "Сотрудники не найдены" in client.get("/admin/council?q=missing").text
|
||||
|
||||
@@ -82,8 +82,15 @@ def test_editor_permissions_csrf_validation_and_missing_article(editor, db_sessi
|
||||
assert db_session.get(CouncilCorrections, 1) is None
|
||||
client.cookies.clear()
|
||||
assert save(client, payload).status_code == 401
|
||||
original_title = db_session.scalar(select(EmployeePublication.title).where(
|
||||
EmployeePublication.employee_id == payload['employee_id']))
|
||||
response = client.get('/admin/council/publications')
|
||||
assert response.status_code == 200 and 'Для редактирования' in response.text
|
||||
assert response.status_code == 200
|
||||
assert original_title in response.text
|
||||
assert 'data-council-edit' not in response.text and 'data-council-dialog' not in response.text
|
||||
fragment = client.get(f"/admin/council/employees/{payload['employee_id']}/articles")
|
||||
assert fragment.status_code == 200 and original_title in fragment.text
|
||||
assert 'data-council-article' not in fragment.text and 'data-council-edit' not in fragment.text
|
||||
|
||||
|
||||
def test_editor_journal_reassignment_year_scope_and_unknown_year(editor, db_session):
|
||||
|
||||
Reference in new issue
Block a user