1414 * See the License for the specific language governing permissions and
1515 * limitations under the License.
1616 */
17- import { Divider , Form , Switch } from 'antd' ;
17+ import { Divider , Form , notification , Switch } from 'antd' ;
1818import React , { useState , forwardRef , useImperativeHandle , useEffect } from 'react' ;
1919import { useIntl } from 'umi' ;
2020import type { FormInstance } from 'antd/es/form' ;
2121
2222import PanelSection from '@/components/PanelSection' ;
23- import { transformRequest } from '@/pages/Upstream/transform' ;
2423import PassiveCheck from './components/passive-check' ;
2524import ActiveCheck from './components/active-check'
2625import Nodes from './components/Nodes'
@@ -31,7 +30,7 @@ import UpstreamSelector from './components/UpstreamSelector';
3130import Retries from './components/Retries' ;
3231import PassHost from './components/PassHost' ;
3332import TLSComponent from './components/TLS' ;
34- import { transformUpstreamDataFromRequest } from './service' ;
33+ import { convertToRequestData } from './service' ;
3534
3635type Upstream = {
3736 name ?: string ;
@@ -46,14 +45,18 @@ type Props = {
4645 // FIXME: use proper typing
4746 ref ?: any ;
4847 required ?: boolean ;
48+ neverReadonly ?: boolean
4949} ;
5050
51+ /**
52+ * UpstreamForm is used to reuse Upstream Form UI,
53+ * before using this component, we need to execute the following command:
54+ * form.setFieldsValue(convertToFormData(VALUE_FROM_API))
55+ */
5156const UpstreamForm : React . FC < Props > = forwardRef (
52- ( { form, disabled, list = [ ] , showSelector, required = true } , ref ) => {
57+ ( { form, disabled = false , list = [ ] , showSelector = false , required = true , neverReadonly = false } , ref ) => {
5358 const { formatMessage } = useIntl ( ) ;
54- const [ readonly , setReadonly ] = useState (
55- Boolean ( form . getFieldValue ( 'upstream_id' ) ) || disabled ,
56- ) ;
59+ const [ readonly , setReadonly ] = useState ( false ) ;
5760 const [ hiddenForm , setHiddenForm ] = useState ( false ) ;
5861
5962 const timeoutFields = [
@@ -75,39 +78,58 @@ const UpstreamForm: React.FC<Props> = forwardRef(
7578 ] ;
7679
7780 useImperativeHandle ( ref , ( ) => ( {
78- getData : ( ) => transformRequest ( form . getFieldsValue ( ) ) ,
81+ getData : ( ) => convertToRequestData ( form . getFieldsValue ( ) ) ,
7982 } ) ) ;
8083
81- useEffect ( ( ) => {
82- const formData = transformRequest ( form . getFieldsValue ( ) ) || { } ;
83- const { upstream_id } = form . getFieldsValue ( ) ;
84+ const resetForm = ( upstream_id : string ) => {
85+ if ( upstream_id === undefined ) {
86+ return
87+ }
8488
89+ if ( ! neverReadonly ) {
90+ setReadonly ( ! [ "Custom" , "None" ] . includes ( upstream_id ) || disabled ) ;
91+ }
92+
93+ /**
94+ * upstream_id === None <==> required === false
95+ * No need to bind Upstream object.
96+ * When creating Route and binds with a Service, no need to configure Upstream in Route.
97+ */
8598 if ( upstream_id === 'None' ) {
8699 setHiddenForm ( true ) ;
87- if ( required ) {
88- requestAnimationFrame ( ( ) => {
89- form . resetFields ( ) ;
90- setHiddenForm ( false ) ;
91- } ) ;
92- }
93- } else {
94- if ( upstream_id ) {
95- requestAnimationFrame ( ( ) => {
96- const targetData = list . find ( ( item ) => item . id === upstream_id ) as UpstreamComponent . ResponseData
97- if ( targetData ) {
98- form . setFieldsValue ( transformUpstreamDataFromRequest ( targetData ) ) ;
99- }
100- } ) ;
101- }
102- if ( ! required && ! Object . keys ( formData ) . length ) {
103- requestAnimationFrame ( ( ) => {
104- form . setFieldsValue ( { upstream_id : 'None' } ) ;
105- setHiddenForm ( true ) ;
106- } ) ;
107- }
100+ form . resetFields ( )
101+ form . setFieldsValue ( { upstream_id : 'None' } )
102+ return
103+ }
104+
105+ setHiddenForm ( false )
106+
107+ // NOTE: Use Ant Design's form object to set data automatically
108+ if ( upstream_id === "Custom" ) {
109+ return
110+ }
111+
112+ // NOTE: Set data from Upstream List (Upstream Selector)
113+ if ( list . length === 0 ) {
114+ return
115+ }
116+ form . resetFields ( )
117+ const targetData = list . find ( ( item ) => item . id === upstream_id ) as UpstreamComponent . ResponseData
118+ if ( targetData ) {
119+ form . setFieldsValue ( targetData ) ;
108120 }
109- setReadonly ( Boolean ( upstream_id ) || disabled ) ;
110- } , [ list ] ) ;
121+ }
122+
123+ /**
124+ * upstream_id
125+ * - None: No need to bind Upstream to a resource (e.g Service).
126+ * - Custom: Users could input values on UpstreamForm
127+ * - Upstream ID from API
128+ */
129+ useEffect ( ( ) => {
130+ const upstream_id = form . getFieldValue ( 'upstream_id' ) ;
131+ resetForm ( upstream_id )
132+ } , [ form . getFieldValue ( 'upstream_id' ) , list ] ) ;
111133
112134 const ActiveHealthCheck = ( ) => (
113135 < React . Fragment >
@@ -192,19 +214,26 @@ const UpstreamForm: React.FC<Props> = forwardRef(
192214 }
193215 </ Form . Item >
194216 < Divider orientation = "left" plain />
195- < Form . Item label = { formatMessage ( { id : 'page.upstream.step.healthyCheck.passive' } ) } name = { [ 'custom' , 'checks' , 'passive' ] } valuePropName = "checked" >
217+ < Form . Item label = { formatMessage ( { id : 'page.upstream.step.healthyCheck.passive' } ) } name = { [ 'custom' , 'checks' , 'passive' ] } valuePropName = "checked" tooltip = { formatMessage ( { id : 'component.upstream.other.health-check.passive-only' } ) } >
196218 < Switch disabled = { readonly } />
197219 </ Form . Item >
198- < Form . Item shouldUpdate noStyle >
220+ < Form . Item shouldUpdate = { ( prev , next ) => prev . custom ?. checks ?. passive !== next . custom ?. checks ?. passive } noStyle >
199221 {
200222 ( ) => {
201223 const passive = form . getFieldValue ( [ 'custom' , 'checks' , 'passive' ] )
224+ const active = form . getFieldValue ( [ 'custom' , 'checks' , 'active' ] )
202225 if ( passive ) {
203226 /*
204227 * When enable passive check, we should enable active check, too.
205228 * When we use form.setFieldsValue to enable active check, error throws.
206229 * We choose to alert users first, and need users to enable active check manually.
207230 */
231+ if ( ! active ) {
232+ notification . warn ( {
233+ message : formatMessage ( { id : 'component.upstream.other.health-check.invalid' } ) ,
234+ description : formatMessage ( { id : 'component.upstream.other.health-check.passive-only' } )
235+ } )
236+ }
208237 return < PassiveHealthCheck />
209238 }
210239 return null
@@ -225,32 +254,8 @@ const UpstreamForm: React.FC<Props> = forwardRef(
225254 list = { list }
226255 disabled = { disabled }
227256 required = { required }
228- shouldUpdate = { ( prev , next ) => {
229- setReadonly ( Boolean ( next . upstream_id ) ) ;
230- if ( prev . upstream_id !== next . upstream_id ) {
231- const id = next . upstream_id ;
232- if ( id ) {
233- const targetData = list . find ( ( item ) => item . id === id ) as UpstreamComponent . ResponseData
234- if ( targetData ) {
235- form . setFieldsValue ( transformUpstreamDataFromRequest ( targetData ) ) ;
236- }
237- form . setFieldsValue ( {
238- upstream_id : id ,
239- } ) ;
240- }
241- }
242- return prev . upstream_id !== next . upstream_id ;
243- } }
244- onChange = { ( upstream_id ) => {
245- setReadonly ( Boolean ( upstream_id ) ) ;
246- setHiddenForm ( Boolean ( upstream_id === 'None' ) ) ;
247- const targetData = list . find ( ( item ) => item . id === upstream_id ) as UpstreamComponent . ResponseData
248- if ( targetData ) {
249- form . setFieldsValue ( transformUpstreamDataFromRequest ( targetData ) ) ;
250- }
251- if ( upstream_id === '' ) {
252- form . resetFields ( ) ;
253- }
257+ onChange = { ( nextUpstreamId ) => {
258+ resetForm ( nextUpstreamId ) ;
254259 } }
255260 />
256261 ) }
0 commit comments