SavePageControls.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React, { useCallback } from 'react';
  2. import { pagePathUtils, PageGrant } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import {
  5. UncontrolledButtonDropdown, Button,
  6. DropdownToggle, DropdownMenu, DropdownItem,
  7. } from 'reactstrap';
  8. // import PageContainer from '~/client/services/PageContainer';
  9. import { CustomWindow } from '~/interfaces/global';
  10. import { IPageGrantData } from '~/interfaces/page';
  11. import {
  12. useIsEditable, useCurrentPageId, useIsAclEnabled,
  13. } from '~/stores/context';
  14. import { useIsEnabledUnsavedWarning } from '~/stores/editor';
  15. import { useCurrentPagePath } from '~/stores/page';
  16. import { useSelectedGrant } from '~/stores/ui';
  17. import loggerFactory from '~/utils/logger';
  18. import GrantSelector from './SavePageControls/GrantSelector';
  19. // import { withUnstatedContainers } from './UnstatedUtils';
  20. const logger = loggerFactory('growi:SavePageControls');
  21. type Props = {
  22. // pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  23. }
  24. const { isTopPage } = pagePathUtils;
  25. export const SavePageControls = (props: Props): JSX.Element | null => {
  26. const { t } = useTranslation();
  27. const { data: currentPagePath } = useCurrentPagePath();
  28. const { data: isEditable } = useIsEditable();
  29. const { data: isAclEnabled } = useIsAclEnabled();
  30. const { data: grantData, mutate: mutateGrant } = useSelectedGrant();
  31. const { data: pageId } = useCurrentPageId();
  32. const updateGrantHandler = useCallback((grantData: IPageGrantData): void => {
  33. mutateGrant(grantData);
  34. }, [mutateGrant]);
  35. const save = useCallback(async(): Promise<void> => {
  36. // save
  37. (window as CustomWindow).globalEmitter.emit('saveAndReturnToView');
  38. }, []);
  39. const saveAndOverwriteScopesOfDescendants = useCallback(() => {
  40. // save
  41. (window as CustomWindow).globalEmitter.emit('saveAndReturnToView', { overwriteScopesOfDescendants: true });
  42. }, []);
  43. if (isEditable == null || isAclEnabled == null || grantData == null) {
  44. return null;
  45. }
  46. if (!isEditable) {
  47. return null;
  48. }
  49. const { grant, grantedGroup } = grantData;
  50. const isRootPage = isTopPage(currentPagePath ?? '');
  51. const labelSubmitButton = pageId == null ? t('Create') : t('Update');
  52. const labelOverwriteScopes = t('page_edit.overwrite_scopes', { operation: labelSubmitButton });
  53. return (
  54. <div className="d-flex align-items-center form-inline flex-nowrap">
  55. {isAclEnabled
  56. && (
  57. <div className="mr-2">
  58. <GrantSelector
  59. grant={grant}
  60. disabled={isRootPage}
  61. grantGroupId={grantedGroup?.id}
  62. grantGroupName={grantedGroup?.name}
  63. onUpdateGrant={updateGrantHandler}
  64. />
  65. </div>
  66. )
  67. }
  68. <UncontrolledButtonDropdown direction="up">
  69. <Button data-testid="save-page-btn" id="caret" color="primary" className="btn-submit" onClick={save}>
  70. {labelSubmitButton}
  71. </Button>
  72. <DropdownToggle caret color="primary" />
  73. <DropdownMenu right>
  74. <DropdownItem onClick={saveAndOverwriteScopesOfDescendants}>
  75. {labelOverwriteScopes}
  76. </DropdownItem>
  77. </DropdownMenu>
  78. </UncontrolledButtonDropdown>
  79. </div>
  80. );
  81. };