import React, { useState, useCallback } from 'react'; import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem, } from 'reactstrap'; import toastr from 'toastr'; import { useTranslation } from 'react-i18next'; import loggerFactory from '~/utils/logger'; import { IPageInfo, IPageInfoCommon, isExistPageInfo, } from '~/interfaces/page'; import { useSWRxPageInfo } from '~/stores/page'; const logger = loggerFactory('growi:cli:PageItemControl'); export type AdditionalMenuItemsRendererProps = { pageInfo: IPageInfoCommon | IPageInfo }; type CommonProps = { pageInfo?: IPageInfoCommon | IPageInfo, isEnableActions?: boolean, hideBookmarkMenuItem?: boolean, onClickBookmarkMenuItem?: (pageId: string, newValue?: boolean) => Promise, onClickRenameMenuItem?: (pageId: string) => void, onClickDeleteMenuItem?: (pageId: string) => void, additionalMenuItemRenderer?: React.FunctionComponent, } type DropdownMenuProps = CommonProps & { pageId: string, } const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.Element => { const { t } = useTranslation(''); const { pageId, pageInfo, isEnableActions, hideBookmarkMenuItem, onClickBookmarkMenuItem, onClickRenameMenuItem, onClickDeleteMenuItem, additionalMenuItemRenderer: AdditionalMenuItems, } = props; // eslint-disable-next-line react-hooks/rules-of-hooks const bookmarkItemClickedHandler = useCallback(async() => { if (!isExistPageInfo(pageInfo) || onClickBookmarkMenuItem == null) { return; } await onClickBookmarkMenuItem(pageId, !pageInfo.isBookmarked); }, [onClickBookmarkMenuItem, pageId, pageInfo]); // eslint-disable-next-line react-hooks/rules-of-hooks const renameItemClickedHandler = useCallback(async() => { if (onClickRenameMenuItem == null) { return; } await onClickRenameMenuItem(pageId); }, [onClickRenameMenuItem, pageId]); // eslint-disable-next-line react-hooks/rules-of-hooks const deleteItemClickedHandler = useCallback(async() => { if (!isExistPageInfo(pageInfo) || onClickDeleteMenuItem == null) { return; } if (!pageInfo.isDeletable) { logger.warn('This page could not be deleted.'); return; } await onClickDeleteMenuItem(pageId); }, [onClickDeleteMenuItem, pageId, pageInfo]); if (pageId == null || pageInfo == null) { return <>; } return ( { !isEnableActions && (

{t('search_result.currently_not_implemented')}

) } {/* Bookmark */} { !hideBookmarkMenuItem && isExistPageInfo(pageInfo) && isEnableActions && ( { pageInfo.isBookmarked ? t('remove_bookmark') : t('add_bookmark') } ) } {/* Duplicate */} { isExistPageInfo(pageInfo) && isEnableActions && ( toastr.warning(t('search_result.currently_not_implemented'))}> {t('Duplicate')} ) } {/* Move/Rename */} { isEnableActions && pageInfo.isMovable && ( {t('Move/Rename')} ) } { AdditionalMenuItems && } {/* divider */} {/* Delete */} { isExistPageInfo(pageInfo) && isEnableActions && pageInfo.isMovable && ( <> {t('Delete')} )}
); }); type PageItemControlSubstanceProps = CommonProps & { pageId: string, fetchOnOpen?: boolean, } export const PageItemControlSubstance = (props: PageItemControlSubstanceProps): JSX.Element => { const { pageId, pageInfo: presetPageInfo, fetchOnOpen, onClickBookmarkMenuItem, } = props; const [isOpen, setIsOpen] = useState(false); const shouldFetch = presetPageInfo == null && (!fetchOnOpen || isOpen); const { data: fetchedPageInfo, mutate: mutatePageInfo } = useSWRxPageInfo(shouldFetch ? pageId : null); // mutate after handle event const bookmarkMenuItemClickHandler = useCallback(async(_pageId: string, _newValue: boolean) => { if (onClickBookmarkMenuItem != null) { await onClickBookmarkMenuItem(_pageId, _newValue); } if (shouldFetch) { mutatePageInfo(); } }, [mutatePageInfo, onClickBookmarkMenuItem, shouldFetch]); return ( setIsOpen(!isOpen)}> ); }; type PageItemControlProps = CommonProps & { pageId?: string, } export const PageItemControl = (props: PageItemControlProps): JSX.Element => { const { pageId } = props; if (pageId == null) { return <>; } return ; }; type AsyncPageItemControlProps = CommonProps & { pageId?: string, } export const AsyncPageItemControl = (props: AsyncPageItemControlProps): JSX.Element => { const { pageId } = props; if (pageId == null) { return <>; } return ; };