ValuesForm.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import React, { Component } from 'react';
  2. import styled from 'styled-components';
  3. import { Section, FormElement } from '../../shared/types';
  4. import { Context } from '../../shared/Context';
  5. import api from '../../shared/api';
  6. import SaveButton from '../SaveButton';
  7. import CheckboxRow from './CheckboxRow';
  8. import InputRow from './InputRow';
  9. import SelectRow from './SelectRow';
  10. type PropsType = {
  11. onSubmit: (formValues: any) => void,
  12. sections?: Section[],
  13. disabled?: boolean,
  14. saveValuesStatus?: string | null,
  15. };
  16. type StateType = any;
  17. export default class ValuesForm extends Component<PropsType, StateType> {
  18. updateFormState() {
  19. let formState: any = {};
  20. this.props.sections.forEach((section: Section, i: number) => {
  21. section.contents.forEach((item: FormElement, i: number) => {
  22. // If no name is assigned use values.yaml variable as identifier
  23. let key = item.name || item.variable;
  24. let def = item.settings && item.settings.default;
  25. switch (item.type) {
  26. case 'checkbox':
  27. formState[key] = def ? def : false;
  28. break;
  29. case 'string-input':
  30. formState[key] = def ? def : '';
  31. break;
  32. case 'number-input':
  33. formState[key] = def.toString() ? def : '';
  34. break;
  35. case 'select':
  36. formState[key] = def ? def : item.settings.options[0].value;
  37. default:
  38. }
  39. });
  40. });
  41. this.setState(formState);
  42. }
  43. // Initialize corresponding state fields for form blocks
  44. componentDidMount() {
  45. this.updateFormState();
  46. }
  47. componentDidUpdate(prevProps: PropsType) {
  48. if (this.props.sections !== prevProps.sections) {
  49. this.updateFormState();
  50. }
  51. }
  52. renderSection = (section: Section) => {
  53. return section.contents.map((item: FormElement, i: number) => {
  54. // If no name is assigned use values.yaml variable as identifier
  55. let key = item.name || item.variable;
  56. switch (item.type) {
  57. case 'heading':
  58. return <Heading key={i}>{item.label}</Heading>
  59. case 'subtitle':
  60. return <Helper key={i}>{item.label}</Helper>
  61. case 'checkbox':
  62. return (
  63. <CheckboxRow
  64. key={i}
  65. checked={this.state[key]}
  66. toggle={() => this.setState({ [key]: !this.state[key] })}
  67. label={item.label}
  68. />
  69. );
  70. case 'string-input':
  71. return (
  72. <InputRow
  73. key={i}
  74. type='text'
  75. value={this.state[key]}
  76. setValue={(x: string) => this.setState({ [key]: x })}
  77. label={item.label}
  78. unit={item.settings ? item.settings.unit : null}
  79. />
  80. );
  81. case 'number-input':
  82. return (
  83. <InputRow
  84. key={i}
  85. type='number'
  86. value={this.state[key]}
  87. setValue={(x: number) => this.setState({ [key]: x })}
  88. label={item.label}
  89. unit={item.settings ? item.settings.unit : null}
  90. />
  91. );
  92. case 'select':
  93. return (
  94. <SelectRow
  95. key={i}
  96. value={this.state[key]}
  97. setActiveValue={(val) => this.setState({ [key]: val })}
  98. options={item.settings.options}
  99. dropdownLabel=''
  100. label={item.label}
  101. />
  102. );
  103. default:
  104. }
  105. });
  106. }
  107. renderFormContents = () => {
  108. if (this.state) {
  109. return this.props.sections.map((section: Section, i: number) => {
  110. // Hide collapsible section if deciding field is false
  111. if (section.show_if) {
  112. if (!this.state[section.show_if]) {
  113. return null;
  114. }
  115. }
  116. return (
  117. <div key={i}>
  118. {this.renderSection(section)}
  119. </div>
  120. );
  121. });
  122. }
  123. }
  124. render() {
  125. return (
  126. <Wrapper>
  127. <StyledValuesForm>
  128. <DarkMatter />
  129. {this.renderFormContents()}
  130. </StyledValuesForm>
  131. <SaveButton
  132. disabled={this.props.disabled}
  133. text='Deploy'
  134. onClick={() => this.props.onSubmit(this.state)}
  135. status={this.props.saveValuesStatus}
  136. makeFlush={true}
  137. />
  138. </Wrapper>
  139. );
  140. }
  141. }
  142. ValuesForm.contextType = Context;
  143. const DarkMatter = styled.div`
  144. margin-top: 0px;
  145. `;
  146. const Wrapper = styled.div`
  147. width: 100%;
  148. height: 100%;
  149. `;
  150. const Helper = styled.div`
  151. color: #aaaabb;
  152. line-height: 1.6em;
  153. font-size: 13px;
  154. margin-bottom: 15px;
  155. margin-top: 20px;
  156. `;
  157. const Heading = styled.div`
  158. color: white;
  159. font-weight: 500;
  160. font-size: 16px;
  161. margin-top: 30px;
  162. margin-bottom: 5px;
  163. `;
  164. const StyledValuesForm = styled.div`
  165. width: 100%;
  166. height: 100%;
  167. background: #ffffff11;
  168. color: #ffffff;
  169. padding: 0px 35px 25px;
  170. position: relative;
  171. border-radius: 5px;
  172. font-size: 13px;
  173. overflow: auto;
  174. `;