PorterForm.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import React, { useContext, useState } from "react";
  2. import {
  3. Section,
  4. FormField,
  5. InputField,
  6. CheckboxField,
  7. KeyValueArrayField,
  8. ArrayInputField,
  9. SelectField,
  10. ServiceIPListField,
  11. ResourceListField,
  12. } from "./types";
  13. import TabRegion, { TabOption } from "../TabRegion";
  14. import Heading from "../values-form/Heading";
  15. import Helper from "../values-form/Helper";
  16. import Input from "./field-components/Input";
  17. import { PorterFormContext } from "./PorterFormContextProvider";
  18. import Checkbox from "./field-components/Checkbox";
  19. import KeyValueArray from "./field-components/KeyValueArray";
  20. import styled from "styled-components";
  21. import SaveButton from "../SaveButton";
  22. import ArrayInput from "./field-components/ArrayInput";
  23. import Select from "./field-components/Select";
  24. import ServiceIPList from "./field-components/ServiceIPList";
  25. import ResourceList from "./field-components/ResourceList";
  26. import VeleroForm from "../forms/VeleroForm";
  27. interface Props {
  28. leftTabOptions?: TabOption[];
  29. rightTabOptions?: TabOption[];
  30. renderTabContents?: (
  31. currentTab: string,
  32. submitValues?: any
  33. ) => React.ReactElement;
  34. saveButtonText?: string;
  35. }
  36. const PorterForm: React.FC<Props> = (props) => {
  37. const { formData, isReadOnly, validationInfo, onSubmit } = useContext(
  38. PorterFormContext
  39. );
  40. const [currentTab, setCurrentTab] = useState(
  41. formData.tabs.length > 0 ? formData.tabs[0].name : ""
  42. );
  43. const renderSectionField = (field: FormField): JSX.Element => {
  44. const bundledProps = {
  45. ...field,
  46. isReadOnly,
  47. };
  48. switch (field.type) {
  49. case "heading":
  50. return <Heading>{field.label}</Heading>;
  51. case "subtitle":
  52. return <Helper>{field.label}</Helper>;
  53. case "input":
  54. return <Input {...(bundledProps as InputField)} />;
  55. case "checkbox":
  56. return <Checkbox {...(bundledProps as CheckboxField)} />;
  57. case "key-value-array":
  58. return <KeyValueArray {...(bundledProps as KeyValueArrayField)} />;
  59. case "array-input":
  60. return <ArrayInput {...(bundledProps as ArrayInputField)} />;
  61. case "select":
  62. return <Select {...(bundledProps as SelectField)} />;
  63. case "service-ip-list":
  64. return <ServiceIPList {...(bundledProps as ServiceIPListField)} />;
  65. case "resource-list":
  66. return <ResourceList {...(bundledProps as ResourceListField)} />;
  67. case "velero-create-backup":
  68. return <VeleroForm />;
  69. }
  70. return <p>Not Implemented: {(field as any).type}</p>;
  71. };
  72. const renderSection = (section: Section): JSX.Element => {
  73. return (
  74. <>
  75. {section.contents.map((field, i) => {
  76. return (
  77. <React.Fragment key={field.id}>
  78. {renderSectionField(field)}
  79. </React.Fragment>
  80. );
  81. })}
  82. </>
  83. );
  84. };
  85. const getTabOptions = (): TabOption[] => {
  86. return (props.leftTabOptions || [])
  87. .concat(
  88. formData.tabs.map((tab) => {
  89. return { label: tab.label, value: tab.name };
  90. })
  91. )
  92. .concat(props.rightTabOptions || []);
  93. };
  94. const renderTab = (name: string): JSX.Element => {
  95. const tab = formData.tabs.filter((tab) => tab.name == name)[0];
  96. if (!tab) {
  97. // tab is external
  98. return props.renderTabContents ? props.renderTabContents(name) : <></>;
  99. }
  100. return (
  101. <>
  102. {tab.sections.map((section) => {
  103. return (
  104. <React.Fragment key={section.name}>
  105. {renderSection(section)}
  106. </React.Fragment>
  107. );
  108. })}
  109. </>
  110. );
  111. };
  112. return (
  113. <>
  114. <TabRegion
  115. options={getTabOptions()}
  116. currentTab={currentTab}
  117. setCurrentTab={setCurrentTab}
  118. >
  119. <StyledPorterForm>{renderTab(currentTab)}</StyledPorterForm>
  120. </TabRegion>
  121. <SaveButton
  122. text={props.saveButtonText || "Deploy"}
  123. onClick={onSubmit}
  124. makeFlush
  125. status={validationInfo.validated ? "" : validationInfo.error}
  126. disabled={isReadOnly || !validationInfo.validated}
  127. />
  128. <Spacer />
  129. </>
  130. );
  131. };
  132. export default PorterForm;
  133. const Spacer = styled.div`
  134. height: 50px;
  135. `;
  136. const StyledPorterForm = styled.div`
  137. width: 100%;
  138. height: 100%;
  139. background: #ffffff11;
  140. color: #ffffff;
  141. padding: 0px 35px 25px;
  142. position: relative;
  143. border-radius: 5px;
  144. font-size: 13px;
  145. overflow: auto;
  146. `;