Explorar el Código

Reload OCI options on migration image map change

This applies to the Replica / Migration wizard.

This commit also contains reloading of options when the minion pool
migration image changes when creating a minion pool.
Sergiu Miclea hace 3 años
padre
commit
f8cf0ee96d

+ 3 - 2
config.ts

@@ -45,8 +45,8 @@ const conf: Config = {
   bareMetalEndpointName: 'appliance-metal-hub',
 
   /**
-   * The list of providers for which and extra source or destination options API call will be made,
-   * if the required fields have any value set.
+   * The list of providers for which and extra source or destination options API call will be made.
+   * The API call will be made only if all the required fields have values.
    * If `requiredValues` is provided, the field specified there needs to have a
    * certain value (specified in values)
    * in order to make the options API call.
@@ -83,6 +83,7 @@ const conf: Config = {
       name: 'oci',
       types: ['destination'],
       requiredFields: ['compartment', 'availability_domain', 'vcn_compartment'],
+      relistFields: ['migr_image_map', 'migr_image'],
     },
     {
       name: 'vmware_vsphere',

+ 13 - 4
src/components/modules/TransferModule/TransferItemModal/TransferItemModal.tsx

@@ -334,7 +334,7 @@ class TransferItemModal extends React.Component<Props, State> {
       const endpoint = type === 'source' ? this.props.sourceEndpoint : this.props.destinationEndpoint
       try {
         await this.loadOptions(endpoint, type, useCache)
-        this.loadExtraOptions(null, type, useCache)
+        this.loadExtraOptions({ type, useCache })
       } catch (err) {
         if (type === 'source') {
           this.setState(prevState => {
@@ -376,7 +376,15 @@ class TransferItemModal extends React.Component<Props, State> {
     })
   }
 
-  loadExtraOptions(field: Field | null, type: 'source' | 'destination', useCache?: boolean) {
+  loadExtraOptions(opts: {
+    field?: Field,
+    type: 'source' | 'destination',
+    useCache?: boolean,
+    parentFieldName?: string
+  }) {
+    const {
+      field, type, useCache, parentFieldName,
+    } = opts
     const endpoint = type === 'source' ? this.props.sourceEndpoint : this.props.destinationEndpoint
     const env = type === 'source' ? this.props.replica.source_environment : this.props.replica.destination_environment
     const stateEnv = type === 'source' ? this.state.sourceData : this.state.destinationData
@@ -388,8 +396,9 @@ class TransferItemModal extends React.Component<Props, State> {
         ...env,
         ...stateEnv,
       },
-      field,
+      field: field || null,
       type,
+      parentFieldName,
     })
 
     if (!envData) {
@@ -509,7 +518,7 @@ class TransferItemModal extends React.Component<Props, State> {
 
     const handleStateUpdate = () => {
       if (field.type !== 'string' || field.enum) {
-        this.loadExtraOptions(field, type)
+        this.loadExtraOptions({ field, type, parentFieldName })
       }
       this.validateOptions(type)
     }

+ 35 - 17
src/components/smart/WizardPage/WizardPage.tsx

@@ -220,6 +220,7 @@ class WizardPage extends React.Component<Props, State> {
   }
 
   handleBackClick() {
+    this.setState({ nextButtonDisabled: false })
     const currentPageIndex = this.pages.findIndex(p => p.id === wizardStore.currentPage.id)
 
     if (currentPageIndex === 0) {
@@ -270,7 +271,7 @@ class WizardPage extends React.Component<Props, State> {
       useCache: true,
     })
     wizardStore.fillWithDefaultValues('source', providerStore.sourceSchema)
-    await this.loadExtraOptions(null, 'source')
+    await this.loadExtraOptions({ type: 'source' })
   }
 
   async handleTargetEndpointChange(target: EndpointType) {
@@ -294,7 +295,7 @@ class WizardPage extends React.Component<Props, State> {
       requiresWindowsImage: this.requiresWindowsImage,
     })
     wizardStore.fillWithDefaultValues('destination', providerStore.destinationSchema)
-    await this.loadExtraOptions(null, 'destination')
+    await this.loadExtraOptions({ type: 'destination' })
   }
 
   handleAddEndpoint(newEndpointType: ProviderTypes, newEndpointFromSource: boolean) {
@@ -356,7 +357,7 @@ class WizardPage extends React.Component<Props, State> {
     // which there potentially other destination options for the new
     // chosen value from the enum
     if (field.type !== 'string' || field.enum) {
-      this.loadExtraOptions(field, 'destination')
+      this.loadExtraOptions({ field, type: 'destination', parentFieldName })
     }
     wizardStore.updateUrlState()
   }
@@ -368,7 +369,7 @@ class WizardPage extends React.Component<Props, State> {
       wizardStore.fillWithDefaultValues('source', providerStore.sourceSchema)
     }
     if (field.type !== 'string' || field.enum) {
-      this.loadExtraOptions(field, 'source')
+      this.loadExtraOptions({ field, type: 'source', parentFieldName })
     }
     wizardStore.updateUrlState()
   }
@@ -431,7 +432,7 @@ class WizardPage extends React.Component<Props, State> {
     })
     wizardStore.fillWithDefaultValues(optionsType, getSchema())
 
-    await this.loadExtraOptions(null, optionsType, false)
+    await this.loadExtraOptions({ type: optionsType, useCache: false })
   }
 
   initializeState(match: any) {
@@ -446,7 +447,15 @@ class WizardPage extends React.Component<Props, State> {
     }
   }
 
-  async loadExtraOptions(field: Field | null, type: 'source' | 'destination', useCache: boolean = true) {
+  async loadExtraOptions(opts: {
+    field?: Field,
+    type: 'source' | 'destination',
+    useCache?: boolean,
+    parentFieldName?: string,
+  }) {
+    const {
+      field, type, useCache, parentFieldName,
+    } = opts
     const endpoint = type === 'source' ? wizardStore.data.source : wizardStore.data.target
     if (!endpoint) {
       return
@@ -455,21 +464,30 @@ class WizardPage extends React.Component<Props, State> {
     const envData = getFieldChangeOptions({
       providerName: endpoint.type,
       schema: getSchema(),
-      data: type === 'source' ? wizardStore.data.sourceOptions : wizardStore.data.destOptions,
-      field,
+      data:
+        type === 'source'
+          ? wizardStore.data.sourceOptions
+          : wizardStore.data.destOptions,
+      field: field || null,
       type,
+      parentFieldName,
     })
     if (!envData) {
       return
     }
-    await providerStore.getOptionsValues({
-      optionsType: type,
-      endpointId: endpoint.id,
-      providerName: endpoint.type,
-      envData,
-      useCache,
-      requiresWindowsImage: this.requiresWindowsImage,
-    })
+    try {
+      await providerStore.getOptionsValues({
+        optionsType: type,
+        endpointId: endpoint.id,
+        providerName: endpoint.type,
+        envData,
+        useCache: useCache !== false,
+        requiresWindowsImage: this.requiresWindowsImage,
+      })
+    } catch (err) {
+      this.setState({ nextButtonDisabled: true })
+    }
+
     wizardStore.fillWithDefaultValues(type, getSchema())
   }
 
@@ -493,7 +511,7 @@ class WizardPage extends React.Component<Props, State> {
       })
       wizardStore.fillWithDefaultValues(optionsType, getSchema())
 
-      await this.loadExtraOptions(null, optionsType)
+      await this.loadExtraOptions({ type: optionsType })
     }
 
     switch (page.id) {

+ 7 - 7
src/stores/ProviderStore.ts

@@ -34,13 +34,14 @@ export const getFieldChangeOptions = (config: {
   data: any,
   field: Field | null,
   type: 'source' | 'destination',
+  parentFieldName?: string,
 }) => {
   const {
-    providerName, schema, data, field, type,
+    providerName, schema, data, field, type, parentFieldName,
   } = config
   const providerWithEnvOptions = configLoader.config.extraOptionsApiCalls
     .find(p => p.name === providerName && p.types.find(t => t === type))
-
+  const fieldName = parentFieldName || field?.name || ''
   if (!providerName || !providerWithEnvOptions) {
     return null
   }
@@ -80,12 +81,11 @@ export const getFieldChangeOptions = (config: {
   const requiredValidFields = requiredFields.filter(filterValidField)
   const relistValidFields = relistFields?.filter(filterValidField)
 
-  const relistField = relistFields?.find(fn => fn === field?.name)
+  const relistField = relistFields?.find(fn => fn === fieldName)
 
-  const isCurrentFieldValid = field ? (
-    requiredValidFields.find(fn => fn === field.name)
-    || relistField
-  ) : true
+  const isCurrentFieldValid = field
+    ? requiredValidFields.find(fn => fn === fieldName) || relistField
+    : true
   if (requiredValidFields.length !== requiredFields.length || !isCurrentFieldValid) {
     return null
   }