RecentActivity.tsx 2.3 KB

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