ShareLinkSetting.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import React, {
  2. useCallback, useEffect, useState,
  3. } from 'react';
  4. import { useTranslation } from 'next-i18next';
  5. import AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';
  6. import { apiv3Delete } from '~/client/util/apiv3-client';
  7. import { toastSuccess, toastError } from '~/client/util/toastr';
  8. import ShareLinkList from '../../PageAccessoriesModal/ShareLink/ShareLinkList';
  9. import PaginationWrapper from '../../PaginationWrapper';
  10. import { withUnstatedContainers } from '../../UnstatedUtils';
  11. import DeleteAllShareLinksModal from './DeleteAllShareLinksModal';
  12. type PagerProps = {
  13. activePage: number,
  14. pagingHandler: (page: number) => Promise<void>,
  15. totalLinks: number,
  16. limit: number,
  17. }
  18. type ShareLinkSettingProps = {
  19. adminGeneralSecurityContainer: AdminGeneralSecurityContainer,
  20. }
  21. const Pager = (props: PagerProps) => {
  22. const {
  23. activePage, pagingHandler, totalLinks, limit,
  24. } = props;
  25. return (
  26. <PaginationWrapper
  27. activePage={activePage}
  28. changePage={pagingHandler}
  29. totalItemsCount={totalLinks}
  30. pagingLimit={limit}
  31. align="center"
  32. size="sm"
  33. />
  34. );
  35. };
  36. const ShareLinkSetting = (props: ShareLinkSettingProps) => {
  37. const { t } = useTranslation('admin');
  38. const { adminGeneralSecurityContainer } = props;
  39. const {
  40. shareLinks, shareLinksActivePage, totalshareLinks, shareLinksPagingLimit,
  41. disableLinkSharing, setupStrategies,
  42. } = adminGeneralSecurityContainer.state;
  43. const [isDeleteConfirmModalShown, setIsDeleteConfirmModalShown] = useState<boolean>();
  44. const getShareLinkList = useCallback(async(page: number) => {
  45. try {
  46. await adminGeneralSecurityContainer.retrieveShareLinksByPagingNum(page);
  47. }
  48. catch (err) {
  49. toastError(err);
  50. }
  51. }, [adminGeneralSecurityContainer]);
  52. // for Next routing
  53. useEffect(() => {
  54. getShareLinkList(1);
  55. }, [getShareLinkList]);
  56. const deleteAllLinksButtonHandler = useCallback(async() => {
  57. try {
  58. const res = await apiv3Delete('/share-links/all');
  59. const { deletedCount } = res.data;
  60. toastSuccess(t('toaster.remove_share_link', { count: deletedCount, ns: 'commons' }));
  61. }
  62. catch (err) {
  63. toastError(err);
  64. }
  65. getShareLinkList(1);
  66. }, [getShareLinkList, t]);
  67. const deleteLinkById = useCallback(async(shareLinkId: string) => {
  68. try {
  69. const res = await apiv3Delete(`/share-links/${shareLinkId}`);
  70. const { deletedShareLink } = res.data;
  71. toastSuccess(t('toaster.remove_share_link_success', { shareLinkId: deletedShareLink._id, ns: 'commons' }));
  72. }
  73. catch (err) {
  74. toastError(err);
  75. }
  76. getShareLinkList(shareLinksActivePage);
  77. }, [shareLinksActivePage, getShareLinkList, t]);
  78. const switchDisableLinkSharing = useCallback(async() => {
  79. try {
  80. await adminGeneralSecurityContainer.switchDisableLinkSharing();
  81. toastSuccess(t('toaster.switch_disable_link_sharing_success'));
  82. }
  83. catch (err) {
  84. toastError(err);
  85. }
  86. }, [adminGeneralSecurityContainer, t]);
  87. return (
  88. <>
  89. <h2 className="alert-anchor border-bottom mb-4">{t('security_settings.share_link_management')}</h2>
  90. <h4>{t('security_settings.share_link_rights')}</h4>
  91. <div className="row mt-4 mb-5">
  92. <div className="col-6 offset-3">
  93. <div className="form-check form-switch form-check-success">
  94. <input
  95. type="checkbox"
  96. className="form-check-input"
  97. id="disableLinkSharing"
  98. checked={!disableLinkSharing}
  99. onChange={() => switchDisableLinkSharing()}
  100. />
  101. <label className="form-label form-check-label" htmlFor="disableLinkSharing">
  102. {t('security_settings.enable_link_sharing')}
  103. </label>
  104. </div>
  105. {!setupStrategies.includes('local') && disableLinkSharing && (
  106. <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>
  107. )}
  108. </div>
  109. </div>
  110. <h4>{t('security_settings.all_share_links')}</h4>
  111. {(shareLinks.length !== 0) ? (
  112. <>
  113. <Pager
  114. activePage={shareLinksActivePage}
  115. pagingHandler={getShareLinkList}
  116. totalLinks={totalshareLinks}
  117. limit={shareLinksPagingLimit}
  118. />
  119. <ShareLinkList
  120. shareLinks={shareLinks}
  121. onClickDeleteButton={deleteLinkById}
  122. isAdmin
  123. />
  124. </>
  125. )
  126. : (<p className="text-center">{t('security_settings.No_share_links')}</p>
  127. )
  128. }
  129. <button
  130. className="pull-right btn btn-danger mt-2"
  131. disabled={shareLinks.length === 0}
  132. type="button"
  133. onClick={() => setIsDeleteConfirmModalShown(true)}
  134. >
  135. {t('security_settings.delete_all_share_links')}
  136. </button>
  137. <DeleteAllShareLinksModal
  138. isOpen={isDeleteConfirmModalShown}
  139. onClose={() => setIsDeleteConfirmModalShown(false)}
  140. onClickDeleteButton={deleteAllLinksButtonHandler}
  141. />
  142. </>
  143. );
  144. };
  145. /**
  146. * Wrapper component for using unstated
  147. */
  148. const ShareLinkSettingWrapper = withUnstatedContainers(ShareLinkSetting, [AdminGeneralSecurityContainer]);
  149. export default ShareLinkSettingWrapper;