Просмотр исходного кода

Merge pull request #514 from smiclea/aws-extra-values

Add AWS to extra options API calls list
Nashwan Azhari 6 лет назад
Родитель
Сommit
d9eb1266c8

+ 5 - 0
config.js

@@ -53,6 +53,11 @@ const conf: Config = {
         },
       ],
     },
+    {
+      name: 'aws',
+      types: ['source', 'destination'],
+      requiredFields: ['region'],
+    },
     {
       name: 'azure',
       types: ['source', 'destination'],

+ 7 - 7
src/components/molecules/FieldInput/FieldInput.jsx

@@ -95,9 +95,9 @@ type Props = {
   layout: 'modal' | 'page',
   width?: number,
   label?: string,
+  description?: string,
   addNullValue?: boolean,
   nullableBoolean?: boolean,
-  description?: string,
   style?: { [string]: mixed },
 }
 @observer
@@ -127,7 +127,7 @@ class FieldInput extends React.Component<Props> {
         type={this.props.password ? 'password' : 'text'}
         value={this.props.value}
         onChange={e => { if (this.props.onChange) this.props.onChange(e.target.value) }}
-        placeholder={LabelDictionary.get(this.props.name)}
+        placeholder={this.props.label}
         disabled={this.props.disabled}
         required={this.props.layout === 'page' ? false : this.props.required}
         disabledLoading={this.props.disabledLoading}
@@ -201,7 +201,7 @@ class FieldInput extends React.Component<Props> {
         highlight={this.props.highlight}
         value={this.props.value}
         onChange={e => { if (this.props.onChange) this.props.onChange(e.target.value) }}
-        placeholder={LabelDictionary.get(this.props.name)}
+        placeholder={this.props.label}
         disabled={this.props.disabled}
         disabledLoading={this.props.disabledLoading}
         required={this.props.layout === 'page' ? false : this.props.required}
@@ -289,7 +289,7 @@ class FieldInput extends React.Component<Props> {
     return (
       <RadioInput
         checked={this.props.value}
-        label={LabelDictionary.get(this.props.name)}
+        label={this.props.label || ''}
         onChange={checked => { if (this.props.onChange) this.props.onChange(checked) }}
         disabled={this.props.disabled}
         disabledLoading={this.props.disabledLoading}
@@ -317,7 +317,7 @@ class FieldInput extends React.Component<Props> {
         onItemChange={item => { if (this.props.onChange) this.props.onChange(item.value) }}
         inputValue={this.props.getFieldValue ? this.props.getFieldValue(fieldName) : ''}
         onInputChange={value => { if (this.props.onFieldChange) this.props.onFieldChange(fieldName, value) }}
-        placeholder={LabelDictionary.get(fieldName)}
+        placeholder={this.props.label}
         highlight={this.props.highlight}
         disabled={this.props.disabled}
         disabledLoading={this.props.disabledLoading}
@@ -358,13 +358,13 @@ class FieldInput extends React.Component<Props> {
       return null
     }
 
-    let description = LabelDictionary.getDescription(this.props.name) || this.props.description
+    let description = this.props.description
     let marginRight = this.props.layout === 'modal' || description || this.props.required ? '24px' : 0
 
     return (
       <Label layout={this.props.layout} disabledLoading={this.props.disabledLoading}>
         <LabelText style={{ marginRight }}>
-          {this.props.label || LabelDictionary.get(this.props.name)}
+          {this.props.label}
         </LabelText>
         {description ? <InfoIcon text={description} marginLeft={-20} marginBottom={this.props.layout === 'page' ? null : 0} /> : null}
         {this.props.layout === 'page' && Boolean(this.props.required) ? <Asterisk marginLeft={description ? '4px' : '-16px'} /> : null}

+ 6 - 0
src/components/organisms/EditReplica/EditReplica.jsx

@@ -481,6 +481,11 @@ class EditReplica extends React.Component<Props, State> {
     if (extraOptionsConfig) {
       optionsLoadingSkipFields = extraOptionsConfig.requiredFields
     }
+    let endpoint = type === 'source' ? this.props.sourceEndpoint : this.props.destinationEndpoint
+    let dictionaryKey = ''
+    if (endpoint) {
+      dictionaryKey = `${endpoint.type}-${type}`
+    }
     return (
       <WizardOptions
         wizardType={`${this.props.type || 'replica'}-${type}-options-edit`}
@@ -500,6 +505,7 @@ class EditReplica extends React.Component<Props, State> {
         optionsLoading={optionsLoading}
         optionsLoadingSkipFields={[...optionsLoadingSkipFields, 'description', 'execute_now',
           'execute_now_options', ...migrationFields.map(f => f.name)]}
+        dictionaryKey={dictionaryKey}
       />
     )
   }

+ 5 - 2
src/components/organisms/MainDetails/MainDetails.jsx

@@ -217,10 +217,13 @@ class MainDetails extends React.Component<Props> {
     let properties = []
     let plugin = endpoint && (OptionsSchemaPlugin[endpoint.type] || OptionsSchemaPlugin.default)
     let migrationImageMapFieldName = plugin && plugin.migrationImageMapFieldName
-
+    let dictionaryKey = ''
+    if (endpoint) {
+      dictionaryKey = `${endpoint.type}-destination`
+    }
     propertyNames.forEach(pn => {
       let value = this.props.item ? this.props.item.destination_environment[pn] : ''
-      let label = LabelDictionary.get(pn)
+      let label = LabelDictionary.get(pn, dictionaryKey)
 
       if (value && value.join) {
         // $FlowIgnore

+ 3 - 2
src/components/organisms/WizardOptions/WizardOptions.jsx

@@ -142,6 +142,7 @@ type Props = {
   loading?: boolean,
   optionsLoading?: boolean,
   optionsLoadingSkipFields?: string[],
+  dictionaryKey: string,
 }
 @observer
 class WizardOptions extends React.Component<Props> {
@@ -261,14 +262,14 @@ class WizardOptions extends React.Component<Props> {
         type={field.type}
         minimum={field.minimum}
         maximum={field.maximum}
-        description={field.description}
+        label={field.label || LabelDictionary.get(field.name, this.props.dictionaryKey)}
+        description={field.description || LabelDictionary.getDescription(field.name, this.props.dictionaryKey)}
         password={this.isPassword(field.name)}
         enum={field.enum}
         addNullValue
         required={field.required}
         data-test-id={`wOptions-field-${field.name}`}
         width={this.props.fieldWidth || StyleProps.inputSizes.wizard.width}
-        label={field.label}
         nullableBoolean={field.nullableBoolean}
         disabledLoading={this.props.optionsLoading && !optionsLoadingReqFields.find(fn => fn === field.name)}
         {...additionalProps}

+ 2 - 0
src/components/organisms/WizardPageContent/WizardPageContent.jsx

@@ -423,6 +423,7 @@ class WizardPageContent extends React.Component<Props, State> {
             wizardType={`${this.props.type}-source-options`}
             layout="page"
             isSource
+            dictionaryKey={`${this.props.wizardData.source ? this.props.wizardData.source.type : ''}-source`}
           />
         )
         break
@@ -445,6 +446,7 @@ class WizardPageContent extends React.Component<Props, State> {
             wizardType={this.props.type}
             onAdvancedOptionsToggle={useAdvancedOptions => { this.handleAdvancedOptionsToggle(useAdvancedOptions) }}
             layout="page"
+            dictionaryKey={`${this.props.wizardData.target ? this.props.wizardData.target.type : ''}-destination`}
           />
         )
         break

+ 4 - 3
src/components/organisms/WizardSummary/WizardSummary.jsx

@@ -260,7 +260,6 @@ class WizardSummary extends React.Component<Props> {
     if (!data.sourceOptions) {
       return null
     }
-
     return (
       <Section>
         <SectionTitle>{type} Source Options</SectionTitle>
@@ -269,7 +268,8 @@ class WizardSummary extends React.Component<Props> {
             if (!data.sourceOptions || data.sourceOptions[optionName] == null || data.sourceOptions[optionName] === '') {
               return null
             }
-            let optionLabel = optionName.split('/').map(n => LabelDictionary.get(n)).join(' - ')
+            let optionLabel = optionName.split('/')
+              .map(n => LabelDictionary.get(n, `${data.source ? data.source.type : ''}-source`)).join(' - ')
             let optionValue = fieldHelper.getValueAlias(optionName, data.sourceOptions && data.sourceOptions[optionName], this.props.sourceSchema, provider)
             return (
               <Option key={optionName}>
@@ -346,7 +346,8 @@ class WizardSummary extends React.Component<Props> {
               return null
             }
 
-            let optionLabel = optionName.split('/').map(n => LabelDictionary.get(n)).join(' - ')
+            let optionLabel = optionName.split('/')
+              .map(n => LabelDictionary.get(n, `${data.target ? data.target.type : ''}-destination`)).join(' - ')
             let optionValue = fieldHelper.getValueAlias(optionName, data.destOptions && data.destOptions[optionName], this.props.destinationSchema, provider)
             return (
               <Option key={optionName}>

+ 4 - 4
src/plugins/endpoint/default/ConnectionSchemaPlugin.js

@@ -19,7 +19,7 @@ import Utils from '../../../utils/ObjectUtils'
 import type { Schema, SchemaProperties, SchemaDefinitions } from '../../../types/Schema'
 import type { Field } from '../../../types/Field'
 
-export const defaultSchemaToFields = (schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, parent?: string): any[] => {
+export const defaultSchemaToFields = (schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, parent?: ?string, dictionaryKey?: string): any[] => {
   if (!schema.properties) {
     return []
   }
@@ -33,18 +33,18 @@ export const defaultSchemaToFields = (schema: SchemaProperties, schemaDefinition
       return {
         name: fieldName,
         type: properties.type ? properties.type : '',
-        properties: properties.properties ? defaultSchemaToFields(properties, null, fieldName) : [],
+        properties: properties.properties ? defaultSchemaToFields(properties, null, fieldName, dictionaryKey) : [],
       }
     } else if (properties.type === 'object' && properties.properties && Object.keys(properties.properties).length) {
       return {
         name: fieldName,
         type: 'object',
-        properties: defaultSchemaToFields(properties, null, fieldName),
+        properties: defaultSchemaToFields(properties, null, fieldName, dictionaryKey),
       }
     }
 
     const name = parent ? `${parent}/${fieldName}` : fieldName
-    LabelDictionary.pushToCache({ name, title: properties.title, description: properties.description })
+    LabelDictionary.pushToCache({ name, title: properties.title, description: properties.description }, dictionaryKey || '')
 
     return {
       ...properties,

+ 2 - 2
src/plugins/endpoint/default/OptionsSchemaPlugin.js

@@ -122,8 +122,8 @@ export const defaultGetMigrationImageMap = (options: ?{ [string]: mixed }, migra
 export default class OptionsSchemaParser {
   static migrationImageMapFieldName = 'migr_image_map'
 
-  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions) {
-    return defaultSchemaToFields(schema, schemaDefinitions)
+  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, dictionaryKey: string) {
+    return defaultSchemaToFields(schema, schemaDefinitions, null, dictionaryKey)
   }
 
   static fillFieldValues(field: Field, options: OptionValues[], customFieldName?: string) {

+ 2 - 2
src/plugins/endpoint/openstack/OptionsSchemaPlugin.js

@@ -26,8 +26,8 @@ import type { NetworkMap } from '../../../types/Network'
 export default class OptionsSchemaParser {
   static migrationImageMapFieldName = DefaultOptionsSchemaPlugin.migrationImageMapFieldName
 
-  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions) {
-    let fields = DefaultOptionsSchemaPlugin.parseSchemaToFields(schema, schemaDefinitions)
+  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, dictionaryKey: string) {
+    let fields = DefaultOptionsSchemaPlugin.parseSchemaToFields(schema, schemaDefinitions, dictionaryKey)
     let exportMechField = fields.find(f => f.name === 'replica_export_mechanism')
     if (exportMechField) {
       exportMechField.subFields = []

+ 2 - 2
src/plugins/endpoint/ovm/OptionsSchemaPlugin.js

@@ -30,8 +30,8 @@ import type { NetworkMap } from '../../../types/Network'
 export default class OptionsSchemaParser {
   static migrationImageMapFieldName = 'migr_template_map'
 
-  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions) {
-    let fields = DefaultOptionsSchemaPlugin.parseSchemaToFields(schema, schemaDefinitions)
+  static parseSchemaToFields(schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, dictionaryKey: string) {
+    let fields = DefaultOptionsSchemaPlugin.parseSchemaToFields(schema, schemaDefinitions, dictionaryKey)
     fields.forEach(f => {
       if (
         f.name !== 'migr_template_username_map'

+ 1 - 1
src/sources/ProviderSource.js

@@ -47,7 +47,7 @@ class ProviderSource {
       let schema = optionsType === 'source' ? schemas.source_environment_schema : schemas.destination_environment_schema
       let fields = []
       if (schema) {
-        fields = SchemaParser.optionsSchemaToFields(providerName, schema)
+        fields = SchemaParser.optionsSchemaToFields(providerName, schema, `${providerName}-${optionsType}`)
       }
       return fields
     } catch (err) {

+ 2 - 2
src/sources/Schemas.js

@@ -32,10 +32,10 @@ class SchemaParser {
     return fields
   }
 
-  static optionsSchemaToFields(provider: string, schema: any) {
+  static optionsSchemaToFields(provider: string, schema: any, dictionaryKey: string) {
     let parser = OptionsSchemaPlugin[provider] || OptionsSchemaPlugin.default
     let schemaRoot = schema.oneOf ? schema.oneOf[0] : schema
-    let fields = parser.parseSchemaToFields(schemaRoot, schema.definitions)
+    let fields = parser.parseSchemaToFields(schemaRoot, schema.definitions, dictionaryKey)
     fields.sort((a, b) => {
       if (a.required && !b.required) {
         return -1

+ 20 - 9
src/utils/LabelDictionary.js

@@ -69,19 +69,25 @@ const dictionary = {
   },
 }
 
-const cache: { name: string, label: ?string, description: ?string }[] = []
+const cache: { name: string, label: ?string, description: ?string, key: string }[] = []
 
 class LabelDictionary {
   // Fields which have enums for which dictionary labels should be used.
   // If a field has enums and is not in this array, their values will be used as labels
   static enumFields = ['port_reuse_policy', 'replica_export_mechanism', 'virtual_disk_clone_type']
 
-  static get(fieldName: ?string): string {
+  /**
+   *
+   * @param {string} fieldName The name of the field
+   * @param {string} dictionaryKey Optional key to more uniquely identify the field added to schema cache.
+   * The `dictionaryKey` is composed by `${provider}-${direction}.
+   * Direction is 'destination' or 'source'.
+   */
+  static get(fieldName: ?string, dictionaryKey?: string): string {
     if (!fieldName) {
       return ''
     }
-
-    let cachItem = cache.find(i => i.name === fieldName)
+    let cachItem = cache.find(i => i.key === dictionaryKey && i.name === fieldName)
     if (cachItem && cachItem.label) {
       return cachItem.label
     }
@@ -105,8 +111,8 @@ class LabelDictionary {
     return words.join(' ')
   }
 
-  static getDescription(fieldName: string): string {
-    let cachItem = cache.find(i => i.name === fieldName)
+  static getDescription(fieldName: string, dictionaryKey?: string): string {
+    let cachItem = cache.find(i => i.key === dictionaryKey && i.name === fieldName)
     if (cachItem && cachItem.description) {
       return cachItem.description
     }
@@ -120,9 +126,14 @@ class LabelDictionary {
     return ''
   }
 
-  static pushToCache(field: Field) {
-    if ((field.title || field.description) && !cache.find(i => i.name === field.name)) {
-      cache.push({ label: field.title, description: field.description, name: field.name })
+  static pushToCache(field: Field, dictionaryKey: string) {
+    if ((field.title || field.description) && !cache.find(i => i.key === dictionaryKey && i.name === field.name)) {
+      cache.push({
+        label: field.title,
+        description: field.description,
+        name: field.name,
+        key: dictionaryKey,
+      })
     }
   }
 }