mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-15 01:48:16 -07: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)
|
||||
- [Connor Smith](https://github.com/ConnorS1110)
|
||||
- [iFraan](https://github.com/iFraan)
|
||||
- [Ali](https://github.com/bu3alwa)
|
||||
|
||||
## Emby Contributors
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
import React, { useCallback, useEffect, 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 React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
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 PermMedia from '@mui/icons-material/PermMedia';
|
||||
@ -14,7 +12,8 @@ import { Link, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import Page from 'components/Page';
|
||||
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 globalize from 'lib/globalize';
|
||||
import { toBoolean } from 'utils/string';
|
||||
@ -41,19 +40,42 @@ const getActivityView = (param: string | null) => {
|
||||
const getRowId = (row: ActivityLogEntry) => row.Id ?? -1;
|
||||
|
||||
const Activity = () => {
|
||||
const { api } = useApi();
|
||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||
|
||||
const [ activityView, setActivityView ] = useState(
|
||||
getActivityView(searchParams.get(VIEW_PARAM)));
|
||||
const [ isLoading, setIsLoading ] = useState(true);
|
||||
|
||||
const [ paginationModel, setPaginationModel ] = useState({
|
||||
page: 0,
|
||||
pageSize: DEFAULT_PAGE_SIZE
|
||||
});
|
||||
const [ rowCount, setRowCount ] = useState(0);
|
||||
const [ rows, setRows ] = useState<ActivityLogEntry[]>([]);
|
||||
const [ users, setUsers ] = useState<Record<string, UserDto>>({});
|
||||
|
||||
const { data: usersData, isLoading: isUsersLoading } = useUsers();
|
||||
|
||||
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 ? [
|
||||
{
|
||||
@ -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(() => {
|
||||
const currentViewParam = getActivityView(searchParams.get(VIEW_PARAM));
|
||||
if (currentViewParam !== activityView) {
|
||||
@ -254,12 +224,12 @@ const Activity = () => {
|
||||
</Box>
|
||||
<DataGrid
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
rows={logEntries?.Items || []}
|
||||
pageSizeOptions={[ 10, 25, 50, 100 ]}
|
||||
paginationMode='server'
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
rowCount={rowCount}
|
||||
rowCount={logEntries?.TotalRecordCount || 0}
|
||||
getRowId={getRowId}
|
||||
loading={isLoading}
|
||||
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