SavePageControls.tsx 3.1 KB

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