Skip to content

Commit

Permalink
feat: optimize pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Mar 9, 2024
1 parent c993fe3 commit 98690e0
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 90 deletions.
2 changes: 1 addition & 1 deletion app/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "chatnio",
"version": "3.10.3"
"version": "3.10.4"
},
"tauri": {
"allowlist": {
Expand Down
11 changes: 3 additions & 8 deletions app/src/assets/pages/home.less
Original file line number Diff line number Diff line change
Expand Up @@ -337,16 +337,15 @@
margin: 0;
background: hsl(var(--background));
transition: 0.2s ease-in-out;
transition-property: width, background, box-shadow, border-right, opacity;
transition-property: width, background, box-shadow;
border-right: 0;
pointer-events: none;
opacity: 0;
overflow-x: hidden;

&.open {
width: 260px;
border-right: 1px solid hsl(var(--border));
pointer-events: auto;
opacity: 1;
}

&.hidden {
Expand All @@ -362,10 +361,6 @@
padding: 4px;
}

&.open .conversation-list {
opacity: 1;
}

.sidebar-menu {
height: max-content;
width: 100%;
Expand Down Expand Up @@ -409,7 +404,6 @@
display: flex;
flex-direction: column;
gap: 6px;
opacity: 0;
width: 100%;
height: 100%;
padding: 6px 0;
Expand Down Expand Up @@ -603,6 +597,7 @@

button {
margin: 0.5rem 0;
white-space: nowrap;
}

.space-footer {
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/SelectGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function SelectGroupMobile(props: SelectGroupProps) {
props.onChange?.(value);
}}
>
<SelectTrigger className="select-group mobile">
<SelectTrigger className="select-group mobile whitespace-nowrap flex-nowrap">
<SelectValue placeholder={props.current?.value || ""} />
</SelectTrigger>
<SelectContent
Expand Down
36 changes: 8 additions & 28 deletions app/src/components/admin/InvitationTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,14 @@ import { useTranslation } from "react-i18next";
import { useState } from "react";
import { InvitationForm, InvitationResponse } from "@/admin/types.ts";
import { Button } from "@/components/ui/button.tsx";
import {
ChevronLeft,
ChevronRight,
Download,
Loader2,
RotateCw,
} from "lucide-react";
import { Download, Loader2, RotateCw } from "lucide-react";
import { useEffectAsync } from "@/utils/hook.ts";
import { generateInvitation, getInvitationList } from "@/admin/api/chart.ts";
import { Input } from "@/components/ui/input.tsx";
import { useToast } from "@/components/ui/use-toast.ts";
import { Textarea } from "@/components/ui/textarea.tsx";
import { saveAsFile } from "@/utils/dom.ts";
import { PaginationAction } from "@/components/ui/pagination.tsx";

function GenerateDialog() {
const { t } = useTranslation();
Expand Down Expand Up @@ -186,27 +181,12 @@ function InvitationTable() {
))}
</TableBody>
</Table>
<div className={`pagination`}>
<Button
variant={`default`}
size={`icon`}
onClick={() => setPage(page - 1)}
disabled={page === 0}
>
<ChevronLeft className={`h-4 w-4`} />
</Button>
<Button variant={`ghost`} size={`icon`}>
{page + 1}
</Button>
<Button
variant={`default`}
size={`icon`}
onClick={() => setPage(page + 1)}
disabled={page + 1 === data.total}
>
<ChevronRight className={`h-4 w-4`} />
</Button>
</div>
<PaginationAction
current={page}
total={data.total}
onPageChange={setPage}
offset
/>
</>
) : (
<div className={`empty`}>
Expand Down
22 changes: 8 additions & 14 deletions app/src/components/admin/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,28 @@ import { useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { mobile } from "@/utils/device.ts";
import { cn } from "@/components/ui/lib/utils.ts";
import { Button } from "@/components/ui/button.tsx";

type MenuItemProps = {
title: string;
icon: React.ReactNode;
path: string;
exit?: boolean;
};

function MenuItem({ title, icon, path }: MenuItemProps) {
function MenuItem({ title, icon, path, exit }: MenuItemProps) {
const location = useLocation();
const dispatch = useDispatch();
const active = useMemo(
() =>
location.pathname === `/admin${path}` ||
location.pathname + "/" === `/admin${path}`,
!exit &&
(location.pathname === `/admin${path}` ||
location.pathname + "/" === `/admin${path}`),
[location.pathname, path],
);

const redirect = async () => {
if (exit) return await router.navigate("/");

if (mobile) dispatch(closeMenu());
await router.navigate(`/admin${path}`);
};
Expand Down Expand Up @@ -87,16 +90,7 @@ function MenuBar() {
icon={<FileClock />}
path={"/logger"}
/>

<div className={`grow mt-6`} />
<Button
variant={`outline`}
size={`icon`}
className={`ml-3`}
onClick={() => router.navigate("/")}
>
<LogOut className={`h-4 w-4`} />
</Button>
<MenuItem title={t("admin.exit")} icon={<LogOut />} path={""} exit />
</div>
);
}
Expand Down
30 changes: 7 additions & 23 deletions app/src/components/admin/UserTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ import {
CalendarCheck2,
CalendarClock,
CalendarOff,
ChevronLeft,
ChevronRight,
CloudCog,
CloudFog,
KeyRound,
Expand All @@ -59,6 +57,7 @@ import { getNumber, parseNumber } from "@/utils/base.ts";
import { useDeeptrain } from "@/conf/env.ts";
import { useSelector } from "react-redux";
import { selectUsername } from "@/store/auth.ts";
import { PaginationAction } from "@/components/ui/pagination.tsx";

type OperationMenuProps = {
user: UserData;
Expand Down Expand Up @@ -435,27 +434,12 @@ function UserTable() {
))}
</TableBody>
</Table>
<div className={`pagination`}>
<Button
variant={`default`}
size={`icon`}
onClick={() => setPage(page - 1)}
disabled={page === 0}
>
<ChevronLeft className={`h-4 w-4`} />
</Button>
<Button variant={`ghost`} size={`icon`}>
{page + 1}
</Button>
<Button
variant={`default`}
size={`icon`}
onClick={() => setPage(page + 1)}
disabled={page + 1 === data.total}
>
<ChevronRight className={`h-4 w-4`} />
</Button>
</div>
<PaginationAction
current={page}
total={data.total}
onPageChange={setPage}
offset
/>
</>
) : loading ? (
<div className={`flex flex-col mb-4 mt-12 items-center`}>
Expand Down
104 changes: 95 additions & 9 deletions app/src/components/ui/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from "react";
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";

import { cn } from "@/components/ui/lib/utils";
import { ButtonProps, buttonVariants } from "src/components/ui/button";
import { ButtonProps, buttonVariants } from "@/components/ui/button";

const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
Expand Down Expand Up @@ -30,7 +30,11 @@ const PaginationItem = React.forwardRef<
HTMLLIElement,
React.ComponentProps<"li">
>(({ className, ...props }, ref) => (
<li ref={ref} className={cn("", className)} {...props} />
<li
ref={ref}
className={cn("cursor-pointer select-none", className)}
{...props}
/>
));
PaginationItem.displayName = "PaginationItem";

Expand Down Expand Up @@ -65,12 +69,11 @@ const PaginationPrevious = ({
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to previous page"
size="default"
className={cn("gap-1 pl-2.5", className)}
size="icon"
className={cn("gap-1", className)}
{...props}
>
<ChevronLeft className="h-4 w-4" />
<span>Previous</span>
</PaginationLink>
);
PaginationPrevious.displayName = "PaginationPrevious";
Expand All @@ -81,11 +84,10 @@ const PaginationNext = ({
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to next page"
size="default"
className={cn("gap-1 pr-2.5", className)}
size="icon"
className={cn("gap-1", className)}
{...props}
>
<span>Next</span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
);
Expand All @@ -101,11 +103,94 @@ const PaginationEllipsis = ({
{...props}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span>
</span>
);
PaginationEllipsis.displayName = "PaginationEllipsis";

type PaginationActionProps = React.ComponentProps<"div"> & {
current: number;
total: number;
offset?: boolean;
onPageChange: (page: number) => void;
};

const PaginationAction = ({
current,
total,
offset = false,
className,
onPageChange,
children,
...props
}: PaginationActionProps) => {
const real = current + (offset ? 1 : 0);
const diff = total - real;

const hasPrev = current > 0;
const hasNext = diff > 1;

const hasStepPrev = current > 1 && !hasNext;
const hasStepNext = diff > 0 && !hasPrev;

const showRightEllipsis = diff > 2;
const showLeftEllipsis = real > 2 && !showRightEllipsis;

return (
<Pagination className={cn("py-4", className)} {...props}>
<PaginationContent>
<PaginationItem onClick={() => hasPrev && onPageChange(current - 1)}>
<PaginationPrevious />
</PaginationItem>

{showLeftEllipsis && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}

{hasStepPrev && (
<PaginationItem onClick={() => onPageChange(current - 2)}>
<PaginationLink>{real - 2}</PaginationLink>
</PaginationItem>
)}

{hasPrev && (
<PaginationItem onClick={() => onPageChange(current - 1)}>
<PaginationLink>{real - 1}</PaginationLink>
</PaginationItem>
)}

<PaginationItem>
<PaginationLink isActive>{real}</PaginationLink>
</PaginationItem>

{hasNext && (
<PaginationItem onClick={() => onPageChange(current + 1)}>
<PaginationLink>{real + 1}</PaginationLink>
</PaginationItem>
)}

{hasStepNext && (
<PaginationItem onClick={() => onPageChange(current + 2)}>
<PaginationLink>{real + 2}</PaginationLink>
</PaginationItem>
)}

{showRightEllipsis && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}

<PaginationItem onClick={() => hasNext && onPageChange(current + 1)}>
<PaginationNext />
</PaginationItem>
</PaginationContent>
</Pagination>
);
};
PaginationAction.displayName = "PaginationAction";

export {
Pagination,
PaginationContent,
Expand All @@ -114,4 +199,5 @@ export {
PaginationLink,
PaginationNext,
PaginationPrevious,
PaginationAction,
};
2 changes: 1 addition & 1 deletion app/src/conf/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { syncSiteInfo } from "@/admin/api/info.ts";
import { setAxiosConfig } from "@/conf/api.ts";

export const version = "3.10.3"; // version of the current build
export const version = "3.10.4"; // version of the current build
export const dev: boolean = getDev(); // is in development mode (for debugging, in localhost origin)
export const deploy: boolean = true; // is production environment (for api endpoint)
export const tokenField = getTokenField(deploy); // token field name for storing token
Expand Down
3 changes: 2 additions & 1 deletion app/src/conf/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ export function setAnnouncement(announcement: string): void {
*/
if (!announcement || announcement.trim() === "") return;

const firstReceived = getMemory("announcement").trim() !== announcement.trim();
const firstReceived =
getMemory("announcement").trim() !== announcement.trim();
setMemory("announcement", announcement);

announcementEvent.emit({
Expand Down
Loading

0 comments on commit 98690e0

Please sign in to comment.