Skip to content

tech-debt(frontend): the display-name fallback is re-implemented six times with two extra rungs #14939

Description

@mrveiss

Found while closing #13957 in #14936, which converged the five Python copies of this rule onto UserCore.full_name / resolve_display_name(). The frontend half was out of that issue's stated scope.

Gap

"Show display_name, fall back to username" is re-implemented in the frontend too, with two more fallback depths than the backend had:

file expression terminus
components/collaboration/InviteUserDialog.vue user.display_name || user.username username
views/llc/MembersView.vue u.display_name || u.username username
views/llc/MembersView.vue member.display_name || member.user_id raw id
composables/llc/useCompanyPeople.ts m.display_name || m.user_id raw id
components/knowledge/ShareKnowledgeDialog.vue userData.display_name || userData.email || userData.username || id email rung, unique to this site
views/AdminUsersView.vue user.display_name || '—' em-dash, no username fallback

Root cause worth fixing first

The || m.user_id rungs exist because the two LLC endpoints disagree about who owns the last rung:

  • list_members can return display_name: null for a membership whose user row is gone, so the client has to invent a label.
  • _compose_human_nodes already resolves that case server-side to str(user_id).

So the frontend compensates for one endpoint and duplicates the other. Aligning the two endpoints removes the reason for two of the six copies, and should happen before a shared frontend helper is written — otherwise the helper just encodes the inconsistency.

AdminUsersView's em-dash terminus is a separate divergence: it renders a blank-looking cell where every other surface renders a username.

Ask

  • Decide the single fallback ladder and which side owns each rung.
  • Make the LLC endpoints agree, then one shared frontend helper for the render-time rule.
  • No hardcoded UI strings — the em-dash terminus needs an i18n key across all 11 locales if it survives.

Related

Activity

  1. mrveiss commented on Sep 11, 2026

    @mrveiss
    OwnerAuthor

    Closing. Delivered by #16265, squash 4da66c79d9 on Dev_new_gui (landed in merge train #16339, tree-equal to its tested run). Each ask is verified on base a12b4bf79d:

    • One fallback ladder is decided, with an owner for each rung.
      • The server owns the user-id rung. autobot-backend/llc/api/companies.py:610 has list_members returning resolve_display_name(names.get(m.user_id), None, str(m.user_id)). That matches _compose_human_nodes (:1051, resolve_display_name(display_name, username, str(user_id))), so display_name is never null.
      • The frontend owns the render-time rule. src/utils/displayName.ts's displayNameOf() returns display_name || username || fallback.
    • The LLC endpoints agree, and there is one shared frontend helper.
      • No display_name || …user_id fallback is left in autobot-frontend/src (0 matches).
      • displayNameOf is used at InviteUserDialog.vue:105, ShareKnowledgeDialog.vue:210 and views/llc/MembersView.vue:98.
      • MembersView.vue:52 and useCompanyPeople.ts:83,88 render the now server-resolved display_name directly.
      • ShareKnowledgeDialog's unique email rung is gone (0 matches).
      • src/utils/__tests__/displayName.test.ts pins the ladder.
    • No hardcoded UI strings. AdminUsersView.vue:66 renders user.display_name || t('adminUsers.displayNameNotSet'), and that key is present in 11 of 11 locale files. Its "not set" meaning is deliberate, because the column sits beside a separate username column.

    Also seen: AdminUsersView.vue:83 still renders '—' for an empty voice-bundle cell. That's a different column, outside this issue's scope. It's a typographic placeholder rather than translatable text, which is why it isn't filed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions