@spinnaker/ecs 2026.2.2 → 2026.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/dist/ecs.module.d.ts +3 -1
  2. package/dist/ecsCluster/ecsCluster.read.service.d.ts +2 -3
  3. package/dist/iamRoles/iamRole.read.service.d.ts +1 -2
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/instance/details/EcsInstanceDetails.d.ts +50 -0
  8. package/dist/loadBalancer/loadBalancer.transformer.d.ts +1 -5
  9. package/dist/loadBalancer/targetGroup.states.d.ts +2 -1
  10. package/dist/metricAlarm/metricAlarm.read.service.d.ts +1 -2
  11. package/dist/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.d.ts +1 -0
  12. package/dist/pipeline/stages/common/EcsServerGroupStepLabel.d.ts +7 -0
  13. package/dist/pipeline/stages/common/EcsStageConfigs.d.ts +11 -0
  14. package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +1 -2
  15. package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +1 -2
  16. package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +1 -2
  17. package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +1 -2
  18. package/dist/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.d.ts +5 -0
  19. package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +1 -2
  20. package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +1 -2
  21. package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +1 -2
  22. package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +1 -2
  23. package/dist/placementStrategy/placementStrategy.service.d.ts +0 -1
  24. package/dist/secrets/secret.read.service.d.ts +1 -2
  25. package/dist/securityGroup/details/EcsSecurityGroupDetails.d.ts +45 -0
  26. package/dist/securityGroup/securityGroup.reader.d.ts +0 -1
  27. package/dist/securityGroup/securityGroup.transformer.d.ts +3 -2
  28. package/dist/serverGroup/configure/dockerImage.util.d.ts +3 -0
  29. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +111 -2
  30. package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +13 -63
  31. package/dist/serverGroup/configure/wizard/EcsCloneServerGroupModal.d.ts +64 -0
  32. package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +29 -4
  33. package/dist/serverGroup/configure/wizard/container/Container.d.ts +3 -3
  34. package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +3 -3
  35. package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
  36. package/dist/serverGroup/configure/wizard/pages/BasicSettings.d.ts +3 -0
  37. package/dist/serverGroup/configure/wizard/pages/ContainerSettings.d.ts +3 -0
  38. package/dist/serverGroup/configure/wizard/pages/HorizontalScalingSettings.d.ts +3 -0
  39. package/dist/serverGroup/configure/wizard/pages/LoggingSettings.d.ts +3 -0
  40. package/dist/serverGroup/configure/wizard/pages/NetworkingSettings.d.ts +3 -0
  41. package/dist/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.d.ts +3 -0
  42. package/dist/serverGroup/configure/wizard/pages/TaskDefinitionSettings.d.ts +3 -0
  43. package/dist/serverGroup/configure/wizard/pages/common.d.ts +8 -0
  44. package/dist/serverGroup/configure/wizard/pages/validation.d.ts +22 -0
  45. package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +5 -3
  46. package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +3 -3
  47. package/dist/serverGroup/details/EcsServerGroupActions.d.ts +6 -0
  48. package/dist/serverGroup/details/ecsServerGroupDetailsGetter.d.ts +3 -0
  49. package/dist/serverGroup/details/resize/EcsResizeServerGroupModal.d.ts +43 -0
  50. package/dist/serverGroup/details/resize/index.d.ts +1 -0
  51. package/dist/serverGroup/details/rollback/EcsRollbackServerGroupModal.d.ts +46 -0
  52. package/dist/serverGroup/details/rollback/index.d.ts +1 -0
  53. package/dist/serverGroup/details/sections/EcsServerGroupDetailsSections.d.ts +9 -0
  54. package/dist/serverGroup/details/sections/EcsServerGroupEventsSection.d.ts +3 -0
  55. package/dist/serverGroup/details/sections/EcsServerGroupInformationSection.d.ts +3 -0
  56. package/dist/serverGroup/events/EcsServerGroupEventsModal.d.ts +22 -0
  57. package/dist/serverGroup/events/EventsLink.d.ts +2 -0
  58. package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +1 -1
  59. package/dist/serverGroup/serverGroup.transformer.d.ts +1 -2
  60. package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +1 -1
  61. package/package.json +3 -9
  62. package/src/ecs.module.spec.ts +86 -0
  63. package/src/ecs.module.ts +68 -84
  64. package/src/ecsCluster/ecsCluster.read.service.ts +3 -9
  65. package/src/iamRoles/iamRole.read.service.ts +1 -7
  66. package/src/index.ts +6 -0
  67. package/src/instance/details/EcsInstanceDetails.spec.tsx +426 -0
  68. package/src/instance/details/EcsInstanceDetails.tsx +474 -0
  69. package/src/loadBalancer/details/loadBalancerDetails.tsx +1 -1
  70. package/src/loadBalancer/details/targetGroupDetails.tsx +1 -1
  71. package/src/loadBalancer/loadBalancer.transformer.ts +2 -7
  72. package/src/loadBalancer/targetGroup.states.ts +55 -53
  73. package/src/metricAlarm/metricAlarm.read.service.ts +1 -7
  74. package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +22 -94
  75. package/src/pipeline/stages/common/EcsServerGroupStepLabel.tsx +16 -0
  76. package/src/pipeline/stages/common/EcsStageConfigs.tsx +587 -0
  77. package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +29 -65
  78. package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +27 -70
  79. package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +21 -84
  80. package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +22 -73
  81. package/src/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.tsx +40 -0
  82. package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +12 -24
  83. package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +30 -128
  84. package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +24 -78
  85. package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +19 -73
  86. package/src/placementStrategy/placementStrategy.service.ts +0 -6
  87. package/src/secrets/secret.read.service.ts +1 -7
  88. package/src/securityGroup/details/EcsSecurityGroupDetails.spec.tsx +245 -0
  89. package/src/securityGroup/details/EcsSecurityGroupDetails.tsx +285 -0
  90. package/src/securityGroup/securityGroup.reader.ts +0 -5
  91. package/src/securityGroup/securityGroup.transformer.js +5 -13
  92. package/src/serverGroup/configure/dockerImage.util.ts +29 -0
  93. package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +215 -278
  94. package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.ts +83 -0
  95. package/src/serverGroup/configure/serverGroupConfiguration.service.ts +16 -633
  96. package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.spec.tsx +2078 -0
  97. package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.tsx +712 -0
  98. package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +98 -49
  99. package/src/serverGroup/configure/wizard/container/Container.spec.tsx +20 -8
  100. package/src/serverGroup/configure/wizard/container/Container.tsx +53 -24
  101. package/src/serverGroup/configure/wizard/networking/Networking.tsx +60 -38
  102. package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +290 -0
  103. package/src/serverGroup/configure/wizard/pages/BasicSettings.tsx +101 -0
  104. package/src/serverGroup/configure/wizard/pages/ContainerSettings.tsx +10 -0
  105. package/src/serverGroup/configure/wizard/pages/HorizontalScalingSettings.tsx +137 -0
  106. package/src/serverGroup/configure/wizard/pages/LoggingSettings.tsx +60 -0
  107. package/src/serverGroup/configure/wizard/pages/NetworkingSettings.tsx +10 -0
  108. package/src/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.tsx +10 -0
  109. package/src/serverGroup/configure/wizard/pages/TaskDefinitionSettings.tsx +59 -0
  110. package/src/serverGroup/configure/wizard/pages/common.ts +10 -0
  111. package/src/serverGroup/configure/wizard/pages/validation.tsx +190 -0
  112. package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +83 -34
  113. package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.spec.tsx +21 -8
  114. package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +63 -33
  115. package/src/serverGroup/details/EcsServerGroupActions.spec.tsx +244 -0
  116. package/src/serverGroup/details/EcsServerGroupActions.tsx +152 -0
  117. package/src/serverGroup/details/ecsServerGroupDetailsGetter.spec.ts +110 -0
  118. package/src/serverGroup/details/ecsServerGroupDetailsGetter.ts +73 -0
  119. package/src/serverGroup/details/resize/EcsResizeServerGroupModal.spec.tsx +130 -0
  120. package/src/serverGroup/details/resize/EcsResizeServerGroupModal.tsx +263 -0
  121. package/src/serverGroup/details/resize/index.ts +1 -0
  122. package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.spec.tsx +173 -0
  123. package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.tsx +285 -0
  124. package/src/serverGroup/details/rollback/index.ts +1 -0
  125. package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.spec.tsx +130 -0
  126. package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.tsx +172 -0
  127. package/src/serverGroup/details/sections/EcsServerGroupEventsSection.tsx +14 -0
  128. package/src/serverGroup/details/sections/EcsServerGroupInformationSection.tsx +25 -0
  129. package/src/serverGroup/events/EcsServerGroupEventsModal.spec.tsx +109 -0
  130. package/src/serverGroup/events/EcsServerGroupEventsModal.tsx +112 -0
  131. package/src/serverGroup/events/EventsLink.tsx +18 -0
  132. package/src/serverGroup/events/serverGroupEventsReader.service.spec.ts +41 -0
  133. package/src/serverGroup/events/serverGroupEventsReader.service.ts +2 -8
  134. package/src/serverGroup/serverGroup.transformer.spec.ts +10 -24
  135. package/src/serverGroup/serverGroup.transformer.ts +1 -5
  136. package/src/serviceDiscovery/serviceDiscovery.read.service.ts +1 -1
  137. package/dist/common/common.module.d.ts +0 -1
  138. package/dist/common/footer.component.d.ts +0 -1
  139. package/dist/instance/details/instance.details.controller.d.ts +0 -2
  140. package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
  141. package/dist/securityGroup/securityGroup.module.d.ts +0 -1
  142. package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +0 -2
  143. package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +0 -2
  144. package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +0 -2
  145. package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +0 -2
  146. package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +0 -1
  147. package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +0 -1
  148. package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +0 -2
  149. package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +0 -2
  150. package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +0 -2
  151. package/dist/serverGroup/details/serverGroupDetails.module.d.ts +0 -1
  152. package/dist/serverGroup/events/events.component.d.ts +0 -3
  153. package/dist/serverGroup/events/events.controller.d.ts +0 -19
  154. package/dist/serverGroup/serverGroup.module.d.ts +0 -1
  155. package/src/common/common.module.ts +0 -6
  156. package/src/common/footer.component.ts +0 -29
  157. package/src/instance/details/instance.details.controller.js +0 -356
  158. package/src/instance/details/instanceDetails.html +0 -204
  159. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +0 -101
  160. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +0 -1
  161. package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
  162. package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
  163. package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
  164. package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
  165. package/src/pipeline/stages/disableCluster/disableClusterStage.html +0 -26
  166. package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
  167. package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
  168. package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +0 -36
  169. package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +0 -9
  170. package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +0 -87
  171. package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +0 -1
  172. package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +0 -35
  173. package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -34
  174. package/src/securityGroup/details/securityGroupDetail.controller.js +0 -147
  175. package/src/securityGroup/details/securityGroupDetail.html +0 -104
  176. package/src/securityGroup/securityGroup.module.ts +0 -12
  177. package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +0 -259
  178. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +0 -194
  179. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +0 -17
  180. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -10
  181. package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +0 -11
  182. package/src/serverGroup/configure/wizard/container/container.html +0 -9
  183. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +0 -118
  184. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +0 -20
  185. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +0 -13
  186. package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +0 -41
  187. package/src/serverGroup/configure/wizard/location/basicSettings.html +0 -137
  188. package/src/serverGroup/configure/wizard/logging/logging.component.html +0 -29
  189. package/src/serverGroup/configure/wizard/logging/logging.component.ts +0 -12
  190. package/src/serverGroup/configure/wizard/logging/logging.html +0 -7
  191. package/src/serverGroup/configure/wizard/networking/networking.html +0 -9
  192. package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -55
  193. package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +0 -11
  194. package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +0 -51
  195. package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +0 -9
  196. package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +0 -10
  197. package/src/serverGroup/details/resize/resizeCapacity.component.html +0 -94
  198. package/src/serverGroup/details/resize/resizeCapacity.component.ts +0 -14
  199. package/src/serverGroup/details/resize/resizeServerGroup.controller.js +0 -85
  200. package/src/serverGroup/details/resize/resizeServerGroup.html +0 -28
  201. package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +0 -97
  202. package/src/serverGroup/details/rollback/rollbackServerGroup.html +0 -67
  203. package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +0 -366
  204. package/src/serverGroup/details/serverGroupDetails.html +0 -216
  205. package/src/serverGroup/details/serverGroupDetails.module.ts +0 -5
  206. package/src/serverGroup/events/events.component.ts +0 -35
  207. package/src/serverGroup/events/events.controller.ts +0 -45
  208. package/src/serverGroup/events/events.html +0 -36
  209. package/src/serverGroup/serverGroup.module.ts +0 -6
@@ -1,17 +1,15 @@
1
- import { module } from 'angular';
1
+ import { isEqual } from 'lodash';
2
2
  import React from 'react';
3
3
  import { Alert } from 'react-bootstrap';
4
- import type { Option } from 'react-select';
5
- import { react2angular } from 'react2angular';
6
4
 
7
- import { HelpField, TetheredSelect, withErrorBoundary } from '@spinnaker/core';
5
+ import { HelpField } from '@spinnaker/core';
8
6
 
9
7
  import type { IEcsCapacityProviderStrategyItem, IEcsServerGroupCommand } from '../../serverGroupConfiguration.service';
10
8
 
11
9
  export interface IEcsCapacityProviderProps {
12
10
  command: IEcsServerGroupCommand;
13
- notifyAngular: (key: string, value: any) => void;
14
- configureCommand: (query: string) => PromiseLike<void>;
11
+ onFieldChange: (key: string, value: any) => void;
12
+ configureCommand: (query: string) => Promise<void>;
15
13
  }
16
14
 
17
15
  interface IEcsCapacityProviderState {
@@ -21,9 +19,10 @@ interface IEcsCapacityProviderState {
21
19
  ecsClusterName: string;
22
20
  useDefaultCapacityProviders: boolean;
23
21
  capacityProviderLoadedFlag: boolean;
22
+ activeCapacityProviderIndex: number | null;
24
23
  }
25
24
 
26
- class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEcsCapacityProviderState> {
25
+ export class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEcsCapacityProviderState> {
27
26
  constructor(props: IEcsCapacityProviderProps) {
28
27
  super(props);
29
28
  const cmd = this.props.command;
@@ -32,11 +31,11 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
32
31
  availableCapacityProviders: this.getAvailableCapacityProviders(cmd),
33
32
  defaultCapacityProviderStrategy: this.getDefaultCapacityProviderStrategy(cmd),
34
33
  ecsClusterName: cmd.ecsClusterName,
35
- useDefaultCapacityProviders:
36
- cmd.useDefaultCapacityProviders || (cmd.capacityProviderStrategy && cmd.capacityProviderStrategy.length == 0),
34
+ useDefaultCapacityProviders: cmd.useDefaultCapacityProviders !== false,
37
35
  capacityProviderStrategy:
38
36
  cmd.capacityProviderStrategy && cmd.capacityProviderStrategy.length > 0 ? cmd.capacityProviderStrategy : [],
39
37
  capacityProviderLoadedFlag: false,
38
+ activeCapacityProviderIndex: null,
40
39
  };
41
40
  }
42
41
 
@@ -44,21 +43,55 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
44
43
  this.props.configureCommand('1').then(() => {
45
44
  const cmd = this.props.command;
46
45
  const useDefaultCapacityProviders = this.state.useDefaultCapacityProviders;
47
- this.setState({
48
- availableCapacityProviders: this.getAvailableCapacityProviders(cmd),
49
- defaultCapacityProviderStrategy: this.getDefaultCapacityProviderStrategy(cmd),
50
- capacityProviderStrategy: this.getCapacityProviderStrategy(useDefaultCapacityProviders, cmd),
51
- capacityProviderLoadedFlag: true,
52
- });
53
- this.props.notifyAngular('useDefaultCapacityProviders', this.state.useDefaultCapacityProviders);
54
- this.props.notifyAngular('capacityProviderStrategy', this.state.capacityProviderStrategy);
46
+ const capacityProviderStrategy = this.getCapacityProviderStrategy(useDefaultCapacityProviders, cmd);
47
+ this.setState(
48
+ {
49
+ availableCapacityProviders: this.getAvailableCapacityProviders(cmd),
50
+ defaultCapacityProviderStrategy: this.getDefaultCapacityProviderStrategy(cmd),
51
+ capacityProviderStrategy,
52
+ capacityProviderLoadedFlag: true,
53
+ },
54
+ () => {
55
+ this.props.onFieldChange('useDefaultCapacityProviders', useDefaultCapacityProviders);
56
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
57
+ },
58
+ );
55
59
  });
56
60
  }
57
61
 
62
+ public componentDidUpdate() {
63
+ const cmd = this.props.command;
64
+ const useDefaultCapacityProviders = cmd.useDefaultCapacityProviders !== false;
65
+ const commandState = {
66
+ availableCapacityProviders: this.getAvailableCapacityProviders(cmd),
67
+ defaultCapacityProviderStrategy: this.getDefaultCapacityProviderStrategy(cmd),
68
+ ecsClusterName: cmd.ecsClusterName,
69
+ useDefaultCapacityProviders,
70
+ capacityProviderStrategy: useDefaultCapacityProviders
71
+ ? this.getDefaultCapacityProviderStrategy(cmd)
72
+ : cmd.capacityProviderStrategy || [],
73
+ };
74
+ const currentState = {
75
+ availableCapacityProviders: this.state.availableCapacityProviders,
76
+ defaultCapacityProviderStrategy: this.state.defaultCapacityProviderStrategy,
77
+ ecsClusterName: this.state.ecsClusterName,
78
+ useDefaultCapacityProviders: this.state.useDefaultCapacityProviders,
79
+ capacityProviderStrategy: this.state.capacityProviderStrategy,
80
+ };
81
+ if (!isEqual(currentState, commandState)) {
82
+ const strategyChanged = !isEqual(cmd.capacityProviderStrategy || [], commandState.capacityProviderStrategy);
83
+ this.setState(commandState, () => {
84
+ if (strategyChanged) {
85
+ this.props.onFieldChange('capacityProviderStrategy', commandState.capacityProviderStrategy);
86
+ }
87
+ });
88
+ }
89
+ }
90
+
58
91
  private getAvailableCapacityProviders = (cmd: IEcsServerGroupCommand) => {
59
- return cmd.backingData && cmd.backingData.filtered && cmd.backingData.filtered.availableCapacityProviders
60
- ? cmd.backingData.filtered.availableCapacityProviders
61
- : [];
92
+ const available = cmd.backingData?.filtered?.availableCapacityProviders || [];
93
+ const persisted = (cmd.capacityProviderStrategy || []).map((strategy) => strategy.capacityProvider);
94
+ return Array.from(new Set([...available, ...persisted])).filter(Boolean);
62
95
  };
63
96
 
64
97
  private getDefaultCapacityProviderStrategy = (cmd: IEcsServerGroupCommand) => {
@@ -79,14 +112,14 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
79
112
  private addCapacityProviderStrategy = () => {
80
113
  const capacityProviderStrategy = this.state.capacityProviderStrategy;
81
114
  capacityProviderStrategy.push({ capacityProvider: '', base: null, weight: null });
82
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
115
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
83
116
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
84
117
  };
85
118
 
86
119
  private removeCapacityProviderStrategy = (index: number) => {
87
120
  const capacityProviderStrategy = this.state.capacityProviderStrategy;
88
121
  capacityProviderStrategy.splice(index, 1);
89
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
122
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
90
123
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
91
124
  };
92
125
 
@@ -94,7 +127,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
94
127
  const capacityProviderStrategy = this.state.capacityProviderStrategy;
95
128
  const targetCapacityProviderStrategy = capacityProviderStrategy[index];
96
129
  targetCapacityProviderStrategy.capacityProvider = targetCapacityProviderName;
97
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
130
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
98
131
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
99
132
  this.props.command.viewState.dirty.customCapacityProviders = [];
100
133
  };
@@ -103,7 +136,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
103
136
  const capacityProviderStrategy = this.state.capacityProviderStrategy;
104
137
  const targetCapacityProviderStrategy = capacityProviderStrategy[index];
105
138
  targetCapacityProviderStrategy.base = targetCapacityProviderBase;
106
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
139
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
107
140
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
108
141
  };
109
142
 
@@ -111,13 +144,13 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
111
144
  const capacityProviderStrategy = this.state.capacityProviderStrategy;
112
145
  const targetCapacityProviderStrategy = capacityProviderStrategy[index];
113
146
  targetCapacityProviderStrategy.weight = targetCapacityProviderWeight;
114
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
147
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
115
148
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
116
149
  };
117
150
 
118
151
  private updateCapacityProviderType = (targetCapacityProviderType: boolean) => {
119
152
  this.setState({ useDefaultCapacityProviders: targetCapacityProviderType });
120
- this.props.notifyAngular('useDefaultCapacityProviders', targetCapacityProviderType);
153
+ this.props.onFieldChange('useDefaultCapacityProviders', targetCapacityProviderType);
121
154
  this.props.command.viewState.dirty.customCapacityProviders = [];
122
155
 
123
156
  const capacityProviderStrategy =
@@ -125,7 +158,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
125
158
  ? this.state.defaultCapacityProviderStrategy
126
159
  : [];
127
160
  this.setState({ capacityProviderStrategy: capacityProviderStrategy });
128
- this.props.notifyAngular('capacityProviderStrategy', capacityProviderStrategy);
161
+ this.props.onFieldChange('capacityProviderStrategy', capacityProviderStrategy);
129
162
  };
130
163
 
131
164
  render(): React.ReactElement<EcsCapacityProvider> {
@@ -170,7 +203,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
170
203
  );
171
204
 
172
205
  const dirtyCapacityProviderList = customDirtyCapacityProviders
173
- ? customDirtyCapacityProviders.map(function (capacityProvider, index) {
206
+ ? customDirtyCapacityProviders.map(function (capacityProvider: string, index: number) {
174
207
  return <li key={index}>{capacityProvider}</li>;
175
208
  })
176
209
  : '';
@@ -194,12 +227,13 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
194
227
 
195
228
  const capacityProviderInputs =
196
229
  capacityProviderStrategy.length > 0 ? (
197
- capacityProviderStrategy.map(function (mapping, index) {
230
+ capacityProviderStrategy.map((mapping, index) => {
198
231
  return (
199
232
  <tr key={index}>
200
233
  {useDefaultCapacityProviders ? (
201
234
  <td>
202
235
  <input
236
+ aria-label={`Capacity provider name ${index + 1}`}
203
237
  data-test-id={'ServerGroup.defaultCapacityProvider.name.' + index}
204
238
  type="string"
205
239
  className="form-control input-sm no-spel"
@@ -209,20 +243,38 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
209
243
  />
210
244
  </td>
211
245
  ) : (
212
- <td data-test-id={'ServerGroup.customCapacityProvider.name.' + index}>
213
- <TetheredSelect
214
- placeholder="Select capacity provider"
215
- options={capacityProviderNames}
216
- value={mapping.capacityProvider}
217
- onChange={(e: Option) => {
218
- updateCapacityProviderName(index, e.label as string);
246
+ <td>
247
+ <input
248
+ aria-label={`Capacity provider name ${index + 1}`}
249
+ className="form-control input-sm"
250
+ data-test-id={'ServerGroup.customCapacityProvider.name.' + index}
251
+ onChange={(event) => {
252
+ this.setState({ activeCapacityProviderIndex: index });
253
+ updateCapacityProviderName(index, event.target.value);
219
254
  }}
220
- clearable={false}
255
+ onFocus={() => this.setState({ activeCapacityProviderIndex: index })}
256
+ type="text"
257
+ value={mapping.capacityProvider || ''}
221
258
  />
259
+ {this.state.activeCapacityProviderIndex === index &&
260
+ capacityProviderNames.map((capacityProvider) => (
261
+ <button
262
+ className="Select-option"
263
+ key={capacityProvider.value}
264
+ onClick={() => {
265
+ updateCapacityProviderName(index, capacityProvider.value);
266
+ this.setState({ activeCapacityProviderIndex: null });
267
+ }}
268
+ type="button"
269
+ >
270
+ {capacityProvider.label}
271
+ </button>
272
+ ))}
222
273
  </td>
223
274
  )}
224
275
  <td>
225
276
  <input
277
+ aria-label={`Capacity provider base ${index + 1}`}
226
278
  data-test-id={'ServerGroup.capacityProvider.base.' + index}
227
279
  disabled={useDefaultCapacityProviders}
228
280
  type="number"
@@ -233,6 +285,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
233
285
  </td>
234
286
  <td>
235
287
  <input
288
+ aria-label={`Capacity provider weight ${index + 1}`}
236
289
  data-test-id={'ServerGroup.capacityProvider.weight.' + index}
237
290
  disabled={useDefaultCapacityProviders}
238
291
  type="number"
@@ -245,10 +298,15 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
245
298
  {!useDefaultCapacityProviders ? (
246
299
  <td>
247
300
  <div className="form-control-static">
248
- <a className="btn-link sm-label" onClick={() => removeCapacityProviderStrategy(index)}>
301
+ <button
302
+ aria-label={`Remove capacity provider ${index + 1}`}
303
+ className="btn-link sm-label"
304
+ onClick={() => removeCapacityProviderStrategy(index)}
305
+ type="button"
306
+ >
249
307
  <span className="glyphicon glyphicon-trash" />
250
308
  <span className="sr-only">Remove</span>
251
- </a>
309
+ </button>
252
310
  </div>
253
311
  </td>
254
312
  ) : (
@@ -281,6 +339,7 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
281
339
  data-test-id="ServerGroup.addCapacityProvider"
282
340
  className="btn btn-block btn-sm add-new"
283
341
  onClick={addCapacityProviderStrategy}
342
+ type="button"
284
343
  >
285
344
  <span className="glyphicon glyphicon-plus-sign" />
286
345
  Add New Capacity Provider
@@ -369,13 +428,3 @@ class EcsCapacityProvider extends React.Component<IEcsCapacityProviderProps, IEc
369
428
  );
370
429
  }
371
430
  }
372
-
373
- export const ECS_CAPACITY_PROVIDER_REACT = 'spinnaker.ecs.serverGroup.configure.wizard.capacityProvider.react';
374
- module(ECS_CAPACITY_PROVIDER_REACT, []).component(
375
- 'ecsCapacityProviderReact',
376
- react2angular(withErrorBoundary(EcsCapacityProvider, 'ecsCapacityProviderReact'), [
377
- 'command',
378
- 'notifyAngular',
379
- 'configureCommand',
380
- ]),
381
- );
@@ -15,7 +15,7 @@ describe('Container', () => {
15
15
  let command: IEcsServerGroupCommand;
16
16
 
17
17
  const configureCommand = (_query: string) => Promise.resolve() as PromiseLike<void>;
18
- const notifyAngular = (_key: string, _value: any) => {};
18
+ const onFieldChange = (_key: string, _value: any) => {};
19
19
 
20
20
  const dockerAccounts: IAccountDetails[] = [
21
21
  {
@@ -50,7 +50,7 @@ describe('Container', () => {
50
50
  describe('updateDockerRegistryAccount', () => {
51
51
  it('calls DockerImageReader.findImages with the selected account', async () => {
52
52
  const wrapper = mount(
53
- <Container command={command} notifyAngular={notifyAngular} configureCommand={configureCommand} />,
53
+ <Container command={command} onFieldChange={onFieldChange} configureCommand={configureCommand} />,
54
54
  );
55
55
 
56
56
  await flushPromises();
@@ -66,21 +66,33 @@ describe('Container', () => {
66
66
 
67
67
  it('updates component state and backingData with images returned for the account', async () => {
68
68
  const wrapper = mount(
69
- <Container command={command} notifyAngular={notifyAngular} configureCommand={configureCommand} />,
69
+ <Container command={command} onFieldChange={onFieldChange} configureCommand={configureCommand} />,
70
70
  );
71
71
 
72
72
  (wrapper.instance() as any).updateDockerRegistryAccount({ value: 'my-docker-account' });
73
73
  await flushPromises();
74
74
  wrapper.update();
75
75
 
76
- expect((wrapper.instance() as Container).state.dockerImages).toEqual(dockerImages as IEcsDockerImage[]);
77
- expect(command.backingData.filtered.images).toEqual(dockerImages as IEcsDockerImage[]);
76
+ const expectedImages = [
77
+ {
78
+ ...dockerImages[0],
79
+ imageId: 'my-registry/my-repo:latest',
80
+ message: '',
81
+ fromTrigger: false,
82
+ fromContext: false,
83
+ stageId: '',
84
+ imageLabelOrSha: '',
85
+ },
86
+ ];
87
+
88
+ expect((wrapper.instance() as Container).state.dockerImages).toEqual(expectedImages as IEcsDockerImage[]);
89
+ expect(command.backingData.filtered.images).toEqual(expectedImages as IEcsDockerImage[]);
78
90
  });
79
91
 
80
92
  it('clears existing images immediately when account changes', () => {
81
93
  command.backingData.filtered.images = dockerImages as IEcsDockerImage[];
82
94
  const wrapper = mount(
83
- <Container command={command} notifyAngular={notifyAngular} configureCommand={configureCommand} />,
95
+ <Container command={command} onFieldChange={onFieldChange} configureCommand={configureCommand} />,
84
96
  );
85
97
 
86
98
  (wrapper.instance() as any).updateDockerRegistryAccount({ value: 'my-docker-account' });
@@ -104,7 +116,7 @@ describe('Container', () => {
104
116
  } as IEcsDockerImage;
105
117
 
106
118
  const wrapper = mount(
107
- <Container command={command} notifyAngular={notifyAngular} configureCommand={configureCommand} />,
119
+ <Container command={command} onFieldChange={onFieldChange} configureCommand={configureCommand} />,
108
120
  );
109
121
 
110
122
  expect((wrapper.instance() as Container).state.selectedDockerAccount).toBe('my-docker-account');
@@ -112,7 +124,7 @@ describe('Container', () => {
112
124
 
113
125
  it('starts with no account selected when imageDescription has no account', () => {
114
126
  const wrapper = mount(
115
- <Container command={command} notifyAngular={notifyAngular} configureCommand={configureCommand} />,
127
+ <Container command={command} onFieldChange={onFieldChange} configureCommand={configureCommand} />,
116
128
  );
117
129
 
118
130
  expect((wrapper.instance() as Container).state.selectedDockerAccount).toBe('');
@@ -1,14 +1,13 @@
1
- import { module } from 'angular';
2
- import { isEqual, uniqWith } from 'lodash';
1
+ import { isEqual, uniq, uniqWith } from 'lodash';
3
2
  import * as React from 'react';
4
3
  import { Alert } from 'react-bootstrap';
5
4
  import type { Option } from 'react-select';
6
- import { react2angular } from 'react2angular';
7
5
 
8
6
  import type { IAccountDetails } from '@spinnaker/core';
9
- import { AccountService, HelpField, TetheredSelect, withErrorBoundary } from '@spinnaker/core';
7
+ import { AccountService, HelpField, TetheredSelect } from '@spinnaker/core';
10
8
  import { DockerImageReader } from '@spinnaker/docker';
11
9
 
10
+ import { normalizeEcsDockerImage } from '../../dockerImage.util';
12
11
  import type {
13
12
  IEcsDockerImage,
14
13
  IEcsServerGroupCommand,
@@ -17,8 +16,8 @@ import type {
17
16
 
18
17
  export interface IContainerProps {
19
18
  command: IEcsServerGroupCommand;
20
- notifyAngular: (key: string, value: any) => void;
21
- configureCommand: (query: string) => PromiseLike<void>;
19
+ onFieldChange: (key: string, value: any) => void;
20
+ configureCommand: (query: string) => Promise<void>;
22
21
  }
23
22
 
24
23
  interface IContainerState {
@@ -67,7 +66,10 @@ export class Container extends React.Component<IContainerProps, IContainerState>
67
66
  dockerRegistryAccounts: [],
68
67
  selectedDockerAccount: cmd.imageDescription?.account ?? '',
69
68
  targetGroupMappings: cmd.targetGroupMappings,
70
- targetGroupsAvailable: cmd.backingData && cmd.backingData.filtered ? cmd.backingData.filtered.targetGroups : [],
69
+ targetGroupsAvailable: uniq([
70
+ ...(cmd.backingData?.filtered?.targetGroups || []),
71
+ ...cmd.targetGroupMappings.map((mapping) => mapping.targetGroup).filter(Boolean),
72
+ ]),
71
73
  };
72
74
 
73
75
  this.state.targetGroupMappings.forEach((targetGroupMapping) => {
@@ -83,11 +85,35 @@ export class Container extends React.Component<IContainerProps, IContainerState>
83
85
  this.props.configureCommand('1').then(() => {
84
86
  this.setState({
85
87
  dockerImages: this.props.command.backingData.filtered.images,
86
- targetGroupsAvailable: this.props.command.backingData.filtered.targetGroups,
88
+ targetGroupsAvailable: uniq([
89
+ ...(this.props.command.backingData.filtered.targetGroups || []),
90
+ ...this.state.targetGroupMappings.map((mapping) => mapping.targetGroup).filter(Boolean),
91
+ ]),
87
92
  });
88
93
  });
89
94
  }
90
95
 
96
+ public componentDidUpdate() {
97
+ const cmd = this.props.command;
98
+ const targetGroupMappings = cmd.targetGroupMappings || [];
99
+ const nextState: IContainerState = {
100
+ imageDescription: cmd.imageDescription || this.getEmptyImageDescription(),
101
+ computeUnits: cmd.computeUnits,
102
+ reservedMemory: cmd.reservedMemory,
103
+ dockerImages: cmd.backingData?.filtered?.images || [],
104
+ dockerRegistryAccounts: this.state.dockerRegistryAccounts,
105
+ selectedDockerAccount: this.state.selectedDockerAccount,
106
+ targetGroupMappings,
107
+ targetGroupsAvailable: uniq([
108
+ ...(cmd.backingData?.filtered?.targetGroups || []),
109
+ ...targetGroupMappings.map((mapping) => mapping.targetGroup).filter(Boolean),
110
+ ]),
111
+ };
112
+ if (!isEqual(this.state, nextState)) {
113
+ this.setState(nextState);
114
+ }
115
+ }
116
+
91
117
  // TODO: Separate docker image component used by both TaskDefinition and Container
92
118
 
93
119
  private getIdToImageMap = (): Map<string, IEcsDockerImage> => {
@@ -116,9 +142,10 @@ export class Container extends React.Component<IContainerProps, IContainerState>
116
142
 
117
143
  private updateDockerRegistryAccount = (newAccount: Option<string>) => {
118
144
  const account = newAccount.value;
145
+ this.props.command.backingData.filtered.images = [];
119
146
  this.setState({ selectedDockerAccount: account, dockerImages: [] });
120
147
  DockerImageReader.findImages({ provider: 'dockerRegistry', account, count: 50 }).then((images) => {
121
- const ecsImages = images as IEcsDockerImage[];
148
+ const ecsImages = images.map((image) => normalizeEcsDockerImage(image));
122
149
  this.props.command.backingData.filtered.images = ecsImages;
123
150
  this.setState({ dockerImages: ecsImages });
124
151
  });
@@ -137,17 +164,17 @@ export class Container extends React.Component<IContainerProps, IContainerState>
137
164
  newImageDescription = this.getEmptyImageDescription();
138
165
  }
139
166
 
140
- this.props.notifyAngular('imageDescription', newImageDescription);
167
+ this.props.onFieldChange('imageDescription', newImageDescription);
141
168
  this.setState({ imageDescription: newImageDescription });
142
169
  };
143
170
 
144
171
  private updateComputeUnits = (newComputeUnits: number) => {
145
- this.props.notifyAngular('computeUnits', newComputeUnits);
172
+ this.props.onFieldChange('computeUnits', newComputeUnits);
146
173
  this.setState({ computeUnits: newComputeUnits });
147
174
  };
148
175
 
149
176
  private updateReservedMemory = (newReservedMemory: number) => {
150
- this.props.notifyAngular('reservedMemory', newReservedMemory);
177
+ this.props.onFieldChange('reservedMemory', newReservedMemory);
151
178
  this.setState({ reservedMemory: newReservedMemory });
152
179
  };
153
180
 
@@ -155,7 +182,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
155
182
  const currentMappings = this.state.targetGroupMappings;
156
183
  const targetMapping = currentMappings[index];
157
184
  targetMapping.targetGroup = newTargetGroup.value;
158
- this.props.notifyAngular('targetGroupMappings', currentMappings);
185
+ this.props.onFieldChange('targetGroupMappings', currentMappings);
159
186
  this.setState({ targetGroupMappings: currentMappings });
160
187
  this.updateDirtyTargetGroups();
161
188
  };
@@ -164,14 +191,14 @@ export class Container extends React.Component<IContainerProps, IContainerState>
164
191
  const currentMappings = this.state.targetGroupMappings;
165
192
  const targetMapping = currentMappings[index];
166
193
  targetMapping.containerPort = targetPort;
167
- this.props.notifyAngular('targetGroupMappings', currentMappings);
194
+ this.props.onFieldChange('targetGroupMappings', currentMappings);
168
195
  this.setState({ targetGroupMappings: currentMappings });
169
196
  };
170
197
 
171
198
  private removeTargetGroupMapping = (index: number) => {
172
199
  const currentMappings = this.state.targetGroupMappings;
173
200
  currentMappings.splice(index, 1);
174
- this.props.notifyAngular('targetGroupMappings', currentMappings);
201
+ this.props.onFieldChange('targetGroupMappings', currentMappings);
175
202
  this.setState({ targetGroupMappings: currentMappings });
176
203
  };
177
204
 
@@ -205,7 +232,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
205
232
  });
206
233
 
207
234
  const dirtyTargetGroupList = dirtyTagetGroups
208
- ? dirtyTagetGroups.map(function (targetGroup, index) {
235
+ ? dirtyTagetGroups.map(function (targetGroup: string, index: number) {
209
236
  return <li key={index}>{targetGroup}</li>;
210
237
  })
211
238
  : '';
@@ -227,6 +254,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
227
254
  className="btn btn-block btn-sm add-new"
228
255
  data-test-id="ContainerInputs.targetGroupAdd"
229
256
  onClick={this.pushTargetGroupMapping}
257
+ type="button"
230
258
  >
231
259
  <span className="glyphicon glyphicon-plus-sign" />
232
260
  Add New Target Group Mapping
@@ -246,6 +274,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
246
274
  <tr key={index}>
247
275
  <td data-test-id="ContainerInputs.targetGroup">
248
276
  <TetheredSelect
277
+ inputProps={{ 'aria-label': `Target group ${index + 1}` }}
249
278
  placeholder="Select a target group to use..."
250
279
  options={targetGroupsAvailable}
251
280
  value={mapping.targetGroup.toString()}
@@ -255,6 +284,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
255
284
  </td>
256
285
  <td>
257
286
  <input
287
+ aria-label={`Target port ${index + 1}`}
258
288
  data-test-id="ContainerInputs.targetGroupPort"
259
289
  type="number"
260
290
  className="form-control input-sm no-spel"
@@ -265,14 +295,16 @@ export class Container extends React.Component<IContainerProps, IContainerState>
265
295
  </td>
266
296
  <td>
267
297
  <div className="form-control-static">
268
- <a
298
+ <button
299
+ aria-label={`Remove target group mapping ${index + 1}`}
269
300
  className="btn-link sm-label"
270
301
  data-test-id="ContainerInputs.targetGroupRemove"
271
302
  onClick={() => removeTargetGroupMapping(index)}
303
+ type="button"
272
304
  >
273
305
  <span className="glyphicon glyphicon-trash" />
274
306
  <span className="sr-only">Remove</span>
275
- </a>
307
+ </button>
276
308
  </div>
277
309
  </td>
278
310
  </tr>
@@ -303,6 +335,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
303
335
  </div>
304
336
  <div className="col-md-9" data-test-id="ContainerInputs.containerImage">
305
337
  <TetheredSelect
338
+ inputProps={{ 'aria-label': 'Container image' }}
306
339
  placeholder="Select an image to use..."
307
340
  options={dockerImageOptions}
308
341
  value={this.state.imageDescription.imageId}
@@ -320,6 +353,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
320
353
  </div>
321
354
  <div className="col-md-9" style={{ width: '100px' }}>
322
355
  <input
356
+ aria-label="Compute units"
323
357
  data-test-id="ContainerInputs.computeUnits"
324
358
  type="number"
325
359
  className="form-control input-sm no-spel"
@@ -336,6 +370,7 @@ export class Container extends React.Component<IContainerProps, IContainerState>
336
370
  </div>
337
371
  <div className="col-md-9" style={{ width: '100px' }}>
338
372
  <input
373
+ aria-label="Reserved memory"
339
374
  data-test-id="ContainerInputs.reservedMemory"
340
375
  type="number"
341
376
  className="form-control input-sm no-spel"
@@ -378,9 +413,3 @@ export class Container extends React.Component<IContainerProps, IContainerState>
378
413
  );
379
414
  }
380
415
  }
381
-
382
- export const CONTAINER_REACT = 'spinnaker.ecs.serverGroup.configure.wizard.container.react';
383
- module(CONTAINER_REACT, []).component(
384
- 'containerReact',
385
- react2angular(withErrorBoundary(Container, 'containerReact'), ['command', 'notifyAngular', 'configureCommand']),
386
- );