44 * Licensed under the MIT License. See License.txt in the project root for license information.
55 *--------------------------------------------------------------------------------------------*/
66
7- import React , { createContext , forwardRef , useContext , useEffect , useImperativeHandle , useReducer , useRef } from 'react' ;
7+ import React , { createContext , forwardRef , useContext , useEffect , useImperativeHandle , useReducer , useRef , useState } from 'react' ;
8+ import { createPortal } from 'react-dom' ;
89import './contentStyle.css' ;
9- import { ConfigProvider , Form } from 'antd' ;
10+ import { Form } from 'antd' ;
11+ import { CloseOutlined } from '@ant-design/icons' ;
1012import { useUpdateEffect } from '@/components/common/UseUpdateEffect.jsx' ;
1113import { EVENT_TYPE } from '@fit-elsa/elsa-core' ;
1214import PropTypes from 'prop-types' ;
@@ -26,117 +28,180 @@ const FormContext = createContext(null);
2628 * @return {JSX.Element }
2729 * @constructor
2830 */
29- export const DefaultRoot = forwardRef ( function ( { shape, component, shapeStatus, borderPadding} , ref ) {
30- const [ data , dispatch ] = useReducer ( component . reducers , component . getJadeConfig ( ) ) ;
31- const id = "react-root-" + shape . id ;
32- const [ form ] = Form . useForm ( ) ;
33- const domRef = useRef ( ) ;
31+ export const DefaultRoot = forwardRef ( function (
32+ { shape, component, shapeStatus, borderPadding} ,
33+ ref ,
34+ ) {
35+ const [ data , dispatch ] = useReducer (
36+ component . reducers ,
37+ component . getJadeConfig ( ) ,
38+ ) ;
39+ const id = 'react-root-' + shape . id ;
40+ const [ form ] = Form . useForm ( ) ;
41+ const domRef = useRef ( ) ;
42+ const [ open , setOpen ] = useState ( false ) ;
3443
35- // 对外暴露方法.
36- useImperativeHandle ( ref , ( ) => {
37- return {
38- getData : ( ) => {
39- return data ;
40- } ,
41- dispatch : ( action ) => {
42- dispatch ( action ) ;
43- }
44- }
45- } ) ;
46-
47- /**
48- * 校验当前节点的form输入是否合法.
49- *
50- * @return Promise 校验结果
51- */
52- shape . validateForm = ( ) => {
53- return form . validateFields ( ) ;
44+ // 对外暴露方法.
45+ useImperativeHandle ( ref , ( ) => {
46+ return {
47+ getData : ( ) => {
48+ return data ;
49+ } ,
50+ dispatch : ( action ) => {
51+ dispatch ( action ) ;
52+ } ,
5453 } ;
54+ } ) ;
5555
56- // 相当于 componentDidMount
57- useEffect ( ( ) => {
58- shape . observe ( ) ;
59- shape . page . addEventListener ( EVENT_TYPE . FOCUSED_SHAPES_CHANGE , onFocusedShapeChange ) ;
60- shape . page . triggerEvent ( { type : "shape_rendered" , value : { id : shape . id } } ) ;
61- return ( ) => {
62- shape . page . removeEventListener ( EVENT_TYPE . FOCUSED_SHAPES_CHANGE , onFocusedShapeChange ) ;
63- } ;
64- } , [ ] ) ;
56+ /**
57+ * 校验当前节点的form输入是否合法.
58+ *
59+ * @return Promise 校验结果
60+ */
61+ shape . validateForm = ( ) => {
62+ return form . validateFields ( ) ;
63+ } ;
6564
66- const onFocusedShapeChange = ( ) => {
67- if ( ! domRef . current ) {
68- return ;
69- }
70- const focusedShapes = shape . page . getFocusedShapes ( ) ;
71- if ( focusedShapes . includes ( shape ) ) {
72- domRef . current . style . pointerEvents = focusedShapes . length > 1 ? "none" : "auto" ;
73- } else {
74- domRef . current . style . pointerEvents = "auto" ;
75- }
65+ // 相当于 componentDidMount
66+ useEffect ( ( ) => {
67+ shape . observe ( ) ;
68+ shape . page . addEventListener (
69+ EVENT_TYPE . FOCUSED_SHAPES_CHANGE ,
70+ onFocusedShapeChange ,
71+ ) ;
72+ shape . page . triggerEvent ( {
73+ type : 'shape_rendered' ,
74+ value : { id : shape . id } ,
75+ } ) ;
76+ return ( ) => {
77+ shape . page . removeEventListener (
78+ EVENT_TYPE . FOCUSED_SHAPES_CHANGE ,
79+ onFocusedShapeChange ,
80+ ) ;
7681 } ;
82+ } , [ ] ) ;
7783
78- // 第一次进来不会触发,第一次发生变化时才触发.
79- useUpdateEffect ( ( ) => {
80- if ( data . jadeNodeConfigChangeIgnored ) {
81- return ;
82- }
83- if ( shape . hasError ) {
84- shape . validateForm ( ) . then ( shape . offError ) ;
85- }
86- shape . graph . dirtied ( null , { action : SYSTEM_ACTION . JADE_NODE_CONFIG_CHANGE , shape : shape . id } ) ;
87- } , [ data ] ) ;
84+ const onFocusedShapeChange = ( ) => {
85+ if ( ! domRef . current ) {
86+ return ;
87+ }
88+ const focusedShapes = shape . page . getFocusedShapes ( ) ;
89+ if ( focusedShapes . includes ( shape ) ) {
90+ domRef . current . style . pointerEvents = focusedShapes . length > 1 ? 'none' : 'auto' ;
91+ } else {
92+ domRef . current . style . pointerEvents = 'auto' ;
93+ }
94+ setOpen ( shape . page . onConfigShape === shape . id ) ;
95+ } ;
8896
89- // 当前是评估页面,并且runnable为false时,才出现遮盖层
90- return ( < >
91- { shape . enableMask && < div className = 'jade-cover-level' style = { {
97+ // 第一次进来不会触发,第一次发生变化时才触发.
98+ useUpdateEffect ( ( ) => {
99+ if ( data . jadeNodeConfigChangeIgnored ) {
100+ return ;
101+ }
102+ if ( shape . hasError ) {
103+ shape . validateForm ( ) . then ( shape . offError ) ;
104+ }
105+ shape . graph . dirtied ( null , {
106+ action : SYSTEM_ACTION . JADE_NODE_CONFIG_CHANGE ,
107+ shape : shape . id ,
108+ } ) ;
109+ } , [ data ] ) ;
110+
111+ // 当前是评估页面,并且runnable为false时,才出现遮盖层
112+ return (
113+ < >
114+ { shape . enableMask && (
115+ < div
116+ className = "jade-cover-level"
117+ style = { {
92118 margin : - borderPadding ,
93119 width : `calc(100% + ${ 2 * borderPadding } px)` ,
94120 height : `calc(100% + ${ 2 * borderPadding } px)` ,
95- } } /> }
96- < div id = { id } style = { { display : 'block' } } ref = { domRef } >
97- < Form form = { form }
98- name = { `form-${ shape . id } ` }
99- layout = 'vertical' // 设置全局的垂直布局
100- className = { 'jade-form' }
101- >
102- < DispatchContext . Provider value = { dispatch } >
103- { shape . drawer . getHeaderComponent ( data , shapeStatus ) }
104- < FormContext . Provider value = { form } >
105- < ShapeContext . Provider value = { shape } >
106- < DataContext . Provider value = { data } >
107- < div
108- className = 'react-node-content'
109- style = { { borderRadius : `${ shape . borderRadius } px` } } >
110- { component . getReactComponents ( shapeStatus , data ) }
111- </ div >
112- </ DataContext . Provider >
113- </ ShapeContext . Provider >
114- </ FormContext . Provider >
115- { shape . drawer . getFooterComponent ( ) }
116- </ DispatchContext . Provider >
117- </ Form >
118- </ div >
119- </ > ) ;
121+ } }
122+ />
123+ ) }
124+ < div id = { id } style = { { display : 'block' } } ref = { domRef } >
125+ < Form
126+ form = { form }
127+ name = { `form-${ shape . id } ` }
128+ layout = "vertical" // 设置全局的垂直布局
129+ className = { 'jade-form' }
130+ >
131+ < DispatchContext . Provider value = { dispatch } >
132+ { shape . drawer . getHeaderComponent ( data , shapeStatus ) }
133+ < FormContext . Provider value = { form } >
134+ < ShapeContext . Provider value = { shape } >
135+ < DataContext . Provider value = { data } >
136+ < div
137+ className = "react-node-content"
138+ style = { { borderRadius : `${ shape . borderRadius } px` } }
139+ >
140+ { component . getReactComponents ( shapeStatus , data , false ) }
141+ </ div >
142+ </ DataContext . Provider >
143+ </ ShapeContext . Provider >
144+ </ FormContext . Provider >
145+ { shape . drawer . getFooterComponent ( ) }
146+ </ DispatchContext . Provider >
147+ </ Form >
148+ </ div >
149+ { createPortal (
150+ < div className = { `jade-form-drawer ${ open ? '' : 'hidden' } ` } >
151+ < Form
152+ form = { form }
153+ name = { `outside-form-${ shape . id } ` }
154+ layout = "vertical" // 设置全局的垂直布局
155+ className = { 'jade-form' }
156+ >
157+ < DispatchContext . Provider value = { dispatch } >
158+ < div className = "sticky-header" >
159+ { shape . drawer . getHeaderComponent ( data , shapeStatus ) }
160+ < div className = "jade-form-drawer-close" onClick = { ( ) => {
161+ shape . page . onConfigShape = undefined ;
162+ setOpen ( false ) ;
163+ } } >
164+ < CloseOutlined style = { { fontSize : '12px' } } />
165+ </ div >
166+ </ div >
167+ < div className = "jade-form-drawer-content" >
168+ < FormContext . Provider value = { form } >
169+ < ShapeContext . Provider value = { shape } >
170+ < DataContext . Provider value = { data } >
171+ < div className = "react-node-content" >
172+ { component . getReactComponents ( shapeStatus , data , true ) }
173+ </ div >
174+ </ DataContext . Provider >
175+ </ ShapeContext . Provider >
176+ </ FormContext . Provider >
177+ </ div >
178+ </ DispatchContext . Provider >
179+ </ Form >
180+ </ div > ,
181+ document . getElementById ( 'elsa-graph' ) ,
182+ ) }
183+ </ >
184+ ) ;
120185} ) ;
121186
122187DefaultRoot . propTypes = {
123- shape : PropTypes . object ,
124- component : PropTypes . object ,
125- shapeStatus : PropTypes . object
188+ shape : PropTypes . object ,
189+ component : PropTypes . object ,
190+ shapeStatus : PropTypes . object ,
126191} ;
127192
128193export function useDataContext ( ) {
129- return useContext ( DataContext ) ;
194+ return useContext ( DataContext ) ;
130195}
131196
132197export function useShapeContext ( ) {
133- return useContext ( ShapeContext ) ;
198+ return useContext ( ShapeContext ) ;
134199}
135200
136201export function useDispatch ( ) {
137- return useContext ( DispatchContext ) ;
202+ return useContext ( DispatchContext ) ;
138203}
139204
140205export function useFormContext ( ) {
141- return useContext ( FormContext ) ;
142- }
206+ return useContext ( FormContext ) ;
207+ }
0 commit comments