|
@@ -5,13 +5,23 @@ import Agent from './NodeType/Agent';
|
|
import Form from './NodeType/Form';
|
|
import Form from './NodeType/Form';
|
|
import Unsupport from './NodeType/Unsupport';
|
|
import Unsupport from './NodeType/Unsupport';
|
|
import * as R from 'ramda'
|
|
import * as R from 'ramda'
|
|
-import { curNodeAtom, curStepAtom, arrowStateAtom, cardInstantAtomFamily, cardInstantAtomsAtom, instantDataAtom, stepsNodesAtom } from '../store';
|
|
|
|
-import { useAtom, useAtomValue } from 'jotai';
|
|
|
|
|
|
+import { curNodeAtom, curStepAtom, arrowStateAtom, cardInstantAtomFamily, cardInstantAtomsAtom, instantDataAtom, stepsNodesAtom, viewedStepAtom, asideInstantAtomsAtom, asideInstantAtomFamily } from '../store';
|
|
|
|
+import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
|
import { exportFlowToDocx } from '../export';
|
|
import { exportFlowToDocx } from '../export';
|
|
import PreviewModal from './PreviewModal';
|
|
import PreviewModal from './PreviewModal';
|
|
|
|
+import { useReducerAtom } from 'jotai/utils';
|
|
|
|
+import ClearAfterFlowConfirmModal from './ClearAfterFlowConfirmModal';
|
|
|
|
|
|
const NodeRender = () => {
|
|
const NodeRender = () => {
|
|
const [curStep, setCurStep] = useAtom(curStepAtom)
|
|
const [curStep, setCurStep] = useAtom(curStepAtom)
|
|
|
|
+ const [viewedStep, dispatchViewedStep] = useReducerAtom(viewedStepAtom, (prev: number, step: number) => {
|
|
|
|
+ return R.max(prev, step)
|
|
|
|
+ })
|
|
|
|
+ const forceSetViewedStep = useSetAtom(viewedStepAtom)
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ dispatchViewedStep(curStep)
|
|
|
|
+ }, [curStep])
|
|
|
|
+ const [confirmClearAfterFlowModalOpen, setConfirmClearAfterFlowModalOpen] = useState(false)
|
|
const node = useAtomValue(curNodeAtom)
|
|
const node = useAtomValue(curNodeAtom)
|
|
const arrowState = useAtomValue(arrowStateAtom)
|
|
const arrowState = useAtomValue(arrowStateAtom)
|
|
const Comp = useMemo(() => {
|
|
const Comp = useMemo(() => {
|
|
@@ -31,15 +41,53 @@ const NodeRender = () => {
|
|
|
|
|
|
// 动态注册当前节点的Atom,并将其放进一个atom集合的atom,方便后续格式化所有节点实例
|
|
// 动态注册当前节点的Atom,并将其放进一个atom集合的atom,方便后续格式化所有节点实例
|
|
const cardInstantAtom = cardInstantAtomFamily(node)
|
|
const cardInstantAtom = cardInstantAtomFamily(node)
|
|
- const [, dispatchCardInstantAtoms] = useAtom(cardInstantAtomsAtom)
|
|
|
|
|
|
+ const [cardInstantAtoms, dispatchCardInstantAtoms] = useAtom(cardInstantAtomsAtom)
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
if (node?.id) {
|
|
if (node?.id) {
|
|
- dispatchCardInstantAtoms({ [node.id]: cardInstantAtom })
|
|
|
|
|
|
+ dispatchCardInstantAtoms({ payload: { [node.id]: cardInstantAtom }, type: 'update' })
|
|
}
|
|
}
|
|
}, [cardInstantAtom])
|
|
}, [cardInstantAtom])
|
|
|
|
|
|
- const onNextStep = () => {
|
|
|
|
|
|
+ const stepsNodes = useAtomValue(stepsNodesAtom);
|
|
|
|
+ const [asideInstantAtoms, dispatchAsideInstantAtoms] = useAtom(asideInstantAtomsAtom)
|
|
|
|
+ const onNextStep = (confirmed?: 'clear' | 'not_clear') => {
|
|
|
|
+ if (!confirmed) {
|
|
|
|
+ if (curStep < viewedStep) {
|
|
|
|
+ setConfirmClearAfterFlowModalOpen(true)
|
|
|
|
+ } else {
|
|
|
|
+ setCurStep(prev => prev + 1)
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ switch (confirmed) {
|
|
|
|
+ case 'clear':
|
|
|
|
+ // Clear node instant data after current node
|
|
|
|
+ const nodesToClear = stepsNodes.slice(curStep + 1);
|
|
|
|
+ const updatedCardInstantAtoms = R.pickBy(
|
|
|
|
+ (_, key) => !nodesToClear.some(node => node.id === key),
|
|
|
|
+ cardInstantAtoms
|
|
|
|
+ );
|
|
|
|
+ dispatchCardInstantAtoms({ payload: updatedCardInstantAtoms, type: 'replace' });
|
|
|
|
+
|
|
|
|
+ const updatedAsideInstantAtoms = R.pickBy(
|
|
|
|
+ (_, key) => !nodesToClear.some(node => node.id === key),
|
|
|
|
+ asideInstantAtoms
|
|
|
|
+ )
|
|
|
|
+ dispatchAsideInstantAtoms({ payload: updatedAsideInstantAtoms, type: 'replace' })
|
|
|
|
+ nodesToClear.forEach((node) => {
|
|
|
|
+ console.log('removed: ', node.id)
|
|
|
|
+ cardInstantAtomFamily.remove(node)
|
|
|
|
+ asideInstantAtomFamily.remove(node)
|
|
|
|
+ })
|
|
|
|
+ forceSetViewedStep(curStep);
|
|
|
|
+ break;
|
|
|
|
+ case 'not_clear':
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
setCurStep(prev => prev + 1)
|
|
setCurStep(prev => prev + 1)
|
|
|
|
+ setConfirmClearAfterFlowModalOpen(false)
|
|
}
|
|
}
|
|
|
|
|
|
const onPrevStep = () => {
|
|
const onPrevStep = () => {
|
|
@@ -60,10 +108,10 @@ const NodeRender = () => {
|
|
{curStep + 1}: {nodeName}
|
|
{curStep + 1}: {nodeName}
|
|
</h2>
|
|
</h2>
|
|
{arrowState.prev &&
|
|
{arrowState.prev &&
|
|
- <button className='btn btn-sm' onClick={onPrevStep}>上一步</button>
|
|
|
|
|
|
+ <button className='btn btn-sm' onClick={() => onPrevStep()}>上一步</button>
|
|
}
|
|
}
|
|
{arrowState.next
|
|
{arrowState.next
|
|
- ? <button className='btn btn-sm' onClick={onNextStep}>下一步</button>
|
|
|
|
|
|
+ ? <button className='btn btn-sm' onClick={() => onNextStep()}>下一步</button>
|
|
: <button className='btn btn-sm btn-neutral' onClick={onPreview}>预览</button>
|
|
: <button className='btn btn-sm btn-neutral' onClick={onPreview}>预览</button>
|
|
}
|
|
}
|
|
</div>
|
|
</div>
|
|
@@ -71,6 +119,11 @@ const NodeRender = () => {
|
|
<Comp key={node?.id} node={node} cardInstantAtom={cardInstantAtom}></Comp>
|
|
<Comp key={node?.id} node={node} cardInstantAtom={cardInstantAtom}></Comp>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
+ <ClearAfterFlowConfirmModal
|
|
|
|
+ open={confirmClearAfterFlowModalOpen}
|
|
|
|
+ onCancel={() => setConfirmClearAfterFlowModalOpen(false)}
|
|
|
|
+ onConfirm={onNextStep}
|
|
|
|
+ />
|
|
<PreviewModal open={isPreviewModalOpen} onClose={() => setPreviewModalOpen(false)} />
|
|
<PreviewModal open={isPreviewModalOpen} onClose={() => setPreviewModalOpen(false)} />
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|