Add pagination to namespace list view (#13195)

* Add client side pagination to namespaces

* Update namespace list after delete operation

* Added changelog

* Added tests

* Clean up

* Added comment for test

* Try ember run loop

* Run test only in enterprise

* Fixed test
This commit is contained in:
Arnav Palnitkar 2021-11-29 13:11:14 -08:00 committed by GitHub
parent 32152e10fd
commit 0a11076322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 141 additions and 9 deletions

3
changelog/13195.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
ui: Added client side paging for namespace list view
```

View File

@ -31,4 +31,7 @@ export default ApplicationAdapter.extend({
} }
return this._super(...arguments); return this._super(...arguments);
}, },
query() {
return this.ajax(`/${this.urlPrefix()}/namespaces?list=true`);
},
}); });

View File

@ -9,6 +9,7 @@ export default Controller.extend({
refreshNamespaceList() { refreshNamespaceList() {
// fetch new namespaces for the namespace picker // fetch new namespaces for the namespace picker
this.namespaceService.findNamespacesForUser.perform(); this.namespaceService.findNamespacesForUser.perform();
this.send('reload');
}, },
}, },
}); });

View File

@ -3,6 +3,11 @@ import Route from '@ember/routing/route';
import UnloadModel from 'vault/mixins/unload-model-route'; import UnloadModel from 'vault/mixins/unload-model-route';
export default Route.extend(UnloadModel, { export default Route.extend(UnloadModel, {
queryParams: {
page: {
refreshModel: true,
},
},
version: service(), version: service(),
beforeModel() { beforeModel() {
this.store.unloadAll('namespace'); this.store.unloadAll('namespace');
@ -10,14 +15,62 @@ export default Route.extend(UnloadModel, {
return this._super(...arguments); return this._super(...arguments);
}); });
}, },
model() {
return this.version.hasNamespaces model(params) {
? this.store.findAll('namespace').catch(e => { if (this.version.hasNamespaces) {
if (e.httpStatus === 404) { return this.store
return []; .lazyPaginatedQuery('namespace', {
} responsePath: 'data.keys',
throw e; page: Number(params?.page) || 1,
}) })
: null; .then(model => {
return model;
})
.catch(err => {
if (err.httpStatus === 404) {
return [];
} else {
throw err;
}
});
}
return null;
},
setupController(controller, model) {
const has404 = this.has404;
controller.setProperties({
model: model,
has404,
hasModel: true,
});
if (!has404) {
controller.setProperties({
page: Number(model?.meta?.currentPage) || 1,
});
}
},
actions: {
error(error, transition) {
/* eslint-disable-next-line ember/no-controller-access-in-routes */
const hasModel = this.controllerFor(this.routeName).get('hasModel');
if (hasModel && error.httpStatus === 404) {
this.set('has404', true);
transition.abort();
} else {
return true;
}
},
willTransition(transition) {
window.scrollTo(0, 0);
if (!transition || transition.targetName !== this.routeName) {
this.store.clearAllDatasets();
}
return true;
},
reload() {
this.store.clearAllDatasets();
this.refresh();
},
}, },
}); });

View File

@ -18,7 +18,7 @@
</ToolbarActions> </ToolbarActions>
</Toolbar> </Toolbar>
<ListView @items={{model}} @itemNoun="namespace" as |list|> <ListView @items={{model}} @itemNoun="namespace" @paginationRouteName="vault.cluster.access.namespaces" as |list|>
{{#if list.empty}} {{#if list.empty}}
<list.empty> <list.empty>
<LinkTo @route="vault.cluster.access.namespaces.create"> <LinkTo @route="vault.cluster.access.namespaces.create">

View File

@ -272,5 +272,32 @@ export default function() {
}; };
}); });
this.get('sys/namespaces', function() {
return {
data: {
keys: [
'ns1/',
'ns2/',
'ns3/',
'ns4/',
'ns5/',
'ns6/',
'ns7/',
'ns8/',
'ns9/',
'ns10/',
'ns11/',
'ns12/',
'ns13/',
'ns14/',
'ns15/',
'ns16/',
'ns17/',
'ns18/',
],
},
};
});
this.passthrough(); this.passthrough();
} }

View File

@ -0,0 +1,40 @@
import { currentRouteName } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import page from 'vault/tests/pages/access/namespaces/index';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
module('Acceptance | Enterprise | /access/namespaces', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
hooks.beforeEach(function() {
return authPage.login();
});
hooks.afterEach(function() {
return logout.visit();
});
test('it navigates to namespaces page', async function(assert) {
assert.expect(1);
await page.visit();
assert.equal(
currentRouteName(),
'vault.cluster.access.namespaces.index',
'navigates to the correct route'
);
});
test('it should render correct number of namespaces', async function(assert) {
assert.expect(3);
await page.visit();
const store = this.owner.lookup('service:store');
// Default page size is 15
assert.equal(store.peekAll('namespace').length, 15, 'Store has 15 namespaces records');
assert.dom('.list-item-row').exists({ count: 15 });
assert.dom('[data-test-list-view-pagination]').exists();
});
});

View File

@ -0,0 +1,5 @@
import { create, visitable } from 'ember-cli-page-object';
export default create({
visit: visitable('/vault/access/namespaces'),
});