mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-13 00:45:47 +01:00
History done
This commit is contained in:
@@ -42,8 +42,7 @@ export default function TorrentsComponent() {
|
||||
(service) =>
|
||||
service.type === 'qBittorrent' ||
|
||||
service.type === 'Transmission' ||
|
||||
service.type === 'Deluge' ||
|
||||
service.type === 'Sabnzbd'
|
||||
service.type === 'Deluge'
|
||||
) ?? [];
|
||||
|
||||
const hideComplete: boolean =
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
import { Center, Table, Text, Title, Tooltip, useMantineTheme } from '@mantine/core';
|
||||
import { Center, Pagination, Skeleton, Table, Text, Title, Tooltip } from '@mantine/core';
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
import { useGetUsenetHistory } from '../../tools/hooks/api';
|
||||
import { humanFileSize } from '../../tools/humanFileSize';
|
||||
import { UsenetHistoryItem } from './types';
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
interface UsenetHistoryListProps {
|
||||
items: UsenetHistoryItem[];
|
||||
serviceId: string;
|
||||
}
|
||||
|
||||
export const UsenetHistoryList: FunctionComponent<UsenetHistoryListProps> = ({ items }) => {
|
||||
const theme = useMantineTheme();
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
if (items.length <= 0) {
|
||||
export const UsenetHistoryList: FunctionComponent<UsenetHistoryListProps> = ({ serviceId }) => {
|
||||
const [page, setPage] = useState(1);
|
||||
|
||||
const { data, isLoading } = useGetUsenetHistory({
|
||||
limit: PAGE_SIZE,
|
||||
offset: (page - 1) * PAGE_SIZE,
|
||||
serviceId,
|
||||
});
|
||||
const totalPages = Math.ceil((data?.total || 1) / PAGE_SIZE);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data || data.items.length <= 0) {
|
||||
return (
|
||||
<Center style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Title order={3}>Queue is empty</Title>
|
||||
@@ -23,49 +42,59 @@ export const UsenetHistoryList: FunctionComponent<UsenetHistoryListProps> = ({ i
|
||||
}
|
||||
|
||||
return (
|
||||
<Table highlightOnHover style={{ tableLayout: 'fixed' }}>
|
||||
<colgroup>
|
||||
<col span={1} />
|
||||
<col span={1} style={{ width: 100 }} />
|
||||
<col span={1} style={{ width: 200 }} />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Download Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((history) => (
|
||||
<tr key={history.id}>
|
||||
<td>
|
||||
<Tooltip position="top" label={history.name}>
|
||||
<Text
|
||||
size="xs"
|
||||
style={{
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{history.name}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<Text size="xs">{humanFileSize(history.size)}</Text>
|
||||
</td>
|
||||
<td>
|
||||
<Text size="xs">
|
||||
{dayjs
|
||||
.duration(history.time, 's')
|
||||
.format(history.time < 60 ? 's [seconds]' : 'm [minutes] s [seconds] ')}
|
||||
</Text>
|
||||
</td>
|
||||
<div>
|
||||
<Table highlightOnHover style={{ tableLayout: 'fixed' }}>
|
||||
<colgroup>
|
||||
<col span={1} />
|
||||
<col span={1} style={{ width: 100 }} />
|
||||
<col span={1} style={{ width: 200 }} />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Download Duration</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.items.map((history) => (
|
||||
<tr key={history.id}>
|
||||
<td>
|
||||
<Tooltip position="top" label={history.name}>
|
||||
<Text
|
||||
size="xs"
|
||||
style={{
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{history.name}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<Text size="xs">{humanFileSize(history.size)}</Text>
|
||||
</td>
|
||||
<td>
|
||||
<Text size="xs">
|
||||
{dayjs
|
||||
.duration(history.time, 's')
|
||||
.format(history.time < 60 ? 's [seconds]' : 'm [minutes] s [seconds] ')}
|
||||
</Text>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
<Pagination
|
||||
size="sm"
|
||||
position="center"
|
||||
mt="md"
|
||||
total={totalPages}
|
||||
page={page}
|
||||
onChange={setPage}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,38 +1,42 @@
|
||||
import { Skeleton, Tabs, useMantineTheme } from '@mantine/core';
|
||||
import { Group, Select, Tabs } from '@mantine/core';
|
||||
import { IconDownload } from '@tabler/icons';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
|
||||
import { IModule } from '../ModuleTypes';
|
||||
import { useGetUsenetDownloads, useGetUsenetHistory } from '../../tools/hooks/api';
|
||||
import { UsenetQueueList } from './UsenetQueueList';
|
||||
import { UsenetHistoryList } from './UsenetHistoryList';
|
||||
import { useGetServiceByType } from '../../tools/hooks/useGetServiceByType';
|
||||
|
||||
export const UsenetComponent: FunctionComponent = () => {
|
||||
const theme = useMantineTheme();
|
||||
const { isLoading, data: nzbs = [] } = useGetUsenetDownloads();
|
||||
const { data: history = [] } = useGetUsenetHistory();
|
||||
const downloadServices = useGetServiceByType('Sabnzbd');
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
</>
|
||||
);
|
||||
const [selectedServiceId, setSelectedService] = useState<string | null>(downloadServices[0]?.id);
|
||||
|
||||
if (!selectedServiceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tabs defaultValue="queue">
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="queue">Queue</Tabs.Tab>
|
||||
<Tabs.Tab value="history">History</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs keepMounted={false} defaultValue="queue">
|
||||
<Group mb="md">
|
||||
<Tabs.List style={{ flex: 1 }}>
|
||||
<Tabs.Tab value="queue">Queue</Tabs.Tab>
|
||||
<Tabs.Tab value="history">History</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
{downloadServices.length > 1 && (
|
||||
<Select
|
||||
value={selectedServiceId}
|
||||
onChange={setSelectedService}
|
||||
ml="xs"
|
||||
data={downloadServices.map((service) => ({ value: service.id, label: service.name }))}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
<Tabs.Panel value="queue">
|
||||
<UsenetQueueList items={nzbs} />
|
||||
<UsenetQueueList serviceId={selectedServiceId} />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="history">
|
||||
<UsenetHistoryList items={history} />
|
||||
<UsenetHistoryList serviceId={selectedServiceId} />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
@@ -1,20 +1,48 @@
|
||||
import { Center, Progress, Table, Text, Title, Tooltip, useMantineTheme } from '@mantine/core';
|
||||
import {
|
||||
Center,
|
||||
Progress,
|
||||
Skeleton,
|
||||
Table,
|
||||
Text,
|
||||
Title,
|
||||
Tooltip,
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import { IconPlayerPause, IconPlayerPlay } from '@tabler/icons';
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
import { useGetUsenetDownloads } from '../../tools/hooks/api';
|
||||
import { humanFileSize } from '../../tools/humanFileSize';
|
||||
import { UsenetQueueItem } from './types';
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
interface UsenetQueueListProps {
|
||||
items: UsenetQueueItem[];
|
||||
serviceId: string;
|
||||
}
|
||||
|
||||
export const UsenetQueueList: FunctionComponent<UsenetQueueListProps> = ({ items }) => {
|
||||
const theme = useMantineTheme();
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
if (items.length <= 0) {
|
||||
export const UsenetQueueList: FunctionComponent<UsenetQueueListProps> = ({ serviceId }) => {
|
||||
const theme = useMantineTheme();
|
||||
const [page, setPage] = useState(1);
|
||||
const { data, isLoading } = useGetUsenetDownloads({
|
||||
limit: PAGE_SIZE,
|
||||
offset: (page - 1) * PAGE_SIZE,
|
||||
serviceId,
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
<Skeleton height={40} mt={10} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data || data.items.length <= 0) {
|
||||
return (
|
||||
<Center style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Title order={3}>Queue is empty</Title>
|
||||
@@ -34,7 +62,7 @@ export const UsenetQueueList: FunctionComponent<UsenetQueueListProps> = ({ items
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((nzb) => (
|
||||
{data.items.map((nzb) => (
|
||||
<tr key={nzb.id}>
|
||||
<td>
|
||||
{nzb.state === 'paused' ? (
|
||||
|
||||
Reference in New Issue
Block a user