feat(tenancy): expandable per-store rows in merchant team table
Some checks failed
CI / pytest (push) Has been cancelled
CI / ruff (push) Successful in 14s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled

Member rows now show a store count with expand/collapse chevron.
Clicking expands sub-rows showing each store with:
- Store name and code
- Per-store role badge
- Per-store status (active/pending independently)
- Per-store actions: resend invitation (pending), remove from store

This fixes the issue where a member active on one store but pending
on another showed misleading combined status and actions.

Member-level actions (view, edit profile) stay on the main row.
Store-level actions (resend, remove) are on each sub-row.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 23:32:47 +02:00
parent f310363f7c
commit 4748368809
2 changed files with 146 additions and 77 deletions

View File

@@ -31,6 +31,9 @@ function merchantTeam() {
// Filters
storeFilter: '',
// Expanded member rows
expandedMembers: [],
// Modal states
showInviteModal: false,
showEditModal: false,
@@ -128,6 +131,39 @@ function merchantTeam() {
);
},
/**
* Toggle expand/collapse for a member's store rows
*/
toggleMemberExpand(userId) {
const idx = this.expandedMembers.indexOf(userId);
if (idx > -1) {
this.expandedMembers.splice(idx, 1);
} else {
this.expandedMembers.push(userId);
}
},
/**
* Resend invitation for a specific store membership
*/
async resendStoreInvitation(storeId, userId) {
this.saving = true;
try {
await apiClient.post(
`/merchants/account/team/stores/${storeId}/members/${userId}/resend`
);
Utils.showToast(I18n.t('tenancy.messages.invitation_resent'), 'success');
merchantTeamLog.info('Resent invitation for store:', storeId, 'user:', userId);
await this.loadTeamData();
} catch (error) {
merchantTeamLog.error('Failed to resend invitation:', error);
Utils.showToast(error.message || 'Failed to resend invitation', 'error');
} finally {
this.saving = false;
}
},
/**
* Open invite modal with reset form
*/