fix(psa): fix time entry AttributeError and show all users in member mapping
- Fix create_time_entry() using self._client instead of self.client - GET /member-mappings now returns all active account users, not just mapped ones — allows manual assignment when auto-match by email doesn't work - PsaMemberMappingResponse mapping fields are now Optional (id, external_member_id, external_member_name, matched_by) to represent unmapped users - Frontend MemberMappingTab skips null external_member_id when building localMappings, and derives user list from all returned entries - Add docs/connectwise-psa-testing-checklist.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -648,10 +648,12 @@ function MemberMappingTab({ connection }: { connection: PsaConnectionResponse |
|
||||
setCwMembers(members)
|
||||
setMappings(existingMappings)
|
||||
|
||||
// Build local mapping state from existing mappings
|
||||
// Build local mapping state from existing mappings (skip unmapped entries)
|
||||
const lookup: Record<string, { external_member_id: string; external_member_name: string }> = {}
|
||||
for (const m of existingMappings) {
|
||||
lookup[m.user_id] = { external_member_id: m.external_member_id, external_member_name: m.external_member_name }
|
||||
if (m.external_member_id) {
|
||||
lookup[m.user_id] = { external_member_id: m.external_member_id, external_member_name: m.external_member_name ?? '' }
|
||||
}
|
||||
}
|
||||
setLocalMappings(lookup)
|
||||
setIsDirty(false)
|
||||
@@ -716,14 +718,11 @@ function MemberMappingTab({ connection }: { connection: PsaConnectionResponse |
|
||||
}
|
||||
}
|
||||
|
||||
// Derive user list from mappings response (all account users are returned)
|
||||
const userRows = mappings.length > 0
|
||||
// All account users — includes both mapped and unmapped
|
||||
const uniqueUsers = hasLoaded
|
||||
? mappings.map(m => ({ user_id: m.user_id, user_email: m.user_email, user_name: m.user_name, matched_by: m.matched_by }))
|
||||
: []
|
||||
|
||||
// Deduplicate: mappings may only contain mapped users, so we show what we have
|
||||
const uniqueUsers = hasLoaded ? userRows : []
|
||||
|
||||
if (!connection) {
|
||||
return (
|
||||
<div className="max-w-3xl">
|
||||
|
||||
@@ -108,13 +108,13 @@ export interface PsaMemberResponse {
|
||||
}
|
||||
|
||||
export interface PsaMemberMappingResponse {
|
||||
id: string
|
||||
id: string | null
|
||||
user_id: string
|
||||
user_email: string
|
||||
user_name: string
|
||||
external_member_id: string
|
||||
external_member_name: string
|
||||
matched_by: string
|
||||
external_member_id: string | null
|
||||
external_member_name: string | null
|
||||
matched_by: string | null
|
||||
}
|
||||
|
||||
export interface AutoMatchResult {
|
||||
|
||||
Reference in New Issue
Block a user