mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-27 00:01:06 +00:00
refactor activity page to use react query requests
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
This commit is contained in:
parent
656799cce7
commit
710fe641e2
@ -92,6 +92,7 @@
|
|||||||
- [Venkat Karasani](https://github.com/venkat-karasani)
|
- [Venkat Karasani](https://github.com/venkat-karasani)
|
||||||
- [Connor Smith](https://github.com/ConnorS1110)
|
- [Connor Smith](https://github.com/ConnorS1110)
|
||||||
- [iFraan](https://github.com/iFraan)
|
- [iFraan](https://github.com/iFraan)
|
||||||
|
- [Ali](https://github.com/bu3alwa)
|
||||||
|
|
||||||
## Emby Contributors
|
## Emby Contributors
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { getActivityLogApi } from '@jellyfin/sdk/lib/utils/api/activity-log-api';
|
|
||||||
import { getUserApi } from '@jellyfin/sdk/lib/utils/api/user-api';
|
|
||||||
import type { ActivityLogEntry } from '@jellyfin/sdk/lib/generated-client/models/activity-log-entry';
|
import type { ActivityLogEntry } from '@jellyfin/sdk/lib/generated-client/models/activity-log-entry';
|
||||||
import type { UserDto } from '@jellyfin/sdk/lib/generated-client/models/user-dto';
|
import type { UserDto } from '@jellyfin/sdk/lib/generated-client/models/user-dto';
|
||||||
import PermMedia from '@mui/icons-material/PermMedia';
|
import PermMedia from '@mui/icons-material/PermMedia';
|
||||||
@ -14,7 +12,8 @@ import { Link, useSearchParams } from 'react-router-dom';
|
|||||||
|
|
||||||
import Page from 'components/Page';
|
import Page from 'components/Page';
|
||||||
import UserAvatar from 'components/UserAvatar';
|
import UserAvatar from 'components/UserAvatar';
|
||||||
import { useApi } from 'hooks/useApi';
|
import { useLogEntires } from 'hooks/useLogEntries';
|
||||||
|
import { useUsers } from 'hooks/useUsers';
|
||||||
import { parseISO8601Date, toLocaleDateString, toLocaleTimeString } from 'scripts/datetime';
|
import { parseISO8601Date, toLocaleDateString, toLocaleTimeString } from 'scripts/datetime';
|
||||||
import globalize from 'lib/globalize';
|
import globalize from 'lib/globalize';
|
||||||
import { toBoolean } from 'utils/string';
|
import { toBoolean } from 'utils/string';
|
||||||
@ -41,19 +40,42 @@ const getActivityView = (param: string | null) => {
|
|||||||
const getRowId = (row: ActivityLogEntry) => row.Id ?? -1;
|
const getRowId = (row: ActivityLogEntry) => row.Id ?? -1;
|
||||||
|
|
||||||
const Activity = () => {
|
const Activity = () => {
|
||||||
const { api } = useApi();
|
|
||||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||||
|
|
||||||
const [ activityView, setActivityView ] = useState(
|
const [ activityView, setActivityView ] = useState(
|
||||||
getActivityView(searchParams.get(VIEW_PARAM)));
|
getActivityView(searchParams.get(VIEW_PARAM)));
|
||||||
const [ isLoading, setIsLoading ] = useState(true);
|
|
||||||
const [ paginationModel, setPaginationModel ] = useState({
|
const [ paginationModel, setPaginationModel ] = useState({
|
||||||
page: 0,
|
page: 0,
|
||||||
pageSize: DEFAULT_PAGE_SIZE
|
pageSize: DEFAULT_PAGE_SIZE
|
||||||
});
|
});
|
||||||
const [ rowCount, setRowCount ] = useState(0);
|
|
||||||
const [ rows, setRows ] = useState<ActivityLogEntry[]>([]);
|
const { data: usersData, isLoading: isUsersLoading } = useUsers();
|
||||||
const [ users, setUsers ] = useState<Record<string, UserDto>>({});
|
|
||||||
|
type UsersRecords = Record<string, UserDto>;
|
||||||
|
const users: UsersRecords = useMemo(() => {
|
||||||
|
if (!usersData) return {};
|
||||||
|
|
||||||
|
return usersData.reduce<UsersRecords>((acc, user) => {
|
||||||
|
const userId = user.Id;
|
||||||
|
if (!userId) return acc;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[userId]: user
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
}, [usersData]);
|
||||||
|
|
||||||
|
const activityParams = useMemo(() => ({
|
||||||
|
startIndex: paginationModel.page * paginationModel.pageSize,
|
||||||
|
limit: paginationModel.pageSize,
|
||||||
|
hasUserId: activityView !== ActivityView.All ? activityView === ActivityView.User : undefined
|
||||||
|
}), [activityView, paginationModel.page, paginationModel.pageSize]);
|
||||||
|
|
||||||
|
const { data: logEntries, isLoading: isLogEntriesLoading } = useLogEntires(activityParams);
|
||||||
|
|
||||||
|
const isLoading = isUsersLoading || isLogEntriesLoading;
|
||||||
|
|
||||||
const userColDef: GridColDef[] = activityView !== ActivityView.System ? [
|
const userColDef: GridColDef[] = activityView !== ActivityView.System ? [
|
||||||
{
|
{
|
||||||
@ -153,58 +175,6 @@ const Activity = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (api) {
|
|
||||||
const fetchUsers = async () => {
|
|
||||||
const { data } = await getUserApi(api).getUsers();
|
|
||||||
const usersById: Record<string, UserDto> = {};
|
|
||||||
data.forEach(user => {
|
|
||||||
if (user.Id) {
|
|
||||||
usersById[user.Id] = user;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setUsers(usersById);
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchUsers()
|
|
||||||
.catch(err => {
|
|
||||||
console.error('[activity] failed to fetch users', err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [ api ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (api) {
|
|
||||||
const fetchActivity = async () => {
|
|
||||||
const params: {
|
|
||||||
startIndex: number,
|
|
||||||
limit: number,
|
|
||||||
hasUserId?: boolean
|
|
||||||
} = {
|
|
||||||
startIndex: paginationModel.page * paginationModel.pageSize,
|
|
||||||
limit: paginationModel.pageSize
|
|
||||||
};
|
|
||||||
if (activityView !== ActivityView.All) {
|
|
||||||
params.hasUserId = activityView === ActivityView.User;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await getActivityLogApi(api)
|
|
||||||
.getLogEntries(params);
|
|
||||||
|
|
||||||
setRowCount(data.TotalRecordCount ?? 0);
|
|
||||||
setRows(data.Items ?? []);
|
|
||||||
setIsLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
setIsLoading(true);
|
|
||||||
fetchActivity()
|
|
||||||
.catch(err => {
|
|
||||||
console.error('[activity] failed to fetch activity log entries', err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [ activityView, api, paginationModel ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentViewParam = getActivityView(searchParams.get(VIEW_PARAM));
|
const currentViewParam = getActivityView(searchParams.get(VIEW_PARAM));
|
||||||
if (currentViewParam !== activityView) {
|
if (currentViewParam !== activityView) {
|
||||||
@ -254,12 +224,12 @@ const Activity = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rows={rows}
|
rows={logEntries?.Items || []}
|
||||||
pageSizeOptions={[ 10, 25, 50, 100 ]}
|
pageSizeOptions={[ 10, 25, 50, 100 ]}
|
||||||
paginationMode='server'
|
paginationMode='server'
|
||||||
paginationModel={paginationModel}
|
paginationModel={paginationModel}
|
||||||
onPaginationModelChange={setPaginationModel}
|
onPaginationModelChange={setPaginationModel}
|
||||||
rowCount={rowCount}
|
rowCount={logEntries?.TotalRecordCount || 0}
|
||||||
getRowId={getRowId}
|
getRowId={getRowId}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
sx={{
|
sx={{
|
||||||
|
33
src/hooks/useLogEntries.tsx
Normal file
33
src/hooks/useLogEntries.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type { ActivityLogApiGetLogEntriesRequest } from '@jellyfin/sdk/lib/generated-client';
|
||||||
|
import type { AxiosRequestConfig } from 'axios';
|
||||||
|
import { getActivityLogApi } from '@jellyfin/sdk/lib/utils/api/activity-log-api';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { JellyfinApiContext, useApi } from './useApi';
|
||||||
|
|
||||||
|
const fetchGetLogEntries = async (
|
||||||
|
currentApi: JellyfinApiContext,
|
||||||
|
requestParams: ActivityLogApiGetLogEntriesRequest,
|
||||||
|
options?: AxiosRequestConfig
|
||||||
|
) => {
|
||||||
|
const { api } = currentApi;
|
||||||
|
|
||||||
|
if (!api) return;
|
||||||
|
|
||||||
|
const response = await getActivityLogApi(api).getLogEntries(requestParams, {
|
||||||
|
signal: options?.signal
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useLogEntires = (
|
||||||
|
requestParams: ActivityLogApiGetLogEntriesRequest
|
||||||
|
) => {
|
||||||
|
const currentApi = useApi();
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['LogEntries', requestParams],
|
||||||
|
queryFn: ({ signal }) =>
|
||||||
|
fetchGetLogEntries(currentApi, requestParams, { signal })
|
||||||
|
});
|
||||||
|
};
|
31
src/hooks/useUsers.tsx
Normal file
31
src/hooks/useUsers.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import type { AxiosRequestConfig } from 'axios';
|
||||||
|
import type { UserApiGetUsersRequest } from '@jellyfin/sdk/lib/generated-client';
|
||||||
|
import { getUserApi } from '@jellyfin/sdk/lib/utils/api/user-api';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { type JellyfinApiContext, useApi } from './useApi';
|
||||||
|
|
||||||
|
export const fetchGetUsers = async (
|
||||||
|
currentApi: JellyfinApiContext,
|
||||||
|
requestParams?: UserApiGetUsersRequest,
|
||||||
|
options?: AxiosRequestConfig
|
||||||
|
) => {
|
||||||
|
const { api } = currentApi;
|
||||||
|
|
||||||
|
if (!api) return;
|
||||||
|
|
||||||
|
const response = await getUserApi(api).getUsers(requestParams, {
|
||||||
|
signal: options?.signal
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUsers = (requestParams?: UserApiGetUsersRequest) => {
|
||||||
|
const currentApi = useApi();
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['Users'],
|
||||||
|
queryFn: ({ signal }) =>
|
||||||
|
fetchGetUsers(currentApi, requestParams, { signal })
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user