mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Refactor cell components
This commit is contained in:
parent
c7ed7ed48f
commit
cb906678e6
8 changed files with 103 additions and 52 deletions
36
src/apps/dashboard/features/activity/api/useLogEntries.tsx
Normal file
36
src/apps/dashboard/features/activity/api/useLogEntries.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import type { ActivityLogApiGetLogEntriesRequest } from '@jellyfin/sdk/lib/generated-client';
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
import type { Api } from '@jellyfin/sdk';
|
||||
import { getActivityLogApi } from '@jellyfin/sdk/lib/utils/api/activity-log-api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { useApi } from 'hooks/useApi';
|
||||
|
||||
const fetchLogEntries = async (
|
||||
api?: Api,
|
||||
requestParams?: ActivityLogApiGetLogEntriesRequest,
|
||||
options?: AxiosRequestConfig
|
||||
) => {
|
||||
if (!api) {
|
||||
console.warn('[fetchLogEntries] No API instance available');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await getActivityLogApi(api).getLogEntries(requestParams, {
|
||||
signal: options?.signal
|
||||
});
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const useLogEntires = (
|
||||
requestParams: ActivityLogApiGetLogEntriesRequest
|
||||
) => {
|
||||
const { api } = useApi();
|
||||
return useQuery({
|
||||
queryKey: ['LogEntries', requestParams],
|
||||
queryFn: ({ signal }) =>
|
||||
fetchLogEntries(api, requestParams, { signal }),
|
||||
enabled: !!api
|
||||
});
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
import IconButton from '@mui/material/IconButton/IconButton';
|
||||
import PermMedia from '@mui/icons-material/PermMedia';
|
||||
import React, { type FC } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import type { ActivityLogEntryCell } from 'apps/dashboard/features/activity/types/ActivityLogEntryCell';
|
||||
import globalize from 'lib/globalize';
|
||||
|
||||
const ActionsCell: FC<ActivityLogEntryCell> = ({ row }) => (
|
||||
row.original.ItemId ? (
|
||||
<IconButton
|
||||
size='large'
|
||||
title={globalize.translate('LabelMediaDetails')}
|
||||
component={Link}
|
||||
to={`/details?id=${row.original.ItemId}`}
|
||||
>
|
||||
<PermMedia fontSize='inherit' />
|
||||
</IconButton>
|
||||
) : undefined
|
||||
);
|
||||
|
||||
export default ActionsCell;
|
|
@ -0,0 +1,13 @@
|
|||
import type { LogLevel } from '@jellyfin/sdk/lib/generated-client/models/log-level';
|
||||
import React, { type FC } from 'react';
|
||||
|
||||
import { ActivityLogEntryCell } from '../types/ActivityLogEntryCell';
|
||||
import LogLevelChip from './LogLevelChip';
|
||||
|
||||
const LogLevelCell: FC<ActivityLogEntryCell> = ({ cell }) => (
|
||||
cell.getValue<LogLevel | undefined>() ? (
|
||||
<LogLevelChip level={cell.getValue<LogLevel>()} />
|
||||
) : undefined
|
||||
);
|
||||
|
||||
export default LogLevelCell;
|
|
@ -0,0 +1,34 @@
|
|||
import { LogLevel } from '@jellyfin/sdk/lib/generated-client/models/log-level';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import React from 'react';
|
||||
|
||||
import globalize from 'lib/globalize';
|
||||
|
||||
const LogLevelChip = ({ level }: { level: LogLevel }) => {
|
||||
let color: 'info' | 'warning' | 'error' | undefined;
|
||||
switch (level) {
|
||||
case LogLevel.Information:
|
||||
color = 'info';
|
||||
break;
|
||||
case LogLevel.Warning:
|
||||
color = 'warning';
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
case LogLevel.Critical:
|
||||
color = 'error';
|
||||
break;
|
||||
}
|
||||
|
||||
const levelText = globalize.translate(`LogLevel.${level}`);
|
||||
|
||||
return (
|
||||
<Chip
|
||||
size='small'
|
||||
color={color}
|
||||
label={levelText}
|
||||
title={levelText}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogLevelChip;
|
|
@ -0,0 +1,66 @@
|
|||
import Info from '@mui/icons-material/Info';
|
||||
import Box from '@mui/material/Box';
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import React, { type FC, useCallback, useState } from 'react';
|
||||
|
||||
import type { ActivityLogEntryCell } from '../types/ActivityLogEntryCell';
|
||||
|
||||
const OverviewCell: FC<ActivityLogEntryCell> = ({ row }) => {
|
||||
const { ShortOverview, Overview } = row.original;
|
||||
const displayValue = ShortOverview ?? Overview;
|
||||
const [ open, setOpen ] = useState(false);
|
||||
|
||||
const onTooltipClose = useCallback(() => {
|
||||
setOpen(false);
|
||||
}, []);
|
||||
|
||||
const onTooltipOpen = useCallback(() => {
|
||||
setOpen(true);
|
||||
}, []);
|
||||
|
||||
if (!displayValue) return null;
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis'
|
||||
}}
|
||||
component='div'
|
||||
title={displayValue}
|
||||
>
|
||||
{displayValue}
|
||||
</Box>
|
||||
{ShortOverview && Overview && (
|
||||
<ClickAwayListener onClickAway={onTooltipClose}>
|
||||
<Tooltip
|
||||
title={Overview}
|
||||
placement='top'
|
||||
arrow
|
||||
onClose={onTooltipClose}
|
||||
open={open}
|
||||
disableFocusListener
|
||||
disableHoverListener
|
||||
disableTouchListener
|
||||
>
|
||||
<IconButton onClick={onTooltipOpen}>
|
||||
<Info />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</ClickAwayListener>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default OverviewCell;
|
|
@ -0,0 +1,27 @@
|
|||
import type { UserDto } from '@jellyfin/sdk/lib/generated-client/models/user-dto';
|
||||
import IconButton from '@mui/material/IconButton/IconButton';
|
||||
import React, { type FC } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import UserAvatar from 'components/UserAvatar';
|
||||
|
||||
interface UserAvatarButtonProps {
|
||||
user?: UserDto
|
||||
}
|
||||
|
||||
const UserAvatarButton: FC<UserAvatarButtonProps> = ({ user }) => (
|
||||
user?.Id ? (
|
||||
<IconButton
|
||||
size='large'
|
||||
color='inherit'
|
||||
sx={{ padding: 0 }}
|
||||
title={user.Name || undefined}
|
||||
component={Link}
|
||||
to={`/dashboard/users/profile?userId=${user.Id}`}
|
||||
>
|
||||
<UserAvatar user={user} />
|
||||
</IconButton>
|
||||
) : undefined
|
||||
);
|
||||
|
||||
export default UserAvatarButton;
|
|
@ -0,0 +1,7 @@
|
|||
import type { ActivityLogEntry } from '@jellyfin/sdk/lib/generated-client/models/activity-log-entry';
|
||||
import type { MRT_Cell, MRT_Row } from 'material-react-table';
|
||||
|
||||
export interface ActivityLogEntryCell {
|
||||
cell: MRT_Cell<ActivityLogEntry>
|
||||
row: MRT_Row<ActivityLogEntry>
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue