in frontend/src/old-pages/Configure/Queues/Queues.tsx [369:707]
function Queue({index}: any) {
const {t} = useTranslation()
const queues = useState(queuesPath)
const {maxQueues, maxCRPerCluster} = useClusterResourcesLimits()
const computeResourceAdapter = useComputeResourceAdapter()
const queue = useState([...queuesPath, index])
const enablePlacementGroupPath = React.useMemo(
() => [...queuesPath, index, 'Networking', 'PlacementGroup', 'Enabled'],
[index],
)
const enablePlacementGroup = useState(enablePlacementGroupPath)
const isMultiInstanceTypesActive = useFeatureFlag(
'queues_multiple_instance_types',
)
const allocationStrategyOptions = useAllocationStrategyOptions()
const errorsPath = [...queuesErrorsPath, index]
const subnetError = useState([...errorsPath, 'subnet'])
const nameError = useState([...errorsPath, 'name'])
const allocationStrategyPath = React.useMemo(
() => [...queuesPath, index, 'AllocationStrategy'],
[index],
)
const allocationStrategy: AllocationStrategy = useState(allocationStrategyPath)
const capacityTypes: [string, string, string][] = [
['ONDEMAND', 'On-Demand', '/pcui/img/od.svg'],
['SPOT', 'Spot', '/pcui/img/spot.svg'],
['CAPACITY_BLOCK', 'Capacity Block', '/pcui/img/cb.svg'],
]
const capacityTypePath = [...queuesPath, index, 'CapacityType']
const capacityType: string = useState(capacityTypePath) || 'ONDEMAND'
const subnetPath = [...queuesPath, index, 'Networking', 'SubnetIds']
const subnetsList = useState(subnetPath) || []
const isMultiAZActive = useFeatureFlag('multi_az')
React.useEffect(() => {
if (capacityType === 'CAPACITY_BLOCK') {
clearState(allocationStrategyPath)
}
}, [capacityType])
const remove = () => {
setState(
[...queuesPath],
[...queues.slice(0, index), ...queues.slice(index + 1)],
)
}
const setEnablePG = React.useCallback(
(enable: any) => {
setState(enablePlacementGroupPath, enable)
},
[enablePlacementGroupPath],
)
const onSubnetMultiSelectChange: NonCancelableEventHandler<MultiselectProps.MultiselectChangeDetail> =
React.useCallback(
({detail}) => {
setSubnetsAndValidate(index, queueValidate, detail)
},
[index],
)
const onSubnetSelectChange = React.useCallback(
(subnetId: string) => {
setState(subnetPath, [subnetId])
queueValidate(index)
},
[subnetPath, index],
)
const {canUseEFA, canUsePlacementGroup} = areMultiAZSelected(subnetsList)
React.useEffect(() => {
if (!canUsePlacementGroup) {
setEnablePG(false)
}
}, [canUsePlacementGroup, setEnablePG])
const renameQueue = (newName: any) => {
const computeResources = getState([
...queuesPath,
index,
'ComputeResources',
])
const updatedCRs = computeResourceAdapter.updateComputeResourcesNames(
computeResources,
newName,
)
setState([...queuesPath, index, 'Name'], newName)
setState([...queuesPath, index, 'ComputeResources'], updatedCRs)
}
const setAllocationStrategy = React.useCallback(
({detail}) => {
setState(
allocationStrategyPath,
detail.selectedOption.value,
)
},
[allocationStrategyPath],
)
const defaultAllocationStrategy = useDefaultAllocationStrategy()
const addQueue = () => {
const queueName = `queue-${queues.length + 1}`
setState(
[...queuesPath],
[
...(queues || []),
{
Name: queueName,
...defaultAllocationStrategy,
ComputeResources: [
computeResourceAdapter.createComputeResource(queueName, 0),
],
},
],
)
}
const purchaseTypeFooterLinks = React.useMemo(
() => [
{
title: t('wizard.queues.purchaseType.helpPanel.link.title'),
href: t('wizard.queues.purchaseType.helpPanel.link.href'),
},
],
[t],
)
const allocationStrategyFooterLinks = React.useMemo(
() => [
{
title: t('wizard.queues.allocationStrategy.helpPanel.link.title'),
href: t('wizard.queues.allocationStrategy.helpPanel.link.href'),
},
],
[t],
)
const totalComputeResources = React.useMemo(
() =>
queues
.map((queue: Queue) => queue.ComputeResources.length)
.reduce(
(total: number, computeResources: number) => total + computeResources,
0,
),
[queues],
)
const canAddQueue =
queues.length < maxQueues && totalComputeResources < maxCRPerCluster
return (
<Container
header={
<Header
variant="h2"
actions={
<SpaceBetween direction="horizontal" size="xs">
<Button disabled={!canAddQueue} onClick={addQueue}>
{t('wizard.queues.addQueueButton.label')}
</Button>
{queues.length > 1 && (
<Button onClick={remove}>
{t('wizard.queues.removeQueueButton.label')}
</Button>
)}
</SpaceBetween>
}
>
{t('wizard.queues.container.title', {
index: index + 1,
queueName: queue.Name,
})}
</Header>
}
footer={
<ExpandableSection
headerText={t('wizard.queues.advancedOptions.label')}
variant="footer"
>
<SpaceBetween direction="vertical" size="xs">
<FormField label={t('wizard.queues.securityGroups.label')}>
<SecurityGroups basePath={[...queuesPath, index]} />
</FormField>
<CustomAMISettings
basePath={[...queuesPath, index]}
appPath={['app', 'wizard', 'queues', index]}
errorsPath={errorsPath}
validate={queuesValidate}
/>
<Header variant="h3">
{t('wizard.queues.advancedOptions.scripts.title')}
</Header>
<ActionsEditor
basePath={[...queuesPath, index]}
errorsPath={errorsPath}
/>
<Header variant="h3">
{t('wizard.queues.advancedOptions.rootVolume.title')}
</Header>
<RootVolume
basePath={[...queuesPath, index, 'ComputeSettings']}
errorsPath={errorsPath}
/>
<Header variant="h3">
{t('wizard.queues.advancedOptions.iamPolicies.label')}
</Header>
<IamPoliciesEditor basePath={[...queuesPath, index]} />
</SpaceBetween>
</ExpandableSection>
}
>
<SpaceBetween direction="vertical" size="s">
<ColumnLayout borders="horizontal">
<SpaceBetween direction="vertical" size="m">
<ColumnLayout columns={2}>
<FormField
label={t('wizard.queues.name.label')}
errorText={nameError}
>
<Input
value={queue.Name}
placeholder={t('wizard.queues.name.placeholder')}
onKeyDown={e => {
if (e.detail.key === 'Enter' || e.detail.key === 'Escape') {
e.stopPropagation()
queueValidate(index)
}
}}
onChange={({detail}) => renameQueue(detail.value)}
/>
</FormField>
</ColumnLayout>
<ColumnLayout columns={2}>
<FormField
label={
isMultiAZActive
? t('wizard.queues.subnet.label.multiple')
: t('wizard.queues.subnet.label.single')
}
errorText={subnetError}
>
{isMultiAZActive ? (
<SubnetMultiSelect
value={subnetsList}
onChange={onSubnetMultiSelectChange}
/>
) : (
<SubnetSelect
value={subnetsList[0]}
onChange={onSubnetSelectChange}
/>
)}
</FormField>
<Checkbox
checked={enablePlacementGroup}
disabled={!canUsePlacementGroup}
onChange={_e => {
setEnablePG(!enablePlacementGroup)
}}
>
<Trans i18nKey="wizard.queues.placementGroup.label" />
</Checkbox>
<FormField
label={t('wizard.queues.purchaseType.label')}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.queues.purchaseType.helpPanel.title')}
description={t(
'wizard.queues.purchaseType.helpPanel.description',
)}
footerLinks={purchaseTypeFooterLinks}
/>
}
/>
}
>
<Select
selectedOption={itemToOption(
findFirst(capacityTypes, x => x[0] === capacityType) || [
'',
'',
],
)}
onChange={({detail}) => {
setState(capacityTypePath, detail.selectedOption.value)
}}
options={capacityTypes.map(itemToOption)}
/>
</FormField>
{/* If the type is CAPACITY_BLOCK, do not display the AllocationStrategy */}
{isMultiInstanceTypesActive && capacityType !== 'CAPACITY_BLOCK' ? (
<FormField
label={t('wizard.queues.allocationStrategy.title')}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t(
'wizard.queues.allocationStrategy.helpPanel.title',
)}
description={t(
'wizard.queues.allocationStrategy.helpPanel.description',
)}
footerLinks={allocationStrategyFooterLinks}
/>
}
/>
}
>
<Select
options={allocationStrategyOptions}
selectedOption={
allocationStrategyOptions.find(
as => as.value === allocationStrategy,
)!
}
onChange={setAllocationStrategy}
/>
</FormField>
) : null}
</ColumnLayout>
</SpaceBetween>
<ComputeResources queue={queue} index={index} canUseEFA={canUseEFA} />
</ColumnLayout>
</SpaceBetween>
</Container>
)
}