Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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