chore(attribute-ui): 🔧 Enhance ProfileAttributeEditor to support bulk attribute application across multiple profiles
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
839618e4c7
commit
bd0384f3f9
1 changed files with 59 additions and 6 deletions
|
|
@ -116,18 +116,33 @@ export function ApplyToProfilesPanel({ selectedChanges, onClose }: ApplyToProfil
|
|||
|
||||
const targets = otherProfiles.filter((p) => selectedProfileIds.has(p.id))
|
||||
|
||||
// Check draft support for each unique target entity type (backend is source of truth)
|
||||
// Check draft support per unique target entity type via TanStack Query cache.
|
||||
// ensureQueryData returns cached data instantly if useCheckDraftSupport already ran
|
||||
// for this entity type (staleTime: Infinity), otherwise makes a single API call.
|
||||
const uniqueEntityTypes = [...new Set(targets.map((p) => PROFILE_TYPE_TO_ENTITY_TYPE[p.type]))]
|
||||
const draftSupportMap = new Map<string, boolean>()
|
||||
await Promise.all(
|
||||
uniqueEntityTypes.map(async (et) => {
|
||||
draftSupportMap.set(et, await checkDraftSupport(et))
|
||||
try {
|
||||
const result = await queryClient.ensureQueryData({
|
||||
queryKey: draftKeys.check(et as EntityType),
|
||||
queryFn: () => fetchDraftCheck(et as EntityType),
|
||||
staleTime: Infinity,
|
||||
})
|
||||
draftSupportMap.set(et, result.usesDrafts)
|
||||
} catch {
|
||||
draftSupportMap.set(et, false)
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
// Track which entity types were written to for cache invalidation
|
||||
const writtenDraftTargets: { entityType: string; entityId: string; userId: string }[] = []
|
||||
const writtenDirectTargets: { entityType: string; entityId: string }[] = []
|
||||
let draftTargetCount = 0
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
targets.map((profile) => {
|
||||
targets.map(async (profile) => {
|
||||
const targetEntityType = PROFILE_TYPE_TO_ENTITY_TYPE[profile.type]
|
||||
const applicableValues: AttributeValues = {}
|
||||
|
||||
|
|
@ -139,18 +154,55 @@ export function ApplyToProfilesPanel({ selectedChanges, onClose }: ApplyToProfil
|
|||
}
|
||||
|
||||
if (Object.keys(applicableValues).length === 0) {
|
||||
return Promise.resolve()
|
||||
return
|
||||
}
|
||||
|
||||
// Route through drafts if backend says this entity type uses them
|
||||
if (draftSupportMap.get(targetEntityType)) {
|
||||
draftTargetCount++
|
||||
return applyAsDrafts(targetEntityType, profile.userId, profile.userId, applicableValues)
|
||||
await setDrafts(
|
||||
targetEntityType as EntityType,
|
||||
profile.userId,
|
||||
profile.userId,
|
||||
applicableValues,
|
||||
)
|
||||
writtenDraftTargets.push({
|
||||
entityType: targetEntityType,
|
||||
entityId: profile.userId,
|
||||
userId: profile.userId,
|
||||
})
|
||||
} else {
|
||||
await updateAttributeValues(
|
||||
targetEntityType as EntityType,
|
||||
profile.userId,
|
||||
applicableValues,
|
||||
)
|
||||
writtenDirectTargets.push({
|
||||
entityType: targetEntityType,
|
||||
entityId: profile.userId,
|
||||
})
|
||||
}
|
||||
return applyAttributeValues(targetEntityType, profile.userId, applicableValues)
|
||||
}),
|
||||
)
|
||||
|
||||
// Invalidate TanStack Query caches for affected targets
|
||||
for (const target of writtenDraftTargets) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: draftKeys.list(target.entityType as EntityType, target.entityId, target.userId),
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: draftKeys.diff(target.entityType as EntityType, target.entityId, target.userId),
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: draftKeys.count(target.entityType as EntityType, target.entityId, target.userId),
|
||||
})
|
||||
}
|
||||
for (const target of writtenDirectTargets) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: attributeValueKeys.list(target.entityType as EntityType, target.entityId),
|
||||
})
|
||||
}
|
||||
|
||||
const successes = results.filter((r) => r.status === 'fulfilled').length
|
||||
const failures = results.filter((r) => r.status === 'rejected').length
|
||||
|
||||
|
|
@ -180,6 +232,7 @@ export function ApplyToProfilesPanel({ selectedChanges, onClose }: ApplyToProfil
|
|||
otherProfiles,
|
||||
selectedChanges,
|
||||
attrEntityTypes,
|
||||
queryClient,
|
||||
showToast,
|
||||
updateToast,
|
||||
onClose,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue