Show effective access roles in HTML5 workspace
This commit is contained in:
@@ -70,7 +70,8 @@ def render_html5_access_page(
|
||||
<div class="panel-title">Группы доступа</div>
|
||||
<div class="access-list">{''.join(_group_card(item) for item in groups[:80]) or '<p class="muted padded">Группы не найдены</p>'}</div>
|
||||
<div class="panel-title">Пользователи</div>
|
||||
<div class="access-list">{''.join(_user_card(item) for item in users[:80]) or '<p class="muted padded">Пользователи не найдены</p>'}</div>
|
||||
<div data-html5-access-user-detail>{render_html5_access_user_detail(project_id=project_id, user_payload=None)}</div>
|
||||
<div class="access-list">{''.join(_user_card(project_id, item) for item in users[:80]) or '<p class="muted padded">Пользователи не найдены</p>'}</div>
|
||||
</aside>
|
||||
</section>
|
||||
</main>
|
||||
@@ -157,6 +158,35 @@ def render_html5_access_profile_apply_result(*, project_id: str, response: objec
|
||||
"""
|
||||
|
||||
|
||||
def render_html5_access_user_detail(*, project_id: str, user_payload: dict | None) -> str:
|
||||
if user_payload is None:
|
||||
return """
|
||||
<section class="access-user-detail">
|
||||
<p class="muted padded">Выберите пользователя, чтобы увидеть группы и эффективные роли.</p>
|
||||
</section>
|
||||
"""
|
||||
user = dict(user_payload.get("user") or {})
|
||||
roles = list(user_payload.get("effective_roles") or [])
|
||||
groups = list(user.get("groups") or [])
|
||||
name = str(user.get("name") or "")
|
||||
full_name = str(user.get("full_name") or "")
|
||||
return f"""
|
||||
<section class="access-user-detail" data-html5-access-user="{escape(name)}">
|
||||
<div class="access-plan-head">
|
||||
<span class="status-pill">пользователь</span>
|
||||
<strong>{escape(name)}</strong>
|
||||
</div>
|
||||
<p class="object-summary">{escape(full_name or "ФИО не загружено")}</p>
|
||||
<div class="report-grid">
|
||||
{_metric("Группы", len(groups))}
|
||||
{_metric("Эффективные роли", len(roles))}
|
||||
</div>
|
||||
{_notice_list("Группы пользователя", groups)}
|
||||
<div class="access-role-grid">{''.join(_role_card(_DictRole(item)) for item in roles) or '<p class="muted padded">Эффективные роли не найдены</p>'}</div>
|
||||
</section>
|
||||
"""
|
||||
|
||||
|
||||
def render_html5_access_profile(*, project_id: str, profile: object | None) -> str:
|
||||
if profile is None:
|
||||
return """
|
||||
@@ -308,11 +338,21 @@ def _group_card(group: object) -> str:
|
||||
return f'<article class="access-card"><strong>{escape(name)}</strong><small>{escape(profile)} · {len(users)} пользователей</small></article>'
|
||||
|
||||
|
||||
def _user_card(user: object) -> str:
|
||||
def _user_card(project_id: str, user: object) -> str:
|
||||
name = str(getattr(user, "name", ""))
|
||||
full_name = str(getattr(user, "full_name", "") or "")
|
||||
groups = list(getattr(user, "groups", []) or [])
|
||||
return f'<article class="access-card"><strong>{escape(name)}</strong><small>{escape(full_name)} · {len(groups)} групп</small></article>'
|
||||
return f"""
|
||||
<article
|
||||
class="access-card"
|
||||
hx-get="/html5/projects/{quote(project_id)}/access/users/{quote(name, safe='')}"
|
||||
hx-target="[data-html5-access-user-detail]"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<strong>{escape(name)}</strong>
|
||||
<small>{escape(full_name)} · {len(groups)} групп</small>
|
||||
</article>
|
||||
"""
|
||||
|
||||
|
||||
def _operation_card(operation: dict) -> str:
|
||||
@@ -359,3 +399,10 @@ class _DictProfile:
|
||||
self.roles = payload.get("roles") or []
|
||||
self.attributes = payload.get("attributes") or {}
|
||||
self.source = payload.get("source") or "workspace"
|
||||
|
||||
|
||||
class _DictRole:
|
||||
def __init__(self, payload: dict):
|
||||
self.role = str(payload.get("role") or payload.get("name") or "")
|
||||
self.role_qualified_name = str(payload.get("role_qualified_name") or payload.get("qualified_name") or self.role)
|
||||
self.source = str(payload.get("source") or "")
|
||||
|
||||
Reference in New Issue
Block a user