From 05f53fc9dcc3d3b8eba331c1a5929f29ef13a053 Mon Sep 17 00:00:00 2001 From: Sergiu Miclea Date: Mon, 15 Jul 2019 16:33:25 +0300 Subject: [PATCH] Update storage mapping default behaviour Auto select the server's storage config default in 'Default Storage' field, found in Wizard target options and Edit Replica target options. When creating a replica, don't send any storage mapping data to the server, if its target mapping is 'Default'. When editing a replica, if a target storage mapping is changed to 'Default', send the 'Default Storage' as the target mapping. In Wizard Summary page, show only the storage mappings that are actually sent to the server. --- src/components/organisms/EditReplica/EditReplica.jsx | 9 +++++---- .../organisms/WizardOptions/WizardOptions.jsx | 8 +++++++- .../organisms/WizardPageContent/WizardPageContent.jsx | 9 +-------- .../organisms/WizardStorage/WizardStorage.jsx | 5 ++--- .../organisms/WizardSummary/WizardSummary.jsx | 11 +++++++---- src/plugins/endpoint/default/OptionsSchemaPlugin.js | 8 ++++---- src/sources/ReplicaSource.js | 8 ++++---- src/stores/EndpointStore.js | 2 ++ src/stores/ReplicaStore.js | 4 ++-- src/stores/WizardStore.js | 2 +- 10 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/components/organisms/EditReplica/EditReplica.jsx b/src/components/organisms/EditReplica/EditReplica.jsx index 6691ef66..6b19fbe4 100644 --- a/src/components/organisms/EditReplica/EditReplica.jsx +++ b/src/components/organisms/EditReplica/EditReplica.jsx @@ -259,10 +259,11 @@ class EditReplica extends React.Component { source: this.state.sourceData, destination: this.state.destinationData, network: this.state.selectedNetworks.length > 0 ? this.getSelectedNetworks() : [], - storage: this.state.destinationData.default_storage || this.state.storageMap.length > 0 ? this.getStorageMap() : [], + storage: this.state.storageMap, } if (this.props.type === 'replica') { - replicaStore.update(this.props.replica, this.props.destinationEndpoint, updateData).then(() => { + let storageConfigDefault = this.getFieldValue('destination', 'default_storage') || endpointStore.storageConfigDefault + replicaStore.update(this.props.replica, this.props.destinationEndpoint, updateData, storageConfigDefault).then(() => { this.props.onRequestClose() this.props.onUpdateComplete(`/replica/executions/${this.props.replica.id}`) }).catch(() => { @@ -360,7 +361,7 @@ class EditReplica extends React.Component { this.state.storageMap.forEach(mapping => { let fieldName = mapping.type === 'backend' ? 'storage_backend_identifier' : 'id' let existingMapping = storageMap.find(m => m.type === mapping.type && - m.source[fieldName] === mapping.source[fieldName] + m.source[fieldName] === String(mapping.source[fieldName]) ) if (existingMapping) { existingMapping.target = mapping.target @@ -388,6 +389,7 @@ class EditReplica extends React.Component { fields={fields} hasStorageMap={type === 'source' ? false : this.hasStorageMap()} storageBackends={endpointStore.storageBackends} + storageConfigDefault={endpointStore.storageConfigDefault} onChange={(f, v) => { this.handleFieldChange(type, f, v) }} oneColumnStyle={{ marginTop: '-16px', display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }} columnStyle={{ marginRight: 0 }} @@ -412,7 +414,6 @@ class EditReplica extends React.Component { storageBackends={endpointStore.storageBackends} instancesDetails={this.props.instancesDetails} storageMap={this.getStorageMap()} - defaultStorage={this.getFieldValue('destination', 'default_storage')} onChange={(s, t, type) => { this.handleStorageChange(s, t, type) }} /> ) diff --git a/src/components/organisms/WizardOptions/WizardOptions.jsx b/src/components/organisms/WizardOptions/WizardOptions.jsx index 6b9ed9e3..b4066b96 100644 --- a/src/components/organisms/WizardOptions/WizardOptions.jsx +++ b/src/components/organisms/WizardOptions/WizardOptions.jsx @@ -81,6 +81,7 @@ type Props = { useAdvancedOptions?: boolean, hasStorageMap: boolean, storageBackends?: StorageBackend[], + storageConfigDefault?: string, onAdvancedOptionsToggle?: (showAdvanced: boolean) => void, wizardType: string, loading?: boolean, @@ -145,7 +146,12 @@ class WizardOptions extends React.Component { } 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) }) + fieldsSchema.push({ + name: 'default_storage', + type: 'string', + enum: this.props.storageBackends.map(s => s.name), + default: this.props.storageConfigDefault, + }) } return fieldsSchema diff --git a/src/components/organisms/WizardPageContent/WizardPageContent.jsx b/src/components/organisms/WizardPageContent/WizardPageContent.jsx index f75b0075..e62c6221 100644 --- a/src/components/organisms/WizardPageContent/WizardPageContent.jsx +++ b/src/components/organisms/WizardPageContent/WizardPageContent.jsx @@ -355,6 +355,7 @@ class WizardPageContent extends React.Component { useAdvancedOptions={this.state.useAdvancedOptions} hasStorageMap={this.props.hasStorageMap} storageBackends={this.props.endpointStore.storageBackends} + storageConfigDefault={this.props.endpointStore.storageConfigDefault} wizardType={this.props.type} onAdvancedOptionsToggle={useAdvancedOptions => { this.handleAdvancedOptionsToggle(useAdvancedOptions) }} /> @@ -378,7 +379,6 @@ class WizardPageContent extends React.Component { storageBackends={this.props.endpointStore.storageBackends} instancesDetails={this.props.instanceStore.instancesDetails} storageMap={this.props.storageMap} - defaultStorage={String(this.props.wizardData.destOptions ? this.props.wizardData.destOptions.default_storage : '')} onChange={this.props.onStorageChange} /> ) @@ -404,13 +404,6 @@ class WizardPageContent extends React.Component { storageMap={this.props.storageMap} wizardType={this.props.type} instancesDetails={this.props.instanceStore.instancesDetails} - defaultStorage={ - this.props.endpointStore.storageBackends.find( - s => this.props.wizardData.destOptions ? - s.name === this.props.wizardData.destOptions.default_storage : - false - ) - } /> ) break diff --git a/src/components/organisms/WizardStorage/WizardStorage.jsx b/src/components/organisms/WizardStorage/WizardStorage.jsx index b2fe89c8..ece1509d 100644 --- a/src/components/organisms/WizardStorage/WizardStorage.jsx +++ b/src/components/organisms/WizardStorage/WizardStorage.jsx @@ -143,7 +143,6 @@ export type Props = { storageBackends: StorageBackend[], instancesDetails: Instance[], storageMap: ?StorageMap[], - defaultStorage: ?string, onChange: (sourceStorage: Disk, targetStorage: StorageBackend, type: 'backend' | 'disk') => void, } @observer @@ -184,8 +183,8 @@ class WizardStorage extends React.Component { } return false }).map(i => i.instance_name) - let selectedItem = storageMap && storageMap.find(s => s.type === type && s.source[diskFieldName] === disk[diskFieldName]) - selectedItem = selectedItem ? selectedItem.target : storageItems.find(i => i.name === this.props.defaultStorage) + let selectedItem = storageMap && storageMap.find(s => s.type === type && String(s.source[diskFieldName]) === String(disk[diskFieldName])) + selectedItem = selectedItem ? selectedItem.target : null return ( diff --git a/src/components/organisms/WizardSummary/WizardSummary.jsx b/src/components/organisms/WizardSummary/WizardSummary.jsx index 623cab03..47820787 100644 --- a/src/components/organisms/WizardSummary/WizardSummary.jsx +++ b/src/components/organisms/WizardSummary/WizardSummary.jsx @@ -144,7 +144,6 @@ type Props = { schedules: Schedule[], storageMap: StorageMap[], instancesDetails: Instance[], - defaultStorage: ?StorageBackend, } @observer class WizardSummary extends React.Component { @@ -297,7 +296,6 @@ class WizardSummary extends React.Component { if ( optionName === 'execute_now' || optionName === 'separate_vm' || - optionName === 'default_storage' || !data.destOptions || data.destOptions[optionName] == null ) { return null @@ -323,7 +321,7 @@ class WizardSummary extends React.Component { let storageMap = this.props.storageMap.filter(mapping => mapping.type === type) let disks = getDisks(this.props.instancesDetails, type) - if (disks.length === 0 || (storageMap.length === 0 && !this.props.defaultStorage)) { + if (disks.length === 0 || storageMap.length === 0) { return null } let fieldName = type === 'backend' ? 'storage_backend_identifier' : 'id' @@ -333,12 +331,17 @@ class WizardSummary extends React.Component { if (diskMapped) { return { source: diskMapped.source, target: diskMapped.target } } - return { source: disk, target: this.props.defaultStorage } + return { source: disk, target: null } }) fullStorageMap.sort((m1, m2) => String(m1.source[fieldName]).localeCompare(String(m2.source[fieldName]))) + fullStorageMap = fullStorageMap.filter(fsm => fsm.target && fsm.target.id) let title = type === 'backend' ? 'Storage Backend Mapping' : 'Disk Mapping' + if (fullStorageMap.length === 0) { + return null + } + return (
{title} diff --git a/src/plugins/endpoint/default/OptionsSchemaPlugin.js b/src/plugins/endpoint/default/OptionsSchemaPlugin.js index 0e087d4b..8a55152a 100644 --- a/src/plugins/endpoint/default/OptionsSchemaPlugin.js +++ b/src/plugins/endpoint/default/OptionsSchemaPlugin.js @@ -137,7 +137,7 @@ export default class OptionsSchemaParser { return payload } - static getStorageMap(defaultStorage: ?string, storageMap: ?StorageMap[]) { + static getStorageMap(defaultStorage: ?string, storageMap: ?StorageMap[], configDefault?: ?string) { if (!defaultStorage && !storageMap) { return null } @@ -152,7 +152,7 @@ export default class OptionsSchemaParser { } storageMap.forEach(mapping => { - if (mapping.target.id === null) { + if (mapping.target.id === null && !configDefault) { return } @@ -162,7 +162,7 @@ export default class OptionsSchemaParser { } payload.backend_mappings.push({ source: mapping.source.storage_backend_identifier, - destination: mapping.target.name, + destination: mapping.target.id === null ? configDefault : mapping.target.name, }) } else { if (!payload.disk_mappings) { @@ -170,7 +170,7 @@ export default class OptionsSchemaParser { } payload.disk_mappings.push({ disk_id: mapping.source.id.toString(), - destination: mapping.target.name, + destination: mapping.target.id === null ? configDefault : mapping.target.name, }) } }) diff --git a/src/sources/ReplicaSource.js b/src/sources/ReplicaSource.js index ae15178b..eab9c327 100644 --- a/src/sources/ReplicaSource.js +++ b/src/sources/ReplicaSource.js @@ -160,7 +160,7 @@ class ReplicaSource { }).then(response => response.data.execution) } - static update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData): Promise { + static update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, storageConfigDefault: string): Promise { const parser = OptionsSchemaPlugin[destinationEndpoint.type] || OptionsSchemaPlugin.default let payload = { replica: {} } @@ -180,9 +180,9 @@ class ReplicaSource { payload.replica.source_environment = parser.getDestinationEnv(updateData.source, replica.source_environment) } - if (updateData.storage.length > 0) { - payload.replica.storage_mappings = parser.getStorageMap( - updateData.destination && updateData.destination.default_storage, updateData.storage) + let defaultStorage = updateData.destination && updateData.destination.default_storage + if (defaultStorage || updateData.storage.length > 0) { + payload.replica.storage_mappings = parser.getStorageMap(defaultStorage, updateData.storage, storageConfigDefault) } return Api.send({ diff --git a/src/stores/EndpointStore.js b/src/stores/EndpointStore.js index 07eadfc6..b567c50f 100644 --- a/src/stores/EndpointStore.js +++ b/src/stores/EndpointStore.js @@ -41,6 +41,7 @@ class EndpointStore { @observable connectionsInfoLoading = false @observable storageBackends: StorageBackend[] = [] @observable storageLoading: boolean = false + @observable storageConfigDefault: string = '' @action getEndpoints(options?: { showLoading: boolean }) { if (options && options.showLoading) { @@ -185,6 +186,7 @@ class EndpointStore { this.storageLoading = true return EndpointSource.loadStorage(endpointId, data).then(storage => { this.storageBackends = storage.storage_backends + this.storageConfigDefault = storage.config_default || '' this.storageLoading = false }).catch(ex => { this.storageLoading = false diff --git a/src/stores/ReplicaStore.js b/src/stores/ReplicaStore.js index 0346bb9c..7661f0d5 100644 --- a/src/stores/ReplicaStore.js +++ b/src/stores/ReplicaStore.js @@ -163,8 +163,8 @@ class ReplicaStore { this.replicaDetails = null } - @action update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData) { - return ReplicaSource.update(replica, destinationEndpoint, updateData) + @action update(replica: MainItem, destinationEndpoint: Endpoint, updateData: UpdateData, storageConfigDefault: string) { + return ReplicaSource.update(replica, destinationEndpoint, updateData, storageConfigDefault) } } diff --git a/src/stores/WizardStore.js b/src/stores/WizardStore.js index 169d63b0..2598075e 100644 --- a/src/stores/WizardStore.js +++ b/src/stores/WizardStore.js @@ -101,7 +101,7 @@ class WizardStore { @action updateStorage(storage: StorageMap) { let diskFieldName = storage.type === 'backend' ? 'storage_backend_identifier' : 'id' this.storageMap = this.storageMap - .filter(n => n.type !== storage.type || n.source[diskFieldName] !== storage.source[diskFieldName]) + .filter(n => n.type !== storage.type || String(n.source[diskFieldName]) !== String(storage.source[diskFieldName])) this.storageMap.push(storage) }