Repository navigation
Bugfix Issue 1630 Assign Roles Name Column Label
Bugfix — Issue #1630: "Last Name" column header over a fused full-name cell in the role-assign grids
Screens: Test Management → User Management → Assign Test Project Roles
(gui/templates/usermanagement/usersAssignProject.html) and its twin
Assign Test Plan Roles (gui/templates/usermanagement/usersAssignPlan.html).
Status: fixed and verified (regression suite 14/14 PASS).
Labels: bug. Refs: #1630.
The 3rd column of the user grid was headed "Last Name" while its cells contained the user's full name — so the label contradicted the data on every row and in every locale:
# Login Last Name Assigned Role <-- BEFORE
1 adesigner Ann Designer <inherited> tester
2 admin Testlink Administrator <inherited> admin
# Login Name Assigned Role <-- AFTER
1 adesigner Ann Designer <inherited> tester
2 admin Testlink Administrator <inherited> admin
Only the label was wrong. The cell content was always correct.
This is a 2.0.1 modernisation regression, not legacy behaviour.
The legacy template gui/templates/dashio/usermanagement/usersAssign.tpl:242
(deleted in commit ab387af72) rendered a single cell under a single
generic localized header:
{$user->login|escape} ({$user->firstName|escape} {$user->lastName|escape})Because the name and the label were one and the same, no column header could ever disagree with the data.
The 2.0.1 rewrite split that cell into two columns — Login + Name — but
borrowed the wrong existing i18n key for the fused one, because the bundles had
no "full name" key at all.
| # | Hop | Location |
|---|---|---|
| 1 | BFF fuses first+last into one name field |
api/roles/index.php:785 (project grid), :949 (plan grid) → 'name' => $u->getDisplayName()
|
| 2 |
getDisplayName() expands the username format |
lib/functions/tlUser.class.php:525-533 |
| 3 | Format is %first% %last%
|
config.inc.php:749 |
| 4 | JSON reaches the page as one fused string | api/roles/index.php:803 |
| 5 | The page renders it into ONE grid column |
usersAssignProject.html:428, usersAssignPlan.html:377
|
| 6 |
← the defect that column's <th> was bound to the last-name-only key |
usersAssignProject.html:86, usersAssignPlan.html:88 → <th data-i18n="user.lastName">Name</th>
|
| 7 | …and that key means "Last Name" in every bundle |
gui/templates/i18n/en.json → "user.lastName": "Last Name"
|
Note the irony: the hard-coded HTML fallback inside those <th> elements was
already the correct word Name. The label only became wrong once TLi18n
resolved user.lastName at load time.
Method chosen: introduce a dedicated i18n key for the fused name and point the two headers at it. This keeps the data path untouched (the BFF was always correct) and keeps the key semantically honest for each language.
- Added
"user.fullName"to all 10 locale bundles (gui/templates/i18n/{en,de,es,fr,it,ja,pt,ro,ru,zh}.json), placed alphabetically betweenuser.firstNameanduser.generateApiKeyto preserve the strictly-sorteduser.*run in each file. - Repointed
usersAssignProject.html:86andusersAssignPlan.html:88todata-i18n="user.fullName".
| bundle | user.fullName |
user.lastName |
distinct? |
|---|---|---|---|
| en | Name | Last Name | yes |
| de | Name | Nachname | yes |
| es | Nombre | Apellido | yes |
| fr | Nom complet | Nom | yes |
| it | Nome | Cognome | yes |
| ja | 氏名 | 姓 | yes |
| pt | Nome | Apelido | yes |
| ro | Nume complet | Nume | yes |
| ru | Полное имя | Фамилия | yes |
| zh | 姓名 | 姓 | yes |
fr and ro are bolded on purpose. The first attempt used plain Nom / Nume,
which the code review caught as a silent no-op: in French and Romanian the
conventional surname label is "Nom" / "Nume" (paired with "Prénom" / "Prenume"),
so the bug would have remained unfixed — merely invisible — in those two
languages. The explicit complet ("full") forms make the fix real everywhere.
gui/templates/usermanagement/usersView.html:106-107 (and its form labels at
:146/:150) keep user.firstName / user.lastName. That grid genuinely shows
two separate columns fed by genuinely split data
(api/users/index.php:110-111, :176-177), so its keys are correct. A blanket
re-pointing of the key, or "fixing" the user.lastName value in en.json,
would have broken it. Verified live after the change:
usersView.html (de): ["Login","Vorname","Nachname","E-Mail", …]
rows: ["adesigner","Ann","Designer","ann@example.org", …]
The BFF (api/roles/index.php) and tlUser.class.php needed no change.
-
Re-point the
<th>atuser.login— wrong label ("Login" over a name column). -
Split the fused
nameback into two columns — would break legacy parity (legacy showed oneFirst Lastcell) and need a BFF change. Out of scope for a label defect. -
Change the value of
user.lastNameinen.json— would corruptusersView.html:106-107, which legitimately has a Last Name column. - Hard-code the header as plain "Name" with no key — would break internationalisation (rule 3) and regress all 9 non-English locales.
Regression suite: tmp/TLU_Test_Cases.md, section
"Regression — Issue #1630" — 14 cases, 14 PASS, including:
- both role-assign grids, in
enand after real locale switches (de,ro,fr); -
dechosen deliberately as the strongest single assertion, becauseuser.lastName(Nachname) ≠user.fullName(Name) there, so it actually distinguishes fix from pre-fix state; -
usersView.htmlasserted unchanged; - the hard-coded i18n fallback;
- all 10 bundles served over HTTP with a real full-name word +
json.toolvalid; - browser console 0 errors / 0 warnings;
- the
eventstable — 1 row,log_level=16(INFO,audit_login_succeeded), 0 Error/Warning entries.
| Before | After |
|---|---|
docs/screenshots/issue-1630-before.png — header "Last Name" |
docs/screenshots/issue-1630-after.png — header "Name" |
- The freshly imported DB has 0 test projects and only the
adminuser, andcustom_fields/cfield_node_typesare empty, so the project combo returnsprojects: []and the grid has to be driven from the console (loadUsers(1)) to render rows. Unrelated to this bug. - Project names are not in the
testprojectstable (it only holdsprefix). - Switching locale =
localStorage.setItem('tl_locale','<loc>')+ a full reload (gui/templates/i18n/i18n.js:28); the bundle is fetched once at load. -
frandrowere the two locales that could not visually reveal this bug before thecompletcorrection — usedeorenfor assertions here. -
user.lastNameis not globally wrong. Only the two fused-name headers were mis-bound;usersView.htmluses it correctly.
| commit | content |
|---|---|
336e9ec95 |
the fix: user.fullName in 10 bundles + repoint the 2 <th>s |
3a905a03e |
regression suite (14 cases) + before/after screenshots |
e7b6ffca2 |
code-review follow-ups: fr/ro explicit labels + alphabetical key placement |
| (this commit) | CHANGELOG + docs + wiki mirror |
Header BEFORE the fix — "Last Name" over cells that hold the full name:

Header AFTER the fix — "Name" over the very same cells:
