diff --git a/src/admin/src/components/identities/IdentityDetail.vue b/src/admin/src/components/identities/IdentityDetail.vue index 9f52225..76c8494 100755 --- a/src/admin/src/components/identities/IdentityDetail.vue +++ b/src/admin/src/components/identities/IdentityDetail.vue @@ -320,6 +320,7 @@ const props = defineProps(); const emit = defineEmits<{ 'update:modelValue': [value: boolean]; deleted: [identityId: number]; + updated: [identity: IdentityResponse]; }>(); const contextStore = useContextStore(); @@ -420,6 +421,10 @@ watch( { immediate: true }, ); +watch(activeTab, (tab) => { + if (tab === 'segments') loadSegmentsData(); +}); + async function onToggleOverride(override: FeatureStateResponse, enabled: boolean | null): Promise { if (enabled === null || !props.identity) return; const envApiKey = contextStore.currentEnvironment?.apiKey; @@ -489,6 +494,12 @@ async function onAddOverride(): Promise { } } +function emitTraitsUpdated(): void { + if (props.identity) { + emit('updated', { ...props.identity, traits: [...editedTraits.value] }); + } +} + async function onSaveTrait(key: string, value: string): Promise { if (!props.identity) return; const envApiKey = contextStore.currentEnvironment?.apiKey; @@ -499,6 +510,7 @@ async function onSaveTrait(key: string, value: string): Promise { await upsertIdentityTrait(envApiKey, props.identity.id, key, { value }); const idx = editedTraits.value.findIndex((t: TraitResponse) => t.key === key); if (idx >= 0) editedTraits.value[idx] = { key, value }; + emitTraitsUpdated(); } catch { traitsError.value = 'Failed to save trait. Please try again.'; } finally { @@ -515,6 +527,7 @@ async function onDeleteTrait(key: string): Promise { try { await deleteIdentityTrait(envApiKey, props.identity.id, key); editedTraits.value = editedTraits.value.filter((t: TraitResponse) => t.key !== key); + emitTraitsUpdated(); } catch { traitsError.value = 'Failed to delete trait. Please try again.'; } finally { @@ -540,6 +553,7 @@ async function onAddTrait(): Promise { } newTraitKey.value = ''; newTraitValue.value = ''; + emitTraitsUpdated(); } catch { traitsError.value = 'Failed to add trait. Please try again.'; } finally { diff --git a/src/admin/src/views/IdentitiesView.vue b/src/admin/src/views/IdentitiesView.vue index 6d1779b..07094bd 100755 --- a/src/admin/src/views/IdentitiesView.vue +++ b/src/admin/src/views/IdentitiesView.vue @@ -91,6 +91,7 @@ v-model="showDetail" :identity="selectedIdentity" @deleted="onIdentityDeleted" + @updated="onIdentityUpdated" /> @@ -246,6 +247,12 @@ function onCreateDialogClosed(): void { createError.value = null; } +function onIdentityUpdated(updated: IdentityResponse): void { + const idx = identities.value.findIndex((i) => i.id === updated.id); + if (idx >= 0) identities.value[idx] = updated; + selectedIdentity.value = updated; +} + function onIdentityDeleted(identityId: number): void { identities.value = identities.value.filter((i) => i.id !== identityId); showDetail.value = false; diff --git a/src/api/MicCheck.Api/Identities/UpsertTraitRequest.cs b/src/api/MicCheck.Api/Identities/UpsertTraitRequest.cs index 5dfa49d..60b9a32 100755 --- a/src/api/MicCheck.Api/Identities/UpsertTraitRequest.cs +++ b/src/api/MicCheck.Api/Identities/UpsertTraitRequest.cs @@ -1,3 +1,3 @@ namespace MicCheck.Api.Identities; -public record UpsertTraitRequest(string Key, string Value); +public record UpsertTraitRequest(string Value);