TrashPageList.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import React, { FC, useMemo, useCallback } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { toastSuccess } from '~/client/util/apiNotification';
  4. import {
  5. IPageHasId,
  6. } from '~/interfaces/page';
  7. import { IPagingResult } from '~/interfaces/paging-result';
  8. import { useShowPageLimitationXL } from '~/stores/context';
  9. import { useEmptyTrashModal } from '~/stores/modal';
  10. import { useSWRxDescendantsPageListForCurrrentPath, useSWRxPageInfoForList } from '~/stores/page-listing';
  11. import CustomNavAndContents from './CustomNavigation/CustomNavAndContents';
  12. import { DescendantsPageListForCurrentPath } from './DescendantsPageList';
  13. import EmptyTrashButton from './EmptyTrashButton';
  14. import PageListIcon from './Icons/PageListIcon';
  15. const convertToIDataWithMeta = (page) => {
  16. return { data: page };
  17. };
  18. const useEmptyTrashButton = () => {
  19. const { data: limit } = useShowPageLimitationXL();
  20. const { data: pagingResult, mutate: mutatePageLists } = useSWRxDescendantsPageListForCurrrentPath(1, limit);
  21. const { t } = useTranslation();
  22. const { open: openEmptyTrashModal } = useEmptyTrashModal();
  23. const pageIds = pagingResult?.items?.map(page => page._id);
  24. const { injectTo } = useSWRxPageInfoForList(pageIds, null, true, true);
  25. const calculateDeletablePages = useCallback((pagingResult?: IPagingResult<IPageHasId>) => {
  26. if (pagingResult == null) { return undefined }
  27. const dataWithMetas = pagingResult.items.map(page => convertToIDataWithMeta(page));
  28. const pageWithMetas = injectTo(dataWithMetas);
  29. return pageWithMetas.filter(page => page.meta?.isAbleToDeleteCompletely);
  30. }, [injectTo]);
  31. const deletablePages = calculateDeletablePages(pagingResult);
  32. const onEmptiedTrashHandler = useCallback(() => {
  33. toastSuccess(t('empty_trash'));
  34. mutatePageLists();
  35. }, [t, mutatePageLists]);
  36. const emptyTrashClickHandler = useCallback(() => {
  37. if (deletablePages == null) { return }
  38. openEmptyTrashModal(deletablePages, { onEmptiedTrash: onEmptiedTrashHandler, canDeleteAllPages: pagingResult?.totalCount === deletablePages.length });
  39. }, [deletablePages, onEmptiedTrashHandler, openEmptyTrashModal, pagingResult?.totalCount]);
  40. const emptyTrashButton = useMemo(() => {
  41. return <EmptyTrashButton onEmptyTrashButtonClick={emptyTrashClickHandler} disableEmptyButton={deletablePages?.length === 0} />;
  42. }, [emptyTrashClickHandler, deletablePages?.length]);
  43. return emptyTrashButton;
  44. };
  45. export const TrashPageList: FC = () => {
  46. const { t } = useTranslation();
  47. const emptyTrashButton = useEmptyTrashButton();
  48. const navTabMapping = useMemo(() => {
  49. return {
  50. pagelist: {
  51. Icon: PageListIcon,
  52. Content: DescendantsPageListForCurrentPath,
  53. i18n: t('page_list'),
  54. index: 0,
  55. },
  56. };
  57. }, [t]);
  58. return (
  59. <div data-testid="trash-page-list" className="mt-5 d-edit-none">
  60. <CustomNavAndContents navTabMapping={navTabMapping} navRightElement={emptyTrashButton} />
  61. </div>
  62. );
  63. };
  64. TrashPageList.displayName = 'TrashPageList';