Fix identity trait add and persistence bugs

Remove Key from UpsertTraitRequest body (comes from URL route). Emit 'updated' event from IdentityDetail on trait mutations and sync parent. Reload segment data on tab activation and dialog open.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 12:45:45 -07:00
parent cbf1aba219
commit b59b56575f
3 changed files with 22 additions and 1 deletions

View File

@@ -320,6 +320,7 @@ const props = defineProps<Props>();
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<void> {
if (enabled === null || !props.identity) return;
const envApiKey = contextStore.currentEnvironment?.apiKey;
@@ -489,6 +494,12 @@ async function onAddOverride(): Promise<void> {
}
}
function emitTraitsUpdated(): void {
if (props.identity) {
emit('updated', { ...props.identity, traits: [...editedTraits.value] });
}
}
async function onSaveTrait(key: string, value: string): Promise<void> {
if (!props.identity) return;
const envApiKey = contextStore.currentEnvironment?.apiKey;
@@ -499,6 +510,7 @@ async function onSaveTrait(key: string, value: string): Promise<void> {
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<void> {
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<void> {
}
newTraitKey.value = '';
newTraitValue.value = '';
emitTraitsUpdated();
} catch {
traitsError.value = 'Failed to add trait. Please try again.';
} finally {

View File

@@ -91,6 +91,7 @@
v-model="showDetail"
:identity="selectedIdentity"
@deleted="onIdentityDeleted"
@updated="onIdentityUpdated"
/>
<!-- Create identity dialog -->
@@ -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;

View File

@@ -1,3 +1,3 @@
namespace MicCheck.Api.Identities;
public record UpsertTraitRequest(string Key, string Value);
public record UpsertTraitRequest(string Value);