ValuesWrapper.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import React, { Component } from 'react';
  2. import styled from 'styled-components';
  3. import { Section, FormElement } from '../../shared/types';
  4. import SaveButton from '../SaveButton';
  5. type PropsType = {
  6. formTabs: any,
  7. onSubmit: (formValues: any) => void,
  8. disabled?: boolean,
  9. saveValuesStatus?: string | null,
  10. isInModal?: boolean,
  11. currentTab?: string, // For resetting state when flipping b/w tabs in ExpandedChart
  12. };
  13. type StateType = any;
  14. // Manages the consolidated state of all form tabs ("metastate")
  15. export default class ValuesWrapper extends Component<PropsType, StateType> {
  16. // No need to render, so OK to set as class variable outside of state
  17. requiredFields: string[] = [];
  18. updateFormState() {
  19. let metaState: any = {};
  20. this.props.formTabs.forEach((tab: any, i: number) => {
  21. // TODO: reconcile tab.name and tab.value
  22. if (tab.name || (tab.value && tab.value.includes('@'))) {
  23. tab.sections.forEach((section: Section, i: number) => {
  24. section.contents.forEach((item: FormElement, i: number) => {
  25. // If no name is assigned use values.yaml variable as identifier
  26. let key = item.name || item.variable;
  27. let def = (item.value && item.value[0]) || (item.settings && item.settings.default);
  28. // Handle add to list of required fields
  29. if (item.required) {
  30. key && this.requiredFields.push(key);
  31. }
  32. switch (item.type) {
  33. case 'checkbox':
  34. metaState[key] = def ? def : false;
  35. break;
  36. case 'string-input':
  37. metaState[key] = def ? def : '';
  38. break;
  39. case 'array-input':
  40. metaState[key] = def ? def : [];
  41. break;
  42. case 'number-input':
  43. metaState[key] = def.toString() ? def : '';
  44. break;
  45. case 'select':
  46. metaState[key] = def ? def : item.settings.options[0].value;
  47. break;
  48. case 'base-64':
  49. metaState[key] = def ? def : '';
  50. case 'base-64-password':
  51. metaState[key] = def ? def : '';
  52. default:
  53. }
  54. });
  55. });
  56. }
  57. });
  58. this.setState(metaState);
  59. }
  60. // Initialize corresponding state fields for form blocks
  61. componentDidMount() {
  62. this.updateFormState();
  63. }
  64. componentDidUpdate(prevProps: PropsType) {
  65. if (this.props.formTabs !== prevProps.formTabs ||
  66. this.props.currentTab !== prevProps.currentTab
  67. ) {
  68. this.updateFormState();
  69. }
  70. }
  71. // Checks if all required fields are set
  72. isDisabled = (): boolean => {
  73. let valueIndicators: any[] = [];
  74. this.requiredFields.forEach((field: string, i: number) => {
  75. valueIndicators.push(this.state[field] && true);
  76. });
  77. return valueIndicators.includes(false) || valueIndicators.includes('')
  78. }
  79. renderButton = () => {
  80. let { formTabs, currentTab } = this.props;
  81. let tab = formTabs.find((t: any) => t.name === currentTab || t.value === currentTab);
  82. if (tab && tab.context && tab.context.type === 'helm/values') {
  83. return (
  84. <SaveButton
  85. disabled={this.isDisabled() || this.props.disabled}
  86. text='Deploy'
  87. onClick={() => this.props.onSubmit(this.state)}
  88. status={this.isDisabled() ? 'Missing required fields' : this.props.saveValuesStatus}
  89. makeFlush={true}
  90. />
  91. );
  92. }
  93. }
  94. render() {
  95. let renderFunc: any = this.props.children;
  96. if (this.props.isInModal) {
  97. return (
  98. <StyledValuesWrapper>
  99. {renderFunc(this.state, (x: any) => this.setState(x))}
  100. {this.renderButton()}
  101. </StyledValuesWrapper>
  102. );
  103. }
  104. return (
  105. <PaddedWrapper>
  106. <StyledValuesWrapper>
  107. {renderFunc(this.state, (x: any) => this.setState(x))}
  108. {this.renderButton()}
  109. </StyledValuesWrapper>
  110. </PaddedWrapper>
  111. );
  112. }
  113. }
  114. const StyledValuesWrapper = styled.div`
  115. width: 100%;
  116. padding: 0;
  117. height: calc(100% - 65px);
  118. `;
  119. const PaddedWrapper = styled.div`
  120. padding-bottom: 65px;
  121. position: relative;
  122. `;