@cryptotaxi247 / CoPilot / commits / 48b81214

fix(users): reliably populate a user's assigned customers in Assign Customer (#899) (#900)

The per-row action dropdown in UsersList used a static `options` array whose render closures read `selectedUser.value`. Because the parent template never references `selectedUser` directly and every row's <n-dropdown> received the same stable array reference, changing `selectedUser` (via @click) never forced NDropdown to re-render. With `display-directive="show"` keeping the menu — and the AssignCustomer modal inside it — mounted, the modal kept a stale `user` prop (often the initial undefined), so loadCurrentAccess() hit its `if (!props.user) return` guard and silently populated nothing. It was intermittent because an unrelated re-render occasionally refreshed the closures. - UsersList.vue: make `options` a computed keyed on `selectedUser` so each selection yields a new array reference, forcing the dropdown to re-render its render closures with the current user. Fixes the same latent bug in the sibling actions (AssignRole, AssignTags, ChangePassword, DeleteUser). - AssignCustomer.vue: reload access when the bound user changes while the modal is open, and clear stale state otherwise, so a previous user's data is never shown. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

taylor_socfortress committed Jun 1, 2026 at 12:23 UTC 48b81214eec272725820b1ce1ce5af5964d645b2
2 files changed +23 -2
frontend/src/components/users/AssignCustomer.vue
+15
@@ -146,4 +146,19 @@ watch(showModal, newVal => {
146 loadCurrentAccess()
147 }
148 })
149 +
150 +// This instance is reused across table rows, so the bound user can change while
151 +// mounted. Reload that user's access if it changes while the modal is open, and
152 +// clear stale state otherwise so a previous user's data is never shown. See #899.
153 +watch(
154 + () => props.user?.id,
155 + () => {
156 + if (showModal.value) {
157 + loadCurrentAccess()
158 + } else {
159 + currentAccess.value = []
160 + formModel.value.customerCodes = []
161 + }
162 + }
163 +)
164 </script>
frontend/src/components/users/UsersList.vue
+8 -2
@@ -153,7 +153,13 @@ function getRoleTagType(roleName: string | null | undefined) {
153 }
154 }
155
156 -const options = [
156 +// Computed (not a static array) so the dropdown re-renders whenever `selectedUser`
157 +// changes. The render closures below read `selectedUser.value`, but the parent
158 +// template never references it directly — if `options` were a stable array
159 +// reference, NDropdown would never re-render and the child modals (kept mounted by
160 +// `display-directive="show"`) would keep a stale `user` prop, intermittently
161 +// showing the wrong user's data or nothing at all. See issue #899.
162 +const options = computed(() => [
163 {
164 key: "AssignRole",
165 type: "render",
@@ -202,7 +208,7 @@ const options = [
208 onLoading: updateLoadingDelete
209 })
210 }
205 -]
211 +])
212
213 function updateLoadingDelete(value: boolean) {
214 loadingDelete.value = value