forked from open-webui/open-webui
		
	Merge pull request #1395 from 7a6ac0/admin_pagination
feat: admin panel user list pagination
This commit is contained in:
		
						commit
						6238495d61
					
				
					 4 changed files with 88 additions and 9 deletions
				
			
		
							
								
								
									
										42
									
								
								src/lib/components/common/Pagination.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/lib/components/common/Pagination.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| <script lang="ts"> | ||||
| 	import { Pagination } from 'bits-ui'; | ||||
| 	import { createEventDispatcher } from 'svelte'; | ||||
| 
 | ||||
| 	import ChevronLeft from '../icons/ChevronLeft.svelte'; | ||||
| 	import ChevronRight from '../icons/ChevronRight.svelte'; | ||||
| 
 | ||||
| 	export let page = 0; | ||||
| 	export let count = 0; | ||||
| 	export let perPage = 20; | ||||
| </script> | ||||
| 
 | ||||
| <div class="flex justify-center"> | ||||
| 	<Pagination.Root bind:page {count} {perPage} let:pages> | ||||
| 		<div class="my-2 flex items-center"> | ||||
| 			<Pagination.PrevButton | ||||
| 				class="mr-[25px] inline-flex size-8 items-center justify-center rounded-[9px] bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 active:scale-98 disabled:cursor-not-allowed disabled:text-gray-400 dark:disabled:text-gray-700 hover:disabled:bg-transparent dark:hover:disabled:bg-transparent" | ||||
| 			> | ||||
| 				<ChevronLeft className="size-4" strokeWidth="2" /> | ||||
| 			</Pagination.PrevButton> | ||||
| 			<div class="flex items-center gap-2.5"> | ||||
| 				{#each pages as page (page.key)} | ||||
| 					{#if page.type === 'ellipsis'} | ||||
| 						<div class="text-sm font-medium text-foreground-alt">...</div> | ||||
| 					{:else} | ||||
| 						<Pagination.Page | ||||
| 							{page} | ||||
| 							class="inline-flex size-8 items-center justify-center rounded-[9px] bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-sm font-medium hover:bg-dark-10 active:scale-98 disabled:cursor-not-allowed disabled:opacity-50 hover:disabled:bg-transparent data-[selected]:bg-black data-[selected]:text-gray-100 data-[selected]:hover:bg-black dark:data-[selected]:bg-white dark:data-[selected]:text-gray-900 dark:data-[selected]:hover:bg-white" | ||||
| 						> | ||||
| 							{page.value} | ||||
| 						</Pagination.Page> | ||||
| 					{/if} | ||||
| 				{/each} | ||||
| 			</div> | ||||
| 			<Pagination.NextButton | ||||
| 				class="ml-[25px]  inline-flex size-8 items-center justify-center rounded-[9px] bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 active:scale-98 disabled:cursor-not-allowed disabled:text-gray-400 dark:disabled:text-gray-700 hover:disabled:bg-transparent dark:hover:disabled:bg-transparent" | ||||
| 			> | ||||
| 				<ChevronRight className="size-4" strokeWidth="2" /> | ||||
| 			</Pagination.NextButton> | ||||
| 		</div> | ||||
| 	</Pagination.Root> | ||||
| </div> | ||||
							
								
								
									
										15
									
								
								src/lib/components/icons/ChevronLeft.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/lib/components/icons/ChevronLeft.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| <script lang="ts"> | ||||
| 	export let className = 'w-4 h-4'; | ||||
| 	export let strokeWidth = '1.5'; | ||||
| </script> | ||||
| 
 | ||||
| <svg | ||||
| 	xmlns="http://www.w3.org/2000/svg" | ||||
| 	fill="none" | ||||
| 	viewBox="0 0 24 24" | ||||
| 	stroke-width={strokeWidth} | ||||
| 	stroke="currentColor" | ||||
| 	class={className} | ||||
| > | ||||
| 	<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" /> | ||||
| </svg> | ||||
							
								
								
									
										15
									
								
								src/lib/components/icons/ChevronRight.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/lib/components/icons/ChevronRight.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| <script lang="ts"> | ||||
| 	export let className = 'w-4 h-4'; | ||||
| 	export let strokeWidth = '1.5'; | ||||
| </script> | ||||
| 
 | ||||
| <svg | ||||
| 	xmlns="http://www.w3.org/2000/svg" | ||||
| 	fill="none" | ||||
| 	viewBox="0 0 24 24" | ||||
| 	stroke-width={strokeWidth} | ||||
| 	stroke="currentColor" | ||||
| 	class={className} | ||||
| > | ||||
| 	<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" /> | ||||
| </svg> | ||||
|  | @ -12,6 +12,7 @@ | |||
| 	import { getSignUpEnabledStatus, toggleSignUpEnabledStatus } from '$lib/apis/auths'; | ||||
| 	import EditUserModal from '$lib/components/admin/EditUserModal.svelte'; | ||||
| 	import SettingsModal from '$lib/components/admin/SettingsModal.svelte'; | ||||
| 	import Pagination from '$lib/components/common/Pagination.svelte'; | ||||
| 
 | ||||
| 	const i18n = getContext('i18n'); | ||||
| 
 | ||||
|  | @ -21,6 +22,8 @@ | |||
| 	let search = ''; | ||||
| 	let selectedUser = null; | ||||
| 
 | ||||
| 	let page = 1; | ||||
| 
 | ||||
| 	let showSettingsModal = false; | ||||
| 	let showEditUserModal = false; | ||||
| 
 | ||||
|  | @ -159,7 +162,8 @@ | |||
| 										</tr> | ||||
| 									</thead> | ||||
| 									<tbody> | ||||
| 										{#each users.filter((user) => { | ||||
| 										{#each users | ||||
| 											.filter((user) => { | ||||
| 												if (search === '') { | ||||
| 													return true; | ||||
| 												} else { | ||||
|  | @ -167,7 +171,8 @@ | |||
| 													const query = search.toLowerCase(); | ||||
| 													return name.includes(query); | ||||
| 												} | ||||
| 										}) as user} | ||||
| 											}) | ||||
| 											.slice((page - 1) * 20, page * 20) as user} | ||||
| 											<tr class="bg-white border-b dark:bg-gray-900 dark:border-gray-700 text-xs"> | ||||
| 												<td class="px-3 py-2 min-w-[7rem] w-28"> | ||||
| 													<button | ||||
|  | @ -270,6 +275,8 @@ | |||
| 							<div class=" text-gray-500 text-xs mt-2 text-right"> | ||||
| 								ⓘ {$i18n.t("Click on the user role button to change a user's role.")} | ||||
| 							</div> | ||||
| 
 | ||||
| 							<Pagination bind:page count={users.length} /> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek