421 collaborator management component refresh required#469
Conversation
Update local collaborator cache and improve UI feedback for role/member changes. - api/Project.js: keep this.collaborators in sync by deleting entries on member removal and updating roles after makeLeader, demoteLeader, setToViewer and setRoles calls so the client-side state reflects server changes. - components/project-collaborators/index.js: add refreshCollaborators() to re-render the collaborators list when roles change. - components/roles-handler/index.js: replace alert() calls with TPEN.eventDispatcher 'tpen-toast' notifications, add try/catch error handling, and call refreshCollaborators() after successful operations to update the UI. These changes ensure consistent local state and provide non-blocking toast notifications instead of modal alerts.
Update RolesHandler to improve accessibility, robustness, and control flow for role management UI. - Added aria-expanded and data-role-management-open attributes to manage button markup for accessibility. - Removed unused userId/isOwnerOrLeader logic. - Removed manageRoleButtons setup and consolidated toggle logic into toggleRoleManagementButtons with defensive checks (valid button, memberId, actions container, and collaborator existence). - Use dataset flags and aria-expanded to track open/closed state and cleanly add/remove role management UI. - Replaced dynamic actions map with an explicit switch-based handler to await async actions and directly handle the manage-roles button case. These changes make the role management UI safer against missing DOM/Project state and clearer in behavior.
* major reorganization for better UX * evening out styling * cleanup and accessibility review * Update index.js * Update collaborators.html * addressing Claude's suggestions Send the correct roles payload from ManageRole (use this.group). Update RolesHandler to improve styling, accessibility, and behavior: switch hardcoded colors/shadows to CSS variables; register a cleanup callback to remove injected styles; add aria-labelledby to the modal; prevent duplicate injected manage buttons; track the trigger element and restore focus when the modal closes; set aria-pressed on toggles; disable the Save button and show a loading state while saving; replace alerts with toasts and improve error handling for ownership transfer. These changes fix a payload bug and enhance reliability and accessibility of the roles UI. * Add custom roles UI and selection logic Render a Custom Roles section in the manage modal and wire up toggle buttons for any non-default roles defined on the project. Adds CSS for custom-role toggles, shows the section only when custom roles exist, and toggles aria-pressed/active state on click. Collects active custom-role-toggle values into selected/current roles when saving and viewing, updates the viewer fallback logic to require absence of LEADER/CONTRIBUTOR, and includes custom roles in the originalSelection comparison. Also makes openManageModal async and tweaks manage-button styling to use CSS vars for background and hover color.
Static Review CommentsBranch: SummaryThis PR overhauls the collaborator role management UI, replacing inline button panels with a unified However, there are several issues: a formatting defect in
Critical Issues 🔴Issue 1: Error-handling architecture mismatch — API errors are silently swallowedFiles: Problem: This means:
Current Code (example — try {
const response = await TPEN.activeProject.cherryPickRoles(memberID, selectedRoles)
if (response) {
// This never runs on API error because cherryPickRoles returns undefined
TPEN.eventDispatcher.dispatch('tpen-toast', { message: 'Roles updated successfully.', status: 'success' })
}
// If response is undefined due to swallowed error, nothing happens here
} catch (error) {
// This catch NEVER fires because cherryPickRoles swallows its own errors
TPEN.eventDispatcher.dispatch('tpen-toast', { message: 'Error updating roles', status: 'error' })
}Current Code (example — async cherryPickRoles(userId, roles) {
try {
// ...
} catch (error) {
userMessage(error.message) // Error is swallowed here
// No re-throw — returns undefined
}
}Suggested Fix — choose ONE approach: Option A (recommended — re-throw from Project methods): async cherryPickRoles(userId, roles) {
try {
// ...
} catch (error) {
userMessage(error.message)
throw error // Let caller handle it too
}
}Option B (check for falsy return in the UI): try {
const response = await TPEN.activeProject.cherryPickRoles(memberID, selectedRoles)
if (response) {
TPEN.eventDispatcher.dispatch('tpen-toast', { message: 'Roles updated successfully.', status: 'success' })
this.closeRoleModal()
this.refreshCollaborators()
} else {
// Handle the "swallowed error" case
TPEN.eventDispatcher.dispatch('tpen-toast', { message: 'Error updating roles', status: 'error' })
}
} catch (error) {
// ...
}How to Verify:
Major Issues 🟠Issue 1: Leftover
|
thehabes
left a comment
There was a problem hiding this comment.
Issues discovered during testing
- Tooltip is cut off in role picker
- I have to refresh the page to see the invited user after a successful invitation. I think it is within this scope to make sure they paginate into the list without needing to refresh.
- I no longer see error messages on the page when I perform illegal actions, such as here after trying to remove the owner and getting a 403.
Once I close the role picker, I see the message
|
There are a few things noted here that are out of scope but should be handled somewhere else.
|
Dispatch a member-invited event and refresh collaborators when a new member is invited. Update RolesHandler UI (padding, overflow, z-index) and make openManageModal synchronous. Replace many direct onclick handlers with renderCleanup.onElement bindings to ensure proper cleanup. Add modal state helpers (getCurrentRoles, hasChanges, updateSaveButtonState) to track unsaved changes and enable/disable the Save button accordingly. Tweak default VIEWER logic so VIEWER is added when no Leader/Contributor is present.
Add getErrorMessage helper to extract user-friendly error text from Error/response objects (handles HTTP status, statusText, response data message/error, and fallbacks). Replace generic toast messages in catch blocks for updating roles, transferring ownership, and removing members to use the new helper so toasts display more informative errors (e.g., 403/404/409/5xx messages or underlying error.message).

This pull request improves the handling of collaborator roles and user feedback in the project management UI. The main changes ensure that collaborator role updates are immediately reflected in the frontend state and UI, and that user actions trigger toast notifications for clearer feedback. Error handling has also been improved for better reliability.
Collaborator Role State Synchronization:
Projectclass (api/Project.js) now updates its localcollaboratorsstate when members are removed, promoted, demoted, or have their roles changed, ensuring the frontend always reflects the most current roles. [1] [2] [3] [4] [5]UI Updates and Feedback:
refreshCollaboratorsmethod to theproject-collaboratorscomponent, and integrated it into theroles-handlercomponent so that collaborator list UI updates automatically after role changes, without needing a full page refresh. [1] [2]