RecentActivity.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React, {
  2. useState, useCallback, useEffect, type JSX,
  3. } from 'react';
  4. import { toastError } from '~/client/util/toastr';
  5. import type { IActivityHasId, ActivityWithPageTarget } from '~/interfaces/activity';
  6. import { useSWRxRecentActivity } from '~/stores/recent-activity';
  7. import loggerFactory from '~/utils/logger';
  8. import PaginationWrapper from '../PaginationWrapper';
  9. import { ActivityListItem } from './ActivityListItem';
  10. const logger = loggerFactory('growi:RecentActivity');
  11. const hasPageTarget = (activity: IActivityHasId): activity is ActivityWithPageTarget => {
  12. return activity.target != null
  13. && typeof activity.target === 'object'
  14. && '_id' in activity.target;
  15. };
  16. export const RecentActivity = (): JSX.Element => {
  17. const [activities, setActivities] = useState<ActivityWithPageTarget[]>([]);
  18. const [activePage, setActivePage] = useState(1);
  19. const [limit] = useState(10);
  20. const [offset, setOffset] = useState(0);
  21. const { data: paginatedData, error } = useSWRxRecentActivity(limit, offset);
  22. const handlePage = useCallback(async(selectedPage: number) => {
  23. const newOffset = (selectedPage - 1) * limit;
  24. setOffset(newOffset);
  25. setActivePage(selectedPage);
  26. }, [limit]);
  27. useEffect(() => {
  28. if (error) {
  29. logger.error('Failed to fetch recent activity data', error);
  30. toastError(error);
  31. return;
  32. }
  33. if (paginatedData) {
  34. const activitiesWithPages = paginatedData.docs
  35. .filter(hasPageTarget);
  36. setActivities(activitiesWithPages);
  37. }
  38. }, [paginatedData, error]);
  39. const totalPageCount = paginatedData?.totalDocs || 0;
  40. return (
  41. <div className="page-list-container-activity">
  42. <ul className="page-list-ul page-list-ul-flat mb-3">
  43. {activities.map(activity => (
  44. <li key={`recent-activity-view:${activity._id}`} className="mt-4">
  45. <ActivityListItem activity={activity} />
  46. </li>
  47. ))}
  48. </ul>
  49. <PaginationWrapper
  50. activePage={activePage}
  51. changePage={handlePage}
  52. totalItemsCount={totalPageCount}
  53. pagingLimit={limit}
  54. align="center"
  55. size="sm"
  56. />
  57. </div>
  58. );
  59. };