فهرست منبع

Move default storage from options to storage

Besides moving the Default Storage dropdown from Wizard Options screen
to Wizard Storage screen, the code logic has also been refactored to
reflect this.
Sergiu Miclea 6 سال پیش
والد
کامیت
233e3a366e

+ 17 - 5
src/components/organisms/EditReplica/EditReplica.jsx

@@ -99,6 +99,7 @@ type State = {
   sourceData: any,
   sourceData: any,
   updateDisabled: boolean,
   updateDisabled: boolean,
   selectedNetworks: NetworkMap[],
   selectedNetworks: NetworkMap[],
+  defaultStorage: ?string,
   storageMap: StorageMap[],
   storageMap: StorageMap[],
   sourceFailed: boolean,
   sourceFailed: boolean,
   destinationFailedMessage: ?string,
   destinationFailedMessage: ?string,
@@ -112,6 +113,7 @@ class EditReplica extends React.Component<Props, State> {
     sourceData: {},
     sourceData: {},
     updateDisabled: false,
     updateDisabled: false,
     selectedNetworks: [],
     selectedNetworks: [],
+    defaultStorage: undefined,
     storageMap: [],
     storageMap: [],
     sourceFailed: false,
     sourceFailed: false,
     destinationFailedMessage: null,
     destinationFailedMessage: null,
@@ -311,9 +313,8 @@ class EditReplica extends React.Component<Props, State> {
       storage: this.state.storageMap,
       storage: this.state.storageMap,
     }
     }
     if (this.props.type === 'replica') {
     if (this.props.type === 'replica') {
-      let storageConfigDefault = this.getFieldValue('destination', 'default_storage') || endpointStore.storageConfigDefault
       try {
       try {
-        await replicaStore.update(this.props.replica, this.props.destinationEndpoint, updateData, storageConfigDefault)
+        await replicaStore.update(this.props.replica, this.props.destinationEndpoint, updateData, this.getDefaultStorage(), endpointStore.storageConfigDefault)
         this.props.onRequestClose()
         this.props.onRequestClose()
         this.props.onUpdateComplete(`/replica/executions/${this.props.replica.id}`)
         this.props.onUpdateComplete(`/replica/executions/${this.props.replica.id}`)
       } catch (err) {
       } catch (err) {
@@ -321,7 +322,8 @@ class EditReplica extends React.Component<Props, State> {
       }
       }
     } else {
     } else {
       try {
       try {
-        let migration: MainItem = await migrationStore.recreate(this.props.replica, this.props.sourceEndpoint, this.props.destinationEndpoint, updateData)
+        let replicaDefaultStorage = this.props.replica.storage_mappings && this.props.replica.storage_mappings.default
+        let migration: MainItem = await migrationStore.recreate(this.props.replica, this.props.sourceEndpoint, this.props.destinationEndpoint, updateData, replicaDefaultStorage, this.state.defaultStorage)
         migrationStore.clearDetails()
         migrationStore.clearDetails()
         this.props.onRequestClose()
         this.props.onRequestClose()
         this.props.onUpdateComplete(`/migration/tasks/${migration.id}`)
         this.props.onUpdateComplete(`/migration/tasks/${migration.id}`)
@@ -347,6 +349,12 @@ class EditReplica extends React.Component<Props, State> {
     this.setState({ storageMap })
     this.setState({ storageMap })
   }
   }
 
 
+  getDefaultStorage() {
+    let storageMappings = this.props.replica.storage_mappings
+    let replicaDefaultStorage = storageMappings && storageMappings.default
+    return this.state.defaultStorage !== undefined ? this.state.defaultStorage : replicaDefaultStorage
+  }
+
   getFieldValue(type: 'source' | 'destination', fieldName: string, defaultValue: any) {
   getFieldValue(type: 'source' | 'destination', fieldName: string, defaultValue: any) {
     let currentData = type === 'source' ? this.state.sourceData : this.state.destinationData
     let currentData = type === 'source' ? this.state.sourceData : this.state.destinationData
     if (currentData[fieldName] !== undefined) {
     if (currentData[fieldName] !== undefined) {
@@ -487,8 +495,8 @@ class EditReplica extends React.Component<Props, State> {
         layout="modal"
         layout="modal"
         isSource={type === 'source'}
         isSource={type === 'source'}
         optionsLoading={optionsLoading}
         optionsLoading={optionsLoading}
-        optionsLoadingSkipFields={[...optionsLoadingSkipFields, 'description', 'execute_now', 'execute_now_options',
-          'default_storage', ...migrationFields.map(f => f.name)]}
+        optionsLoadingSkipFields={[...optionsLoadingSkipFields, 'description', 'execute_now',
+          'execute_now_options', ...migrationFields.map(f => f.name)]}
       />
       />
     )
     )
   }
   }
@@ -503,6 +511,10 @@ class EditReplica extends React.Component<Props, State> {
 
 
     return (
     return (
       <WizardStorage
       <WizardStorage
+        defaultStorage={this.getDefaultStorage()}
+        onDefaultStorageChange={defaultStorage => { this.setState({ defaultStorage }) }}
+        storageConfigDefault={endpointStore.storageConfigDefault}
+        defaultStorageLayout="modal"
         storageBackends={endpointStore.storageBackends}
         storageBackends={endpointStore.storageBackends}
         instancesDetails={this.props.instancesDetails}
         instancesDetails={this.props.instancesDetails}
         storageMap={this.getStorageMap(endpointStore.storageBackends)}
         storageMap={this.getStorageMap(endpointStore.storageBackends)}

+ 0 - 9
src/components/organisms/WizardOptions/WizardOptions.jsx

@@ -196,15 +196,6 @@ class WizardOptions extends React.Component<Props> {
       fieldsSchema = [...fieldsSchema, ...migrationFields]
       fieldsSchema = [...fieldsSchema, ...migrationFields]
     }
     }
 
 
-    if (this.props.hasStorageMap && this.props.useAdvancedOptions && this.props.storageBackends && this.props.storageBackends.length > 0) {
-      fieldsSchema.push({
-        name: 'default_storage',
-        type: 'string',
-        enum: this.props.storageBackends.map(s => s.name),
-        default: this.props.storageConfigDefault,
-      })
-    }
-
     return fieldsSchema
     return fieldsSchema
   }
   }
 
 

+ 8 - 1
src/components/organisms/WizardPageContent/WizardPageContent.jsx

@@ -174,6 +174,7 @@ type Props = {
   wizardData: WizardData,
   wizardData: WizardData,
   schedules: ScheduleType[],
   schedules: ScheduleType[],
   storageMap: StorageMap[],
   storageMap: StorageMap[],
+  defaultStorage: ?string,
   hasStorageMap: boolean,
   hasStorageMap: boolean,
   hasSourceOptions: boolean,
   hasSourceOptions: boolean,
   pages: WizardPage[],
   pages: WizardPage[],
@@ -192,6 +193,7 @@ type Props = {
   onSourceOptionsChange: (field: Field, value: any) => void,
   onSourceOptionsChange: (field: Field, value: any) => void,
   onNetworkChange: (nic: Nic, network: Network, secGroups: ?SecurityGroup[]) => void,
   onNetworkChange: (nic: Nic, network: Network, secGroups: ?SecurityGroup[]) => void,
   onStorageChange: (sourceStorage: Disk, targetStorage: StorageBackend, type: 'backend' | 'disk') => void,
   onStorageChange: (sourceStorage: Disk, targetStorage: StorageBackend, type: 'backend' | 'disk') => void,
+  onDefaultStorageChange: (value: ?string) => void,
   onAddScheduleClick: (schedule: ScheduleType) => void,
   onAddScheduleClick: (schedule: ScheduleType) => void,
   onScheduleChange: (scheduleId: string, schedule: ScheduleType) => void,
   onScheduleChange: (scheduleId: string, schedule: ScheduleType) => void,
   onScheduleRemove: (scheudleId: string) => void,
   onScheduleRemove: (scheudleId: string) => void,
@@ -431,7 +433,7 @@ class WizardPageContent extends React.Component<Props, State> {
             optionsLoading={this.props.providerStore.destinationOptionsSecondaryLoading}
             optionsLoading={this.props.providerStore.destinationOptionsSecondaryLoading}
             optionsLoadingSkipFields={[
             optionsLoadingSkipFields={[
               ...getOptionsLoadingSkipFields('destination'), 'description', 'execute_now',
               ...getOptionsLoadingSkipFields('destination'), 'description', 'execute_now',
-              'execute_now_options', 'default_storage', ...migrationFields.map(f => f.name)]}
+              'execute_now_options', ...migrationFields.map(f => f.name)]}
             selectedInstances={this.props.wizardData.selectedInstances}
             selectedInstances={this.props.wizardData.selectedInstances}
             fields={this.props.providerStore.destinationSchema}
             fields={this.props.providerStore.destinationSchema}
             onChange={this.props.onDestOptionsChange}
             onChange={this.props.onDestOptionsChange}
@@ -465,6 +467,10 @@ class WizardPageContent extends React.Component<Props, State> {
             instancesDetails={this.props.instanceStore.instancesDetails}
             instancesDetails={this.props.instanceStore.instancesDetails}
             storageMap={this.props.storageMap}
             storageMap={this.props.storageMap}
             onChange={this.props.onStorageChange}
             onChange={this.props.onStorageChange}
+            storageConfigDefault={this.props.endpointStore.storageConfigDefault}
+            defaultStorage={this.props.defaultStorage}
+            onDefaultStorageChange={this.props.onDefaultStorageChange}
+            defaultStorageLayout="page"
           />
           />
         )
         )
         break
         break
@@ -496,6 +502,7 @@ class WizardPageContent extends React.Component<Props, State> {
           <WizardSummary
           <WizardSummary
             data={this.props.wizardData}
             data={this.props.wizardData}
             schedules={this.props.schedules}
             schedules={this.props.schedules}
+            defaultStorage={this.props.defaultStorage}
             storageMap={this.props.storageMap}
             storageMap={this.props.storageMap}
             wizardType={this.props.type}
             wizardType={this.props.type}
             instancesDetails={this.props.instanceStore.instancesDetails}
             instancesDetails={this.props.instanceStore.instancesDetails}

+ 34 - 1
src/components/organisms/WizardStorage/WizardStorage.jsx

@@ -20,6 +20,7 @@ import styled from 'styled-components'
 
 
 import AutocompleteDropdown from '../../molecules/AutocompleteDropdown'
 import AutocompleteDropdown from '../../molecules/AutocompleteDropdown'
 import Dropdown from '../../molecules/Dropdown'
 import Dropdown from '../../molecules/Dropdown'
+import FieldInput from '../../molecules/FieldInput'
 
 
 import Palette from '../../styleUtils/Palette'
 import Palette from '../../styleUtils/Palette'
 import StyleProps from '../../styleUtils/StyleProps'
 import StyleProps from '../../styleUtils/StyleProps'
@@ -34,9 +35,12 @@ import arrowImage from './images/arrow.svg'
 const Wrapper = styled.div`
 const Wrapper = styled.div`
   width: 100%;
   width: 100%;
   display: flex;
   display: flex;
-  justify-content: center;
+  flex-direction: column;
   overflow: auto;
   overflow: auto;
 `
 `
+const DefaultStorageWrapper = styled.div`
+  margin-bottom: 32px;
+`
 const Mapping = styled.div`
 const Mapping = styled.div`
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
@@ -151,6 +155,10 @@ export type Props = {
   storageBackends: StorageBackend[],
   storageBackends: StorageBackend[],
   instancesDetails: Instance[],
   instancesDetails: Instance[],
   storageMap: ?StorageMap[],
   storageMap: ?StorageMap[],
+  defaultStorageLayout: 'modal' | 'page',
+  defaultStorage: ?string,
+  storageConfigDefault: ?string,
+  onDefaultStorageChange: (value: ?string) => void,
   onChange: (sourceStorage: Disk, targetStorage: StorageBackend, type: 'backend' | 'disk') => void,
   onChange: (sourceStorage: Disk, targetStorage: StorageBackend, type: 'backend' | 'disk') => void,
   style?: any,
   style?: any,
   titleWidth?: number,
   titleWidth?: number,
@@ -295,9 +303,34 @@ class WizardStorage extends React.Component<Props> {
     return this.renderStorageWrapper(disks, 'disk')
     return this.renderStorageWrapper(disks, 'disk')
   }
   }
 
 
+  renderDefaultStorage() {
+    let disks = getDisks(this.props.instancesDetails, 'disk', this.props.storageMap)
+
+    if (disks.length === 0 || this.props.storageBackends.length === 0) {
+      return null
+    }
+
+    return (
+      <DefaultStorageWrapper>
+        <FieldInput
+          layout={this.props.defaultStorageLayout}
+          name="default_storage"
+          type="string"
+          description="Storage type on the destination to default to"
+          enum={this.props.storageBackends.map(s => s.name)}
+          addNullValue
+          width={StyleProps.inputSizes.regular.width}
+          value={this.props.defaultStorage !== undefined ? this.props.defaultStorage : this.props.storageConfigDefault}
+          onChange={value => { this.props.onDefaultStorageChange(value) }}
+        />
+      </DefaultStorageWrapper>
+    )
+  }
+
   render() {
   render() {
     return (
     return (
       <Wrapper style={this.props.style}>
       <Wrapper style={this.props.style}>
+        {this.renderDefaultStorage()}
         <Mapping>
         <Mapping>
           {this.renderBackendMapping()}
           {this.renderBackendMapping()}
           {this.renderDiskMapping()}
           {this.renderDiskMapping()}

+ 3 - 0
src/components/organisms/WizardStorage/test.jsx

@@ -66,6 +66,9 @@ const defaultProps: Props = {
   }],
   }],
   defaultStorage: 'sback1',
   defaultStorage: 'sback1',
   onChange: () => { },
   onChange: () => { },
+  defaultStorageLayout: 'page',
+  onDefaultStorageChange: () => { },
+  storageConfigDefault: null,
 }
 }
 const wrap = (props: Props) => new TW(shallow(<Component {...props} />), TEST_ID)
 const wrap = (props: Props) => new TW(shallow(<Component {...props} />), TEST_ID)
 
 

+ 9 - 0
src/components/organisms/WizardSummary/WizardSummary.jsx

@@ -167,6 +167,7 @@ type Props = {
   data: WizardData,
   data: WizardData,
   wizardType: 'replica' | 'migration',
   wizardType: 'replica' | 'migration',
   schedules: Schedule[],
   schedules: Schedule[],
+  defaultStorage: ?string,
   storageMap: StorageMap[],
   storageMap: StorageMap[],
   instancesDetails: Instance[],
   instancesDetails: Instance[],
   sourceSchema: Field[],
   sourceSchema: Field[],
@@ -317,6 +318,13 @@ class WizardSummary extends React.Component<Props> {
       ),
       ),
     ]
     ]
 
 
+    let defaultStorageOption = (
+      <Option>
+        <OptionLabel>Default Storage</OptionLabel>
+        <OptionValue>{this.props.defaultStorage}</OptionValue>
+      </Option>
+    )
+
     return (
     return (
       <Section>
       <Section>
         <SectionTitle>{type} Target Options</SectionTitle>
         <SectionTitle>{type} Target Options</SectionTitle>
@@ -324,6 +332,7 @@ class WizardSummary extends React.Component<Props> {
           {this.props.wizardType === 'replica' ? executeNowOption : null}
           {this.props.wizardType === 'replica' ? executeNowOption : null}
           {this.props.wizardType === 'migration' ? migrationOptions : null}
           {this.props.wizardType === 'migration' ? migrationOptions : null}
           {this.props.data.selectedInstances && this.props.data.selectedInstances.length > 1 ? separateVmOption : null}
           {this.props.data.selectedInstances && this.props.data.selectedInstances.length > 1 ? separateVmOption : null}
+          {this.props.defaultStorage ? defaultStorageOption : null}
           {data.destOptions ? Object.keys(data.destOptions).map(optionName => {
           {data.destOptions ? Object.keys(data.destOptions).map(optionName => {
             if (
             if (
               optionName === 'execute_now' ||
               optionName === 'execute_now' ||

+ 9 - 0
src/components/pages/WizardPage/WizardPage.jsx

@@ -323,6 +323,11 @@ class WizardPage extends React.Component<Props, State> {
     wizardStore.updateUrlState()
     wizardStore.updateUrlState()
   }
   }
 
 
+  handleDefaultStorageChange(value: ?string) {
+    wizardStore.updateDefaultStorage(value)
+    wizardStore.updateUrlState()
+  }
+
   handleStorageChange(source: Disk, target: StorageBackend, type: 'backend' | 'disk') {
   handleStorageChange(source: Disk, target: StorageBackend, type: 'backend' | 'disk') {
     wizardStore.updateStorage({ source, target, type })
     wizardStore.updateStorage({ source, target, type })
     wizardStore.updateUrlState()
     wizardStore.updateUrlState()
@@ -481,6 +486,7 @@ class WizardPage extends React.Component<Props, State> {
     await wizardStore.createMultiple(
     await wizardStore.createMultiple(
       this.state.type,
       this.state.type,
       wizardStore.data,
       wizardStore.data,
+      wizardStore.defaultStorage,
       wizardStore.storageMap,
       wizardStore.storageMap,
       wizardStore.uploadedUserScripts,
       wizardStore.uploadedUserScripts,
     )
     )
@@ -500,6 +506,7 @@ class WizardPage extends React.Component<Props, State> {
       await wizardStore.create(
       await wizardStore.create(
         this.state.type,
         this.state.type,
         wizardStore.data,
         wizardStore.data,
+        wizardStore.defaultStorage,
         wizardStore.storageMap,
         wizardStore.storageMap,
         wizardStore.uploadedUserScripts,
         wizardStore.uploadedUserScripts,
       )
       )
@@ -607,6 +614,7 @@ class WizardPage extends React.Component<Props, State> {
             wizardData={wizardStore.data}
             wizardData={wizardStore.data}
             hasStorageMap={Boolean(this.pages.find(p => p.id === 'storage'))}
             hasStorageMap={Boolean(this.pages.find(p => p.id === 'storage'))}
             hasSourceOptions={Boolean(this.pages.find(p => p.id === 'source-options'))}
             hasSourceOptions={Boolean(this.pages.find(p => p.id === 'source-options'))}
+            defaultStorage={wizardStore.defaultStorage}
             storageMap={wizardStore.storageMap}
             storageMap={wizardStore.storageMap}
             schedules={wizardStore.schedules}
             schedules={wizardStore.schedules}
             nextButtonDisabled={this.isNextButtonDisabled()}
             nextButtonDisabled={this.isNextButtonDisabled()}
@@ -624,6 +632,7 @@ class WizardPage extends React.Component<Props, State> {
             onDestOptionsChange={(field, value) => { this.handleDestOptionsChange(field, value) }}
             onDestOptionsChange={(field, value) => { this.handleDestOptionsChange(field, value) }}
             onSourceOptionsChange={(field, value) => { this.handleSourceOptionsChange(field, value) }}
             onSourceOptionsChange={(field, value) => { this.handleSourceOptionsChange(field, value) }}
             onNetworkChange={(sourceNic, targetNetwork, secGroups) => { this.handleNetworkChange(sourceNic, targetNetwork, secGroups) }}
             onNetworkChange={(sourceNic, targetNetwork, secGroups) => { this.handleNetworkChange(sourceNic, targetNetwork, secGroups) }}
+            onDefaultStorageChange={value => { this.handleDefaultStorageChange(value) }}
             onStorageChange={(source, target, type) => { this.handleStorageChange(source, target, type) }}
             onStorageChange={(source, target, type) => { this.handleStorageChange(source, target, type) }}
             onAddScheduleClick={schedule => { this.handleAddScheduleClick(schedule) }}
             onAddScheduleClick={schedule => { this.handleAddScheduleClick(schedule) }}
             onScheduleChange={(scheduleId, data) => { this.handleScheduleChange(scheduleId, data) }}
             onScheduleChange={(scheduleId, data) => { this.handleScheduleChange(scheduleId, data) }}

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

@@ -73,7 +73,7 @@ export const defaultFillMigrationImageMapValues = (field: Field, option: OptionV
 
 
 export const defaultGetDestinationEnv = (options: ?{ [string]: mixed }, oldOptions?: ?{ [string]: mixed }): any => {
 export const defaultGetDestinationEnv = (options: ?{ [string]: mixed }, oldOptions?: ?{ [string]: mixed }): any => {
   let env = {}
   let env = {}
-  let specialOptions = ['execute_now', 'separate_vm', 'skip_os_morphing', 'default_storage', 'description']
+  let specialOptions = ['execute_now', 'separate_vm', 'skip_os_morphing', 'description']
     .concat(migrationFields.map(f => f.name))
     .concat(migrationFields.map(f => f.name))
     .concat(executionOptions.map(o => o.name))
     .concat(executionOptions.map(o => o.name))
     .concat(migrationImageOsTypes.map(o => `${o}_os_image`))
     .concat(migrationImageOsTypes.map(o => `${o}_os_image`))

+ 1 - 1
src/sources/AssessmentSource.js

@@ -33,7 +33,7 @@ class AssessmentSourceUtils {
     if (vmSize) {
     if (vmSize) {
       env.vm_size = vmSize
       env.vm_size = vmSize
     }
     }
-    let skipFields = ['use_replica', 'separate_vm', 'shutdown_instances', 'skip_os_morphing', 'default_storage']
+    let skipFields = ['use_replica', 'separate_vm', 'shutdown_instances', 'skip_os_morphing']
     Object.keys(data.fieldValues).filter(f => !skipFields.find(sf => sf === f)).forEach(fieldName => {
     Object.keys(data.fieldValues).filter(f => !skipFields.find(sf => sf === f)).forEach(fieldName => {
       if (data.fieldValues[fieldName] != null) {
       if (data.fieldValues[fieldName] != null) {
         env[fieldName] = data.fieldValues[fieldName]
         env[fieldName] = data.fieldValues[fieldName]

+ 3 - 1
src/sources/MigrationSource.js

@@ -82,6 +82,8 @@ class MigrationSource {
     updatedSourceEnv?: ?{ [string]: any },
     updatedSourceEnv?: ?{ [string]: any },
     storageMappings: ?{ [string]: any },
     storageMappings: ?{ [string]: any },
     updatedStorageMappings: ?StorageMap[],
     updatedStorageMappings: ?StorageMap[],
+    defaultStorage: ?string,
+    updatedDefaultStorage: ?string,
     networkMappings: ?{ [string]: any },
     networkMappings: ?{ [string]: any },
     updatedNetworkMappings: ?NetworkMap[],
     updatedNetworkMappings: ?NetworkMap[],
   }): Promise<MainItem> {
   }): Promise<MainItem> {
@@ -122,7 +124,7 @@ class MigrationSource {
       || (opts.updatedStorageMappings && opts.updatedStorageMappings.length)) {
       || (opts.updatedStorageMappings && opts.updatedStorageMappings.length)) {
       payload.migration.storage_mappings = {
       payload.migration.storage_mappings = {
         ...opts.storageMappings,
         ...opts.storageMappings,
-        ...destParser.getStorageMap(getValue('default_storage'), opts.updatedStorageMappings),
+        ...destParser.getStorageMap(opts.updatedDefaultStorage || opts.defaultStorage, opts.updatedStorageMappings),
       }
       }
     }
     }
 
 

+ 1 - 2
src/sources/ReplicaSource.js

@@ -203,7 +203,7 @@ class ReplicaSource {
     return response.data.execution
     return response.data.execution
   }
   }
 
 
-  async update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, storageConfigDefault: string): Promise<Execution> {
+  async update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, defaultStorage: ?string, storageConfigDefault: string): Promise<Execution> {
     const parser = OptionsSchemaPlugin[destinationEndpoint.type] || OptionsSchemaPlugin.default
     const parser = OptionsSchemaPlugin[destinationEndpoint.type] || OptionsSchemaPlugin.default
     let payload = { replica: {} }
     let payload = { replica: {} }
 
 
@@ -219,7 +219,6 @@ class ReplicaSource {
       payload.replica.source_environment = parser.getDestinationEnv(updateData.source, replica.source_environment)
       payload.replica.source_environment = parser.getDestinationEnv(updateData.source, replica.source_environment)
     }
     }
 
 
-    let defaultStorage = updateData.destination && updateData.destination.default_storage
     if (defaultStorage || updateData.storage.length > 0) {
     if (defaultStorage || updateData.storage.length > 0) {
       payload.replica.storage_mappings = parser.getStorageMap(defaultStorage, updateData.storage, storageConfigDefault)
       payload.replica.storage_mappings = parser.getStorageMap(defaultStorage, updateData.storage, storageConfigDefault)
     }
     }

+ 3 - 2
src/sources/WizardSource.js

@@ -28,13 +28,13 @@ class WizardSource {
   async create(
   async create(
     type: string,
     type: string,
     data: WizardData,
     data: WizardData,
+    defaultStorage: ?string,
     storageMap: StorageMap[],
     storageMap: StorageMap[],
     uploadedUserScripts: InstanceScript[]
     uploadedUserScripts: InstanceScript[]
   ): Promise<MainItem> {
   ): Promise<MainItem> {
     const sourceParser = data.source ? OptionsSchemaPlugin[data.source.type] || OptionsSchemaPlugin.default : OptionsSchemaPlugin.default
     const sourceParser = data.source ? OptionsSchemaPlugin[data.source.type] || OptionsSchemaPlugin.default : OptionsSchemaPlugin.default
     const destParser = data.target ? OptionsSchemaPlugin[data.target.type] || OptionsSchemaPlugin.default : OptionsSchemaPlugin.default
     const destParser = data.target ? OptionsSchemaPlugin[data.target.type] || OptionsSchemaPlugin.default : OptionsSchemaPlugin.default
     let payload = {}
     let payload = {}
-    let defaultStorage: ?string = data.destOptions && data.destOptions.default_storage
     payload[type] = {
     payload[type] = {
       origin_endpoint_id: data.source ? data.source.id : 'null',
       origin_endpoint_id: data.source ? data.source.id : 'null',
       destination_endpoint_id: data.target ? data.target.id : 'null',
       destination_endpoint_id: data.target ? data.target.id : 'null',
@@ -72,6 +72,7 @@ class WizardSource {
   async createMultiple(
   async createMultiple(
     type: string,
     type: string,
     data: WizardData,
     data: WizardData,
+    defaultStorage: ?string,
     storageMap: StorageMap[],
     storageMap: StorageMap[],
     uploadedUserScripts: InstanceScript[]
     uploadedUserScripts: InstanceScript[]
   ): Promise<MainItem[]> {
   ): Promise<MainItem[]> {
@@ -82,7 +83,7 @@ class WizardSource {
       let newData = { ...data }
       let newData = { ...data }
       newData.selectedInstances = [instance]
       newData.selectedInstances = [instance]
       try {
       try {
-        let mainItem: MainItem = await this.create(type, newData, storageMap, uploadedUserScripts)
+        let mainItem: MainItem = await this.create(type, newData, defaultStorage, storageMap, uploadedUserScripts)
         return mainItem
         return mainItem
       } catch (err) {
       } catch (err) {
         notificationStore.alert(`Error while creating ${type} for instance ${instance.name}`, 'error')
         notificationStore.alert(`Error while creating ${type} for instance ${instance.name}`, 'error')

+ 5 - 1
src/stores/MigrationStore.js

@@ -59,7 +59,9 @@ class MigrationStore {
     migration: MainItem,
     migration: MainItem,
     sourceEndpoint: Endpoint,
     sourceEndpoint: Endpoint,
     destEndpoint: Endpoint,
     destEndpoint: Endpoint,
-    updateData: UpdateData
+    updateData: UpdateData,
+    defaultStorage: ?string,
+    updatedDefaultStorage: ?string
   ): Promise<MainItem> {
   ): Promise<MainItem> {
     let migrationResult = await MigrationSource.recreate({
     let migrationResult = await MigrationSource.recreate({
       sourceEndpoint,
       sourceEndpoint,
@@ -71,6 +73,8 @@ class MigrationStore {
       updatedDestEnv: updateData.destination,
       updatedDestEnv: updateData.destination,
       storageMappings: migration.storage_mappings,
       storageMappings: migration.storage_mappings,
       updatedStorageMappings: updateData.storage,
       updatedStorageMappings: updateData.storage,
+      defaultStorage,
+      updatedDefaultStorage,
       networkMappings: migration.network_map,
       networkMappings: migration.network_map,
       updatedNetworkMappings: updateData.network,
       updatedNetworkMappings: updateData.network,
     })
     })

+ 2 - 2
src/stores/ReplicaStore.js

@@ -185,8 +185,8 @@ class ReplicaStore {
     this.replicaDetails = null
     this.replicaDetails = null
   }
   }
 
 
-  async update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, storageConfigDefault: string) {
-    await ReplicaSource.update(replica, destinationEndpoint, updateData, storageConfigDefault)
+  async update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, defaultStorage: ?string, storageConfigDefault: string) {
+    await ReplicaSource.update(replica, destinationEndpoint, updateData, defaultStorage, storageConfigDefault)
   }
   }
 }
 }
 
 

+ 18 - 3
src/stores/WizardStore.js

@@ -54,6 +54,7 @@ const updateOptions = (oldOptions: ?{ [string]: mixed }, data: { field: Field, v
 class WizardStore {
 class WizardStore {
   @observable data: WizardData = {}
   @observable data: WizardData = {}
   @observable schedules: Schedule[] = []
   @observable schedules: Schedule[] = []
+  @observable defaultStorage: ?string = null
   @observable storageMap: StorageMap[] = []
   @observable storageMap: StorageMap[] = []
   @observable currentPage: WizardPage = wizardPages[0]
   @observable currentPage: WizardPage = wizardPages[0]
   @observable createdItem: ?MainItem = null
   @observable createdItem: ?MainItem = null
@@ -84,6 +85,7 @@ class WizardStore {
   @action clearData() {
   @action clearData() {
     this.data = {}
     this.data = {}
     this.currentPage = wizardPages[0]
     this.currentPage = wizardPages[0]
+    this.clearStorageMap()
   }
   }
 
 
   @action setCurrentPage(page: WizardPage) {
   @action setCurrentPage(page: WizardPage) {
@@ -109,6 +111,10 @@ class WizardStore {
     this.data.networks.push(network)
     this.data.networks.push(network)
   }
   }
 
 
+  @action updateDefaultStorage(value: ?string) {
+    this.defaultStorage = value
+  }
+
   @action updateStorage(storage: StorageMap) {
   @action updateStorage(storage: StorageMap) {
     let diskFieldName = storage.type === 'backend' ? 'storage_backend_identifier' : 'id'
     let diskFieldName = storage.type === 'backend' ? 'storage_backend_identifier' : 'id'
     this.storageMap = this.storageMap
     this.storageMap = this.storageMap
@@ -118,6 +124,7 @@ class WizardStore {
 
 
   @action clearStorageMap() {
   @action clearStorageMap() {
     this.storageMap = []
     this.storageMap = []
+    this.defaultStorage = null
   }
   }
 
 
   @action addSchedule(schedule: Schedule) {
   @action addSchedule(schedule: Schedule) {
@@ -151,13 +158,14 @@ class WizardStore {
   @action async create(
   @action async create(
     type: string,
     type: string,
     data: WizardData,
     data: WizardData,
+    defaultStorage: ?string,
     storageMap: StorageMap[],
     storageMap: StorageMap[],
     uploadedUserScripts: InstanceScript[]
     uploadedUserScripts: InstanceScript[]
   ): Promise<void> {
   ): Promise<void> {
     this.creatingItem = true
     this.creatingItem = true
 
 
     try {
     try {
-      let item: MainItem = await source.create(type, data, storageMap, uploadedUserScripts)
+      let item: MainItem = await source.create(type, data, defaultStorage, storageMap, uploadedUserScripts)
       runInAction(() => { this.createdItem = item })
       runInAction(() => { this.createdItem = item })
     } catch (err) {
     } catch (err) {
       throw err
       throw err
@@ -169,13 +177,14 @@ class WizardStore {
   @action async createMultiple(
   @action async createMultiple(
     type: string,
     type: string,
     data: WizardData,
     data: WizardData,
+    defaultStorage: ?string,
     storageMap: StorageMap[],
     storageMap: StorageMap[],
     uploadedUserScripts: InstanceScript[]
     uploadedUserScripts: InstanceScript[]
   ): Promise<void> {
   ): Promise<void> {
     this.creatingItems = true
     this.creatingItems = true
 
 
     try {
     try {
-      let items: MainItem[] = await source.createMultiple(type, data, storageMap, uploadedUserScripts)
+      let items: MainItem[] = await source.createMultiple(type, data, defaultStorage, storageMap, uploadedUserScripts)
       runInAction(() => { this.createdItems = items })
       runInAction(() => { this.createdItems = items })
     } finally {
     } finally {
       runInAction(() => { this.creatingItems = false })
       runInAction(() => { this.creatingItems = false })
@@ -183,7 +192,12 @@ class WizardStore {
   }
   }
 
 
   updateUrlState() {
   updateUrlState() {
-    source.setUrlState({ data: this.data, schedules: this.schedules, storageMap: this.storageMap })
+    source.setUrlState({
+      data: this.data,
+      schedules: this.schedules,
+      storageMap: this.storageMap,
+      defaultStorage: this.defaultStorage,
+    })
   }
   }
 
 
   @action getUrlState() {
   @action getUrlState() {
@@ -194,6 +208,7 @@ class WizardStore {
     this.data = state.data
     this.data = state.data
     this.schedules = state.schedules
     this.schedules = state.schedules
     this.storageMap = state.storageMap
     this.storageMap = state.storageMap
+    this.defaultStorage = state.defaultStorage
   }
   }
 
 
   @action cancelUploadedScript(global: ?string, instanceName: ?string) {
   @action cancelUploadedScript(global: ?string, instanceName: ?string) {