From a61e1fb2e3c10708dda9f75e5b1a82831d36012b Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 20 Jun 2025 17:04:13 -0500 Subject: [PATCH 1/3] refine agents page pagination --- src/lib/common/markdown/Markdown.svelte | 7 ++- src/lib/helpers/utils/common.js | 20 +++++++- src/routes/page/agent/+page.svelte | 50 +++++++++++++++++-- .../agent-components/agent-utility.svelte | 1 + 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/lib/common/markdown/Markdown.svelte b/src/lib/common/markdown/Markdown.svelte index 70b16578..e3950a20 100644 --- a/src/lib/common/markdown/Markdown.svelte +++ b/src/lib/common/markdown/Markdown.svelte @@ -18,6 +18,9 @@ /** @type {boolean} */ export let rawText = false; + /** @type {boolean} */ + export let scrollable = false; + const scrollbarId = uuidv4(); const options = { @@ -33,7 +36,9 @@ }; onMount(() => { - initScrollbar(); + if (scrollable) { + initScrollbar(); + } }); function initScrollbar() { diff --git a/src/lib/helpers/utils/common.js b/src/lib/helpers/utils/common.js index 6ac0218d..9434093a 100644 --- a/src/lib/helpers/utils/common.js +++ b/src/lib/helpers/utils/common.js @@ -81,4 +81,22 @@ export function removeDuplicates(arr, key) { /** * @param {(string | null)[]} args */ -export const classnames = (...args) => args.filter(Boolean).join(' '); \ No newline at end of file +export const classnames = (...args) => args.filter(Boolean).join(' '); + + +/** + * @param {URL} url + * @param {import('$commonTypes').KeyValuePair[]} pairs + * @param {() => void} [callback] + */ +export function setUrlQueryParams(url, pairs, callback) { + if (!pairs?.length) { + return; + } + + pairs?.map(p => { + url.searchParams.set(p.key, p.value); + }); + + callback?.(); +} \ No newline at end of file diff --git a/src/routes/page/agent/+page.svelte b/src/routes/page/agent/+page.svelte index 5f2006f9..e0ec3e2a 100644 --- a/src/routes/page/agent/+page.svelte +++ b/src/routes/page/agent/+page.svelte @@ -3,6 +3,7 @@ import { _ } from 'svelte-i18n'; import { goto } from '$app/navigation'; import Swal from 'sweetalert2'; + import { page } from '$app/stores'; import { Button, Col, Row } from '@sveltestrap/sveltestrap'; import Breadcrumb from '$lib/common/Breadcrumb.svelte'; import HeadTitle from '$lib/common/HeadTitle.svelte'; @@ -15,6 +16,7 @@ import { ADMIN_ROLES } from '$lib/helpers/constants'; import { globalEventStore } from '$lib/helpers/store'; import CardAgent from './card-agent.svelte'; + import { setUrlQueryParams } from '$lib/helpers/utils/common'; const firstPage = 1; @@ -32,7 +34,7 @@ }; /** @type {import('$agentTypes').AgentFilter} */ - let filter = { ... initFilter }; + let filter = { ...initFilter }; /** @type {import('$commonTypes').Pagination} */ let pager = filter.pager; @@ -57,6 +59,21 @@ let selectedAgentLabels = []; onMount(async () => { + const { pageNum, pageSizeNum } = getQueryParams(); + setUrlQueryParams($page.url, [ + { key: 'page', value: `${pageNum}` }, + { key: 'pageSize', value: `${pageSizeNum}` } + ], () => replaceUrl()); + + filter = { + ...filter, + pager: { + ...filter.pager, + page: pageNum, + size: pageSizeNum + } + }; + user = await myInfo(); getPagedAgents(); getAgentLabelOptions(); @@ -70,6 +87,11 @@ labels: selectedAgentLabels?.length > 0 ? selectedAgentLabels : null, similarName: event.payload || null }; + + setUrlQueryParams($page.url, [ + { key: 'page', value: `${filter.pager.page}` } + ], () => () => replaceUrl()); + getPagedAgents(); }); }); @@ -131,6 +153,22 @@ refreshPager(agents.count, filter.pager.page, filter.pager.size); } + function getQueryParams() { + const pNum = Number($page.url.searchParams.get('page')); + const pSize = Number($page.url.searchParams.get('pageSize')); + const pageNum = pNum > 0 ? pNum : firstPage; + const pageSizeNum = pSize > 0 ? Math.min(pSize, 30) : pageSize; + + return { + pageNum, + pageSizeNum + }; + } + + function replaceUrl() { + goto(`${$page.url.pathname}${$page.url.search}`, { replaceState: true }); + } + function refreshAgents() { agents = { items: agents?.items?.map(t => { return { ...t }; }) || [], @@ -148,12 +186,16 @@ } /** - * @param {number} pageNum + * @param {number} pn */ - function pageTo(pageNum) { + function pageTo(pn) { + setUrlQueryParams($page.url, [ + { key: 'page', value: `${pn}` } + ], () => replaceUrl()); + pager = { ...pager, - page: pageNum + page: pn }; filter = { diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte index e76f2a79..ff05b55b 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte @@ -439,6 +439,7 @@ > Date: Mon, 23 Jun 2025 14:10:41 -0500 Subject: [PATCH 2/3] refine paging --- src/lib/helpers/utils/common.js | 28 ++++++++- src/routes/page/agent/+page.svelte | 66 +++++++++----------- src/routes/page/conversation/+page.svelte | 47 ++++++++++++-- src/routes/page/instruction/log/+page.svelte | 44 ++++++++++--- src/routes/page/plugin/+page.svelte | 47 ++++++++++++-- src/routes/page/users/+page.svelte | 47 ++++++++++++-- 6 files changed, 218 insertions(+), 61 deletions(-) diff --git a/src/lib/helpers/utils/common.js b/src/lib/helpers/utils/common.js index 9434093a..05f1ae52 100644 --- a/src/lib/helpers/utils/common.js +++ b/src/lib/helpers/utils/common.js @@ -1,3 +1,5 @@ +import { goto } from '$app/navigation'; + export function range(size = 3, startAt = 0) { return [...Array(size).keys()].map((i) => i + startAt); }; @@ -84,6 +86,22 @@ export function removeDuplicates(arr, key) { export const classnames = (...args) => args.filter(Boolean).join(' '); +/** + * @param {{ page: number | string | null, pageSize: number | string | null }} args + * @param {{ defaultPageSize: number, maxPageSize?: number }} defaults + */ +export function getPagingQueryParams(args, defaults = { defaultPageSize: 12, maxPageSize: 30 }) { + const pNum = Number(args.page); + const pSize = Number(args.pageSize); + const pageNum = pNum > 0 ? pNum : 1; + const pageSizeNum = pSize > 0 ? Math.min(pSize, defaults.maxPageSize || 30) : defaults.defaultPageSize; + + return { + pageNum, + pageSizeNum + }; +} + /** * @param {URL} url * @param {import('$commonTypes').KeyValuePair[]} pairs @@ -99,4 +117,12 @@ export function setUrlQueryParams(url, pairs, callback) { }); callback?.(); -} \ No newline at end of file +} + +/** + * @param {string} url + * @param {boolean} replaceState + */ +export function goToUrl(url, replaceState = true) { + goto(url, { replaceState: replaceState }); +} diff --git a/src/routes/page/agent/+page.svelte b/src/routes/page/agent/+page.svelte index e0ec3e2a..83efd7aa 100644 --- a/src/routes/page/agent/+page.svelte +++ b/src/routes/page/agent/+page.svelte @@ -16,7 +16,11 @@ import { ADMIN_ROLES } from '$lib/helpers/constants'; import { globalEventStore } from '$lib/helpers/store'; import CardAgent from './card-agent.svelte'; - import { setUrlQueryParams } from '$lib/helpers/utils/common'; + import { + getPagingQueryParams, + setUrlQueryParams, + goToUrl + } from '$lib/helpers/utils/common'; const firstPage = 1; @@ -59,12 +63,11 @@ let selectedAgentLabels = []; onMount(async () => { - const { pageNum, pageSizeNum } = getQueryParams(); - setUrlQueryParams($page.url, [ - { key: 'page', value: `${pageNum}` }, - { key: 'pageSize', value: `${pageSizeNum}` } - ], () => replaceUrl()); - + const { pageNum, pageSizeNum } = getPagingQueryParams({ + page: $page.url.searchParams.get("page"), + pageSize: $page.url.searchParams.get("pageSize") + }, { defaultPageSize: pageSize }); + filter = { ...filter, pager: { @@ -74,6 +77,11 @@ } }; + setUrlQueryParams($page.url, [ + { key: 'page', value: `${filter.pager.page}` }, + { key: 'pageSize', value: `${filter.pager.size}` } + ], () => goToUrl(`${$page.url.pathname}${$page.url.search}`)); + user = await myInfo(); getPagedAgents(); getAgentLabelOptions(); @@ -82,7 +90,11 @@ if (event.name !== GlobalEvent.Search) return; filter = { - pager: initFilter.pager, + pager: { + ...filter.pager, + page: firstPage, + count: 0 + }, types: selectedAgentTypes?.length > 0 ? selectedAgentTypes : null, labels: selectedAgentLabels?.length > 0 ? selectedAgentLabels : null, similarName: event.payload || null @@ -90,7 +102,7 @@ setUrlQueryParams($page.url, [ { key: 'page', value: `${filter.pager.page}` } - ], () => () => replaceUrl()); + ], () => () => goToUrl(`${$page.url.pathname}${$page.url.search}`)); getPagedAgents(); }); @@ -150,23 +162,7 @@ function refresh() { refreshAgents(); - refreshPager(agents.count, filter.pager.page, filter.pager.size); - } - - function getQueryParams() { - const pNum = Number($page.url.searchParams.get('page')); - const pSize = Number($page.url.searchParams.get('pageSize')); - const pageNum = pNum > 0 ? pNum : firstPage; - const pageSizeNum = pSize > 0 ? Math.min(pSize, 30) : pageSize; - - return { - pageNum, - pageSizeNum - }; - } - - function replaceUrl() { - goto(`${$page.url.pathname}${$page.url.search}`, { replaceState: true }); + refreshPager(agents.count, filter.pager.page); } function refreshAgents() { @@ -177,25 +173,21 @@ } /** @param {number} totalItemsCount */ - function refreshPager(totalItemsCount, page = firstPage, pageCount = pageSize) { + function refreshPager(totalItemsCount, page = firstPage) { pager = { + ...filter.pager, page: page, - size: pageCount || 0, count: totalItemsCount || 0 }; } /** - * @param {number} pn + * @param {number} pageNum */ - function pageTo(pn) { - setUrlQueryParams($page.url, [ - { key: 'page', value: `${pn}` } - ], () => replaceUrl()); - + function pageTo(pageNum) { pager = { ...pager, - page: pn + page: pageNum }; filter = { @@ -203,6 +195,10 @@ pager: pager }; + setUrlQueryParams($page.url, [ + { key: 'page', value: `${pageNum}` } + ], () => goToUrl(`${$page.url.pathname}${$page.url.search}`)); + getPagedAgents(); } diff --git a/src/routes/page/conversation/+page.svelte b/src/routes/page/conversation/+page.svelte index 5ed551cc..0ba8ffac 100644 --- a/src/routes/page/conversation/+page.svelte +++ b/src/routes/page/conversation/+page.svelte @@ -1,5 +1,6 @@