import { unset } from 'lodash'; import React from 'react'; import type { Option } from 'react-select'; import Select from 'react-select'; import type { IDeploymentStrategy, IDeploymentStrategyAdditionalFieldsProps } from './deploymentStrategy.registry'; import { DeploymentStrategyRegistry } from './deploymentStrategy.registry'; import { HelpField } from '../help/HelpField'; import { Markdown } from '../presentation'; import type { IServerGroupCommand } from '../serverGroup'; export interface IDeploymentStrategySelectorProps { command: IServerGroupCommand; onFieldChange: (key: string, value: any) => void; onStrategyChange: (command: IServerGroupCommand, strategy: IDeploymentStrategy) => void; labelColumns?: string; fieldColumns?: string; } export interface IDeploymentStrategySelectorState { strategies: IDeploymentStrategy[]; currentStrategy: string; AdditionalFieldsComponent: React.ComponentType; } export class DeploymentStrategySelector extends React.Component< IDeploymentStrategySelectorProps, IDeploymentStrategySelectorState > { public static defaultProps: Partial = { fieldColumns: '7', labelColumns: '3', }; public state: IDeploymentStrategySelectorState = { strategies: DeploymentStrategyRegistry.listStrategies( this.props.command.selectedProvider || this.props.command.cloudProvider, ), currentStrategy: null, AdditionalFieldsComponent: undefined, }; public selectStrategy(strategy: string, onMount = false): void { const { command, onStrategyChange } = this.props; const oldStrategy = DeploymentStrategyRegistry.getStrategy(this.state.currentStrategy); const newStrategy = DeploymentStrategyRegistry.getStrategy(strategy); if (oldStrategy && oldStrategy.additionalFields) { oldStrategy.additionalFields.forEach((field) => { if (!newStrategy || !newStrategy.additionalFields || !newStrategy.additionalFields.includes(field)) { unset(command, field); } }); } let AdditionalFieldsComponent; if (newStrategy) { AdditionalFieldsComponent = newStrategy.AdditionalFieldsComponent; // do not run on mount otherwise we'll confusingly fill in things that weren't there if (newStrategy.initializationMethod && !onMount) { newStrategy.initializationMethod(command); } } // Usage of the angular do not have an onStrategyChange and simply expect command.strategy to be updated // This was previously done by command.strategy = strategy; if (onStrategyChange && newStrategy) { onStrategyChange(command, newStrategy); } this.setState({ currentStrategy: strategy, AdditionalFieldsComponent }); } public strategyChanged = (option: Option) => { this.selectStrategy(option.key); }; public componentDidMount() { this.selectStrategy(this.props.command.strategy, true); } public render() { const { command, fieldColumns, labelColumns, onFieldChange } = this.props; const { AdditionalFieldsComponent, currentStrategy, strategies } = this.state; const hasAdditionalFields = Boolean(AdditionalFieldsComponent); if (strategies && strategies.length) { return (
Strategy