import React from 'react'; import { Button, Modal } from 'react-bootstrap'; import type { ILoadBalancerIncompatibility, ILoadBalancerModalProps } from '@spinnaker/core'; import { CloudProviderRegistry, Markdown, ModalClose, noop, ReactModal } from '@spinnaker/core'; import type { IAmazonLoadBalancerConfig } from './LoadBalancerTypes'; import { LoadBalancerTypes } from './LoadBalancerTypes'; import { AWSProviderSettings } from '../../aws.settings'; export interface IAmazonLoadBalancerChoiceModalState { choices: IAmazonLoadBalancerConfig[]; selectedChoice: IAmazonLoadBalancerConfig; } export class AmazonLoadBalancerChoiceModal extends React.Component< ILoadBalancerModalProps, IAmazonLoadBalancerChoiceModalState > { public static defaultProps: Partial = { closeModal: noop, dismissModal: noop, }; public static show(props: ILoadBalancerModalProps): Promise { return ReactModal.show( AmazonLoadBalancerChoiceModal, { ...props, className: 'create-pipeline-modal-overflow-visible modal-lg', }, { bsSize: 'lg' }, ); } constructor(props: ILoadBalancerModalProps) { super(props); this.state = { choices: LoadBalancerTypes, selectedChoice: LoadBalancerTypes[0], }; } public choiceSelected(choice: IAmazonLoadBalancerConfig): void { this.setState({ selectedChoice: choice }); } private choose = (): void => { const { children, ...loadBalancerProps } = this.props; this.close(); this.state.selectedChoice.component .show(loadBalancerProps) .then((loadBalancer) => { this.props.closeModal(loadBalancer); }) .catch(() => {}); }; public close = (reason?: any): void => { this.props.dismissModal(reason); }; private getIncompatibility(choice: IAmazonLoadBalancerConfig, cloudProvider: string): ILoadBalancerIncompatibility { const { loadBalancer = {} } = CloudProviderRegistry.getProvider(cloudProvider); const { incompatibleLoadBalancerTypes = [], }: { incompatibleLoadBalancerTypes: ILoadBalancerIncompatibility[] } = loadBalancer; return incompatibleLoadBalancerTypes.find((lb) => lb.type === choice.type); } private isIncompatibleWithAllProviders(choice: IAmazonLoadBalancerConfig) { const { app: { attributes }, } = this.props; const { cloudProviders = [] }: { cloudProviders: string[] } = attributes; if (cloudProviders.length > 0) { return cloudProviders.every((cloudProvider: string) => !!this.getIncompatibility(choice, cloudProvider)); } // If the list of cloud providers is empty, assume it is compatible by default return false; } public render() { const { app: { attributes }, } = this.props; const { cloudProviders = [] }: { cloudProviders: string[] } = attributes; const { choices, selectedChoice } = this.state; // Remove any choices that are not compatible with all configured cloud providers const filteredChoices = choices.filter((choice) => !this.isIncompatibleWithAllProviders(choice)); // Compute incompatibilities with the current selected choice so we can display a warning const incompatibilities: ILoadBalancerIncompatibility[] = cloudProviders .map((cloudProvider) => this.getIncompatibility(selectedChoice, cloudProvider)) .filter((x: ILoadBalancerIncompatibility) => x); const loadBalancerWarning = AWSProviderSettings.createLoadBalancerWarnings && AWSProviderSettings.createLoadBalancerWarnings[selectedChoice.type]; return ( <> Select Type of Load Balancer
{filteredChoices.map((choice) => (
this.choiceSelected(choice)} >

{choice.label}

({choice.sublabel})

{choice.description}
))}
<> {incompatibilities.length > 0 && incompatibilities.map((incompatibility) => (

{incompatibility.reason}

))} {!!loadBalancerWarning && (

)}
); } }