Add pagination component
This commit is contained in:
parent
2251443c10
commit
3c9a0b0d95
8 changed files with 169 additions and 2 deletions
46
app/components/pagination.hbs
Normal file
46
app/components/pagination.hbs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{{#if (gt this.totalPages 1)}}
|
||||
<nav class="flex justify-center relative z-0 my-4" aria-label="Pagination">
|
||||
{{#let "inline-flex items-center justify-center px-2 mx-1 font-display text-lg" as |commonClasses|}}
|
||||
{{#if this.previousPage}}
|
||||
<LinkTo
|
||||
@route={{this.router.currentRouteName}}
|
||||
@models={{if @model (array @model) (array)}}
|
||||
@query={{hash page=this.previousPage}}
|
||||
class={{commonClasses}}
|
||||
title="Previous page"
|
||||
>
|
||||
<MdIcon @icon="chevron-left" />
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
|
||||
{{#each this.availablePages as |i|}}
|
||||
{{#if (eq @current i)}}
|
||||
<span class="{{commonClasses}} border rounded">{{i}}</span>
|
||||
{{else if (eq "..." i)}}
|
||||
<span class={{commonClasses}}>{{i}}</span>
|
||||
{{else}}
|
||||
<LinkTo
|
||||
@route={{this.router.currentRouteName}}
|
||||
@models={{if @model (array @model) (array)}}
|
||||
@query={{hash page=i}}
|
||||
class={{commonClasses}}
|
||||
>
|
||||
{{i}}
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
|
||||
{{#if this.nextPage}}
|
||||
<LinkTo
|
||||
@route={{this.router.currentRouteName}}
|
||||
@models={{if @model (array @model) (array)}}
|
||||
@query={{hash page=this.nextPage}}
|
||||
class={{commonClasses}}
|
||||
title="Next page"
|
||||
>
|
||||
<MdIcon @icon="chevron-right" />
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
</nav>
|
||||
{{/if}}
|
||||
65
app/components/pagination.js
Normal file
65
app/components/pagination.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import Component from '@glimmer/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class PaginationComponent extends Component {
|
||||
@service router;
|
||||
|
||||
numberPagesToShow = 2;
|
||||
|
||||
get availablePages() {
|
||||
const availablePages = [];
|
||||
|
||||
for (let i = 1; i <= this.totalPages; i++) {
|
||||
if (i === this.args.current) {
|
||||
availablePages.push(i);
|
||||
} else if (
|
||||
i < this.args.current &&
|
||||
i >= this.args.current - this.numberPagesToShow
|
||||
) {
|
||||
availablePages.push(i);
|
||||
} else if (
|
||||
i > this.args.current &&
|
||||
i <= this.args.current + this.numberPagesToShow
|
||||
) {
|
||||
availablePages.push(i);
|
||||
} else if (
|
||||
this.args.current > this.totalPages &&
|
||||
i <= this.args.current + this.numberPagesToShow
|
||||
) {
|
||||
availablePages.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
const firstPage = availablePages[0];
|
||||
if (firstPage > 1) {
|
||||
if (firstPage - 1 > 1) {
|
||||
availablePages.unshift('...');
|
||||
}
|
||||
|
||||
availablePages.unshift(1);
|
||||
}
|
||||
|
||||
const lastPage = availablePages[availablePages.length - 1];
|
||||
if (lastPage < this.totalPages) {
|
||||
if (lastPage + 1 < this.totalPages) {
|
||||
availablePages.push('...');
|
||||
}
|
||||
|
||||
availablePages.push(this.totalPages);
|
||||
}
|
||||
|
||||
return availablePages;
|
||||
}
|
||||
|
||||
get totalPages() {
|
||||
return Math.ceil(this.args.count / this.args.perPage);
|
||||
}
|
||||
|
||||
get previousPage() {
|
||||
return this.args.current > 1 ? this.args.current - 1 : null;
|
||||
}
|
||||
|
||||
get nextPage() {
|
||||
return this.args.current < this.totalPages ? this.args.current + 1 : null;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ import { trackedFunction } from 'ember-resources';
|
|||
|
||||
export default class AdminIndexesItemDataController extends Controller {
|
||||
@tracked searchText = 'hello';
|
||||
@tracked offset = 0;
|
||||
@tracked page = 0;
|
||||
|
||||
request = trackedFunction(this, async () => {
|
||||
if (typeof this.searchText !== 'string' || this.searchText.length < 1) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import Route from '@ember/routing/route';
|
|||
|
||||
export default class AdminIndexesRoute extends Route {
|
||||
// @service meilisearch;
|
||||
|
||||
// async model() {
|
||||
// return this.modelFor('admin');
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<h2 class="text-xl mb-4">Results:</h2>
|
||||
<div class=" ">
|
||||
{{#each this.data.hits as |item|}}
|
||||
<div class="mb-8 rounded-md overflow-hidden shadow">
|
||||
<div class="mb-8 rounded-md border overflow-hidden shadow">
|
||||
{{#each-in item as |key value|}}
|
||||
<div class="grid grid-cols-3 gap-4 p-4 odd:bg-gray-50">
|
||||
<div>{{key}}</div>
|
||||
|
|
@ -32,4 +32,10 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Pagination
|
||||
@count={{this.data.nbHits}}
|
||||
@current={{this.page}}
|
||||
@perPage={{this.data.limit}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
|||
22
package-lock.json
generated
22
package-lock.json
generated
|
|
@ -54,6 +54,7 @@
|
|||
"ember-resources": "^4.4.0",
|
||||
"ember-source": "~4.2.0",
|
||||
"ember-template-lint": "^4.2.0",
|
||||
"ember-truth-helpers": "^3.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.4.0",
|
||||
"eslint-plugin-ember": "^10.5.9",
|
||||
|
|
@ -13442,6 +13443,18 @@
|
|||
"node": ">=8.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ember-truth-helpers": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ember-truth-helpers/-/ember-truth-helpers-3.0.0.tgz",
|
||||
"integrity": "sha512-hPKG9QqruAELh0li5xaiLZtr88ioWYxWCXisAWHWE0qCP4a2hgtuMzKUPpiTCkltvKjuqpzTZCU4VhQ+IlRmew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ember-cli-babel": "^7.22.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "10.* || >= 12.*"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
|
|
@ -35053,6 +35066,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ember-truth-helpers": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ember-truth-helpers/-/ember-truth-helpers-3.0.0.tgz",
|
||||
"integrity": "sha512-hPKG9QqruAELh0li5xaiLZtr88ioWYxWCXisAWHWE0qCP4a2hgtuMzKUPpiTCkltvKjuqpzTZCU4VhQ+IlRmew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ember-cli-babel": "^7.22.1"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
"ember-resources": "^4.4.0",
|
||||
"ember-source": "~4.2.0",
|
||||
"ember-template-lint": "^4.2.0",
|
||||
"ember-truth-helpers": "^3.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.4.0",
|
||||
"eslint-plugin-ember": "^10.5.9",
|
||||
|
|
|
|||
26
tests/integration/components/pagination-test.js
Normal file
26
tests/integration/components/pagination-test.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Component | pagination', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.set('myAction', function(val) { ... });
|
||||
|
||||
await render(hbs`<Pagination />`);
|
||||
|
||||
assert.dom(this.element).hasText('');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
<Pagination>
|
||||
template block text
|
||||
</Pagination>
|
||||
`);
|
||||
|
||||
assert.dom(this.element).hasText('template block text');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue