Skip to content

Commit fcbf166

Browse files
authored
Merge pull request #10 from iceljc/features/conversation-paging
add conversation pagination
2 parents d689e39 + fddf0d3 commit fcbf166

File tree

4 files changed

+130
-35
lines changed

4 files changed

+130
-35
lines changed

src/lib/common/Pager.svelte

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,36 @@
22
import { onMount } from 'svelte';
33
import Link from 'svelte-link';
44
5-
/** @type {import('$lib/types').Pagination} */
5+
/** @type {import('$lib/helpers/types').Pagination} */
66
export let pagination;
7+
/** @type {(pageNum: number) => void} */
8+
export let pageTo;
9+
10+
const firstPage = 1;
11+
const offSet = 2;
712
813
/** @type {number} */
914
$: totalPages = Math.ceil(pagination.count / pagination.size);
1015
/** @type {number} */
11-
$: offset = pagination.page * pagination.size;
16+
$: start = (pagination.page - 1) * pagination.size + 1;
17+
/** @type {number} */
18+
$: end = Math.min(pagination.page * pagination.size, pagination.count);
19+
/** @type {number} */
20+
$: minPage = Math.max(Math.min(pagination.page - offSet, totalPages - 2 * offSet), firstPage);
21+
/** @type {number} */
22+
$: maxPage = Math.min(Math.max(pagination.page + offSet, firstPage + 2 * offSet), totalPages);
1223
/** @type {number[]} */
13-
$: pages = Array.from(String(totalPages), Number);
24+
$: pages = Array.from({ length: maxPage - minPage + 1 }, (_, i) => minPage + i);
25+
26+
/**
27+
* @param {any} e
28+
* @param {number} pageNum
29+
*/
30+
function handlePageTo(e, pageNum) {
31+
e.preventDefault();
32+
if (pagination.page === pageNum || pageNum < firstPage || pageNum > totalPages) return;
33+
pageTo(pageNum);
34+
}
1435
1536
onMount(async () => {
1637
@@ -19,32 +40,40 @@
1940

2041
<div class="row justify-content-between align-items-center">
2142
<div class="col-auto me-auto">
22-
<p class="text-muted mb-0">Showing <b>{offset}</b> to <b>{offset + pagination.size}</b> of <b>{pagination.count}</b> entries</p>
43+
<p class="text-muted mb-0">Showing <b>{start}</b> to <b>{end}</b> of <b>{pagination.count}</b> entries</p>
2344
</div>
2445
<div class="col-auto">
2546
<div class="card d-inline-block ms-auto mb-0">
2647
<div class="card-body p-2">
2748
<nav aria-label="Page navigation example" class="mb-0">
2849
<ul class="pagination mb-0">
2950
<li class="page-item">
30-
<Link class="page-link" href="#" aria-label="Previous">
51+
<Link class="page-link" aria-label="Begin" on:click={(e) => handlePageTo(e, firstPage)}>
52+
<span aria-hidden="true">&laquo;&laquo;</span>
53+
</Link>
54+
</li>
55+
<li class="page-item">
56+
<Link class="page-link" aria-label="Previous" on:click={(e) => handlePageTo(e, pagination.page - 1)}>
3157
<span aria-hidden="true">&laquo;</span>
3258
</Link>
3359
</li>
3460

3561
{#each pages as page}
36-
{#if page == pagination.page + 1}
37-
<li class="page-item active"><Link class="page-link" href="#">{page}</Link></li>
38-
{:else}
39-
<li class="page-item"><Link class="page-link" href="#">{page}</Link></li>
40-
{/if}
62+
<li class={`page-item ${page === pagination.page ? 'active' : ''}`}>
63+
<Link class="page-link" on:click={(e) => handlePageTo(e, page)}>{page}</Link>
64+
</li>
4165
{/each}
4266

4367
<li class="page-item">
44-
<Link class="page-link" href="#" aria-label="Next">
68+
<Link class="page-link" aria-label="Next" on:click={(e) => handlePageTo(e, pagination.page + 1)}>
4569
<span aria-hidden="true">&raquo;</span>
4670
</Link>
4771
</li>
72+
<li class="page-item">
73+
<Link class="page-link" aria-label="Last" on:click={(e) => handlePageTo(e, totalPages)}>
74+
<span aria-hidden="true">&raquo;&raquo;</span>
75+
</Link>
76+
</li>
4877
</ul>
4978
</nav>
5079
</div>

src/lib/scss/custom/components/_pagination.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@
1414
text-align: center;
1515
line-height: 32px;
1616
}
17-
}
17+
}
18+
19+
.page-link:focus {
20+
outline: none;
21+
box-shadow: none;
22+
}

src/lib/services/conversation-service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export async function getConversation(id) {
3131
*/
3232
export async function getConversations(filter) {
3333
let url = endpoints.conversationsUrl;
34-
const response = await axios.get(url, {
35-
params: filter
34+
const response = await axios.post(url, {
35+
...filter
3636
});
3737
return response.data;
3838
}

src/routes/page/conversation/+page.svelte

Lines changed: 82 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
DropdownToggle,
1111
Input,
1212
Row,
13-
Table
13+
Table,
14+
Alert
1415
} from '@sveltestrap/sveltestrap';
1516
import Breadcrumb from '$lib/common/Breadcrumb.svelte';
1617
import HeadTitle from '$lib/common/HeadTitle.svelte';
@@ -20,48 +21,108 @@
2021
import { getConversations, deleteConversation } from '$lib/services/conversation-service.js';
2122
import { format } from '$lib/helpers/datetime';
2223
24+
let isLoading = false;
25+
let isComplete = false;
26+
let isError = false;
27+
const duration = 3000;
28+
const firstPage = 1;
29+
const pageSize = 10;
30+
2331
/** @type {import('$types').PagedItems<import('$types').ConversationModel>} */
24-
let conversations = {count: 0, items: []};
32+
let conversations = { count: 0, items: [] };
33+
34+
/** @type {import('$types').ConversationFilter} */
35+
let initFilter = {
36+
pager: { page: 1, size: pageSize, count: 0 }
37+
};
2538
2639
/** @type {import('$types').ConversationFilter} */
27-
let filter = {
28-
pager: { page: 0, size: 20, count: 0 }
29-
};
40+
let filter = { ... initFilter };
3041
3142
/** @type {import('$types').Pagination} */
32-
let pager = filter.pager;
43+
let pager = filter.pager;
3344
3445
onMount(async () => {
3546
await getConversationList();
3647
});
3748
38-
function refreshPager() {
39-
pager = {
40-
page: filter.pager.page,
41-
size: filter.pager.size,
42-
count: conversations.count
43-
}
44-
}
49+
/** @param {number} totalItemsCount */
50+
function refreshPager(totalItemsCount, page = firstPage, size = pageSize) {
51+
pager = {
52+
page: page,
53+
size: pageSize,
54+
count: totalItemsCount
55+
};
56+
}
4557
4658
async function getConversationList() {
4759
conversations = await getConversations(filter);
60+
refreshPager(conversations.count, filter.pager.page, filter.pager.size);
61+
}
4862
49-
refreshPager();
63+
async function refreshConversationList() {
64+
filter = { ...initFilter };
65+
conversations = await getConversations(filter);
66+
refreshPager(conversations.count);
5067
}
5168
5269
/** @param {string} conversationId */
53-
async function handleConversationDeletion(conversationId) {
54-
await deleteConversation(conversationId);
55-
conversations.count--;
56-
conversations.items = conversations.items.filter(x => x.id != conversationId);
57-
refreshPager();
70+
function handleConversationDeletion(conversationId) {
71+
isLoading = true;
72+
deleteConversation(conversationId).then(async () => {
73+
isLoading = false;
74+
isComplete = true;
75+
setTimeout(() => {
76+
isComplete = false;
77+
}, duration);
78+
79+
await refreshConversationList();
80+
}).catch(err => {
81+
isLoading = false;
82+
isComplete = false;
83+
isError = true;
84+
setTimeout(() => {
85+
isError = false;
86+
}, duration);
87+
});
5888
}
89+
90+
/** @param {number} pageNum */
91+
function pageTo(pageNum) {
92+
pager = {
93+
...pager,
94+
page: pageNum
95+
};
96+
97+
filter = {
98+
pager: pager
99+
};
100+
101+
getConversationList();
102+
}
59103
</script>
60104

61105
<HeadTitle title="Conversation List" />
62-
63106
<Breadcrumb title="Communication" pagetitle="Conversations" />
64107

108+
{#if isLoading}
109+
<Alert color="secondary">
110+
<div>In Progress...</div>
111+
</Alert>
112+
{/if}
113+
114+
{#if isComplete}
115+
<Alert color="success">
116+
<div>Update completed!</div>
117+
</Alert>
118+
{/if}
119+
120+
{#if isError}
121+
<Alert color="danger">
122+
<div>Error!</div>
123+
</Alert>
124+
{/if}
125+
65126
<Row>
66127
<Col lg="12">
67128
<Card>
@@ -169,7 +230,7 @@
169230
</Table>
170231
</div>
171232

172-
<Pagination pagination={pager} />
233+
<Pagination pagination={pager} pageTo={pageTo} />
173234

174235
</CardBody>
175236
</Card>

0 commit comments

Comments
 (0)