fix(GroupModal): fix the display of a child group (show it's name rather it's UUID)
This commit is contained in:
@@ -60,6 +60,14 @@ const groupsView = {
|
|||||||
/** @type {GroupMemberItem[]} — direct members of the current group */
|
/** @type {GroupMemberItem[]} — direct members of the current group */
|
||||||
_members: [],
|
_members: [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Id → full `GroupItem` for every nested group seen in `_members`.
|
||||||
|
* `listMembers` only emits `{kind, id}`, so we resolve names + virtual
|
||||||
|
* flag separately via `groups.resolveGroups` and look them up here.
|
||||||
|
* @type {Record<string, import('../../core/types.js').GroupItem>}
|
||||||
|
*/
|
||||||
|
_memberGroupMeta: {},
|
||||||
|
|
||||||
/** @type {GroupItem[]} — most recent list page */
|
/** @type {GroupItem[]} — most recent list page */
|
||||||
_items: [],
|
_items: [],
|
||||||
_nextOffset: 0,
|
_nextOffset: 0,
|
||||||
@@ -331,12 +339,33 @@ const groupsView = {
|
|||||||
const [group, members] = await Promise.all([groups.get(groupId), groups.listMembers(groupId)]);
|
const [group, members] = await Promise.all([groups.get(groupId), groups.listMembers(groupId)]);
|
||||||
this._currentGroup = group;
|
this._currentGroup = group;
|
||||||
this._members = members;
|
this._members = members;
|
||||||
|
await this._refreshMemberGroupMeta();
|
||||||
this._renderDetailInto(this._bodyEl);
|
this._renderDetailInto(this._bodyEl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._showFatalError(/** @type {Error} */ (err).message);
|
this._showFatalError(/** @type {Error} */ (err).message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve full GroupItem records for every nested-group member of the
|
||||||
|
* current group. `listMembers` returns just `{kind, id}` so without
|
||||||
|
* this the rows would render the raw UUID. One batch search covers
|
||||||
|
* all nested groups visible in the detail view.
|
||||||
|
*/
|
||||||
|
async _refreshMemberGroupMeta() {
|
||||||
|
const ids = new Set(this._members.filter((m) => m.kind === 'group').map((m) => m.id));
|
||||||
|
if (ids.size === 0) {
|
||||||
|
this._memberGroupMeta = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this._memberGroupMeta = await groups.resolveGroups(ids);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('groupsView: failed to resolve nested-group names', err);
|
||||||
|
this._memberGroupMeta = {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/** @param {HTMLElement} root */
|
/** @param {HTMLElement} root */
|
||||||
_renderDetailInto(root) {
|
_renderDetailInto(root) {
|
||||||
const group = this._currentGroup;
|
const group = this._currentGroup;
|
||||||
@@ -430,11 +459,16 @@ const groupsView = {
|
|||||||
if (m.kind === 'user') {
|
if (m.kind === 'user') {
|
||||||
row.appendChild(createUserVignette(m.id, 'sm', { showEmail: true }));
|
row.appendChild(createUserVignette(m.id, 'sm', { showEmail: true }));
|
||||||
} else {
|
} else {
|
||||||
// Nested group — show the vignette. We don't pre-load the name
|
// Nested group — `listMembers` only returned `{kind, id}`, so
|
||||||
// (it's just the id from the API). To get the name we'd need an
|
// the resolved name + virtual flag come from `_memberGroupMeta`
|
||||||
// extra fetch; for v1, show the id-as-name (small UX cost) and
|
// (populated by `_refreshMemberGroupMeta` after every list-of-
|
||||||
// upgrade once `list_direct_members` returns enriched rows.
|
// members reload). Fallback to the id if the resolver couldn't
|
||||||
row.appendChild(createGroupVignette(m.id, 'sm'));
|
// find it (rare — would mean the group was deleted between the
|
||||||
|
// listMembers and the resolveGroups call).
|
||||||
|
const meta = this._memberGroupMeta[m.id];
|
||||||
|
const displayName = meta ? groupDisplayName(meta) : m.id;
|
||||||
|
const icon = meta ? groupIconClass(meta) : 'fa-user-group';
|
||||||
|
row.appendChild(createGroupVignette(displayName, 'sm', { icon }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._currentGroup?.can_manage && !this._currentGroup?.is_virtual) {
|
if (this._currentGroup?.can_manage && !this._currentGroup?.is_virtual) {
|
||||||
@@ -763,6 +797,7 @@ const groupsView = {
|
|||||||
try {
|
try {
|
||||||
await groups.addUserMember(group.id, userId);
|
await groups.addUserMember(group.id, userId);
|
||||||
this._members = await groups.listMembers(group.id);
|
this._members = await groups.listMembers(group.id);
|
||||||
|
await this._refreshMemberGroupMeta();
|
||||||
this._renderDetailInto(this._bodyEl);
|
this._renderDetailInto(this._bodyEl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._showInlineError(/** @type {Error} */ (err).message);
|
this._showInlineError(/** @type {Error} */ (err).message);
|
||||||
@@ -776,6 +811,7 @@ const groupsView = {
|
|||||||
try {
|
try {
|
||||||
await groups.addGroupMember(group.id, groupId);
|
await groups.addGroupMember(group.id, groupId);
|
||||||
this._members = await groups.listMembers(group.id);
|
this._members = await groups.listMembers(group.id);
|
||||||
|
await this._refreshMemberGroupMeta();
|
||||||
this._renderDetailInto(this._bodyEl);
|
this._renderDetailInto(this._bodyEl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._showInlineError(/** @type {Error} */ (err).message);
|
this._showInlineError(/** @type {Error} */ (err).message);
|
||||||
@@ -793,6 +829,7 @@ const groupsView = {
|
|||||||
await groups.removeGroupMember(group.id, m.id);
|
await groups.removeGroupMember(group.id, m.id);
|
||||||
}
|
}
|
||||||
this._members = await groups.listMembers(group.id);
|
this._members = await groups.listMembers(group.id);
|
||||||
|
await this._refreshMemberGroupMeta();
|
||||||
this._renderDetailInto(this._bodyEl);
|
this._renderDetailInto(this._bodyEl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._showInlineError(/** @type {Error} */ (err).message);
|
this._showInlineError(/** @type {Error} */ (err).message);
|
||||||
|
|||||||
Reference in New Issue
Block a user