refactor(templates): use role_display_name and improve role/admin clarity

Clarify role display names, refine admin role labeling, and update confirmation messages for better UX.
This commit is contained in:
sankalp committed 2026-06-29 06:57:52 +05:45
1 parent 80c05d8fc7
commit 7431c8f050
5 files changed
+106 -12

No files matched your search

+90
View File
@@ -0,0 +1,90 @@
{% extends "base.html" %}
{% block title %}Roles{% endblock %}
{% block breadcrumb %}
<nav class="mb-4" aria-label="Breadcrumb">
<ol class="flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400">
<li><a href="{% url 'dashboard' %}" class="hover:text-gray-700 dark:hover:text-gray-300">Dashboard</a></li>
<li class="text-gray-300 dark:text-gray-600">/</li>
<li class="text-gray-900 dark:text-white font-medium" aria-current="page">Roles</li>
</ol>
</nav>
{% endblock %}
{% block content %}
<div class="mb-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<div>
<h1 class="text-2xl font-bold">Roles</h1>
<p class="text-gray-500 dark:text-gray-400 text-sm mt-1">{{ roles.count }} role{{ roles.count|pluralize }}</p>
</div>
</div>
{% if request.user.is_admin %}
<div class="dk-card divide-y divide-gray-200 dark:divide-gray-600 mb-6">
<div class="px-6 py-4"><h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100">Create Custom Role</h3><p class="text-xs text-gray-500 mt-0.5">Define a new role for your organization</p></div>
<div class="px-6 py-5">
<form method="post" action="{% url 'role-add' %}" class="flex items-end gap-3">
{% csrf_token %}
<div>
<label class="block text-xs font-medium text-gray-500 mb-1">Name</label>
<input type="text" name="name" required placeholder="e.g. Senior Developer"
class="w-60 text-sm border border-gray-200 dark:border-gray-600 rounded-lg px-3 py-2 bg-white dark:bg-gray-950 focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<button type="submit" class="dk-btn dk-btn-primary"><i class="fas fa-plus"></i> Create</button>
</form>
</div>
</div>
{% endif %}
<div class="dk-card overflow-hidden divide-y divide-gray-200 dark:divide-gray-600">
<div class="px-6 py-4"><h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100">All Roles</h3><p class="text-xs text-gray-500 mt-0.5">System roles cannot be deleted</p></div>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800">
<th class="text-left px-4 py-3 font-semibold text-xs text-gray-500 dark:text-gray-400">Name</th>
<th class="text-left px-4 py-3 font-semibold text-xs text-gray-500 dark:text-gray-400">Slug</th>
<th class="text-left px-4 py-3 font-semibold text-xs text-gray-500 dark:text-gray-400">Type</th>
<th class="text-left px-4 py-3 font-semibold text-xs text-gray-500 dark:text-gray-400">Users</th>
{% if request.user.is_admin %}
<th class="text-right px-4 py-3 font-semibold text-xs text-gray-500 dark:text-gray-400">Actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for r in roles %}
<tr class="border-b border-gray-100 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50">
<td class="px-4 py-3 font-medium text-gray-900 dark:text-white">
{{ r.name }}
{% if r.slug in admin_roles %}
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 ml-1.5">System</span>
{% endif %}
</td>
<td class="px-4 py-3 text-gray-500 dark:text-gray-400 font-mono text-xs">{{ r.slug }}</td>
<td class="px-4 py-3">
{% if r.slug in admin_roles %}
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400">Hardcoded — full access</span>
{% else %}
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400">Custom — follows rules</span>
{% endif %}
</td>
<td class="px-4 py-3 text-gray-500 dark:text-gray-400">{{ r.users.count }}</td>
{% if request.user.is_admin %}
<td class="px-4 py-3 text-right">
{% if not r.is_system %}
<form method="post" action="{% url 'role-delete' r.id %}" class="inline">
{% csrf_token %}
<button type="button" @click="confirmAction({title:'Delete Role', message:'Delete role <strong>{{ r.name|escapejs }}</strong>? Users with this role will become unassigned.', confirmText:'Delete', danger:true, onConfirm:function(){ $el.closest('form').submit() }})" class="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-red-600 dark:text-red-400 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors shadow-sm">Delete</button>
</form>
{% else %}
<span class="text-xs text-gray-400 italic">Protected</span>
{% endif %}
</td>
{% endif %}
</tr>
{% empty %}
<tr><td colspan="5" class="text-center py-12 text-gray-400">No roles defined</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
+2 -1
View File
@@ -21,8 +21,9 @@
<a href="/dashboard/tickets/" class="dk-sidebar-link dk-sidebar-link-inactive"><i class="fas fa-ticket w-5 text-center"></i><span>Tickets</span></a>
<a href="/dashboard/ticket-timeline/" class="dk-sidebar-link dk-sidebar-link-inactive"><i class="fas fa-calendar w-5 text-center"></i><span>Ticket Timeline</span></a>
<a href="/dashboard/epics/" class="dk-sidebar-link dk-sidebar-link-inactive"><i class="fas fa-flag w-5 text-center"></i><span>Epics</span></a>
{% if request.user.role == 'superadmin' %}
{% if request.user.is_admin %}
<p class="px-3 text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mt-6 mb-2">Administration</p>
<a href="/dashboard/roles/" class="dk-sidebar-link dk-sidebar-link-inactive" @click="mobileSidebar = false"><i class="fas fa-user-tag w-5 text-center"></i><span>Roles</span></a>
<a href="/dashboard/users/" class="dk-sidebar-link {% if '/users/' in request.path %}dk-sidebar-link-active{% else %}dk-sidebar-link-inactive{% endif %}" title="Users" @click="mobileSidebar = false">
<i class="fas fa-users w-5 text-center"></i><span class="flex-1">Users</span>
<span class="dk-badge bg-blue-600 text-white text-[10px]">{{ total_users }}</span>
+4 -1
View File
@@ -54,8 +54,11 @@
<a href="/dashboard/settings/ui/" class="dk-sidebar-link {% if '/settings/ui/' in request.path %}dk-sidebar-link-active{% else %}dk-sidebar-link-inactive{% endif %}" title="UI Settings">
<i class="fas fa-cog w-5 text-center"></i><span x-show="sidebarOpen">UI Settings</span>
</a>
{% if request.user.role == 'superadmin' %}
{% if request.user.is_admin %}
<p class="dk-sidebar-group px-3 text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mt-6 mb-2"><span x-show="sidebarOpen">Administration</span></p>
<a href="/dashboard/roles/" class="dk-sidebar-link {% if '/roles/' in request.path %}dk-sidebar-link-active{% else %}dk-sidebar-link-inactive{% endif %}" title="Roles">
<i class="fas fa-user-tag w-5 text-center"></i><span x-show="sidebarOpen">Roles</span>
</a>
<a href="/dashboard/users/" class="dk-sidebar-link {% if '/users/' in request.path %}dk-sidebar-link-active{% else %}dk-sidebar-link-inactive{% endif %}" title="Users">
<i class="fas fa-users w-5 text-center"></i><span x-show="sidebarOpen" class="flex-1">Users</span>
<span class="dk-badge bg-blue-600 text-white text-[10px]" x-show="sidebarOpen">{{ total_users }}</span>
+5 -5
View File
@@ -785,9 +785,9 @@ class="space-y-6"
<select name="role" required
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-950 px-3 py-2 text-sm focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
<option value="">Select a role</option>
{% for role_key, role_label in role_choices %}
{% if role_key not in admin_roles %}
<option value="{{ role_key }}">{{ role_label }}</option>
{% for role in role_choices %}
{% if role.slug not in admin_roles %}
<option value="{{ role.slug }}">{{ role.name }}</option>
{% endif %}
{% endfor %}
</select>
@@ -826,7 +826,7 @@ class="space-y-6"
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
{% for perm in permissions %}
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/30">
<td class="px-4 py-3 font-medium text-gray-900 dark:text-white">{{ perm.get_role_display }}</td>
<td class="px-4 py-3 font-medium text-gray-900 dark:text-white">{{ perm.role_display_name }}</td>
<td class="px-4 py-3">
<div class="flex flex-wrap gap-1.5">
{% for status in perm.move_to_statuses.all %}
@@ -842,7 +842,7 @@ class="space-y-6"
<td class="px-4 py-3 text-right">
<form method="post" action="{% url 'board-permission-delete' selected_project.id perm.id %}" class="inline">
{% csrf_token %}
<button type="button" @click="confirmAction({title:'Delete Permission', message:'Delete permission for <strong>' + '{{ perm.get_role_display|escapejs }}' + '</strong>?', confirmText:'Delete', danger:true, onConfirm:function(){ $el.closest('form').submit() }})" class="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium text-red-600 dark:text-red-400 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors shadow-sm">
<button type="button" @click="confirmAction({title:'Delete Permission', message:'Delete permission for <strong>' + '{{ perm.role_display_name|escapejs }}' + '</strong>?', confirmText:'Delete', danger:true, onConfirm:function(){ $el.closest('form').submit() }})" class="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium text-red-600 dark:text-red-400 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors shadow-sm">
<i class="fas fa-trash"></i>
</button>
</form>
+5 -5
View File
@@ -722,9 +722,9 @@
<select name="role" required
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-950 px-3 py-2 text-sm focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
<option value="">Select a role</option>
{% for role_key, role_label in role_choices %}
{% if role_key not in admin_roles %}
<option value="{{ role_key }}">{{ role_label }}</option>
{% for role in role_choices %}
{% if role.slug not in admin_roles %}
<option value="{{ role.slug }}">{{ role.name }}</option>
{% endif %}
{% endfor %}
</select>
@@ -763,7 +763,7 @@
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
{% for perm in permissions %}
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/30">
<td class="px-4 py-3 font-medium text-gray-900 dark:text-white">{{ perm.get_role_display }}</td>
<td class="px-4 py-3 font-medium text-gray-900 dark:text-white">{{ perm.role_display_name }}</td>
<td class="px-4 py-3">
<div class="flex flex-wrap gap-1.5">
{% for status in perm.move_to_statuses.all %}
@@ -779,7 +779,7 @@
<td class="px-4 py-3 text-right">
<form method="post" action="{% url 'board-permission-delete' project.id perm.id %}" class="inline">
{% csrf_token %}
<button type="button" @click="confirmAction({title:'Delete Permission', message:'Delete permission for <strong>' + '{{ perm.get_role_display|escapejs }}' + '</strong>?', confirmText:'Delete', danger:true, onConfirm:function(){ $el.closest('form').submit() }})" class="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium text-red-600 dark:text-red-400 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors shadow-sm">
<button type="button" @click="confirmAction({title:'Delete Permission', message:'Delete permission for <strong>' + '{{ perm.role_display_name|escapejs }}' + '</strong>?', confirmText:'Delete', danger:true, onConfirm:function(){ $el.closest('form').submit() }})" class="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium text-red-600 dark:text-red-400 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors shadow-sm">
<i class="fas fa-trash"></i>
</button>
</form>