Skip to content

Commit

Permalink
add conversation pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
Jicheng Lu committed Jan 18, 2024
1 parent c7cba25 commit fddf0d3
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 35 deletions.
51 changes: 40 additions & 11 deletions src/lib/common/Pager.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,36 @@
import { onMount } from 'svelte';
import Link from 'svelte-link';
/** @type {import('$lib/types').Pagination} */
/** @type {import('$lib/helpers/types').Pagination} */
export let pagination;
/** @type {(pageNum: number) => void} */
export let pageTo;
const firstPage = 1;
const offSet = 2;
/** @type {number} */
$: totalPages = Math.ceil(pagination.count / pagination.size);
/** @type {number} */
$: offset = pagination.page * pagination.size;
$: start = (pagination.page - 1) * pagination.size + 1;
/** @type {number} */
$: end = Math.min(pagination.page * pagination.size, pagination.count);
/** @type {number} */
$: minPage = Math.max(Math.min(pagination.page - offSet, totalPages - 2 * offSet), firstPage);
/** @type {number} */
$: maxPage = Math.min(Math.max(pagination.page + offSet, firstPage + 2 * offSet), totalPages);
/** @type {number[]} */
$: pages = Array.from(String(totalPages), Number);
$: pages = Array.from({ length: maxPage - minPage + 1 }, (_, i) => minPage + i);
/**
* @param {any} e
* @param {number} pageNum
*/
function handlePageTo(e, pageNum) {
e.preventDefault();
if (pagination.page === pageNum || pageNum < firstPage || pageNum > totalPages) return;
pageTo(pageNum);
}
onMount(async () => {
Expand All @@ -19,32 +40,40 @@

<div class="row justify-content-between align-items-center">
<div class="col-auto me-auto">
<p class="text-muted mb-0">Showing <b>{offset}</b> to <b>{offset + pagination.size}</b> of <b>{pagination.count}</b> entries</p>
<p class="text-muted mb-0">Showing <b>{start}</b> to <b>{end}</b> of <b>{pagination.count}</b> entries</p>
</div>
<div class="col-auto">
<div class="card d-inline-block ms-auto mb-0">
<div class="card-body p-2">
<nav aria-label="Page navigation example" class="mb-0">
<ul class="pagination mb-0">
<li class="page-item">
<Link class="page-link" href="#" aria-label="Previous">
<Link class="page-link" aria-label="Begin" on:click={(e) => handlePageTo(e, firstPage)}>
<span aria-hidden="true">&laquo;&laquo;</span>
</Link>
</li>
<li class="page-item">
<Link class="page-link" aria-label="Previous" on:click={(e) => handlePageTo(e, pagination.page - 1)}>
<span aria-hidden="true">&laquo;</span>
</Link>
</li>

{#each pages as page}
{#if page == pagination.page + 1}
<li class="page-item active"><Link class="page-link" href="#">{page}</Link></li>
{:else}
<li class="page-item"><Link class="page-link" href="#">{page}</Link></li>
{/if}
<li class={`page-item ${page === pagination.page ? 'active' : ''}`}>
<Link class="page-link" on:click={(e) => handlePageTo(e, page)}>{page}</Link>
</li>
{/each}

<li class="page-item">
<Link class="page-link" href="#" aria-label="Next">
<Link class="page-link" aria-label="Next" on:click={(e) => handlePageTo(e, pagination.page + 1)}>
<span aria-hidden="true">&raquo;</span>
</Link>
</li>
<li class="page-item">
<Link class="page-link" aria-label="Last" on:click={(e) => handlePageTo(e, totalPages)}>
<span aria-hidden="true">&raquo;&raquo;</span>
</Link>
</li>
</ul>
</nav>
</div>
Expand Down
7 changes: 6 additions & 1 deletion src/lib/scss/custom/components/_pagination.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@
text-align: center;
line-height: 32px;
}
}
}

.page-link:focus {
outline: none;
box-shadow: none;
}
4 changes: 2 additions & 2 deletions src/lib/services/conversation-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export async function getConversation(id) {
*/
export async function getConversations(filter) {
let url = endpoints.conversationsUrl;
const response = await axios.get(url, {
params: filter
const response = await axios.post(url, {
...filter
});
return response.data;
}
Expand Down
103 changes: 82 additions & 21 deletions src/routes/page/conversation/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
DropdownToggle,
Input,
Row,
Table
Table,
Alert
} from '@sveltestrap/sveltestrap';
import Breadcrumb from '$lib/common/Breadcrumb.svelte';
import HeadTitle from '$lib/common/HeadTitle.svelte';
Expand All @@ -20,48 +21,108 @@
import { getConversations, deleteConversation } from '$lib/services/conversation-service.js';
import { format } from '$lib/helpers/datetime';
let isLoading = false;
let isComplete = false;
let isError = false;
const duration = 3000;
const firstPage = 1;
const pageSize = 10;
/** @type {import('$types').PagedItems<import('$types').ConversationModel>} */
let conversations = {count: 0, items: []};
let conversations = { count: 0, items: [] };
/** @type {import('$types').ConversationFilter} */
let initFilter = {
pager: { page: 1, size: pageSize, count: 0 }
};
/** @type {import('$types').ConversationFilter} */
let filter = {
pager: { page: 0, size: 20, count: 0 }
};
let filter = { ... initFilter };
/** @type {import('$types').Pagination} */
let pager = filter.pager;
let pager = filter.pager;
onMount(async () => {
await getConversationList();
});
function refreshPager() {
pager = {
page: filter.pager.page,
size: filter.pager.size,
count: conversations.count
}
}
/** @param {number} totalItemsCount */
function refreshPager(totalItemsCount, page = firstPage, size = pageSize) {
pager = {
page: page,
size: pageSize,
count: totalItemsCount
};
}
async function getConversationList() {
conversations = await getConversations(filter);
refreshPager(conversations.count, filter.pager.page, filter.pager.size);
}
refreshPager();
async function refreshConversationList() {
filter = { ...initFilter };
conversations = await getConversations(filter);
refreshPager(conversations.count);
}
/** @param {string} conversationId */
async function handleConversationDeletion(conversationId) {
await deleteConversation(conversationId);
conversations.count--;
conversations.items = conversations.items.filter(x => x.id != conversationId);
refreshPager();
function handleConversationDeletion(conversationId) {
isLoading = true;
deleteConversation(conversationId).then(async () => {
isLoading = false;
isComplete = true;
setTimeout(() => {
isComplete = false;
}, duration);
await refreshConversationList();
}).catch(err => {
isLoading = false;
isComplete = false;
isError = true;
setTimeout(() => {
isError = false;
}, duration);
});
}
/** @param {number} pageNum */
function pageTo(pageNum) {
pager = {
...pager,
page: pageNum
};
filter = {
pager: pager
};
getConversationList();
}
</script>

<HeadTitle title="Conversation List" />

<Breadcrumb title="Communication" pagetitle="Conversations" />

{#if isLoading}
<Alert color="secondary">
<div>In Progress...</div>
</Alert>
{/if}

{#if isComplete}
<Alert color="success">
<div>Update completed!</div>
</Alert>
{/if}

{#if isError}
<Alert color="danger">
<div>Error!</div>
</Alert>
{/if}

<Row>
<Col lg="12">
<Card>
Expand Down Expand Up @@ -169,7 +230,7 @@
</Table>
</div>

<Pagination pagination={pager} />
<Pagination pagination={pager} pageTo={pageTo} />

</CardBody>
</Card>
Expand Down

0 comments on commit fddf0d3

Please sign in to comment.