[UI][VAULT-43922] Update serializer to factor in optional data obj in payload (#14197) (#14214) (#14216)

* fix(serializer):  update model serializer to factor in optional data obj with keys

* chore(changelog): add bug fix desc for changelog

Co-authored-by: Nina Bucholtz <nina.balachandranmary@gmail.com>
This commit is contained in:
Vault Automation 2026-04-23 10:39:27 -04:00 committed by GitHub
parent 1cdc4c28f4
commit 9b6b25087d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 2 deletions

3
changelog/_14197.txt Normal file
View file

@ -0,0 +1,3 @@
```release-note:bug
ui: Fix entities page to show success message after successfully editing an entity.
```

View file

@ -7,7 +7,10 @@ import ApplicationSerializer from '../application';
export default ApplicationSerializer.extend({
normalizeItems(payload) {
if (payload.data.keys && Array.isArray(payload.data.keys)) {
// Extract the keys array into individual objects with the key as the id, if it exists.
// This is for endpoints that return a list of keys and a separate key_info object with
// the details for each key, such as the list endpoint for entities.
if (payload.data?.keys && Array.isArray(payload.data?.keys)) {
if (typeof payload.data.keys[0] !== 'string') {
// If keys is not an array of strings, it was already normalized into objects in extractLazyPaginatedData
return payload.data.keys;

View file

@ -60,7 +60,11 @@
{{/if}}
{{/if}}
{{#if item.canEdit}}
<dd.Interactive @route="vault.cluster.access.identity.edit" @model={{item.id}}>Edit</dd.Interactive>
<dd.Interactive
data-test-popup-menu="edit"
@route="vault.cluster.access.identity.edit"
@model={{item.id}}
>Edit</dd.Interactive>
{{#if item.disabled}}
<dd.Interactive {{on "click" (action "toggleDisabled" item)}}>Enable</dd.Interactive>
{{else if (eq this.identityType "entity")}}

View file

@ -136,4 +136,47 @@ module('Acceptance | /access/identity/entities', function (hooks) {
const message = `There was a problem deleting entity: test - ${error}`;
assert.true(flashSpy.calledWith(message), 'Correct flash message is shown');
});
test('it should render correct flash message on entity edit success', async function (assert) {
server.get('/identity/entity/id', () => ({
data: {
key_info: { test: { name: 'foo' } },
keys: ['test'],
},
}));
server.get('/identity/entity/id/test', () => ({ data: { name: 'foo' } }));
server.put('/identity/entity/id/test', () => new Response(200, {}, {}));
const flashSpy = sinon.spy(this.owner.lookup('service:flashMessages'), 'success');
await page.visit({ item_type: 'entities' });
await click(`${SELECTORS.listItem('foo')} ${GENERAL.menuTrigger}`);
await click(`${SELECTORS.listItem('foo')} ${GENERAL.menuItem('edit')}`);
await click(GENERAL.submitButton);
const message = `Successfully saved Entity test.`;
assert.true(flashSpy.calledWith(message), 'Correct flash message is shown');
});
test('it should render correct flash message on entity edit failure', async function (assert) {
server.get('/identity/entity/id', () => ({
data: {
key_info: { test: { name: 'foo' } },
keys: ['test'],
},
}));
server.get('/identity/entity/id/test', () => ({ data: { name: 'foo' } }));
const error = 'The entity could not be edited';
server.put('/identity/entity/id/test', () => new Response(500, {}, { errors: [error] }));
await page.visit({ item_type: 'entities' });
await click(`${SELECTORS.listItem('foo')} ${GENERAL.menuTrigger}`);
await click(`${SELECTORS.listItem('foo')} ${GENERAL.menuItem('edit')}`);
await click(GENERAL.submitButton);
assert.dom(GENERAL.messageError).exists();
assert.dom(GENERAL.messageDescription).hasText(error, 'Specific error message is rendered');
});
});