Skip to content

Commit a51b5d0

Browse files
devGregAclaude
andcommitted
ui(authorized-users): collapse row delete into kebab menu, equalize columns
The Authorized Users panel on Product, Product Type, and View User pages showed a red trash button per row that took its own column. Replace with the kebab dropdown pattern used elsewhere in the UI (view_group.html etc.) and balance the data columns so the action column shrinks to fit. - Product / Product Type: User and Email columns each get width: 50% - View User: single Org/Asset column gets width: 100% - Delete still POSTs through a hidden form to preserve CSRF Applied to both dojo/templates/ (Tailwind) and dojo/templates_classic/ (Bootstrap) so the rendering matches across UI preferences. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9215ce8 commit a51b5d0

6 files changed

Lines changed: 124 additions & 52 deletions

File tree

dojo/templates/dojo/view_product_details.html

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,31 @@ <h4 class="pull-left">{% trans "Authorized Users" %}</h4>
304304
{% if prod|has_object_permission:"staff_only" %}
305305
<th label="Actions"></th>
306306
{% endif %}
307-
<th>{% trans "User" %}</th>
308-
<th>{% trans "Email" %}</th>
307+
<th style="width: 50%;">{% trans "User" %}</th>
308+
<th style="width: 50%;">{% trans "Email" %}</th>
309309
</tr>
310310
</thead>
311311
<tbody>
312312
{% for u in authorized_users %}
313313
<tr>
314314
{% if prod|has_object_permission:"staff_only" %}
315315
<td>
316-
<form method="post" action="{% url 'delete_product_authorized_user' prod.id u.id %}" style="display:inline"
317-
onsubmit="return confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}');">
316+
<form method="post" action="{% url 'delete_product_authorized_user' prod.id u.id %}" id="remove-authorized-user-{{ u.id }}" style="display:none;">
318317
{% csrf_token %}
319-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Remove">
320-
<i class="fa-solid fa-trash" style="color:#fff"></i>
321-
</button>
322318
</form>
319+
<ul>
320+
<li class="dropdown" style="list-style:none">
321+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownAuthorizedUserActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
322+
<ul class="dropdown-menu">
323+
<li>
324+
<a name="removeAuthorizedUser" href="#"
325+
onclick="if (confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}')) { document.getElementById('remove-authorized-user-{{ u.id }}').submit(); } return false;">
326+
<i class="fa-solid fa-trash"></i> {% trans "Remove" %}
327+
</a>
328+
</li>
329+
</ul>
330+
</li>
331+
</ul>
323332
</td>
324333
{% endif %}
325334
<td name="authorized_user_username">{{ u.username }}</td>

dojo/templates/dojo/view_product_type.html

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,31 @@ <h4 class="pull-left">{% trans "Authorized Users" %}</h4>
162162
{% if pt|has_object_permission:"staff_only" %}
163163
<th></th>
164164
{% endif %}
165-
<th>{% trans "User" %}</th>
166-
<th>{% trans "Email" %}</th>
165+
<th style="width: 50%;">{% trans "User" %}</th>
166+
<th style="width: 50%;">{% trans "Email" %}</th>
167167
</tr>
168168
</thead>
169169
<tbody>
170170
{% for u in authorized_users %}
171171
<tr>
172172
{% if pt|has_object_permission:"staff_only" %}
173173
<td>
174-
<form method="post" action="{% url 'delete_product_type_authorized_user' pt.id u.id %}" style="display:inline"
175-
onsubmit="return confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}');">
174+
<form method="post" action="{% url 'delete_product_type_authorized_user' pt.id u.id %}" id="remove-authorized-user-{{ u.id }}" style="display:none;">
176175
{% csrf_token %}
177-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Remove">
178-
<i class="fa-solid fa-trash" style="color:#fff"></i>
179-
</button>
180176
</form>
177+
<ul>
178+
<li class="dropdown" style="list-style:none">
179+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownAuthorizedUserActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
180+
<ul class="dropdown-menu">
181+
<li>
182+
<a name="removeAuthorizedUser" href="#"
183+
onclick="if (confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}')) { document.getElementById('remove-authorized-user-{{ u.id }}').submit(); } return false;">
184+
<i class="fa-solid fa-trash"></i> {% trans "Remove" %}
185+
</a>
186+
</li>
187+
</ul>
188+
</li>
189+
</ul>
181190
</td>
182191
{% endif %}
183192
<td name="authorized_user_username">{{ u.username }}</td>

dojo/templates/dojo/view_user.html

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,30 @@ <h4 class="pull-left">{{ labels.ORG_USERS_LABEL }}</h4>
130130
<thead>
131131
<tr>
132132
{% if request.user.is_staff %}<th></th>{% endif %}
133-
<th>{{ labels.ORG_LABEL }}</th>
133+
<th style="width: 100%;">{{ labels.ORG_LABEL }}</th>
134134
</tr>
135135
</thead>
136136
<tbody>
137137
{% for pt in accessible_product_types %}
138138
<tr>
139139
{% if request.user.is_staff %}
140140
<td>
141-
<form method="post" action="{% url 'revoke_user_from_product_type' user.id pt.id %}" style="display:inline"
142-
onsubmit="return confirm('{% blocktrans with username=user.username pt=pt.name %}Revoke {{ username }} from {{ pt }}?{% endblocktrans %}');">
141+
<form method="post" action="{% url 'revoke_user_from_product_type' user.id pt.id %}" id="revoke-product-type-{{ pt.id }}" style="display:none;">
143142
{% csrf_token %}
144-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Revoke">
145-
<i class="fa-solid fa-trash" style="color:#fff"></i>
146-
</button>
147143
</form>
144+
<ul>
145+
<li class="dropdown" style="list-style:none">
146+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownProductTypeActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
147+
<ul class="dropdown-menu">
148+
<li>
149+
<a name="revokeProductType" href="#"
150+
onclick="if (confirm('{% blocktrans with username=user.username pt=pt.name %}Revoke {{ username }} from {{ pt }}?{% endblocktrans %}')) { document.getElementById('revoke-product-type-{{ pt.id }}').submit(); } return false;">
151+
<i class="fa-solid fa-trash"></i> {% trans "Revoke" %}
152+
</a>
153+
</li>
154+
</ul>
155+
</li>
156+
</ul>
148157
</td>
149158
{% endif %}
150159
<td name="member_product_type"><a href="{% url 'view_product_type' pt.id %}">{{ pt.name }}</a></td>
@@ -189,21 +198,30 @@ <h4 class="pull-left">{{ labels.ASSET_USERS_ACCESS_LABEL }}</h4>
189198
<thead>
190199
<tr>
191200
{% if request.user.is_staff %}<th></th>{% endif %}
192-
<th>{{ labels.ASSET_LABEL }}</th>
201+
<th style="width: 100%;">{{ labels.ASSET_LABEL }}</th>
193202
</tr>
194203
</thead>
195204
<tbody>
196205
{% for p in accessible_products %}
197206
<tr>
198207
{% if request.user.is_staff %}
199208
<td>
200-
<form method="post" action="{% url 'revoke_user_from_product' user.id p.id %}" style="display:inline"
201-
onsubmit="return confirm('{% blocktrans with username=user.username product=p.name %}Revoke {{ username }} from {{ product }}?{% endblocktrans %}');">
209+
<form method="post" action="{% url 'revoke_user_from_product' user.id p.id %}" id="revoke-product-{{ p.id }}" style="display:none;">
202210
{% csrf_token %}
203-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Revoke">
204-
<i class="fa-solid fa-trash" style="color:#fff"></i>
205-
</button>
206211
</form>
212+
<ul>
213+
<li class="dropdown" style="list-style:none">
214+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownProductActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
215+
<ul class="dropdown-menu">
216+
<li>
217+
<a name="revokeProduct" href="#"
218+
onclick="if (confirm('{% blocktrans with username=user.username product=p.name %}Revoke {{ username }} from {{ product }}?{% endblocktrans %}')) { document.getElementById('revoke-product-{{ p.id }}').submit(); } return false;">
219+
<i class="fa-solid fa-trash"></i> {% trans "Revoke" %}
220+
</a>
221+
</li>
222+
</ul>
223+
</li>
224+
</ul>
207225
</td>
208226
{% endif %}
209227
<td name="member_product"><a href="{% url 'view_product' p.id %}">{{ p.name }}</a></td>

dojo/templates_classic/dojo/view_product_details.html

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,31 @@ <h4 class="pull-left">{% trans "Authorized Users" %}</h4>
304304
{% if prod|has_object_permission:"Product_Manage_Members" %}
305305
<th label="Actions"></th>
306306
{% endif %}
307-
<th>{% trans "User" %}</th>
308-
<th>{% trans "Email" %}</th>
307+
<th style="width: 50%;">{% trans "User" %}</th>
308+
<th style="width: 50%;">{% trans "Email" %}</th>
309309
</tr>
310310
</thead>
311311
<tbody>
312312
{% for u in authorized_users %}
313313
<tr>
314314
{% if prod|has_object_permission:"Product_Manage_Members" %}
315315
<td>
316-
<form method="post" action="{% url 'delete_product_authorized_user' prod.id u.id %}" style="display:inline"
317-
onsubmit="return confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}');">
316+
<form method="post" action="{% url 'delete_product_authorized_user' prod.id u.id %}" id="remove-authorized-user-{{ u.id }}" style="display:none;">
318317
{% csrf_token %}
319-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Remove">
320-
<i class="fa-solid fa-trash" style="color:#fff"></i>
321-
</button>
322318
</form>
319+
<ul>
320+
<li class="dropdown" style="list-style:none">
321+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownAuthorizedUserActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
322+
<ul class="dropdown-menu">
323+
<li>
324+
<a name="removeAuthorizedUser" href="#"
325+
onclick="if (confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}')) { document.getElementById('remove-authorized-user-{{ u.id }}').submit(); } return false;">
326+
<i class="fa-solid fa-trash"></i> {% trans "Remove" %}
327+
</a>
328+
</li>
329+
</ul>
330+
</li>
331+
</ul>
323332
</td>
324333
{% endif %}
325334
<td name="authorized_user_username">{{ u.username }}</td>

dojo/templates_classic/dojo/view_product_type.html

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,31 @@ <h4 class="pull-left">{% trans "Authorized Users" %}</h4>
162162
{% if pt|has_object_permission:"Product_Type_Manage_Members" %}
163163
<th></th>
164164
{% endif %}
165-
<th>{% trans "User" %}</th>
166-
<th>{% trans "Email" %}</th>
165+
<th style="width: 50%;">{% trans "User" %}</th>
166+
<th style="width: 50%;">{% trans "Email" %}</th>
167167
</tr>
168168
</thead>
169169
<tbody>
170170
{% for u in authorized_users %}
171171
<tr>
172172
{% if pt|has_object_permission:"Product_Type_Manage_Members" %}
173173
<td>
174-
<form method="post" action="{% url 'delete_product_type_authorized_user' pt.id u.id %}" style="display:inline"
175-
onsubmit="return confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}');">
174+
<form method="post" action="{% url 'delete_product_type_authorized_user' pt.id u.id %}" id="remove-authorized-user-{{ u.id }}" style="display:none;">
176175
{% csrf_token %}
177-
<button type="submit" class="btn btn-sm btn-danger" aria-label="Remove">
178-
<i class="fa-solid fa-trash" style="color:#fff"></i>
179-
</button>
180176
</form>
177+
<ul>
178+
<li class="dropdown" style="list-style:none">
179+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" label="Actions" name="dropdownAuthorizedUserActions">&nbsp;<b class="fa-solid fa-ellipsis-vertical"></b>&nbsp;</a>
180+
<ul class="dropdown-menu">
181+
<li>
182+
<a name="removeAuthorizedUser" href="#"
183+
onclick="if (confirm('{% blocktrans with username=u.username %}Remove {{ username }} from authorized users?{% endblocktrans %}')) { document.getElementById('remove-authorized-user-{{ u.id }}').submit(); } return false;">
184+
<i class="fa-solid fa-trash"></i> {% trans "Remove" %}
185+
</a>
186+
</li>
187+
</ul>
188+
</li>
189+
</ul>
181190
</td>
182191
{% endif %}
183192
<td name="authorized_user_username">{{ u.username }}</td>

0 commit comments

Comments
 (0)