mirror of
https://github.com/stonith404/pingvin-share.git
synced 2024-07-06 17:30:10 +02:00
feat: sort shared files
This commit is contained in:
parent
c807d208d8
commit
b25c30d1ed
41
frontend/src/components/core/SortIcon.tsx
Normal file
41
frontend/src/components/core/SortIcon.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { ActionIcon } from "@mantine/core";
|
||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
|
import { TbChevronDown, TbChevronUp, TbSelector } from "react-icons/tb";
|
||||||
|
|
||||||
|
export type TableSort = {
|
||||||
|
property?: string;
|
||||||
|
direction: "asc" | "desc";
|
||||||
|
};
|
||||||
|
|
||||||
|
const TableSortIcon = ({
|
||||||
|
sort,
|
||||||
|
setSort,
|
||||||
|
property,
|
||||||
|
}: {
|
||||||
|
sort: TableSort;
|
||||||
|
setSort: Dispatch<SetStateAction<TableSort>>;
|
||||||
|
property: string;
|
||||||
|
}) => {
|
||||||
|
if (sort.property === property) {
|
||||||
|
return (
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() =>
|
||||||
|
setSort({
|
||||||
|
property,
|
||||||
|
direction: sort.direction === "asc" ? "desc" : "asc",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{sort.direction === "asc" ? <TbChevronDown /> : <TbChevronUp />}
|
||||||
|
</ActionIcon>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<ActionIcon onClick={() => setSort({ property, direction: "asc" })}>
|
||||||
|
<TbSelector />
|
||||||
|
</ActionIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableSortIcon;
|
@ -9,6 +9,7 @@ import {
|
|||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useClipboard } from "@mantine/hooks";
|
import { useClipboard } from "@mantine/hooks";
|
||||||
import { useModals } from "@mantine/modals";
|
import { useModals } from "@mantine/modals";
|
||||||
|
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||||
import { TbDownload, TbEye, TbLink } from "react-icons/tb";
|
import { TbDownload, TbEye, TbLink } from "react-icons/tb";
|
||||||
import useConfig from "../../hooks/config.hook";
|
import useConfig from "../../hooks/config.hook";
|
||||||
import shareService from "../../services/share.service";
|
import shareService from "../../services/share.service";
|
||||||
@ -16,14 +17,17 @@ import { FileMetaData } from "../../types/File.type";
|
|||||||
import { Share } from "../../types/share.type";
|
import { Share } from "../../types/share.type";
|
||||||
import { byteToHumanSizeString } from "../../utils/fileSize.util";
|
import { byteToHumanSizeString } from "../../utils/fileSize.util";
|
||||||
import toast from "../../utils/toast.util";
|
import toast from "../../utils/toast.util";
|
||||||
|
import TableSortIcon, { TableSort } from "../core/SortIcon";
|
||||||
import showFilePreviewModal from "./modals/showFilePreviewModal";
|
import showFilePreviewModal from "./modals/showFilePreviewModal";
|
||||||
|
|
||||||
const FileList = ({
|
const FileList = ({
|
||||||
files,
|
files,
|
||||||
|
setShare,
|
||||||
share,
|
share,
|
||||||
isLoading,
|
isLoading,
|
||||||
}: {
|
}: {
|
||||||
files?: FileMetaData[];
|
files?: FileMetaData[];
|
||||||
|
setShare: Dispatch<SetStateAction<Share | undefined>>;
|
||||||
share: Share;
|
share: Share;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
@ -31,6 +35,32 @@ const FileList = ({
|
|||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const modals = useModals();
|
const modals = useModals();
|
||||||
|
|
||||||
|
const [sort, setSort] = useState<TableSort>({
|
||||||
|
property: undefined,
|
||||||
|
direction: "desc",
|
||||||
|
});
|
||||||
|
|
||||||
|
const sortFiles = () => {
|
||||||
|
if (files && sort.property) {
|
||||||
|
const sortedFiles = files.sort((a: any, b: any) => {
|
||||||
|
if (sort.direction === "asc") {
|
||||||
|
return b[sort.property!].localeCompare(a[sort.property!], undefined, {
|
||||||
|
numeric: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return a[sort.property!].localeCompare(b[sort.property!], undefined, {
|
||||||
|
numeric: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setShare({
|
||||||
|
...share,
|
||||||
|
files: sortedFiles,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const copyFileLink = (file: FileMetaData) => {
|
const copyFileLink = (file: FileMetaData) => {
|
||||||
const link = `${config.get("general.appUrl")}/api/shares/${
|
const link = `${config.get("general.appUrl")}/api/shares/${
|
||||||
share.id
|
share.id
|
||||||
@ -51,13 +81,25 @@ const FileList = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(sortFiles, [sort]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: "block", overflowX: "auto" }}>
|
<Box sx={{ display: "block", overflowX: "auto" }}>
|
||||||
<Table>
|
<Table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>
|
||||||
<th>Size</th>
|
<Group spacing="xs">
|
||||||
|
Name
|
||||||
|
<TableSortIcon sort={sort} setSort={setSort} property="name" />
|
||||||
|
</Group>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<Group spacing="xs">
|
||||||
|
Size
|
||||||
|
<TableSortIcon sort={sort} setSort={setSort} property="size" />
|
||||||
|
</Group>
|
||||||
|
</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -89,7 +89,12 @@ const Share = ({ shareId }: { shareId: string }) => {
|
|||||||
{share?.files.length > 1 && <DownloadAllButton shareId={shareId} />}
|
{share?.files.length > 1 && <DownloadAllButton shareId={shareId} />}
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<FileList files={share?.files} share={share!} isLoading={!share} />
|
<FileList
|
||||||
|
files={share?.files}
|
||||||
|
setShare={setShare}
|
||||||
|
share={share!}
|
||||||
|
isLoading={!share}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user