From 469aaf6d38d8206180c954ff729f0e2a72868240 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Wed, 17 Nov 2021 09:27:49 -0800 Subject: [PATCH 1/9] Add client side pagination to namespaces --- ui/app/adapters/namespace.js | 5 ++ .../vault/cluster/access/namespaces/index.js | 67 +++++++++++++++++-- .../vault/cluster/access/namespaces/index.hbs | 2 +- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/ui/app/adapters/namespace.js b/ui/app/adapters/namespace.js index d403841cd51c..bbf916bf232c 100644 --- a/ui/app/adapters/namespace.js +++ b/ui/app/adapters/namespace.js @@ -31,4 +31,9 @@ export default ApplicationAdapter.extend({ } return this._super(...arguments); }, + query() { + return this.ajax(`/${this.urlPrefix()}/namespaces?list=true`).then(resp => { + return resp; + }); + }, }); diff --git a/ui/app/routes/vault/cluster/access/namespaces/index.js b/ui/app/routes/vault/cluster/access/namespaces/index.js index c756e607d6fe..7a8132d0dea7 100644 --- a/ui/app/routes/vault/cluster/access/namespaces/index.js +++ b/ui/app/routes/vault/cluster/access/namespaces/index.js @@ -3,6 +3,11 @@ import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; export default Route.extend(UnloadModel, { + queryParams: { + page: { + refreshModel: true, + }, + }, version: service(), beforeModel() { this.store.unloadAll('namespace'); @@ -10,14 +15,62 @@ export default Route.extend(UnloadModel, { return this._super(...arguments); }); }, - model() { - return this.version.hasNamespaces - ? this.store.findAll('namespace').catch(e => { - if (e.httpStatus === 404) { + + model(params) { + if (this.version.hasNamespaces) { + return this.store + .lazyPaginatedQuery('namespace', { + responsePath: 'data.keys', + page: Number(params?.page) || 1, + }) + .then(model => { + return model; + }) + .catch(err => { + if (err.httpStatus === 404) { return []; + } else { + throw err; } - throw e; - }) - : null; + }); + } + return null; + }, + + setupController(controller, model) { + const has404 = this.has404; + controller.set('hasModel', true); + controller.setProperties({ + model: model, + has404, + }); + 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(); + }, }, }); diff --git a/ui/app/templates/vault/cluster/access/namespaces/index.hbs b/ui/app/templates/vault/cluster/access/namespaces/index.hbs index 4a1bf1b9f97b..f8c0e0c60b7e 100644 --- a/ui/app/templates/vault/cluster/access/namespaces/index.hbs +++ b/ui/app/templates/vault/cluster/access/namespaces/index.hbs @@ -18,7 +18,7 @@ - + {{#if list.empty}} From 76d3e21659e5d9f639ded9ed62a4752b2b6b572b Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Wed, 17 Nov 2021 14:51:44 -0800 Subject: [PATCH 2/9] Update namespace list after delete operation --- ui/app/controllers/vault/cluster/access/namespaces/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/controllers/vault/cluster/access/namespaces/index.js b/ui/app/controllers/vault/cluster/access/namespaces/index.js index 87487c1ff927..c2b6041daf25 100644 --- a/ui/app/controllers/vault/cluster/access/namespaces/index.js +++ b/ui/app/controllers/vault/cluster/access/namespaces/index.js @@ -9,6 +9,7 @@ export default Controller.extend({ refreshNamespaceList() { // fetch new namespaces for the namespace picker this.namespaceService.findNamespacesForUser.perform(); + this.send('reload'); }, }, }); From 9953626ee9b3425584e58a11029ea568804730d7 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Wed, 17 Nov 2021 15:21:49 -0800 Subject: [PATCH 3/9] Added changelog --- changelog/13195.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/13195.txt diff --git a/changelog/13195.txt b/changelog/13195.txt new file mode 100644 index 000000000000..0f9ce70c05f4 --- /dev/null +++ b/changelog/13195.txt @@ -0,0 +1,3 @@ +```release-note:improvement +ui: Added client side paging for namespace list view +``` \ No newline at end of file From a9a0e8ad753e2be881688cee7d74889a451550b9 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Sun, 28 Nov 2021 22:40:26 -0800 Subject: [PATCH 4/9] Added tests --- ui/mirage/config.js | 27 +++++++++++++++ .../access/namespaces/index-test.js | 34 +++++++++++++++++++ ui/tests/pages/access/namespaces/index.js | 5 +++ 3 files changed, 66 insertions(+) create mode 100644 ui/tests/acceptance/access/namespaces/index-test.js create mode 100644 ui/tests/pages/access/namespaces/index.js diff --git a/ui/mirage/config.js b/ui/mirage/config.js index b3a2b0df7a86..efde1e3ad47a 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -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(); } diff --git a/ui/tests/acceptance/access/namespaces/index-test.js b/ui/tests/acceptance/access/namespaces/index-test.js new file mode 100644 index 000000000000..6a2ae6914370 --- /dev/null +++ b/ui/tests/acceptance/access/namespaces/index-test.js @@ -0,0 +1,34 @@ +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'; + +module('Acceptance | /access/namespaces', function(hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function() { + return authPage.login(); + }); + + 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'); + assert.equal(store.peekAll('namespace').length, 15, '15 namespaces records'); + assert.dom('.list-item-row').exists({ count: 15 }); + assert.dom('[data-test-list-view-pagination]').exists(); + }); +}); diff --git a/ui/tests/pages/access/namespaces/index.js b/ui/tests/pages/access/namespaces/index.js new file mode 100644 index 000000000000..8eb174bc4ff8 --- /dev/null +++ b/ui/tests/pages/access/namespaces/index.js @@ -0,0 +1,5 @@ +import { create, visitable } from 'ember-cli-page-object'; + +export default create({ + visit: visitable('/vault/access/namespaces'), +}); From 30101710ccb74fefbcc513de544654714bd6abc0 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Sun, 28 Nov 2021 23:06:33 -0800 Subject: [PATCH 5/9] Clean up --- ui/app/adapters/namespace.js | 4 +--- ui/app/routes/vault/cluster/access/namespaces/index.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ui/app/adapters/namespace.js b/ui/app/adapters/namespace.js index bbf916bf232c..2c9d8a97e4a3 100644 --- a/ui/app/adapters/namespace.js +++ b/ui/app/adapters/namespace.js @@ -32,8 +32,6 @@ export default ApplicationAdapter.extend({ return this._super(...arguments); }, query() { - return this.ajax(`/${this.urlPrefix()}/namespaces?list=true`).then(resp => { - return resp; - }); + return this.ajax(`/${this.urlPrefix()}/namespaces?list=true`); }, }); diff --git a/ui/app/routes/vault/cluster/access/namespaces/index.js b/ui/app/routes/vault/cluster/access/namespaces/index.js index 7a8132d0dea7..f598997fa594 100644 --- a/ui/app/routes/vault/cluster/access/namespaces/index.js +++ b/ui/app/routes/vault/cluster/access/namespaces/index.js @@ -39,10 +39,10 @@ export default Route.extend(UnloadModel, { setupController(controller, model) { const has404 = this.has404; - controller.set('hasModel', true); controller.setProperties({ model: model, has404, + hasModel: true, }); if (!has404) { controller.setProperties({ From 55f351b987e459e72b95513b4d36057a5c7ee773 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Sun, 28 Nov 2021 23:31:50 -0800 Subject: [PATCH 6/9] Added comment for test --- ui/tests/acceptance/access/namespaces/index-test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/tests/acceptance/access/namespaces/index-test.js b/ui/tests/acceptance/access/namespaces/index-test.js index 6a2ae6914370..ae6565a8caec 100644 --- a/ui/tests/acceptance/access/namespaces/index-test.js +++ b/ui/tests/acceptance/access/namespaces/index-test.js @@ -4,6 +4,7 @@ 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 | /access/namespaces', function(hooks) { setupApplicationTest(hooks); @@ -13,6 +14,10 @@ module('Acceptance | /access/namespaces', function(hooks) { return authPage.login(); }); + hooks.afterEach(function() { + return logout.visit(); + }); + test('it navigates to namespaces page', async function(assert) { assert.expect(1); await page.visit(); @@ -27,7 +32,8 @@ module('Acceptance | /access/namespaces', function(hooks) { assert.expect(3); await page.visit(); const store = this.owner.lookup('service:store'); - assert.equal(store.peekAll('namespace').length, 15, '15 namespaces records'); + // 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(); }); From e2f65895f79b60da9930c2650a834c85876f13f1 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Mon, 29 Nov 2021 10:45:05 -0800 Subject: [PATCH 7/9] Try ember run loop --- ui/tests/acceptance/access/namespaces/index-test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/tests/acceptance/access/namespaces/index-test.js b/ui/tests/acceptance/access/namespaces/index-test.js index ae6565a8caec..58599dc9043b 100644 --- a/ui/tests/acceptance/access/namespaces/index-test.js +++ b/ui/tests/acceptance/access/namespaces/index-test.js @@ -1,4 +1,5 @@ -import { currentRouteName } from '@ember/test-helpers'; +import { currentRouteName, settled } from '@ember/test-helpers'; +import { run } from '@ember/runloop'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import { setupMirage } from 'ember-cli-mirage/test-support'; @@ -32,8 +33,12 @@ module('Acceptance | /access/namespaces', function(hooks) { assert.expect(3); await page.visit(); const store = this.owner.lookup('service:store'); + let totalRecords = run(() => { + return store.peekAll('namespace').length; + }); + await settled(); // Default page size is 15 - assert.equal(store.peekAll('namespace').length, 15, 'Store has 15 namespaces records'); + assert.equal(totalRecords, 15, 'Store has 15 namespaces records'); assert.dom('.list-item-row').exists({ count: 15 }); assert.dom('[data-test-list-view-pagination]').exists(); }); From c8038291fa430be0c12c8c5ec8e4a4e5f4d29eba Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Mon, 29 Nov 2021 12:22:54 -0800 Subject: [PATCH 8/9] Run test only in enterprise --- ui/tests/acceptance/access/namespaces/index-test.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ui/tests/acceptance/access/namespaces/index-test.js b/ui/tests/acceptance/access/namespaces/index-test.js index 58599dc9043b..ae6565a8caec 100644 --- a/ui/tests/acceptance/access/namespaces/index-test.js +++ b/ui/tests/acceptance/access/namespaces/index-test.js @@ -1,5 +1,4 @@ -import { currentRouteName, settled } from '@ember/test-helpers'; -import { run } from '@ember/runloop'; +import { currentRouteName } from '@ember/test-helpers'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import { setupMirage } from 'ember-cli-mirage/test-support'; @@ -33,12 +32,8 @@ module('Acceptance | /access/namespaces', function(hooks) { assert.expect(3); await page.visit(); const store = this.owner.lookup('service:store'); - let totalRecords = run(() => { - return store.peekAll('namespace').length; - }); - await settled(); // Default page size is 15 - assert.equal(totalRecords, 15, 'Store has 15 namespaces records'); + 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(); }); From d2729582cb83bd86e35db6ef80e9e55e6c882f44 Mon Sep 17 00:00:00 2001 From: Arnav Palnitkar Date: Mon, 29 Nov 2021 12:25:03 -0800 Subject: [PATCH 9/9] Fixed test --- ui/tests/acceptance/access/namespaces/index-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/tests/acceptance/access/namespaces/index-test.js b/ui/tests/acceptance/access/namespaces/index-test.js index ae6565a8caec..908f3d4cf7bf 100644 --- a/ui/tests/acceptance/access/namespaces/index-test.js +++ b/ui/tests/acceptance/access/namespaces/index-test.js @@ -6,7 +6,7 @@ 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 | /access/namespaces', function(hooks) { +module('Acceptance | Enterprise | /access/namespaces', function(hooks) { setupApplicationTest(hooks); setupMirage(hooks);