Repository navigation
Task Issue 1645 Assign Plan Roles No Rights Row Marker
Task 1645 — not_authorized_user row marker for <no rights> users in Assign Test Plan Roles (gap vs legacy)
Issue: #1645
Status: IMPLEMENTED & VERIFIED, issue CLOSED — branch task/issue-1645
Related: #1676, #1664, #946, #926 (the sibling screen that introduced the modern grey rendering)
Legacy usersAssign.tpl — the template SHARED by the test-project and the
test-plan contexts — tagged every user row whose effective role on the
selected feature was TL_ROLES_NO_RIGHTS (3):
{* gui/templates/dashio/usermanagement/usersAssign.tpl:234-237 (deleted in ab387af72) *}
{$user_row_class=''}
{if $effective_role_id == $smarty.const.TL_ROLES_NO_RIGHTS}
{$user_row_class='class="not_authorized_user"'}
{/if}
<tr {$user_row_class} bgcolor="{cycle values="#eeeeee,#d0d0d0"}">$effective_role_id is $gui->userFeatureRoles[$uID].effective_role_id
(usersAssign.tpl:225-228), i.e. the value produced by
get_tproject_effective_role() / get_tplan_effective_role()
(lib/functions/roles.inc.php), not the explicit assignment row. The common
case for the marker is every non-admin user on a private test plan, where
the effective role is TL_ROLES_NO_RIGHTS.
What the class did in 1.9.20 (verified by git grep not_authorized_user ab387af72^): the class appears ONLY in the two legacy .tpl files — there is no
CSS for it anywhere, so legacy never greyed the row. It was a machine-readable
marker: usersAssign.tpl:46 defines toggleRowByClass(oid,className,...)
(hiding/showing every tr whose className == className) for the
show_only_authorized_users label the template fetches at usersAssign.tpl:12
— but the dashio/tl-classic templates never call it, so on 1.9.20 the marker
was effectively inert markup. The grey rendering is the modern screens' own
choice, introduced by the sibling project screen
(usersAssignProject.html:33, issue #926) and reused here for consistency with
it. The unrendered "show only authorized users" filter is a separate
unported legacy capability.
What modern did instead: the modern plan screen wrote
<tr data-uid="…"> (gui/templates/usermanagement/usersAssignPlan.html:600)
and nothing else: no not_authorized_user class, and no CSS rule for it, so a
<no rights> row was visually identical to a normal one.
The BFF already returned everything needed — effectiveRoleID is part of the
tplan-roles payload (api/roles/index.php:967) — and the sibling project
screen carried the constant, the CSS rule and the row-class expression
(usersAssignProject.html:33, :125, :462). The plan screen had none of the
three.
No BFF change, no model change, no new i18n key (the marker is visual-only in
legacy too — no new user-facing text was introduced). Three additions to
gui/templates/usermanagement/usersAssignPlan.html:
-
CSS rule in the
<style>block (sibling parity withusersAssignProject.html:33):.assign-table tr.not_authorized_user td { color: #999; } -
Constant next to
ADMIN_ROLE_ID:var NO_RIGHTS_ROLE_ID = 3;— the front-end twin ofconfig.inc.phpTL_ROLES_NO_RIGHTS(same value asusersAssignProject.html:125). -
Row class in
renderUsersTable(), derived from the loadedu.effectiveRoleID— the same expression the sibling screen uses atusersAssignProject.html:345:var rowClass = (u.effectiveRoleID == NO_RIGHTS_ROLE_ID) ? ' not_authorized_user' : '';wrapped into theclassattribute exactly likeusersAssignProject.html:377.
Yes — and this was verified rather than assumed, because an earlier draft of this
work claimed the opposite. DataTables 1.13.7 applies its striping with
$(tr).removeClass(prevStripe).addClass(...), i.e. additively: a class
present in the row markup is never discarded. Measured on the shipped plan screen
with the createdRow hook deliberately removed — the class survived initial
render, search, column sort, Show All and the bulk Do full re-render, and
combined with the changed highlight (class="not_authorized_user changed odd").
The same was confirmed on the sibling project screen, which writes the class in
its markup and has no createdRow: with an explicit project role 3 for
ua1645designer it renders class="not_authorized_user even" with
rgb(153,153,153). So the marker needs the markup only — the implementation
follows the sibling and keeps the condition in one place.
Fixture php tmp/fixtures_1645.php (re-runnable, on this branch): public
project ALPHA1645 id 1; plans A-PUBLIC-1645 id 5 (is_public=1, control)
and A-PRIVATE-1645 id 6 (is_public=0); users ua1645designer (id 2, role
4), ua1645guest (id 3, role 5), ua1645tester (id 4, role 7, holding an
explicit plan role 7 on plan 6 → control row that must NOT be marked).
| Plan | user | effectiveRoleID |
before | after |
|---|---|---|---|---|
| 6 (private) | ua1645designer |
3 |
class="even", rgb(51,51,51)
|
class="not_authorized_user even", rgb(153,153,153)
|
| 6 (private) | ua1645guest |
3 |
class="odd", rgb(51,51,51)
|
class="not_authorized_user odd", rgb(153,153,153)
|
| 6 (private) | ua1645tester |
7 (explicit) | class="even" |
class="even" (unchanged, correct) |
| 6 (private) | admin |
8 | class="odd" |
class="odd" (unchanged, correct) |
| 5 (public) | all | 4/5/7 inherited |
odd/even
|
odd/even — nobody marked |
The marker was also measured as surviving every DataTables redraw — search,
column sort (2×), Show All and the bulk Do full re-render — and combining
correctly with the changed highlight (class="not_authorized_user changed even"). Save round trip: granting guest to ua1645designer and saving
reloads the grid, where the row is no longer marked (its effective role is no
longer 3) while ua1645guest stays marked.
Console: 0 errors, 0 warnings on every state. Event Viewer: no new
Error/Warning entries (only the expected log_level 16 AUDIT rows from the
Save).
- Cross-check on the sibling project screen: with an explicit project role 3 for
ua1645designer(user_testproject_roles(1,2,3)) it rendersclass="not_authorized_user even"/rgb(153,153,153)— the two screens agree. - The marker reflects the effective role as loaded, exactly like legacy,
which computed the class while rendering the page and never updated it. A
role picked in the
<select>therefore greys/ungreys the row on the next grid load (Save reloads it), not before — the same as legacy. - The
Inherited Rolecolumn and the pre-selected<no rights>option (issue #1664) remain the textual carriers of the same information; the marker is the visual carrier legacy provided. - The
Inherited Rolecolumn and the pre-selected<no rights>option stay the textual carriers; the marker is the visual one. - Still unported from the same legacy template: the
show_only_authorized_usersfilter (usersAssign.tpl:12+:46) — legacy fetched the label and shipped thetoggleRowByClass()helper but never wired them together. Any modern implementation must match withclassList.contains('not_authorized_user'), because legacy's exacttr.className ==compare can never match a modern row (they also carry DataTables'odd/even).
