Add collaboration state indicators#26574
Merged
AlexGaillard merged 387 commits intomainfrom Feb 16, 2026
Merged
Conversation
formfcw
requested changes
Feb 13, 2026
Contributor
formfcw
left a comment
There was a problem hiding this comment.
Thank you @alvarosabu ❤️
Made some updates and a few things to consider in the comments.
I’ve also refactored to use VListItem. As a result, we are now rendering a <button> inside a <ul>, which is not semantically correct. However, this pattern is already used elsewhere in the application. Since the same issue exists in multiple places, it would be better to address it in a separate ticket and resolve it consistently across the app.
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorField.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorField.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
…ng user focus IDs and add unit tests for getFocusId functionality.
…wn user names gracefully by using translation fallback.
…s based on user focus state
formfcw
requested changes
Feb 16, 2026
app/src/views/private/components/collab/CollabIndicatorHeader.vue
Outdated
Show resolved
Hide resolved
…ntext to improve clarity and consistency in CollabIndicatorHeader component.
…onent for better readability.
formfcw
approved these changes
Feb 16, 2026
Contributor
formfcw
left a comment
There was a problem hiding this comment.
Thank you @alvarosabu ❤️
LGTM 🎉
barry86m
pushed a commit
to barry86m/directus-private-view-header-bar-title-thumbnail-fix
that referenced
this pull request
Feb 16, 2026
* Remove room * Add missing await * Patch unit tests * Merge async deepMapWithSchema and refactor sanitization * Fix usages and tests * Fix relational null updates treated as objects * Prevent unauthorized field unsets and relationship updates * Propagate item deletion * Simplify room lifecycle and add recovery * Update tests * Implement distributed cleanup and standardize env configuration * Cleanup and refactor to RoomManager * Address CodeQL warning * Add blackbox tests * Handle integer PK and handle invalid schema * add error messages to client * fix error types * Add basic deep relational tests * Patch tests and improve websocket transport * remove unused import * add frontend delete * improve error handling and fix item delete * clearn up room logic * update tests * Update blackbox tests * Use waitForMatchingMessage * Specify timeout for seeding * Improve tests * fix room tests * fix sanitize-payload and verify-permissions * update discard banner in app * Implicitly switch focus when updating * Try accounting for misordered messages * clean console * Fix build * fmt * fmt * fmt * Verify permissions before relational processing * Improve update clearing * Fix double join events * Fix disconnected icon when disabled * Handle error from getService * Pass collab context to overlay * Broadcast to all users to fix relational item not receiving update * Skip disabling interfaces with relational specials * Add shared discard and drawer refinements * sync item update notification * fix double save message in frontend * Add collab for users and files * fix join error showing on non existent items * Reset changes when last person leaves * don't focus on focused fields * fix headerCollab not showing with coll-template * Check if values has changed on update * fix page header hiding collab * Remove unused imports * Fix versioned propagation * Improve copy * Fix delete handler * Update collab tests * fmt * Update comments * fix making color tab persistent * only enable collab if needed * fix wrong collision on no changes * Validate changes on join and update * Update packages/utils/shared/generate-joi.ts Co-authored-by: judda <[email protected]> * Simplify permission tagging and add integration test * Test color propagation * Fix rerun constraint * Optional colors * cleanup code * Add namespace config and fix redlock * update room functions to use global memory * code cleanup * Add fields to discard * Fix messenger mock * fix m2m and m2a and initialChanges in frontend * Mock global rooms * update error types and improve verify permissions * add version permission check * Match message instead * Add missing await for version check * Ensure consistent error types and patch tests * Fix lint * Fix version perms check * Update mock and errors * Use fake timers * Improve collab disabling * Add leader based room closure * Optimize distributed messaging and implement non-blocking termination * Optimize with validateItemAccess Co-authored-by: judda <[email protected]> * Streamline field permissions check * Fix focus erroring * Try improve blackbox stability with waitForMatchingMessage * Improve numeric keys stability * Fallback to collection perms when sanitizing missing items * Add tests * Sanitize encrypt field special Co-authored-by: judda <[email protected]> * Fix double o2m edits not cleared in app * Reuse util * Clear relational detailed update syntax * Unify event sync to distributed bus * Catch unhandled promise rejections during test cleanup * Fix M2O null propagation by ensuring correct item context * Update api/src/websocket/handlers/collab/sanitize-payload.ts Co-authored-by: judda <[email protected]> * Consolidate watchers to resolve double join and race conditions * Allow metadata propagation in detailed relational updates * simplify discard message * early return on empty updateAll message * improve discard further * fix tests * Consolidate and optimize payload validation and sanitization * fix permission check on discard * fix collab connecting when it shouldn't * maybe fix room closure bug * Polish Co-authored-by: judda <[email protected]> * Check singleton create * Reconcile M2O objects * fix orphan clients cleanup * cleanup and fix code further * move deep-map-with-schema to shared * improve logs * fix leave message * cleanup singleton check * remove duplicate perm check * improve message handler singleton check * fix self refernced relation disconnects * fix frontend user name containing null * fix * in discard * fix leave counter * fix race condition on edits being updated before fieldUpdate gets called * separate ws sdk * move collab sdk inside use-collab * remove unused imports * move collab folder 1 level up * fix test * fix headerCollab when formFieldLabel is hidden * Cleanup discard message in app * Discard should check read and update perms * Rename to collaborative editing * Add to telemetry * Move getSchema in * Fix renaming * use newer sdk functions * Remove moved files * fix rejoining rooms * Optimize discard * Collab editing design fixes (directus#26528) * Update avatar border styling and adjust x-small size in v-avatar component to match title baseline * Refactor HeaderCollab component to use UserPopover for user avatars * Remove unused template for HeaderCollab and clean up overlay-item component by deleting the "Avatars" span * Remove unnecessary blank line in HeaderCollab component styling * Move HeaderCollab to action slot and self align center * Add v-avatar border color and width variables * Add font-size comment for v-avatar in HeaderCollab component * Update v-avatar border width to use theme variable instead of local variable * Apply minor styles fixes * Refactor HeaderCollab component template by repositioning icons and margin rules * Refactor HeaderCollab slot position in other files * Enhance form field label styles by adding flex-grow property and adjusting HeaderCollab margin for improved layout * Remove unnecessary margin styles from header-collab in item and overlay-item components * format * Remove unnecessary hide-current and x-small prop from HeaderCollab component * improve focus handling * refactor v-avatar component to use a single component tag for clickable and non-clickable states * fix: adjust sizes in HeaderCollab * feat: add type prop to HeaderCollab for flexible usage in header and field contexts * fix: adjust HeaderCollab styling for field context and improve layout in form-field-label * fix: update HeaderCollab instances to use 'avatars' class for improved styling * refactor: replace HeaderCollab with CollabAvatars component across multiple files for consistent collaboration user display * fix eslint --------- Co-authored-by: ian <[email protected]> Co-authored-by: formfcw <[email protected]> * Rename blackbox for consistency * Handle empty buffers to prevent errors during race conditions or disconnects * Optimizations * Use debug instead of info * Cleanup on shutdown signal * Cleanup optimization * Add test and cleanup * Ensure sequential bus processing * Use isRelational util Co-authored-by: Florian C. Wachmann <[email protected]> * Fix import and accept DeepPartial * Wait for connection * fix too strict pk check * Improve bb flakiness * Unset should not acquire focus * Test sticky focus behavior * Update telemetry to include env accuracy * Use getter for reactivity * Ensure focus state initialization * Add composable tests * Await lock releasing * Update memory tests * Update translations * Add websockets_enabled to telemetry * Update changesets * Reduce LRU cache capacity to 2000 * Add missing await * Fix room cleanup * Fix non-existent items (null) skipping cache * Move zod to dependencies in @directus/types * Update lockfile * Fmt * Skip cache metadata calculation if invalidated Co-authored-by: judda <[email protected]> * Add reconnect param Co-authored-by: judda <[email protected]> * make relational disabled on focus again * only show 1st letter in CollabAvatars * fix: use collab typescript (directus#26549) * Refactor message handling in useCollab composable for type safety * Enhance type safety in useCollab composable by updating field definitions to use object syntax for nested fields * Add CollabUserInfo type for user data structure in useCollab composable * Update TODO links in useCollab to GH issue instead * Refactor field definitions in useCollab to use dot notation for nested avatar properties and keep types * Update field definitions in useCollab to utilize DirectusUser * Revert to object notation * fix sending leave message on item delete * Optimize client room lookup to check local node only (directus#26569) * Optimize client room lookup to check local node only * Update test * Update comment * Update wording Co-authored-by: Nitwel <[email protected]> --------- Co-authored-by: Nitwel <[email protected]> * Replace tooltip with VList and current state * update unknown user to use icon instead * code cleanup * Refactor collaboration components: replace CollabAvatars with CollabField and CollabHeader in various files for improved user display and functionality. * Remove unnecessary mouseleave event from VAvatar in CollabHeader for cleaner user interaction. * Fix blackbox create policy naming * Format and linting * Adding new translation keys for editing and viewing states * Remove unnecessary flex properties from .v-list-item in CollabHeader for improved layout consistency. * Remove unused more-button CSS rules from CollabField.vue * Remove unused classes on collab field * Remove unused .user-status class from CollabHeader.vue for cleaner CSS * Update user count display in CollabHeader.vue to reflect DISPLAY_LIMIT instead of a hardcoded value for better maintainability. * Add focused and connectionId props to CollabHeader in item.vue and overlay-item.vue for enhanced collaboration features * Refactor CollabHandler to streamline client accountability checks in onJoin method. Removed redundant checks for unauthenticated clients and improved handling of share accounts. * Refactor CollabHeader and related components for improved readability by formatting template code and enhancing the structure of conditional rendering. * Update CollabHeader.vue to replace min-width with min-inline-size for better CSS compatibility. * Update CollabHeader.vue to handle unknown user names and adjust gap spacing for improved layout consistency. * Update English translations in en-US.yaml to use curly quotes for the collab_editing_field string. * Add cursor style to CollabField component for better user experience * Add popover for current user * Add invert prop to VMenu component for color customization and update CollabHeader to utilize the new feature. * Refactor collaboration components to reuse logic * remove unrelated changesets * Rename CollabField and CollabHeader imports to CollabIndicatorField and CollabIndicatorHeader across multiple components * remove unintended change * Refactor CSS class names for collab styles components for consistency * improve typography * Refactor CollabIndicatorHeader to use VList and VListItem for user display and ensure only avatars currently editing are clickable * Refactor CSS for CollabIndicatorHeader to remove redundant styles for avatar margins * Refactor Collab components to utilize getFocusId utility for generating user focus IDs and add unit tests for getFocusId functionality. * Update CollabIndicatorField and CollabIndicatorHeader to handle unknown user names gracefully by using translation fallback. * Update CollabIndicatorHeader to conditionally enable clickable avatars based on user focus state * Add translation for current user in collaborative editing context * Add collaboration state indicators and minor design updates for user editing/viewing status * Fix import formatting in utils.test.ts for consistency * Update CollabIndicatorHeader to correctly identify the current user based on connection * Refactor translation key for current user in collaborative editing context to improve clarity and consistency in CollabIndicatorHeader component. * Improve formatting of user name display in CollabIndicatorHeader component for better readability. --------- Co-authored-by: ian <[email protected]> Co-authored-by: Nitwel <[email protected]> Co-authored-by: judda <[email protected]> Co-authored-by: formfcw <[email protected]>
barry86m
added a commit
to barry86m/directus-private-view-header-bar-title-thumbnail-fix
that referenced
this pull request
Feb 16, 2026
This reverts commit 708b17c.
barry86m
added a commit
to barry86m/directus-private-view-header-bar-title-thumbnail-fix
that referenced
this pull request
Feb 16, 2026
This reverts commit 708b17c.
AlexGaillard
pushed a commit
that referenced
this pull request
Feb 18, 2026
* Remove room * Add missing await * Patch unit tests * Merge async deepMapWithSchema and refactor sanitization * Fix usages and tests * Fix relational null updates treated as objects * Prevent unauthorized field unsets and relationship updates * Propagate item deletion * Simplify room lifecycle and add recovery * Update tests * Implement distributed cleanup and standardize env configuration * Cleanup and refactor to RoomManager * Address CodeQL warning * Add blackbox tests * Handle integer PK and handle invalid schema * add error messages to client * fix error types * Add basic deep relational tests * Patch tests and improve websocket transport * remove unused import * add frontend delete * improve error handling and fix item delete * clearn up room logic * update tests * Update blackbox tests * Use waitForMatchingMessage * Specify timeout for seeding * Improve tests * fix room tests * fix sanitize-payload and verify-permissions * update discard banner in app * Implicitly switch focus when updating * Try accounting for misordered messages * clean console * Fix build * fmt * fmt * fmt * Verify permissions before relational processing * Improve update clearing * Fix double join events * Fix disconnected icon when disabled * Handle error from getService * Pass collab context to overlay * Broadcast to all users to fix relational item not receiving update * Skip disabling interfaces with relational specials * Add shared discard and drawer refinements * sync item update notification * fix double save message in frontend * Add collab for users and files * fix join error showing on non existent items * Reset changes when last person leaves * don't focus on focused fields * fix headerCollab not showing with coll-template * Check if values has changed on update * fix page header hiding collab * Remove unused imports * Fix versioned propagation * Improve copy * Fix delete handler * Update collab tests * fmt * Update comments * fix making color tab persistent * only enable collab if needed * fix wrong collision on no changes * Validate changes on join and update * Update packages/utils/shared/generate-joi.ts Co-authored-by: judda <[email protected]> * Simplify permission tagging and add integration test * Test color propagation * Fix rerun constraint * Optional colors * cleanup code * Add namespace config and fix redlock * update room functions to use global memory * code cleanup * Add fields to discard * Fix messenger mock * fix m2m and m2a and initialChanges in frontend * Mock global rooms * update error types and improve verify permissions * add version permission check * Match message instead * Add missing await for version check * Ensure consistent error types and patch tests * Fix lint * Fix version perms check * Update mock and errors * Use fake timers * Improve collab disabling * Add leader based room closure * Optimize distributed messaging and implement non-blocking termination * Optimize with validateItemAccess Co-authored-by: judda <[email protected]> * Streamline field permissions check * Fix focus erroring * Try improve blackbox stability with waitForMatchingMessage * Improve numeric keys stability * Fallback to collection perms when sanitizing missing items * Add tests * Sanitize encrypt field special Co-authored-by: judda <[email protected]> * Fix double o2m edits not cleared in app * Reuse util * Clear relational detailed update syntax * Unify event sync to distributed bus * Catch unhandled promise rejections during test cleanup * Fix M2O null propagation by ensuring correct item context * Update api/src/websocket/handlers/collab/sanitize-payload.ts Co-authored-by: judda <[email protected]> * Consolidate watchers to resolve double join and race conditions * Allow metadata propagation in detailed relational updates * simplify discard message * early return on empty updateAll message * improve discard further * fix tests * Consolidate and optimize payload validation and sanitization * fix permission check on discard * fix collab connecting when it shouldn't * maybe fix room closure bug * Polish Co-authored-by: judda <[email protected]> * Check singleton create * Reconcile M2O objects * fix orphan clients cleanup * cleanup and fix code further * move deep-map-with-schema to shared * improve logs * fix leave message * cleanup singleton check * remove duplicate perm check * improve message handler singleton check * fix self refernced relation disconnects * fix frontend user name containing null * fix * in discard * fix leave counter * fix race condition on edits being updated before fieldUpdate gets called * separate ws sdk * move collab sdk inside use-collab * remove unused imports * move collab folder 1 level up * fix test * fix headerCollab when formFieldLabel is hidden * Cleanup discard message in app * Discard should check read and update perms * Rename to collaborative editing * Add to telemetry * Move getSchema in * Fix renaming * use newer sdk functions * Remove moved files * fix rejoining rooms * Optimize discard * Collab editing design fixes (#26528) * Update avatar border styling and adjust x-small size in v-avatar component to match title baseline * Refactor HeaderCollab component to use UserPopover for user avatars * Remove unused template for HeaderCollab and clean up overlay-item component by deleting the "Avatars" span * Remove unnecessary blank line in HeaderCollab component styling * Move HeaderCollab to action slot and self align center * Add v-avatar border color and width variables * Add font-size comment for v-avatar in HeaderCollab component * Update v-avatar border width to use theme variable instead of local variable * Apply minor styles fixes * Refactor HeaderCollab component template by repositioning icons and margin rules * Refactor HeaderCollab slot position in other files * Enhance form field label styles by adding flex-grow property and adjusting HeaderCollab margin for improved layout * Remove unnecessary margin styles from header-collab in item and overlay-item components * format * Remove unnecessary hide-current and x-small prop from HeaderCollab component * improve focus handling * refactor v-avatar component to use a single component tag for clickable and non-clickable states * fix: adjust sizes in HeaderCollab * feat: add type prop to HeaderCollab for flexible usage in header and field contexts * fix: adjust HeaderCollab styling for field context and improve layout in form-field-label * fix: update HeaderCollab instances to use 'avatars' class for improved styling * refactor: replace HeaderCollab with CollabAvatars component across multiple files for consistent collaboration user display * fix eslint --------- Co-authored-by: ian <[email protected]> Co-authored-by: formfcw <[email protected]> * Rename blackbox for consistency * Handle empty buffers to prevent errors during race conditions or disconnects * Optimizations * Use debug instead of info * Cleanup on shutdown signal * Cleanup optimization * Add test and cleanup * Ensure sequential bus processing * Use isRelational util Co-authored-by: Florian C. Wachmann <[email protected]> * Fix import and accept DeepPartial * Wait for connection * fix too strict pk check * Improve bb flakiness * Unset should not acquire focus * Test sticky focus behavior * Update telemetry to include env accuracy * Use getter for reactivity * Ensure focus state initialization * Add composable tests * Await lock releasing * Update memory tests * Update translations * Add websockets_enabled to telemetry * Update changesets * Reduce LRU cache capacity to 2000 * Add missing await * Fix room cleanup * Fix non-existent items (null) skipping cache * Move zod to dependencies in @directus/types * Update lockfile * Fmt * Skip cache metadata calculation if invalidated Co-authored-by: judda <[email protected]> * Add reconnect param Co-authored-by: judda <[email protected]> * make relational disabled on focus again * only show 1st letter in CollabAvatars * fix: use collab typescript (#26549) * Refactor message handling in useCollab composable for type safety * Enhance type safety in useCollab composable by updating field definitions to use object syntax for nested fields * Add CollabUserInfo type for user data structure in useCollab composable * Update TODO links in useCollab to GH issue instead * Refactor field definitions in useCollab to use dot notation for nested avatar properties and keep types * Update field definitions in useCollab to utilize DirectusUser * Revert to object notation * fix sending leave message on item delete * Optimize client room lookup to check local node only (#26569) * Optimize client room lookup to check local node only * Update test * Update comment * Update wording Co-authored-by: Nitwel <[email protected]> --------- Co-authored-by: Nitwel <[email protected]> * Replace tooltip with VList and current state * update unknown user to use icon instead * code cleanup * Refactor collaboration components: replace CollabAvatars with CollabField and CollabHeader in various files for improved user display and functionality. * Remove unnecessary mouseleave event from VAvatar in CollabHeader for cleaner user interaction. * Fix blackbox create policy naming * Format and linting * Adding new translation keys for editing and viewing states * Remove unnecessary flex properties from .v-list-item in CollabHeader for improved layout consistency. * Remove unused more-button CSS rules from CollabField.vue * Remove unused classes on collab field * Remove unused .user-status class from CollabHeader.vue for cleaner CSS * Update user count display in CollabHeader.vue to reflect DISPLAY_LIMIT instead of a hardcoded value for better maintainability. * Add focused and connectionId props to CollabHeader in item.vue and overlay-item.vue for enhanced collaboration features * Refactor CollabHandler to streamline client accountability checks in onJoin method. Removed redundant checks for unauthenticated clients and improved handling of share accounts. * Refactor CollabHeader and related components for improved readability by formatting template code and enhancing the structure of conditional rendering. * Update CollabHeader.vue to replace min-width with min-inline-size for better CSS compatibility. * Update CollabHeader.vue to handle unknown user names and adjust gap spacing for improved layout consistency. * Update English translations in en-US.yaml to use curly quotes for the collab_editing_field string. * Add cursor style to CollabField component for better user experience * Add popover for current user * Add invert prop to VMenu component for color customization and update CollabHeader to utilize the new feature. * Refactor collaboration components to reuse logic * remove unrelated changesets * Rename CollabField and CollabHeader imports to CollabIndicatorField and CollabIndicatorHeader across multiple components * remove unintended change * Refactor CSS class names for collab styles components for consistency * improve typography * Refactor CollabIndicatorHeader to use VList and VListItem for user display and ensure only avatars currently editing are clickable * Refactor CSS for CollabIndicatorHeader to remove redundant styles for avatar margins * Refactor Collab components to utilize getFocusId utility for generating user focus IDs and add unit tests for getFocusId functionality. * Update CollabIndicatorField and CollabIndicatorHeader to handle unknown user names gracefully by using translation fallback. * Update CollabIndicatorHeader to conditionally enable clickable avatars based on user focus state * Add translation for current user in collaborative editing context * Add collaboration state indicators and minor design updates for user editing/viewing status * Fix import formatting in utils.test.ts for consistency * Update CollabIndicatorHeader to correctly identify the current user based on connection * Refactor translation key for current user in collaborative editing context to improve clarity and consistency in CollabIndicatorHeader component. * Improve formatting of user name display in CollabIndicatorHeader component for better readability. --------- Co-authored-by: ian <[email protected]> Co-authored-by: Nitwel <[email protected]> Co-authored-by: judda <[email protected]> Co-authored-by: formfcw <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
What's changed:
CollabAvatarsinto two focused components:CollabIndicatorHeader(item header) andCollabIndicatorField(form field label)(you)labelfocusedandconnectionIdfromuseCollabcomposableinvertprop toVMenufor dark popover stylingcollab/utils.tswithformatUserAvatarandgetFocusIdutilitiesformatUserAvatarandgetFocusIdPotential Risks / Drawbacks
VMenuinvertprop adds a new styling variant — should be reviewed for consistency with existing dark UI patternsTested Scenarios
collab/utils.tsReview Notes / Questions
VMenuinvertprop implementationdocument.getElementByIdwith field keys as IDsChecklist