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

Hide non-linux images from export image

A warning message is display to indicate this.
Sergiu Miclea 4 лет назад
Родитель
Сommit
d1cb4fcf00

+ 1 - 0
src/@types/Field.ts

@@ -52,6 +52,7 @@ export type Field = {
   readOnly?: boolean,
   readOnly?: boolean,
   title?: string,
   title?: string,
   description?: string,
   description?: string,
+  warning?: string,
   subFields?: Field[],
   subFields?: Field[],
   groupName?: string
   groupName?: string
 }
 }

+ 1 - 0
src/components/modules/WizardModule/WizardOptions/WizardOptions.tsx

@@ -352,6 +352,7 @@ class WizardOptions extends React.Component<Props> {
         minimum={field.minimum}
         minimum={field.minimum}
         maximum={field.maximum}
         maximum={field.maximum}
         label={field.label || LabelDictionary.get(field.name, this.props.dictionaryKey)}
         label={field.label || LabelDictionary.get(field.name, this.props.dictionaryKey)}
+        warning={field.warning}
         description={field.description
         description={field.description
           || LabelDictionary.getDescription(field.name, this.props.dictionaryKey)}
           || LabelDictionary.getDescription(field.name, this.props.dictionaryKey)}
         password={this.isPassword(field.name)}
         password={this.isPassword(field.name)}

+ 14 - 0
src/components/ui/FieldInput/FieldInput.tsx

@@ -63,6 +63,13 @@ const Label = styled.div<any>`
     opacity: 0.5;
     opacity: 0.5;
   ` : '')}
   ` : '')}
 `
 `
+const WarningLabel = styled.div<{ fontSize: number }>`
+  font-weight: 300;
+  font-size: ${props => props.fontSize}px;
+  color: ${ThemePalette.grayscale[3]};
+  display: inline-block;
+  margin-left: 4px;
+`
 const LabelText = styled.span``
 const LabelText = styled.span``
 const Asterisk = styled.div<any>`
 const Asterisk = styled.div<any>`
   ${ThemeProps.exactSize('16px')}
   ${ThemeProps.exactSize('16px')}
@@ -99,6 +106,7 @@ type Props = {
   width?: number,
   width?: number,
   label?: string,
   label?: string,
   description?: string,
   description?: string,
+  warning?: string,
   addNullValue?: boolean,
   addNullValue?: boolean,
   nullableBoolean?: boolean,
   nullableBoolean?: boolean,
   labelRenderer?: ((prop: string) => string) | null,
   labelRenderer?: ((prop: string) => string) | null,
@@ -392,6 +400,7 @@ class FieldInput extends React.Component<Props> {
     }
     }
 
 
     const description = this.props.description
     const description = this.props.description
+    const warning = this.props.warning
     const marginRight = this.props.layout === 'modal' || description || this.props.required ? '24px' : 0
     const marginRight = this.props.layout === 'modal' || description || this.props.required ? '24px' : 0
 
 
     return (
     return (
@@ -405,7 +414,12 @@ class FieldInput extends React.Component<Props> {
           {this.props.label}
           {this.props.label}
         </LabelText>
         </LabelText>
         {description ? <InfoIcon text={description} marginLeft={-20} marginBottom={this.props.layout === 'page' ? null : 0} /> : null}
         {description ? <InfoIcon text={description} marginLeft={-20} marginBottom={this.props.layout === 'page' ? null : 0} /> : null}
+        {/*
+        {warning ? <InfoIcon warning filled text={warning}
+         marginLeft={3} marginBottom={this.props.layout === 'page' ? null : 0} style={{ transform: 'scale(0.8)' }} /> : null}
+        */}
         {this.props.layout === 'page' && Boolean(this.props.required) ? <Asterisk marginLeft={description ? '4px' : '-16px'} /> : null}
         {this.props.layout === 'page' && Boolean(this.props.required) ? <Asterisk marginLeft={description ? '4px' : '-16px'} /> : null}
+        {warning ? <WarningLabel fontSize={this.props.layout === 'page' ? 10 : 6}>{warning}</WarningLabel> : null}
       </Label>
       </Label>
     )
     )
   }
   }

+ 1 - 1
src/components/ui/InfoIcon/InfoIcon.tsx

@@ -32,7 +32,7 @@ type Props = {
   marginLeft?: number | null,
   marginLeft?: number | null,
   marginBottom?: number | null,
   marginBottom?: number | null,
   className?: string,
   className?: string,
-  style?: any,
+  style?: React.CSSProperties,
   warning?: boolean,
   warning?: boolean,
   filled?: boolean,
   filled?: boolean,
 }
 }

+ 3 - 15
src/plugins/aws/OptionsSchemaPlugin.ts

@@ -13,7 +13,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 */
 
 
 import type { InstanceScript } from '@src/@types/Instance'
 import type { InstanceScript } from '@src/@types/Instance'
-import { Field, isEnumSeparator } from '@src/@types/Field'
+import { Field } from '@src/@types/Field'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { NetworkMap } from '@src/@types/Network'
 import type { NetworkMap } from '@src/@types/Network'
@@ -23,6 +23,7 @@ import DefaultOptionsSchemaPlugin, {
   defaultGetMigrationImageMap,
   defaultGetMigrationImageMap,
   defaultFillFieldValues,
   defaultFillFieldValues,
   defaultFillMigrationImageMapValues,
   defaultFillMigrationImageMapValues,
+  removeExportImageFieldValues,
 } from '../default/OptionsSchemaPlugin'
 } from '../default/OptionsSchemaPlugin'
 
 
 export default class OptionsSchemaParser {
 export default class OptionsSchemaParser {
@@ -69,20 +70,7 @@ export default class OptionsSchemaParser {
       requiresWindowsImage,
       requiresWindowsImage,
     })) {
     })) {
       defaultFillFieldValues(field, option)
       defaultFillFieldValues(field, option)
-
-      if (field.name === 'export_image') {
-        field.enum?.forEach(exportImageValue => {
-          if (typeof exportImageValue === 'string' || isEnumSeparator(exportImageValue)) {
-            return
-          }
-          // @ts-ignore
-          const osType = exportImageValue.os_type
-          if (osType !== 'unknown' && osType !== 'linux') {
-            exportImageValue.disabled = true
-            exportImageValue.subtitleLabel = `Source plugins rely on a Linux-based temporary virtual machine to perform data exports, but the platform reports this image to be of OS type '${osType}'.`
-          }
-        })
-      }
+      removeExportImageFieldValues(field)
     }
     }
   }
   }
 
 

+ 17 - 1
src/plugins/default/OptionsSchemaPlugin.ts

@@ -16,7 +16,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 import Utils from '@src/utils/ObjectUtils'
 import Utils from '@src/utils/ObjectUtils'
 
 
-import type { Field } from '@src/@types/Field'
+import { Field, isEnumSeparator } from '@src/@types/Field'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { NetworkMap } from '@src/@types/Network'
 import type { NetworkMap } from '@src/@types/Network'
@@ -42,6 +42,22 @@ export const defaultFillFieldValues = (field: Field, option: OptionValues) => {
   }
   }
 }
 }
 
 
+export const removeExportImageFieldValues = (field: Field) => {
+  if (field.name === 'export_image') {
+    field.enum = field.enum?.filter(exportImageValue => {
+      if (typeof exportImageValue === 'string' || isEnumSeparator(exportImageValue)) {
+        return true
+      }
+      // @ts-ignore
+      const isLinux = exportImageValue.os_type === 'linux' || exportImageValue.os_type === 'unknown'
+      if (!isLinux) {
+        field.warning = 'Only Linux images are listed.'
+      }
+      return isLinux
+    })
+  }
+}
+
 export const defaultFillMigrationImageMapValues = (opts: {
 export const defaultFillMigrationImageMapValues = (opts: {
   field: Field,
   field: Field,
   option: OptionValues,
   option: OptionValues,

+ 3 - 14
src/plugins/openstack/OptionsSchemaPlugin.ts

@@ -13,7 +13,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 */
 
 
 import type { InstanceScript } from '@src/@types/Instance'
 import type { InstanceScript } from '@src/@types/Instance'
-import { Field, isEnumSeparator } from '@src/@types/Field'
+import { Field } from '@src/@types/Field'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { OptionValues, StorageMap } from '@src/@types/Endpoint'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { SchemaProperties, SchemaDefinitions } from '@src/@types/Schema'
 import type { NetworkMap } from '@src/@types/Network'
 import type { NetworkMap } from '@src/@types/Network'
@@ -23,6 +23,7 @@ import DefaultOptionsSchemaPlugin, {
   defaultGetMigrationImageMap,
   defaultGetMigrationImageMap,
   defaultFillFieldValues,
   defaultFillFieldValues,
   defaultFillMigrationImageMapValues,
   defaultFillMigrationImageMapValues,
+  removeExportImageFieldValues,
 } from '../default/OptionsSchemaPlugin'
 } from '../default/OptionsSchemaPlugin'
 
 
 export default class OptionsSchemaParser {
 export default class OptionsSchemaParser {
@@ -73,19 +74,7 @@ export default class OptionsSchemaParser {
             DefaultOptionsSchemaPlugin.fillFieldValues({
             DefaultOptionsSchemaPlugin.fillFieldValues({
               field: f, options, customFieldName: f.name.split('/')[1], requiresWindowsImage,
               field: f, options, customFieldName: f.name.split('/')[1], requiresWindowsImage,
             })
             })
-            if (f.name === 'export_image') {
-              f.enum?.forEach(exportImageValue => {
-                if (typeof exportImageValue === 'string' || isEnumSeparator(exportImageValue)) {
-                  return
-                }
-                // @ts-ignore
-                const osType = exportImageValue.os_type
-                if (osType !== 'unknown' && osType !== 'linux') {
-                  exportImageValue.disabled = true
-                  exportImageValue.subtitleLabel = `Source plugins rely on a Linux-based temporary virtual machine to perform data exports, but the platform reports this image to be of OS type '${osType}'.`
-                }
-              })
-            }
+            removeExportImageFieldValues(f)
           })
           })
         }
         }
       })
       })

+ 2 - 0
src/stores/ProviderStore.ts

@@ -25,6 +25,7 @@ import { OptionsSchemaPlugin } from '@src/plugins'
 import type { OptionValues } from '@src/@types/Endpoint'
 import type { OptionValues } from '@src/@types/Endpoint'
 import type { Field } from '@src/@types/Field'
 import type { Field } from '@src/@types/Field'
 import type { Providers, ProviderTypes } from '@src/@types/Providers'
 import type { Providers, ProviderTypes } from '@src/@types/Providers'
+import ObjectUtils from '@src/utils/ObjectUtils'
 import regionStore from './RegionStore'
 import regionStore from './RegionStore'
 
 
 export const getFieldChangeOptions = (config: {
 export const getFieldChangeOptions = (config: {
@@ -304,6 +305,7 @@ class ProviderStore {
     const providerType = optionsType === 'source' ? providerTypes.SOURCE_OPTIONS : providerTypes.DESTINATION_OPTIONS
     const providerType = optionsType === 'source' ? providerTypes.SOURCE_OPTIONS : providerTypes.DESTINATION_OPTIONS
 
 
     await this.loadProviders()
     await this.loadProviders()
+    await ObjectUtils.waitFor(() => !this.providersLoading)
     if (!this.providers) {
     if (!this.providers) {
       return []
       return []
     }
     }