import React, { useState, useEffect, useCallback, useMemo, } from 'react'; import type { IUser } from '@growi/core'; import { MergeViewer, CodeMirrorEditorDiff, GlobalCodeMirrorEditorKey, useCodeMirrorEditorIsolated, } from '@growi/editor'; import { UserPicture } from '@growi/ui/dist/components'; import { format } from 'date-fns/format'; import { useTranslation } from 'next-i18next'; import { Modal, ModalHeader, ModalBody, ModalFooter, } from 'reactstrap'; import { useCurrentUser } from '~/stores/context'; import { useConflictDiffModal } from '~/stores/modal'; import { useSWRxCurrentPage } from '~/stores/page'; import { useRemoteRevisionBody, useRemoteRevisionId, useRemoteRevisionLastUpdatedAt, useRemoteRevisionLastUpdateUser, } from '~/stores/remote-latest-page'; import styles from './ConflictDiffModal.module.scss'; type IRevisionOnConflict = { revisionBody: string createdAt: Date user: IUser } type ConflictDiffModalCoreProps = { request: IRevisionOnConflict latest: IRevisionOnConflict }; const formatedDate = (date: Date): string => { return format(date, 'yyyy/MM/dd HH:mm:ss'); }; const ConflictDiffModalCore = (props: ConflictDiffModalCoreProps): JSX.Element => { const { request, latest } = props; const [resolvedRevision, setResolvedRevision] = useState(''); const [isRevisionselected, setIsRevisionSelected] = useState(false); const [revisionSelectedToggler, setRevisionSelectedToggler] = useState(false); const [isModalExpanded, setIsModalExpanded] = useState(false); const { t } = useTranslation(); const { data: conflictDiffModalStatus, close: closeConflictDiffModal } = useConflictDiffModal(); const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.DIFF); const selectRevisionHandler = useCallback((selectedRevision: string) => { setResolvedRevision(selectedRevision); setRevisionSelectedToggler(prev => !prev); if (!isRevisionselected) { setIsRevisionSelected(true); } }, [isRevisionselected]); const resolveConflictHandler = useCallback(async() => { const newBody = codeMirrorEditor?.getDoc(); if (newBody == null) { return; } await conflictDiffModalStatus?.onResolve?.(newBody); }, [codeMirrorEditor, conflictDiffModalStatus]); useEffect(() => { codeMirrorEditor?.initDoc(resolvedRevision); // Enable selecting the same revision after editing by including revisionSelectedToggler in the dependency array of useEffect }, [codeMirrorEditor, resolvedRevision, revisionSelectedToggler]); const headerButtons = useMemo(() => (
), [closeConflictDiffModal, isModalExpanded]); return ( error{t('modal_resolve_conflict.resolve_conflict')}

{t('modal_resolve_conflict.resolve_conflict_message')}

{t('modal_resolve_conflict.requested_revision')}

updated by {request.user.username}

{ formatedDate(request.createdAt) }

{t('modal_resolve_conflict.latest_revision')}

updated by {latest.user.username}

{ formatedDate(latest.createdAt) }

{t('modal_resolve_conflict.selected_editable_revision')}

); }; export const ConflictDiffModal = (): JSX.Element => { const { data: currentUser } = useCurrentUser(); const { data: currentPage } = useSWRxCurrentPage(); const { data: conflictDiffModalStatus } = useConflictDiffModal(); // state for latest page const { data: remoteRevisionId } = useRemoteRevisionId(); const { data: remoteRevisionBody } = useRemoteRevisionBody(); const { data: remoteRevisionLastUpdateUser } = useRemoteRevisionLastUpdateUser(); const { data: remoteRevisionLastUpdatedAt } = useRemoteRevisionLastUpdatedAt(); const isRemotePageDataInappropriate = remoteRevisionId == null || remoteRevisionBody == null || remoteRevisionLastUpdateUser == null; if (!conflictDiffModalStatus?.isOpened || currentUser == null || currentPage == null || isRemotePageDataInappropriate) { return <>; } const currentTime: Date = new Date(); const request: IRevisionOnConflict = { revisionBody: conflictDiffModalStatus.requestRevisionBody ?? '', createdAt: currentTime, user: currentUser, }; const latest: IRevisionOnConflict = { revisionBody: remoteRevisionBody, createdAt: new Date(remoteRevisionLastUpdatedAt ?? currentTime.toString()), user: remoteRevisionLastUpdateUser, }; return ; };