Repository navigation
Task Issue 931 Assign Project Roles Save Feedback
Issue: #931
Status: IMPLEMENTED & VERIFIED (2026-09-18) — branch task/issue-931
Legacy lib/usermanagement/usersAssign.php:80-92 sets a user_feedback string
after an update attempt:
- empty submitted role map →
user_feedback = lang_get('no_users_selected')($TLS_no_users_selected = "No users selected - nothing done"); - successful
doUpdate()→user_feedback = $gui->roles_updated=test_project_user_roles_updated= "User Roles updated" (usersAssign.php:51);
and gui/templates/dashio/usermanagement/inc_update.tpl:26-35 renders that as a
localized div.user_feedback box at the top of the page (usersAssign.tpl:132-134).
The modern usersAssignProject.html saveAssignments() instead silently
reloaded the list on success and had no error handler at all (silent
uncaught ajax failure). The empty-assignment no-op was indistinguishable from a
real save.
-
usersAssign.php:82-84— empty map →no_users_selected; -
usersAssign.php:87-89— afterdoUpdate()→test_project_user_roles_updated; -
usersAssign.php:557-573—doUpdate()skips role-0 entries, deletes then re-adds the users' project roles; -
include/inc_update.tpl:26-35—$user_feedbackbox.
BFF (api/roles/index.php, PUT /tproject-roles only — issue scope is the
project screen):
- empty-map no-op and admin-strip-to-empty now return
out(['status'=>'ok','feedback_key'=>'no_users_selected']); - real update returns
out(['status'=>'ok','feedback_key'=>'assign_roles_updated']).
Screen (gui/templates/usermanagement/usersAssignProject.html):
- Dashio
#toastelement + CSS (base identical torolesView.html:49-51, plus a.toast.warnstate for the "nothing done" notice); -
toast(msg, cls)helper — bottom-right banner, 4s auto-hide, resets.ok/.warn/.errclasses between calls; -
assignFeedback(feedbackKey)maps the two BFF keys toassign.rolesUpdated/assign.noUsersSelected; -
saveAssignments():successrenders the toast fromfeedback_key(warning forno_users_selected, success otherwise) then reloads;errorresolves the localized message: BFFmessageKey→ demo-moderole.demoUpdateDisabled→ HTTP 403common.forbidden→ genericassign.updateFailed. All toast text goes through.text()— no HTML injection.
i18n: assign.rolesUpdated / assign.noUsersSelected / assign.updateFailed
added to all 10 locale bundles, translated after the legacy $TLS_* strings.
Success toast after Save:

Empty-assignment (no users selected) warning:

Error toast on a failed save:

- Success: role change + Save →
{"text":"User Roles updated","cls":"toast ok", visible};user_testproject_rolesupdated; list reloads. - BFF success payload:
PUT /roles/tproject-roles {tproject_id:1,assignments:{2:7}}→{status:ok, feedback_key:"assign_roles_updated"}. - Empty map:
PUT ... {assignments:{}}→{status:ok, feedback_key:"no_users_selected"}; screen shows the amber warn toast. - BFF validation error (
tproject_id:0):400→ red toast "Missing tproject_id". - 403 → "Insufficient rights"; demo-mode → "Demo mode enabled => Update Role DISABLED"; generic 500 → "Error updating user roles" (all via TLi18n).
- Event Viewer /
eventstable: only AUDIT (log_level 16) rows from Save ops; 0 rows ≥ 32. No browser console errors. - Test suite:
tmp/TLU_Test_Cases.md— "Task — Issue #931" — 12/12 PASS.
Refs #931.