|
@@ -29,6 +29,8 @@ import backendImage from './images/backend.svg'
|
|
|
import diskImage from './images/disk.svg'
|
|
import diskImage from './images/disk.svg'
|
|
|
import bigStorageImage from './images/storage-big.svg'
|
|
import bigStorageImage from './images/storage-big.svg'
|
|
|
import arrowImage from './images/arrow.svg'
|
|
import arrowImage from './images/arrow.svg'
|
|
|
|
|
+import StatusImage from '../../atoms/StatusImage/StatusImage'
|
|
|
|
|
+import Button from '../../atoms/Button/Button'
|
|
|
|
|
|
|
|
const Wrapper = styled.div<any>`
|
|
const Wrapper = styled.div<any>`
|
|
|
width: 100%;
|
|
width: 100%;
|
|
@@ -129,15 +131,26 @@ const NoStorageTitle = styled.div<any>`
|
|
|
margin-bottom: 10px;
|
|
margin-bottom: 10px;
|
|
|
font-size: 18px;
|
|
font-size: 18px;
|
|
|
`
|
|
`
|
|
|
-const NoStorageSubtitle = styled.div<any>`
|
|
|
|
|
|
|
+const NoStorageSubtitle = styled.div`
|
|
|
color: ${Palette.grayscale[4]};
|
|
color: ${Palette.grayscale[4]};
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
|
|
+ margin-bottom: 42px;
|
|
|
`
|
|
`
|
|
|
const DiskDisabledMessage = styled.div<any>`
|
|
const DiskDisabledMessage = styled.div<any>`
|
|
|
width: 224px;
|
|
width: 224px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
color: gray;
|
|
color: gray;
|
|
|
`
|
|
`
|
|
|
|
|
+const LoadingWrapper = styled.div`
|
|
|
|
|
+ margin-top: 32px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+`
|
|
|
|
|
+const LoadingText = styled.div`
|
|
|
|
|
+ margin-top: 38px;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+`
|
|
|
|
|
|
|
|
export const getDisks = (instancesDetails: Instance[], type: 'backend' | 'disk', storageMap?: StorageMap[] | null): Disk[] => {
|
|
export const getDisks = (instancesDetails: Instance[], type: 'backend' | 'disk', storageMap?: StorageMap[] | null): Disk[] => {
|
|
|
const fieldName = type === 'backend' ? 'storage_backend_identifier' : 'id'
|
|
const fieldName = type === 'backend' ? 'storage_backend_identifier' : 'id'
|
|
@@ -164,6 +177,8 @@ export const TEST_ID = 'wizardStorage'
|
|
|
|
|
|
|
|
export type Props = {
|
|
export type Props = {
|
|
|
storageBackends: StorageBackend[],
|
|
storageBackends: StorageBackend[],
|
|
|
|
|
+ loading: boolean,
|
|
|
|
|
+ onReloadClick?: () => void
|
|
|
instancesDetails: Instance[],
|
|
instancesDetails: Instance[],
|
|
|
storageMap: StorageMap[] | null | undefined,
|
|
storageMap: StorageMap[] | null | undefined,
|
|
|
defaultStorageLayout: 'modal' | 'page',
|
|
defaultStorageLayout: 'modal' | 'page',
|
|
@@ -178,12 +193,15 @@ export type Props = {
|
|
|
class WizardStorage extends React.Component<Props> {
|
|
class WizardStorage extends React.Component<Props> {
|
|
|
renderNoStorage() {
|
|
renderNoStorage() {
|
|
|
return (
|
|
return (
|
|
|
- <NoStorageMessage data-test-id={`${TEST_ID}-noStorage`}>
|
|
|
|
|
|
|
+ <NoStorageMessage>
|
|
|
<BigStorageImage />
|
|
<BigStorageImage />
|
|
|
<NoStorageTitle>No storage backends were found</NoStorageTitle>
|
|
<NoStorageTitle>No storage backends were found</NoStorageTitle>
|
|
|
<NoStorageSubtitle>
|
|
<NoStorageSubtitle>
|
|
|
We could not find any storage backends. Coriolis will skip this step.
|
|
We could not find any storage backends. Coriolis will skip this step.
|
|
|
</NoStorageSubtitle>
|
|
</NoStorageSubtitle>
|
|
|
|
|
+ {this.props.onReloadClick ? (
|
|
|
|
|
+ <Button hollow onClick={this.props.onReloadClick}>Try again</Button>
|
|
|
|
|
+ ) : null}
|
|
|
</NoStorageMessage>
|
|
</NoStorageMessage>
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
@@ -197,39 +215,6 @@ class WizardStorage extends React.Component<Props> {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // renderBusTypeDropdown(selectedStorageMap: StorageMap | null | undefined) {
|
|
|
|
|
- // if (!selectedStorageMap) {
|
|
|
|
|
- // return null
|
|
|
|
|
- // }
|
|
|
|
|
- // type DropdownItem = {label: string, value: string | null}
|
|
|
|
|
- // const storageBusTypes: DropdownItem[] | undefined = this.props.storageBackends
|
|
|
|
|
- // .find(s => s.id === selectedStorageMap.target.id)?.additional_provider_properties?.supported_bus_types?.map(value => ({
|
|
|
|
|
- // label: value,
|
|
|
|
|
- // value,
|
|
|
|
|
- // }))
|
|
|
|
|
- // if (!storageBusTypes || !storageBusTypes.length) {
|
|
|
|
|
- // return null
|
|
|
|
|
- // }
|
|
|
|
|
- // storageBusTypes.unshift({
|
|
|
|
|
- // label: 'Choose a Bus Type',
|
|
|
|
|
- // value: null,
|
|
|
|
|
- // })
|
|
|
|
|
- // const selectedBusType = selectedStorageMap?.targetBusType
|
|
|
|
|
-
|
|
|
|
|
- // return (
|
|
|
|
|
- // <Dropdown
|
|
|
|
|
- // width={StyleProps.inputSizes.large.width}
|
|
|
|
|
- // noSelectionMessage="Choose a Bus Type"
|
|
|
|
|
- // centered
|
|
|
|
|
- // items={storageBusTypes}
|
|
|
|
|
- // selectedItem={selectedBusType}
|
|
|
|
|
- // onChange={(item: DropdownItem) => {
|
|
|
|
|
- // this.props.onChange({ ...selectedStorageMap, targetBusType: item.value })
|
|
|
|
|
- // }}
|
|
|
|
|
- // />
|
|
|
|
|
- // )
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
renderStorageDropdown(
|
|
renderStorageDropdown(
|
|
|
storageItems: Array<StorageBackend>,
|
|
storageItems: Array<StorageBackend>,
|
|
|
selectedItem: StorageBackend | null | undefined,
|
|
selectedItem: StorageBackend | null | undefined,
|
|
@@ -396,40 +381,6 @@ class WizardStorage extends React.Component<Props> {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // const renderDefaultBusTypeDropdown = () => {
|
|
|
|
|
- // if (!this.props.defaultStorage || !this.props.defaultStorage.value) {
|
|
|
|
|
- // return null
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // type DropdownItem = { label: string, value: string | null }
|
|
|
|
|
- // const storageBusTypes: DropdownItem[] | undefined = this.props.storageBackends
|
|
|
|
|
- // .find(s => s.id === this.props.defaultStorage?.value)?.additional_provider_properties?.supported_bus_types?.map(value => ({
|
|
|
|
|
- // label: value,
|
|
|
|
|
- // value,
|
|
|
|
|
- // }))
|
|
|
|
|
- // if (!storageBusTypes || !storageBusTypes.length) {
|
|
|
|
|
- // return null
|
|
|
|
|
- // }
|
|
|
|
|
- // storageBusTypes.unshift({
|
|
|
|
|
- // label: 'Choose a Bus Type',
|
|
|
|
|
- // value: null,
|
|
|
|
|
- // })
|
|
|
|
|
- // const selectedBusType = this.props.defaultStorage.busType
|
|
|
|
|
-
|
|
|
|
|
- // return (
|
|
|
|
|
- // <Dropdown
|
|
|
|
|
- // width={StyleProps.inputSizes.regular.width}
|
|
|
|
|
- // noSelectionMessage="Choose a Bus Type"
|
|
|
|
|
- // centered
|
|
|
|
|
- // items={storageBusTypes}
|
|
|
|
|
- // selectedItem={selectedBusType}
|
|
|
|
|
- // onChange={(item: DropdownItem) => {
|
|
|
|
|
- // this.props.onDefaultStorageChange(this.props.defaultStorage?.value || null, item.value)
|
|
|
|
|
- // }}
|
|
|
|
|
- // />
|
|
|
|
|
- // )
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
return (
|
|
return (
|
|
|
<StorageWrapper>
|
|
<StorageWrapper>
|
|
|
<StorageSection>
|
|
<StorageSection>
|
|
@@ -457,14 +408,25 @@ class WizardStorage extends React.Component<Props> {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ renderLoading() {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <LoadingWrapper>
|
|
|
|
|
+ <StatusImage loading />
|
|
|
|
|
+ <LoadingText>Loading storage...</LoadingText>
|
|
|
|
|
+ </LoadingWrapper>
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
render() {
|
|
render() {
|
|
|
return (
|
|
return (
|
|
|
<Wrapper style={this.props.style} ref={this.props.onScrollableRef}>
|
|
<Wrapper style={this.props.style} ref={this.props.onScrollableRef}>
|
|
|
- <Mapping>
|
|
|
|
|
- {this.renderDefaultStorage()}
|
|
|
|
|
- {this.renderBackendMapping()}
|
|
|
|
|
- {this.renderDiskMapping()}
|
|
|
|
|
- </Mapping>
|
|
|
|
|
|
|
+ {this.props.loading ? this.renderLoading() : (
|
|
|
|
|
+ <Mapping>
|
|
|
|
|
+ {this.renderDefaultStorage()}
|
|
|
|
|
+ {this.renderBackendMapping()}
|
|
|
|
|
+ {this.renderDiskMapping()}
|
|
|
|
|
+ </Mapping>
|
|
|
|
|
+ )}
|
|
|
</Wrapper>
|
|
</Wrapper>
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|