import React, { useCallback, useState, useEffect } from 'react'; import type EventEmitter from 'events'; import { PageGrant } from '@growi/core'; import { isTopPage, isUsersProtectedPages } from '@growi/core/dist/utils/page-path-utils'; import { LoadingSpinner } from '@growi/ui/dist/components'; import { useTranslation } from 'next-i18next'; import { UncontrolledButtonDropdown, Button, DropdownToggle, DropdownMenu, DropdownItem, Modal, } from 'reactstrap'; import { useIsEditable, useIsAclEnabled, useIsSlackConfigured, } from '~/stores-universal/context'; import { useEditorMode } from '~/stores-universal/ui'; import { useWaitingSaveProcessing, useSWRxSlackChannels, useIsSlackEnabled } from '~/stores/editor'; import { useSWRxCurrentPage, useCurrentPagePath } from '~/stores/page'; import { useIsDeviceLargerThanMd, useSelectedGrant } from '~/stores/ui'; import loggerFactory from '~/utils/logger'; import { NotAvailable } from './NotAvailable'; import { GrantSelector } from './SavePageControls/GrantSelector'; import { SlackNotification } from './SlackNotification'; declare global { // eslint-disable-next-line vars-on-top, no-var var globalEmitter: EventEmitter; } const logger = loggerFactory('growi:SavePageControls'); const SavePageButton = (props: {slackChannels: string, isSlackEnabled?: boolean, isDeviceLargerThanMd?: boolean}) => { const { t } = useTranslation(); const { data: _isWaitingSaveProcessing } = useWaitingSaveProcessing(); const [isSavePageModalShown, setIsSavePageModalShown] = useState(false); const { data: selectedGrant } = useSelectedGrant(); const { slackChannels, isSlackEnabled, isDeviceLargerThanMd } = props; const isWaitingSaveProcessing = _isWaitingSaveProcessing === true; // ignore undefined const save = useCallback(async(): Promise => { // save globalEmitter.emit('saveAndReturnToView', { wip: false, slackChannels, isSlackEnabled }); }, [isSlackEnabled, slackChannels]); const saveAndOverwriteScopesOfDescendants = useCallback(() => { // save globalEmitter.emit('saveAndReturnToView', { wip: false, overwriteScopesOfDescendants: true, slackChannels, isSlackEnabled, }); }, [isSlackEnabled, slackChannels]); const saveAndMakeWip = useCallback(() => { // save globalEmitter.emit('saveAndReturnToView', { wip: true, slackChannels, isSlackEnabled }); }, [isSlackEnabled, slackChannels]); const labelSubmitButton = t('Update'); const labelOverwriteScopes = t('page_edit.overwrite_scopes', { operation: labelSubmitButton }); const labelUnpublishPage = t('wip_page.save_as_wip'); const restrictedGrantOverrideErrorTitle = t('Not available when "anyone with the link" is selected'); return ( <> { isDeviceLargerThanMd ? ( <> {labelOverwriteScopes} {labelUnpublishPage} ) : ( <> setIsSavePageModalShown(true)} /> setIsSavePageModalShown(false)} >
) }
); }; export const SavePageControls = (): JSX.Element | null => { const { t } = useTranslation('commons'); const { data: currentPage } = useSWRxCurrentPage(); const { data: isEditable } = useIsEditable(); const { data: isAclEnabled } = useIsAclEnabled(); const { data: editorMode } = useEditorMode(); const { data: currentPagePath } = useCurrentPagePath(); const { data: isSlackConfigured } = useIsSlackConfigured(); const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useIsSlackEnabled(); const { data: slackChannelsData } = useSWRxSlackChannels(currentPagePath); const { data: isDeviceLargerThanMd } = useIsDeviceLargerThanMd(); const [slackChannels, setSlackChannels] = useState(''); const [isSavePageControlsModalShown, setIsSavePageControlsModalShown] = useState(false); // DO NOT dependent on slackChannelsData directly: https://github.com/weseek/growi/pull/7332 const slackChannelsDataString = slackChannelsData?.toString(); useEffect(() => { if (editorMode === 'editor') { setSlackChannels(slackChannelsDataString ?? ''); mutateIsSlackEnabled(false); } }, [editorMode, mutateIsSlackEnabled, slackChannelsDataString]); const isSlackEnabledToggleHandler = (bool: boolean) => { mutateIsSlackEnabled(bool, false); }; const slackChannelsChangedHandler = useCallback((slackChannels: string) => { setSlackChannels(slackChannels); }, []); if (isEditable == null || isAclEnabled == null) { return null; } if (!isEditable) { return null; } const isGrantSelectorDisabledPage = isTopPage(currentPage?.path ?? '') || isUsersProtectedPages(currentPage?.path ?? ''); return (
{ isDeviceLargerThanMd ? ( <> { isSlackConfigured && (
{isSlackEnabled != null && ( )}
) } { isAclEnabled && (
) } ) : ( <>
{ isAclEnabled && ( <> ) } { isSlackConfigured && isSlackEnabled != null && ( <> ) }
) }
); };