|
|
@ -1,4 +1,4 @@ |
|
|
|
import { useEffect, useState } from 'react'; |
|
|
|
import { useCallback, useEffect, useState } from 'react'; |
|
|
|
import { Box, Checkbox, Dialog, DialogProps, FormControl } from '@mui/material'; |
|
|
|
import { Box, Checkbox, Dialog, DialogProps, FormControl } from '@mui/material'; |
|
|
|
import { |
|
|
|
import { |
|
|
|
dSize as baseDSize, |
|
|
|
dSize as baseDSize, |
|
|
@ -9,15 +9,16 @@ import { |
|
|
|
|
|
|
|
|
|
|
|
import Autocomplete from './Autocomplete'; |
|
|
|
import Autocomplete from './Autocomplete'; |
|
|
|
import MenuItem from './MenuItem'; |
|
|
|
import MenuItem from './MenuItem'; |
|
|
|
import OutlinedInput, { OutlinedInputProps } from './OutlinedInput'; |
|
|
|
import OutlinedInput from './OutlinedInput'; |
|
|
|
import OutlinedInputLabel from './OutlinedInputLabel'; |
|
|
|
import OutlinedInputLabel from './OutlinedInputLabel'; |
|
|
|
|
|
|
|
import OutlinedInputWithLabel, { |
|
|
|
|
|
|
|
OutlinedInputWithLabelProps, |
|
|
|
|
|
|
|
} from './OutlinedInputWithLabel'; |
|
|
|
import { Panel, PanelHeader } from './Panels'; |
|
|
|
import { Panel, PanelHeader } from './Panels'; |
|
|
|
import Select, { SelectProps } from './Select'; |
|
|
|
import Select, { SelectProps } from './Select'; |
|
|
|
import Slider, { SliderProps } from './Slider'; |
|
|
|
import Slider, { SliderProps } from './Slider'; |
|
|
|
import { BodyText, HeaderText } from './Text'; |
|
|
|
import { BodyText, HeaderText } from './Text'; |
|
|
|
import ContainedButton from './ContainedButton'; |
|
|
|
import ContainedButton from './ContainedButton'; |
|
|
|
import { OutlinedInputLabelProps } from './OutlinedInputLabel/OutlinedInputLabel'; |
|
|
|
|
|
|
|
import OutlinedInputWithLabel from './OutlinedInputWithLabel'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type SelectItem<SelectItemValueType = string> = { |
|
|
|
type SelectItem<SelectItemValueType = string> = { |
|
|
|
displayValue?: SelectItemValueType; |
|
|
|
displayValue?: SelectItemValueType; |
|
|
@ -362,12 +363,10 @@ const createOutlinedInputWithSelect = ( |
|
|
|
label: string, |
|
|
|
label: string, |
|
|
|
selectItems: SelectItem[], |
|
|
|
selectItems: SelectItem[], |
|
|
|
{ |
|
|
|
{ |
|
|
|
inputProps, |
|
|
|
inputWithLabelProps, |
|
|
|
inputLabelProps, |
|
|
|
|
|
|
|
selectProps, |
|
|
|
selectProps, |
|
|
|
}: { |
|
|
|
}: { |
|
|
|
inputProps?: Partial<OutlinedInputProps>; |
|
|
|
inputWithLabelProps?: Partial<OutlinedInputWithLabelProps>; |
|
|
|
inputLabelProps?: Partial<OutlinedInputLabelProps>; |
|
|
|
|
|
|
|
selectProps?: Partial<SelectProps>; |
|
|
|
selectProps?: Partial<SelectProps>; |
|
|
|
} = {}, |
|
|
|
} = {}, |
|
|
|
) => ( |
|
|
|
) => ( |
|
|
@ -381,7 +380,14 @@ const createOutlinedInputWithSelect = ( |
|
|
|
}, |
|
|
|
}, |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
<OutlinedInputWithLabel {...{ id, label, inputProps, inputLabelProps }} /> |
|
|
|
<OutlinedInputWithLabel |
|
|
|
|
|
|
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
|
|
|
|
|
|
{...{ |
|
|
|
|
|
|
|
id, |
|
|
|
|
|
|
|
label, |
|
|
|
|
|
|
|
...inputWithLabelProps, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
/> |
|
|
|
{createOutlinedSelect(`${id}-nested-select`, undefined, selectItems, { |
|
|
|
{createOutlinedSelect(`${id}-nested-select`, undefined, selectItems, { |
|
|
|
selectProps, |
|
|
|
selectProps, |
|
|
|
})} |
|
|
|
})} |
|
|
@ -540,9 +546,15 @@ const dSizeToBytes = ( |
|
|
|
value: FormatDataSizeInputValue, |
|
|
|
value: FormatDataSizeInputValue, |
|
|
|
fromUnit: DataSizeUnit, |
|
|
|
fromUnit: DataSizeUnit, |
|
|
|
onSuccess: (newValue: bigint, unit: DataSizeUnit) => void, |
|
|
|
onSuccess: (newValue: bigint, unit: DataSizeUnit) => void, |
|
|
|
|
|
|
|
onFailure?: ( |
|
|
|
|
|
|
|
error?: unknown, |
|
|
|
|
|
|
|
unchangedValue?: string, |
|
|
|
|
|
|
|
unit?: DataSizeUnit, |
|
|
|
|
|
|
|
) => void, |
|
|
|
) => { |
|
|
|
) => { |
|
|
|
dSize(value, { |
|
|
|
dSize(value, { |
|
|
|
fromUnit, |
|
|
|
fromUnit, |
|
|
|
|
|
|
|
onFailure, |
|
|
|
onSuccess: { |
|
|
|
onSuccess: { |
|
|
|
bigint: onSuccess, |
|
|
|
bigint: onSuccess, |
|
|
|
}, |
|
|
|
}, |
|
|
@ -650,6 +662,8 @@ const filterAnvils = ( |
|
|
|
); |
|
|
|
); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type FilterAnvilsParameters = Parameters<typeof filterAnvils>; |
|
|
|
|
|
|
|
|
|
|
|
const filterStorageGroups = ( |
|
|
|
const filterStorageGroups = ( |
|
|
|
organizedStorageGroups: OrganizedStorageGroupMetadataForProvisionServer[], |
|
|
|
organizedStorageGroups: OrganizedStorageGroupMetadataForProvisionServer[], |
|
|
|
virtualDiskSize: bigint, |
|
|
|
virtualDiskSize: bigint, |
|
|
@ -700,7 +714,8 @@ const ProvisionServerDialog = ({ |
|
|
|
const [inputCPUCoresMax, setInputCPUCoresMax] = useState<number>(0); |
|
|
|
const [inputCPUCoresMax, setInputCPUCoresMax] = useState<number>(0); |
|
|
|
|
|
|
|
|
|
|
|
const [memoryValue, setMemoryValue] = useState<bigint>(BIGINT_ZERO); |
|
|
|
const [memoryValue, setMemoryValue] = useState<bigint>(BIGINT_ZERO); |
|
|
|
const [inputMemoryMax, setInputMemoryMax] = useState<bigint>(BIGINT_ZERO); |
|
|
|
const [memoryValueMax, setMemoryValueMax] = useState<bigint>(BIGINT_ZERO); |
|
|
|
|
|
|
|
const [inputMemoryMax, setInputMemoryMax] = useState<string>('0'); |
|
|
|
const [inputMemoryValue, setInputMemoryValue] = useState<string>(''); |
|
|
|
const [inputMemoryValue, setInputMemoryValue] = useState<string>(''); |
|
|
|
const [inputMemoryUnit, setInputMemoryUnit] = useState<DataSizeUnit>('B'); |
|
|
|
const [inputMemoryUnit, setInputMemoryUnit] = useState<DataSizeUnit>('B'); |
|
|
|
|
|
|
|
|
|
|
@ -725,7 +740,12 @@ const ProvisionServerDialog = ({ |
|
|
|
const [anvilValue, setAnvilValue] = useState<string[]>([]); |
|
|
|
const [anvilValue, setAnvilValue] = useState<string[]>([]); |
|
|
|
const [includeAnvilUUIDs, setIncludeAnvilUUIDs] = useState<string[]>([]); |
|
|
|
const [includeAnvilUUIDs, setIncludeAnvilUUIDs] = useState<string[]>([]); |
|
|
|
|
|
|
|
|
|
|
|
const updateLimits = (...args: Parameters<typeof filterAnvils>) => { |
|
|
|
const updateLimits = ( |
|
|
|
|
|
|
|
filterArgs: FilterAnvilsParameters, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
newInputMemoryUnit = inputMemoryUnit, |
|
|
|
|
|
|
|
}: { newInputMemoryUnit?: DataSizeUnit } = {}, |
|
|
|
|
|
|
|
) => { |
|
|
|
const { |
|
|
|
const { |
|
|
|
anvilUUIDs, |
|
|
|
anvilUUIDs, |
|
|
|
fileUUIDs, |
|
|
|
fileUUIDs, |
|
|
@ -733,15 +753,48 @@ const ProvisionServerDialog = ({ |
|
|
|
maxMemory, |
|
|
|
maxMemory, |
|
|
|
maxVirtualDiskSize, |
|
|
|
maxVirtualDiskSize, |
|
|
|
storageGroupUUIDs, |
|
|
|
storageGroupUUIDs, |
|
|
|
} = filterAnvils(...args); |
|
|
|
} = filterAnvils(...filterArgs); |
|
|
|
|
|
|
|
|
|
|
|
setInputCPUCoresMax(maxCPUCores); |
|
|
|
setInputCPUCoresMax(maxCPUCores); |
|
|
|
setInputMemoryMax(maxMemory); |
|
|
|
setMemoryValueMax(maxMemory); |
|
|
|
setInputVirtualDiskSizeMax(maxVirtualDiskSize); |
|
|
|
setInputVirtualDiskSizeMax(maxVirtualDiskSize); |
|
|
|
|
|
|
|
|
|
|
|
setIncludeAnvilUUIDs(anvilUUIDs); |
|
|
|
setIncludeAnvilUUIDs(anvilUUIDs); |
|
|
|
setIncludeFileUUIDs(fileUUIDs); |
|
|
|
setIncludeFileUUIDs(fileUUIDs); |
|
|
|
setIncludeStorageGroupUUIDs(storageGroupUUIDs); |
|
|
|
setIncludeStorageGroupUUIDs(storageGroupUUIDs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dSize(maxMemory, { |
|
|
|
|
|
|
|
fromUnit: 'B', |
|
|
|
|
|
|
|
onSuccess: { |
|
|
|
|
|
|
|
string: (value) => setInputMemoryMax(value), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
toUnit: newInputMemoryUnit, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const memorizedUpdateLimit = useCallback(updateLimits, [inputMemoryUnit]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleInputMemoryValueChange = (value: string) => { |
|
|
|
|
|
|
|
setInputMemoryValue(value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const filterArgs: FilterAnvilsParameters = [ |
|
|
|
|
|
|
|
allAnvils, |
|
|
|
|
|
|
|
cpuCoresValue, |
|
|
|
|
|
|
|
BIGINT_ZERO, |
|
|
|
|
|
|
|
[installISOFileUUID, driverISOFileUUID], |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dSizeToBytes( |
|
|
|
|
|
|
|
value, |
|
|
|
|
|
|
|
inputMemoryUnit, |
|
|
|
|
|
|
|
(convertedMemoryValue) => { |
|
|
|
|
|
|
|
setMemoryValue(convertedMemoryValue); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filterArgs[2] = convertedMemoryValue; |
|
|
|
|
|
|
|
updateLimits(filterArgs); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
() => updateLimits(filterArgs), |
|
|
|
|
|
|
|
); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
@ -764,7 +817,7 @@ const ProvisionServerDialog = ({ |
|
|
|
setFileSelectItems(localFileSelectItems); |
|
|
|
setFileSelectItems(localFileSelectItems); |
|
|
|
setStorageGroupSelectItems(localStorageGroupSelectItems); |
|
|
|
setStorageGroupSelectItems(localStorageGroupSelectItems); |
|
|
|
|
|
|
|
|
|
|
|
updateLimits(localAllAnvils, 0, BIGINT_ZERO, []); |
|
|
|
memorizedUpdateLimit([localAllAnvils, 0, BIGINT_ZERO, []]); |
|
|
|
|
|
|
|
|
|
|
|
setOSAutocompleteOptions( |
|
|
|
setOSAutocompleteOptions( |
|
|
|
data.osList.map((keyValuePair) => { |
|
|
|
data.osList.map((keyValuePair) => { |
|
|
@ -776,7 +829,7 @@ const ProvisionServerDialog = ({ |
|
|
|
}; |
|
|
|
}; |
|
|
|
}), |
|
|
|
}), |
|
|
|
); |
|
|
|
); |
|
|
|
}, []); |
|
|
|
}, [memorizedUpdateLimit]); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<Dialog |
|
|
|
<Dialog |
|
|
@ -797,6 +850,7 @@ const ProvisionServerDialog = ({ |
|
|
|
flexDirection: 'column', |
|
|
|
flexDirection: 'column', |
|
|
|
maxHeight: '50vh', |
|
|
|
maxHeight: '50vh', |
|
|
|
overflowY: 'scroll', |
|
|
|
overflowY: 'scroll', |
|
|
|
|
|
|
|
paddingTop: '.6em', |
|
|
|
|
|
|
|
|
|
|
|
'& > :not(:first-child)': { |
|
|
|
'& > :not(:first-child)': { |
|
|
|
marginTop: '1em', |
|
|
|
marginTop: '1em', |
|
|
@ -811,9 +865,11 @@ const ProvisionServerDialog = ({ |
|
|
|
|
|
|
|
|
|
|
|
setCPUCoresValue(newCPUCoresValue); |
|
|
|
setCPUCoresValue(newCPUCoresValue); |
|
|
|
|
|
|
|
|
|
|
|
updateLimits(allAnvils, newCPUCoresValue, memoryValue, [ |
|
|
|
updateLimits([ |
|
|
|
installISOFileUUID, |
|
|
|
allAnvils, |
|
|
|
driverISOFileUUID, |
|
|
|
newCPUCoresValue, |
|
|
|
|
|
|
|
memoryValue, |
|
|
|
|
|
|
|
[installISOFileUUID, driverISOFileUUID], |
|
|
|
]); |
|
|
|
]); |
|
|
|
}, |
|
|
|
}, |
|
|
|
max: inputCPUCoresMax, |
|
|
|
max: inputCPUCoresMax, |
|
|
@ -821,42 +877,56 @@ const ProvisionServerDialog = ({ |
|
|
|
}, |
|
|
|
}, |
|
|
|
})} |
|
|
|
})} |
|
|
|
<BodyText |
|
|
|
<BodyText |
|
|
|
text={`Memory: ${memoryValue.toString()}, Max: ${inputMemoryMax.toString()}`} |
|
|
|
text={`Memory: ${memoryValue.toString()}, Max: ${memoryValueMax.toString()}`} |
|
|
|
/> |
|
|
|
/> |
|
|
|
{createOutlinedInputWithSelect('ps-memory', 'Memory', DATA_SIZE_UNITS, { |
|
|
|
{createOutlinedInputWithSelect('ps-memory', 'Memory', DATA_SIZE_UNITS, { |
|
|
|
|
|
|
|
inputWithLabelProps: { |
|
|
|
inputProps: { |
|
|
|
inputProps: { |
|
|
|
type: 'number', |
|
|
|
endAdornment: ( |
|
|
|
|
|
|
|
<ContainedButton |
|
|
|
|
|
|
|
onClick={() => handleInputMemoryValueChange(inputMemoryMax)} |
|
|
|
|
|
|
|
sx={{ |
|
|
|
|
|
|
|
marginLeft: '14px', |
|
|
|
|
|
|
|
minWidth: 'unset', |
|
|
|
|
|
|
|
whiteSpace: 'nowrap', |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
>{`Max: ${inputMemoryMax} ${inputMemoryUnit}`}</ContainedButton> |
|
|
|
|
|
|
|
), |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
setInputMemoryValue(value); |
|
|
|
handleInputMemoryValueChange(value); |
|
|
|
|
|
|
|
|
|
|
|
dSizeToBytes(value, inputMemoryUnit, (convertedMemoryValue) => { |
|
|
|
|
|
|
|
setMemoryValue(convertedMemoryValue); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateLimits(allAnvils, cpuCoresValue, convertedMemoryValue, [ |
|
|
|
|
|
|
|
installISOFileUUID, |
|
|
|
|
|
|
|
driverISOFileUUID, |
|
|
|
|
|
|
|
]); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
type: 'number', |
|
|
|
value: inputMemoryValue, |
|
|
|
value: inputMemoryValue, |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
selectProps: { |
|
|
|
selectProps: { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
const selectedUnit = value as DataSizeUnit; |
|
|
|
const selectedUnit = value as DataSizeUnit; |
|
|
|
|
|
|
|
|
|
|
|
setInputMemoryUnit(selectedUnit); |
|
|
|
setInputMemoryUnit(selectedUnit); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const filterArgs: FilterAnvilsParameters = [ |
|
|
|
|
|
|
|
allAnvils, |
|
|
|
|
|
|
|
cpuCoresValue, |
|
|
|
|
|
|
|
BIGINT_ZERO, |
|
|
|
|
|
|
|
[installISOFileUUID, driverISOFileUUID], |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
dSizeToBytes( |
|
|
|
dSizeToBytes( |
|
|
|
inputMemoryValue, |
|
|
|
inputMemoryValue, |
|
|
|
selectedUnit, |
|
|
|
selectedUnit, |
|
|
|
(convertedMemoryValue) => { |
|
|
|
(convertedMemoryValue) => { |
|
|
|
setMemoryValue(convertedMemoryValue); |
|
|
|
setMemoryValue(convertedMemoryValue); |
|
|
|
|
|
|
|
|
|
|
|
updateLimits(allAnvils, cpuCoresValue, convertedMemoryValue, [ |
|
|
|
filterArgs[2] = convertedMemoryValue; |
|
|
|
installISOFileUUID, |
|
|
|
updateLimits(filterArgs, { |
|
|
|
driverISOFileUUID, |
|
|
|
newInputMemoryUnit: selectedUnit, |
|
|
|
]); |
|
|
|
}); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
() => |
|
|
|
|
|
|
|
updateLimits(filterArgs, { |
|
|
|
|
|
|
|
newInputMemoryUnit: selectedUnit, |
|
|
|
|
|
|
|
}), |
|
|
|
); |
|
|
|
); |
|
|
|
}, |
|
|
|
}, |
|
|
|
value: inputMemoryUnit, |
|
|
|
value: inputMemoryUnit, |
|
|
@ -870,8 +940,8 @@ const ProvisionServerDialog = ({ |
|
|
|
'Virtual disk size', |
|
|
|
'Virtual disk size', |
|
|
|
DATA_SIZE_UNITS, |
|
|
|
DATA_SIZE_UNITS, |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
inputWithLabelProps: { |
|
|
|
inputProps: { |
|
|
|
inputProps: { |
|
|
|
type: 'number', |
|
|
|
|
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
setInputVirtualDiskSizeValue(value); |
|
|
|
setInputVirtualDiskSizeValue(value); |
|
|
|
|
|
|
|
|
|
|
@ -881,8 +951,10 @@ const ProvisionServerDialog = ({ |
|
|
|
setVirtualDiskSizeValue, |
|
|
|
setVirtualDiskSizeValue, |
|
|
|
); |
|
|
|
); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
type: 'number', |
|
|
|
value: inputVirtualDiskSizeValue, |
|
|
|
value: inputVirtualDiskSizeValue, |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
selectProps: { |
|
|
|
selectProps: { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
onChange: ({ target: { value } }) => { |
|
|
|
const selectedUnit = value as DataSizeUnit; |
|
|
|
const selectedUnit = value as DataSizeUnit; |
|
|
@ -930,9 +1002,11 @@ const ProvisionServerDialog = ({ |
|
|
|
|
|
|
|
|
|
|
|
setInstallISOFileUUID(newInstallISOFileUUID); |
|
|
|
setInstallISOFileUUID(newInstallISOFileUUID); |
|
|
|
|
|
|
|
|
|
|
|
updateLimits(allAnvils, cpuCoresValue, memoryValue, [ |
|
|
|
updateLimits([ |
|
|
|
newInstallISOFileUUID, |
|
|
|
allAnvils, |
|
|
|
driverISOFileUUID, |
|
|
|
cpuCoresValue, |
|
|
|
|
|
|
|
memoryValue, |
|
|
|
|
|
|
|
[newInstallISOFileUUID, driverISOFileUUID], |
|
|
|
]); |
|
|
|
]); |
|
|
|
}, |
|
|
|
}, |
|
|
|
value: installISOFileUUID, |
|
|
|
value: installISOFileUUID, |
|
|
@ -951,9 +1025,11 @@ const ProvisionServerDialog = ({ |
|
|
|
|
|
|
|
|
|
|
|
setDriverISOFileUUID(newDriverISOFileUUID); |
|
|
|
setDriverISOFileUUID(newDriverISOFileUUID); |
|
|
|
|
|
|
|
|
|
|
|
updateLimits(allAnvils, cpuCoresValue, memoryValue, [ |
|
|
|
updateLimits([ |
|
|
|
installISOFileUUID, |
|
|
|
allAnvils, |
|
|
|
newDriverISOFileUUID, |
|
|
|
cpuCoresValue, |
|
|
|
|
|
|
|
memoryValue, |
|
|
|
|
|
|
|
[installISOFileUUID, newDriverISOFileUUID], |
|
|
|
]); |
|
|
|
]); |
|
|
|
}, |
|
|
|
}, |
|
|
|
value: driverISOFileUUID, |
|
|
|
value: driverISOFileUUID, |
|
|
|