Manual Reference Source

basic/NodeInstancesFilter.js

  1. /**
  2. * Created by jakubniezgoda on 07/06/2018.
  3. */
  4.  
  5. import PropTypes from 'prop-types';
  6. import React from 'react';
  7.  
  8. import Form from './form/Form';
  9. import StageUtils from '../../utils/stageUtils';
  10.  
  11. /**
  12. * NodeInstancesFilter - a component showing dropdown with nodes instances of specified deployment.
  13. * Data is dynamically fetched from manager.
  14. *
  15. * ## Access
  16. * `Stage.Basic.NodeInstancesFilter`
  17. *
  18. * ## Usage
  19. * ![NodeInstancesFilter](manual/asset/NodeInstancesFilter_0.png)
  20. *
  21. * ```
  22. * <NodeInstancesFilter name='nodeFilter' value={[]} onChange={()=>{}} deploymentId='nodecellar' />
  23. * ```
  24. *
  25. */
  26. export default class NodeInstancesFilter extends React.Component {
  27. constructor(props, context) {
  28. super(props, context);
  29.  
  30. this.state = NodeInstancesFilter.initialState(props);
  31. this.toolbox = StageUtils.getToolbox(() => {}, () => {}, null);
  32. }
  33.  
  34. /**
  35. * propTypes
  36. *
  37. * @property {string} name name of the field
  38. * @property {string} value value of the field
  39. * @property {string} deploymentId ID of deployment for which Node Instances will be fetched
  40. * @property {Function} onChange function to be called on field's value change
  41. * @property {string} [label=''] field label
  42. * @property {string} [placeholder=''] field's placeholder
  43. * @property {string} [help=''] field's help description
  44. * @property {boolean} [upward=false] make dropdown to expand upwards
  45. */
  46. static propTypes = {
  47. name: PropTypes.string.isRequired,
  48. value: PropTypes.array.isRequired,
  49. onChange: PropTypes.func.isRequired,
  50. deploymentId: PropTypes.string,
  51. label: PropTypes.string,
  52. placeholder: PropTypes.string,
  53. help: PropTypes.string,
  54. upward: PropTypes.bool
  55. };
  56.  
  57. static defaultProps = {
  58. label: '',
  59. placeholder: '',
  60. help: '',
  61. upward: false
  62. };
  63.  
  64. static initialState = props => ({
  65. value: props.value,
  66. nodeInstances: [],
  67. loading: false,
  68. errors: {}
  69. });
  70.  
  71. shouldComponentUpdate(nextProps, nextState) {
  72. return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
  73. }
  74.  
  75. componentDidUpdate(prevProps) {
  76. if (prevProps.deploymentId !== this.props.deploymentId) {
  77. this.setState({ ...NodeInstancesFilter.initialState(this.props) });
  78. this._fetchData();
  79. }
  80. }
  81.  
  82. componentDidMount() {
  83. this._fetchData();
  84. }
  85.  
  86. _fetchData() {
  87. if (_.isEmpty(this.props.deploymentId)) {
  88. return;
  89. }
  90.  
  91. const params = { _include: 'id', deployment_id: this.props.deploymentId };
  92. const fetchUrl = '/node-instances';
  93. const errors = { ...this.state.errors };
  94. errors.nodeInstanceIds = null;
  95.  
  96. this.setState({ loading: true, nodeInstances: [], errors });
  97. this.toolbox
  98. .getManager()
  99. .doGet(fetchUrl, params)
  100. .then(data => {
  101. const parsedData = _.chain(data.items || {})
  102. .map(item => ({ text: item.id, value: item.id, key: item.id }))
  103. .unshift({ text: '', value: '', key: '' })
  104. .uniqWith(_.isEqual)
  105. .value();
  106. this.setState({ loading: false, nodeInstances: parsedData });
  107. })
  108. .catch(error => {
  109. errors.nodeInstanceIds = `Data fetching error: ${error.message}`;
  110. this.setState({ loading: false, nodeInstances: [], errors });
  111. });
  112. }
  113.  
  114. _handleInputChange(event, field) {
  115. this.setState({ value: field.value }, () => {
  116. this.props.onChange(event, {
  117. name: this.props.name,
  118. value: this.state.value
  119. });
  120. });
  121. }
  122.  
  123. render() {
  124. const { errors } = this.state;
  125.  
  126. return (
  127. <Form.Field error={this.state.errors.nodeInstanceIds} label={this.props.label} help={this.props.help}>
  128. <Form.Dropdown
  129. search
  130. selection
  131. multiple
  132. value={errors.nodeInstanceIds ? '' : this.state.value}
  133. placeholder={errors.nodeInstanceIds || this.props.placeholder}
  134. options={this.state.nodeInstances}
  135. onChange={this._handleInputChange.bind(this)}
  136. name="nodeInstanceIds"
  137. loading={this.state.loading}
  138. upward={this.props.upward}
  139. />
  140. </Form.Field>
  141. );
  142. }
  143. }