diff --git a/src/backend/InvenTree/part/api.py b/src/backend/InvenTree/part/api.py
index 7f31aebca4..d7acfe8dbf 100644
--- a/src/backend/InvenTree/part/api.py
+++ b/src/backend/InvenTree/part/api.py
@@ -522,7 +522,10 @@ class PartThumbs(ListAPI):
data = serializer.data
- return Response(data)
+ if page is not None:
+ return self.get_paginated_response(data)
+ else:
+ return Response(data)
filter_backends = [InvenTreeSearchFilter]
diff --git a/src/frontend/src/components/details/DetailsImage.tsx b/src/frontend/src/components/details/DetailsImage.tsx
index 89a61f4159..d5001b31be 100644
--- a/src/frontend/src/components/details/DetailsImage.tsx
+++ b/src/frontend/src/components/details/DetailsImage.tsx
@@ -305,7 +305,7 @@ function ImageActionButtons({
modals.open({
title: {t`Select Image`},
- size: 'xxl',
+ size: '80%',
children:
});
}}
diff --git a/src/frontend/src/tables/part/PartThumbTable.tsx b/src/frontend/src/tables/part/PartThumbTable.tsx
index 1120af09fd..29ee2d8777 100644
--- a/src/frontend/src/tables/part/PartThumbTable.tsx
+++ b/src/frontend/src/tables/part/PartThumbTable.tsx
@@ -4,6 +4,7 @@ import {
Button,
Divider,
Group,
+ Pagination,
Paper,
SimpleGrid,
Skeleton,
@@ -11,12 +12,13 @@ import {
Text,
TextInput
} from '@mantine/core';
-import { useHover } from '@mantine/hooks';
+import { useDebouncedValue, useHover } from '@mantine/hooks';
import { modals } from '@mantine/modals';
import { useQuery } from '@tanstack/react-query';
import type React from 'react';
-import { Suspense, useEffect, useState } from 'react';
+import { Suspense, useState } from 'react';
+import { IconX } from '@tabler/icons-react';
import { api } from '../../App';
import { Thumbnail } from '../../components/images/Thumbnail';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
@@ -27,9 +29,6 @@ import { apiUrl } from '../../states/ApiState';
*/
export type ThumbTableProps = {
pk: string;
- limit?: number;
- offset?: number;
- search?: string;
setImage: (image: string) => void;
};
@@ -122,37 +121,42 @@ async function setNewImage(
/**
* Renders a "table" of thumbnails
*/
-export function PartThumbTable({
- limit = 24,
- offset = 0,
- search = '',
- pk,
- setImage
-}: Readonly) {
+export function PartThumbTable({ pk, setImage }: Readonly) {
+ const limit = 24;
+
const [thumbImage, setThumbImage] = useState(null);
const [filterInput, setFilterInput] = useState('');
- const [filterQuery, setFilterQuery] = useState(search);
+
+ const [page, setPage] = useState(1);
+ const [totalPages, setTotalPages] = useState(1);
// Keep search filters from updating while user is typing
- useEffect(() => {
- const timeoutId = setTimeout(() => setFilterQuery(filterInput), 500);
- return () => clearTimeout(timeoutId);
- }, [filterInput]);
+ const [searchText] = useDebouncedValue(filterInput, 500);
// Fetch thumbnails from API
const thumbQuery = useQuery({
- queryKey: [
- ApiEndpoints.part_thumbs_list,
- { limit: limit, offset: offset, search: filterQuery }
- ],
+ queryKey: [ApiEndpoints.part_thumbs_list, page, searchText],
queryFn: async () => {
- return api.get(apiUrl(ApiEndpoints.part_thumbs_list), {
- params: {
- offset: offset,
- limit: limit,
- search: filterQuery
- }
- });
+ const offset = Math.max(0, page - 1) * limit;
+
+ return api
+ .get(apiUrl(ApiEndpoints.part_thumbs_list), {
+ params: {
+ offset: offset,
+ limit: limit,
+ search: searchText
+ }
+ })
+ .then((response) => {
+ const records = response?.data?.count ?? 1;
+ setTotalPages(Math.ceil(records / limit));
+ return response.data?.results ?? response.data;
+ })
+ .catch((error) => {
+ setTotalPages(1);
+ setPage(1);
+ return [];
+ });
}
});
@@ -161,18 +165,20 @@ export function PartThumbTable({
-
+
{!thumbQuery.isFetching
- ? thumbQuery.data?.data.map(
- (data: ImageElement, index: number) => (
-
- )
- )
+ ? thumbQuery?.data.map((data: ImageElement, index: number) => (
+
+ ))
: [...Array(limit)].map((elem, idx) => (
-
- {
- setFilterInput(event.currentTarget.value);
- }}
- />
+
+
+ {
+ setFilterInput(event.currentTarget.value);
+ }}
+ rightSection={
+ setFilterInput('')}
+ />
+ }
+ />
+ setPage(value)}
+ />
+