diff --git a/ui/v2.5/src/components/List/PagedList.tsx b/ui/v2.5/src/components/List/PagedList.tsx index ab27e2697..e42eebf06 100644 --- a/ui/v2.5/src/components/List/PagedList.tsx +++ b/ui/v2.5/src/components/List/PagedList.tsx @@ -1,11 +1,37 @@ import React, { PropsWithChildren, useMemo } from "react"; -import { QueryResult } from "@apollo/client"; +import { ApolloError, QueryResult } from "@apollo/client"; import { ListFilterModel } from "src/models/list-filter/filter"; import { Pagination, PaginationIndex } from "./Pagination"; import { LoadingIndicator } from "../Shared/LoadingIndicator"; import { ErrorMessage } from "../Shared/ErrorMessage"; import { FormattedMessage } from "react-intl"; +export const LoadedContent: React.FC< + PropsWithChildren<{ + loading?: boolean; + error?: ApolloError; + }> +> = ({ loading, error, children }) => { + if (loading) { + return ; + } + if (error) { + return ( + + } + error={error.message} + /> + ); + } + + return <>{children}; +}; + export const PagedList: React.FC< PropsWithChildren<{ result: QueryResult; @@ -63,25 +89,8 @@ export const PagedList: React.FC< ]); const content = useMemo(() => { - if (result.loading) { - return ; - } - if (result.error) { - return ( - - } - error={result.error.message} - /> - ); - } - return ( - <> + {children} {!!pages && ( <> @@ -89,7 +98,7 @@ export const PagedList: React.FC< {pagination} )} - + ); }, [ result.loading, diff --git a/ui/v2.5/src/components/List/Pagination.tsx b/ui/v2.5/src/components/List/Pagination.tsx index 6ee08680b..e5cc89b40 100644 --- a/ui/v2.5/src/components/List/Pagination.tsx +++ b/ui/v2.5/src/components/List/Pagination.tsx @@ -13,12 +13,19 @@ import useFocus from "src/utils/focus"; import { Icon } from "../Shared/Icon"; import { faCheck, faChevronDown } from "@fortawesome/free-solid-svg-icons"; import { useStopWheelScroll } from "src/utils/form"; +import { Placement } from "react-bootstrap/esm/Overlay"; const PageCount: React.FC<{ totalPages: number; currentPage: number; onChangePage: (page: number) => void; -}> = ({ totalPages, currentPage, onChangePage }) => { + pagePopupPlacement?: Placement; +}> = ({ + totalPages, + currentPage, + onChangePage, + pagePopupPlacement = "bottom", +}) => { const intl = useIntl(); const currentPageCtrl = useRef(null); const [pageInput, pageFocus] = useFocus(); @@ -94,7 +101,7 @@ const PageCount: React.FC<{ setShowSelectPage(false)} > @@ -138,9 +145,11 @@ interface IPaginationProps { totalItems: number; metadataByline?: React.ReactNode; onChangePage: (page: number) => void; + pagePopupPlacement?: Placement; } interface IPaginationIndexProps { + loading?: boolean; itemsPerPage: number; currentPage: number; totalItems: number; @@ -154,6 +163,7 @@ export const Pagination: React.FC = ({ currentPage, totalItems, onChangePage, + pagePopupPlacement, }) => { const intl = useIntl(); const totalPages = useMemo( @@ -168,6 +178,7 @@ export const Pagination: React.FC = ({ totalPages={totalPages} currentPage={currentPage} onChangePage={onChangePage} + pagePopupPlacement={pagePopupPlacement} /> ); @@ -183,7 +194,7 @@ export const Pagination: React.FC = ({ )); - }, [totalPages, currentPage, onChangePage]); + }, [totalPages, currentPage, onChangePage, pagePopupPlacement]); if (totalPages <= 1) return
; @@ -227,6 +238,7 @@ export const Pagination: React.FC = ({ }; export const PaginationIndex: React.FC = ({ + loading, itemsPerPage, currentPage, totalItems, @@ -234,6 +246,8 @@ export const PaginationIndex: React.FC = ({ }) => { const intl = useIntl(); + if (loading) return null; + // Build the pagination index string const firstItemCount: number = Math.min( (currentPage - 1) * itemsPerPage + 1, diff --git a/ui/v2.5/src/components/List/styles.scss b/ui/v2.5/src/components/List/styles.scss index 3372ee2f3..9f78354a6 100644 --- a/ui/v2.5/src/components/List/styles.scss +++ b/ui/v2.5/src/components/List/styles.scss @@ -942,3 +942,19 @@ input[type="range"].zoom-slider { margin-right: 0.5rem; } } + +.pagination-footer { + background-color: $body-bg; + bottom: $navbar-height; + padding: 0.5rem 1rem; + position: sticky; + z-index: 10; + + @include media-breakpoint-up(sm) { + bottom: 0; + } + + .pagination { + margin-bottom: 0; + } +} diff --git a/ui/v2.5/src/components/Scenes/SceneList.tsx b/ui/v2.5/src/components/Scenes/SceneList.tsx index fd2ad1657..3f9bf6315 100644 --- a/ui/v2.5/src/components/Scenes/SceneList.tsx +++ b/ui/v2.5/src/components/Scenes/SceneList.tsx @@ -25,7 +25,7 @@ import { objectTitle } from "src/core/files"; import TextUtils from "src/utils/text"; import { View } from "../List/views"; import { FileSize } from "../Shared/FileSize"; -import { PagedList } from "../List/PagedList"; +import { LoadedContent } from "../List/PagedList"; import { useCloseEditDelete, useFilterOperations } from "../List/util"; import { IListFilterOperation } from "../List/ListOperationButtons"; import { FilteredListToolbar } from "../List/FilteredListToolbar"; @@ -48,6 +48,7 @@ import { useFilteredSidebarKeybinds, } from "../List/Filters/FilterSidebar"; import { PatchContainerComponent } from "src/patch"; +import { Pagination, PaginationIndex } from "../List/Pagination"; function renderMetadataByline(result: GQL.FindScenesQueryResult) { const duration = result?.data?.findScenes?.duration; @@ -488,14 +489,15 @@ export const FilteredSceneList = (props: IFilteredScenes) => { onRemoveAll={() => clearAllCriteria()} /> - + /> + + { onSelectChange={onSelectChange} fromGroupId={fromGroupId} /> - + + + {totalCount > filter.itemsPerPage && ( +
+ +
+ )}
diff --git a/ui/v2.5/src/index.scss b/ui/v2.5/src/index.scss index 730ad9eb2..9393397ed 100755 --- a/ui/v2.5/src/index.scss +++ b/ui/v2.5/src/index.scss @@ -51,15 +51,21 @@ body { -webkit-font-smoothing: antialiased; margin: 0; overflow-x: hidden; - padding: 4rem 0 0 0; + padding: $navbar-height 0 0 0; @include media-breakpoint-down(xs) { @media (orientation: portrait) { - padding: 1rem 0 5rem; + padding: 1rem 0 $navbar-height; } } } +.main { + @include media-breakpoint-up(sm) { + padding-top: 0.5rem; + } +} + #group-page, #performer-page, #studio-page,