123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- 'use client';
- import React, { useEffect, useMemo, useState } from 'react'
- import Agent from './NodeType/Agent';
- import Form from './NodeType/Form';
- import Unsupport from './NodeType/Unsupport';
- import * as R from 'ramda'
- import { curNodeAtom, curStepAtom, arrowStateAtom, cardInstantAtomFamily, cardInstantAtomsAtom, instantDataAtom, stepsNodesAtom, viewedStepAtom, asideInstantAtomsAtom, asideInstantAtomFamily } from '../store';
- import { useAtom, useAtomValue, useSetAtom } from 'jotai';
- import { exportFlowToDocx } from '../export';
- import PreviewModal from './PreviewModal';
- import { useReducerAtom } from 'jotai/utils';
- import ClearAfterFlowConfirmModal from './ClearAfterFlowConfirmModal';
- const NodeRender = () => {
- 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 arrowState = useAtomValue(arrowStateAtom)
- const Comp = useMemo(() => {
- return R.cond([
- [R.propEq('form_card', 'type'), R.always(Form)],
- [R.propEq('UserTask', 'type'), R.always(Agent)],
- [R.T, R.always(Unsupport)],
- ])(node)
- }, [node, node?.id])
- const nodeName = useMemo(() => {
- return R.cond([
- [R.propEq('form_card', 'type'), R.always('表单填写')],
- [R.propEq('UserTask', 'type'), R.pathOr('Unknown Agent', ['properties', 'item', 'assistantName'])],
- [R.T, R.always('Unknown')],
- ])(node)
- }, [node, node?.id])
- // 动态注册当前节点的Atom,并将其放进一个atom集合的atom,方便后续格式化所有节点实例
- const cardInstantAtom = cardInstantAtomFamily(node)
- const [cardInstantAtoms, dispatchCardInstantAtoms] = useAtom(cardInstantAtomsAtom)
- useEffect(() => {
- if (node?.id) {
- dispatchCardInstantAtoms({ payload: { [node.id]: cardInstantAtom }, type: 'update' })
- }
- }, [cardInstantAtom])
- 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)
- setConfirmClearAfterFlowModalOpen(false)
- }
- const onPrevStep = () => {
- setCurStep(prev => prev - 1)
- }
- const [isPreviewModalOpen, setPreviewModalOpen] = useState(false)
- const onPreview = () => {
- setPreviewModalOpen(true)
- }
- return (
- <div className="card card-compact shadow-xl flex-1 overflow-hidden">
- <div className="card-body overflow-hidden">
- <div className="card-title rounded-box bg-slate-100 p-2">
- <h2 className="flex-1">
- {curStep + 1}: {nodeName}
- </h2>
- {arrowState.prev &&
- <button className='btn btn-sm' onClick={() => onPrevStep()}>上一步</button>
- }
- {arrowState.next
- ? <button className='btn btn-sm' onClick={() => onNextStep()}>下一步</button>
- : <button className='btn btn-sm btn-neutral' onClick={onPreview}>预览</button>
- }
- </div>
- <div className="flex-1 flex flex-col items-stretch overflow-auto">
- <Comp key={node?.id} node={node} cardInstantAtom={cardInstantAtom}></Comp>
- </div>
- </div>
- <ClearAfterFlowConfirmModal
- open={confirmClearAfterFlowModalOpen}
- onCancel={() => setConfirmClearAfterFlowModalOpen(false)}
- onConfirm={onNextStep}
- />
- <PreviewModal open={isPreviewModalOpen} onClose={() => setPreviewModalOpen(false)} />
- </div>
- )
- }
- export default React.memo(React.forwardRef(NodeRender))
|