FossilRepo

1
{% extends "base.html" %}
2
{% block title %}{{ title }} — Fossilrepo{% endblock %}
3
4
{% block content %}
5
<div class="mb-6">
6
<a href="{% url 'organization:role_list' %}" class="text-sm text-brand-light hover:text-brand">&larr; Back to Roles</a>
7
</div>
8
9
<div class="mx-auto max-w-3xl">
10
<h1 class="text-2xl font-bold text-gray-100 mb-6">{{ title }}</h1>
11
12
<form method="post" class="space-y-6">
13
{% csrf_token %}
14
15
<div class="rounded-lg bg-gray-800 p-6 shadow border border-gray-700 space-y-6">
16
<div>
17
<label for="{{ form.name.id_for_label }}" class="block text-sm font-medium text-gray-300">
18
Name <span class="text-red-400">*</span>
19
</label>
20
<div class="mt-1">{{ form.name }}</div>
21
{% if form.name.errors %}
22
<p class="mt-1 text-sm text-red-400">{{ form.name.errors.0 }}</p>
23
{% endif %}
24
</div>
25
26
<div>
27
<label for="{{ form.description.id_for_label }}" class="block text-sm font-medium text-gray-300">
28
Description
29
</label>
30
<div class="mt-1">{{ form.description }}</div>
31
{% if form.description.errors %}
32
<p class="mt-1 text-sm text-red-400">{{ form.description.errors.0 }}</p>
33
{% endif %}
34
</div>
35
36
<div>
37
<div class="flex items-center gap-3">
38
{{ form.is_default }}
39
<label for="{{ form.is_default.id_for_label }}" class="text-sm font-medium text-gray-300">
40
Default role
41
</label>
42
</div>
43
<p class="mt-1 text-sm text-gray-500">Assigned to new users automatically.</p>
44
</div>
45
</div>
46
47
<div>
48
<h2 class="text-lg font-semibold text-gray-100 mb-4">Permissions</h2>
49
{% if form.permissions.errors %}
50
<p class="mb-2 text-sm text-red-400">{{ form.permissions.errors.0 }}</p>
51
{% endif %}
52
53
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2" x-data="{ selectAll(groupId) {
54
document.querySelectorAll('#perm-group-' + groupId + ' input[type=checkbox]').forEach(cb => cb.checked = true);
55
}, deselectAll(groupId) {
56
document.querySelectorAll('#perm-group-' + groupId + ' input[type=checkbox]').forEach(cb => cb.checked = false);
57
}}">
58
{% for category, perms in form.grouped_permissions.items %}
59
<div class="overflow-hidden rounded-lg border border-gray-700 bg-gray-800 shadow-sm"
60
id="perm-group-{{ forloop.counter }}">
61
<div class="bg-gray-900 px-4 py-3 flex items-center justify-between">
62
<h3 class="text-sm font-semibold text-gray-200">{{ category }}</h3>
63
<div class="flex gap-2">
64
<button type="button" @click="selectAll({{ forloop.counter }})"
65
class="text-xs text-brand-light hover:text-brand">All</button>
66
<span class="text-gray-600">|</span>
67
<button type="button" @click="deselectAll({{ forloop.counter }})"
68
class="text-xs text-gray-400 hover:text-gray-200">None</button>
69
</div>
70
</div>
71
<div class="px-4 py-3 grid grid-cols-1 gap-2">
72
{% for item in perms %}
73
<label class="flex items-center gap-2 text-sm text-gray-300 cursor-pointer hover:text-gray-100">
74
<input type="checkbox" name="permissions" value="{{ item.perm.pk }}"
75
{% if item.checked %}checked{% endif %}
76
class="rounded border-gray-600 text-brand focus:ring-brand bg-gray-700">
77
<span>{{ item.perm.name }}</span>
78
</label>
79
{% endfor %}
80
</div>
81
</div>
82
{% endfor %}
83
</div>
84
</div>
85
86
<div class="flex justify-end gap-3 pt-4">
87
<a href="{% url 'organization:role_list' %}"
88
class="rounded-md bg-gray-700 px-4 py-2 text-sm font-semibold text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 hover:bg-gray-600">
89
Cancel
90
</a>
91
<button type="submit"
92
class="rounded-md bg-brand px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
93
{% if role %}Update{% else %}Create{% endif %}
94
</button>
95
</div>
96
</form>
97
</div>
98
{% endblock %}
99

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button