FormDebugger.tsx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. import React, { Component } from "react";
  2. import styled from "styled-components";
  3. import AceEditor from "react-ace";
  4. import FormWrapper from "components/values-form/FormWrapper";
  5. import CheckboxRow from "components/values-form/CheckboxRow";
  6. import yaml from "js-yaml";
  7. import "shared/ace-porter-theme";
  8. import "ace-builds/src-noconflict/mode-text";
  9. import Heading from "./Heading";
  10. import Helper from "./Helper";
  11. type PropsType = {
  12. goBack: () => void;
  13. };
  14. type StateType = {
  15. rawYaml: string;
  16. showBonusTabs: boolean;
  17. showStateDebugger: boolean;
  18. valuesToOverride: any;
  19. checkbox_a: boolean;
  20. isReadOnly: boolean;
  21. };
  22. const tabOptions = [
  23. { value: "a", label: "Bonus Tab A" },
  24. { value: "b", label: "Bonus Tab B" },
  25. ];
  26. export default class FormDebugger extends Component<PropsType, StateType> {
  27. state = {
  28. rawYaml: initYaml,
  29. showBonusTabs: false,
  30. showStateDebugger: true,
  31. valuesToOverride: {
  32. checkbox_a: {
  33. value: true,
  34. },
  35. } as any,
  36. checkbox_a: true,
  37. isReadOnly: false,
  38. };
  39. renderTabContents = (currentTab: string) => {
  40. return (
  41. <TabWrapper>
  42. {this.state.rawYaml.toString().slice(0, 300) || "No raw YAML inputted."}
  43. </TabWrapper>
  44. );
  45. };
  46. aceEditorRef = React.createRef<AceEditor>();
  47. render() {
  48. let formData = {};
  49. try {
  50. formData = yaml.load(this.state.rawYaml);
  51. } catch (err: any) {
  52. console.log("YAML parsing error.");
  53. }
  54. return (
  55. <StyledFormDebugger>
  56. <Button onClick={this.props.goBack}>
  57. <i className="material-icons">keyboard_backspace</i>
  58. Back
  59. </Button>
  60. <Heading>✨ Form.yaml Editor</Heading>
  61. <Helper>Write and test form.yaml free of consequence.</Helper>
  62. <EditorWrapper>
  63. <AceEditor
  64. ref={this.aceEditorRef}
  65. mode="yaml"
  66. value={this.state.rawYaml}
  67. theme="porter"
  68. onChange={(e: string) => this.setState({ rawYaml: e })}
  69. name="codeEditor"
  70. editorProps={{ $blockScrolling: true }}
  71. height="450px"
  72. width="100%"
  73. style={{
  74. borderRadius: "5px",
  75. border: "1px solid #ffffff22",
  76. marginTop: "27px",
  77. marginBottom: "27px",
  78. }}
  79. showPrintMargin={false}
  80. showGutter={true}
  81. highlightActiveLine={true}
  82. />
  83. </EditorWrapper>
  84. <CheckboxRow
  85. label="Show form state debugger"
  86. checked={this.state.showStateDebugger}
  87. toggle={() =>
  88. this.setState({ showStateDebugger: !this.state.showStateDebugger })
  89. }
  90. />
  91. <CheckboxRow
  92. label="Read-only"
  93. checked={this.state.isReadOnly}
  94. toggle={() =>
  95. this.setState({
  96. isReadOnly: !this.state.isReadOnly,
  97. })
  98. }
  99. />
  100. <CheckboxRow
  101. label="Include non-form dummy tabs"
  102. checked={this.state.showBonusTabs}
  103. toggle={() =>
  104. this.setState({ showBonusTabs: !this.state.showBonusTabs })
  105. }
  106. />
  107. <CheckboxRow
  108. label="checkbox_a"
  109. checked={this.state.checkbox_a}
  110. toggle={() =>
  111. this.setState({
  112. checkbox_a: !this.state.checkbox_a,
  113. // Override the form value for checkbox_a
  114. valuesToOverride: {
  115. checkbox_a: {
  116. value: !this.state.checkbox_a,
  117. },
  118. },
  119. })
  120. }
  121. />
  122. <Heading>🎨 Rendered Form</Heading>
  123. <Br />
  124. <FormWrapper
  125. valuesToOverride={this.state.valuesToOverride}
  126. clearValuesToOverride={() =>
  127. this.setState({ valuesToOverride: null })
  128. }
  129. showStateDebugger={this.state.showStateDebugger}
  130. formData={formData}
  131. isReadOnly={this.state.isReadOnly}
  132. tabOptions={this.state.showBonusTabs ? tabOptions : []}
  133. renderTabContents={
  134. this.state.showBonusTabs ? this.renderTabContents : null
  135. }
  136. onSubmit={(values: any) => {
  137. alert("Check console output.");
  138. console.log("Raw submission values:");
  139. console.log(values);
  140. }}
  141. />
  142. </StyledFormDebugger>
  143. );
  144. }
  145. }
  146. const Br = styled.div`
  147. width: 100%;
  148. height: 12px;
  149. `;
  150. const TabWrapper = styled.div`
  151. background: #ffffff11;
  152. height: 200px;
  153. width: 100%;
  154. border-radius: 5px;
  155. display: flex;
  156. align-items: center;
  157. justify-content: center;
  158. font-size: 13px;
  159. overflow: auto;
  160. padding: 50px;
  161. `;
  162. const EditorWrapper = styled.div`
  163. .ace_editor,
  164. .ace_editor * {
  165. font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas",
  166. monospace !important;
  167. font-size: 12px !important;
  168. font-weight: 400 !important;
  169. letter-spacing: 0 !important;
  170. }
  171. `;
  172. const StyledFormDebugger = styled.div`
  173. position: relative;
  174. `;
  175. const Button = styled.div`
  176. display: flex;
  177. flex-direction: row;
  178. align-items: center;
  179. justify-content: space-between;
  180. font-size: 13px;
  181. cursor: pointer;
  182. font-family: "Work Sans", sans-serif;
  183. border-radius: 20px;
  184. color: white;
  185. height: 35px;
  186. margin-left: -2px;
  187. padding: 0px 8px;
  188. width: 85px;
  189. float: right;
  190. padding-bottom: 1px;
  191. font-weight: 500;
  192. padding-right: 15px;
  193. overflow: hidden;
  194. white-space: nowrap;
  195. text-overflow: ellipsis;
  196. cursor: pointer;
  197. border: 2px solid #969fbbaa;
  198. :hover {
  199. background: #ffffff11;
  200. }
  201. > i {
  202. color: white;
  203. width: 18px;
  204. height: 18px;
  205. color: #969fbbaa;
  206. font-weight: 600;
  207. font-size: 14px;
  208. border-radius: 20px;
  209. display: flex;
  210. align-items: center;
  211. margin-right: 5px;
  212. justify-content: center;
  213. }
  214. `;
  215. const initYaml = `name: Porter Example
  216. hasSource: true
  217. tabs:
  218. - name: main
  219. label: Main
  220. sections:
  221. - name: header
  222. contents:
  223. - type: heading
  224. label: 🍺 Porter Demo Form
  225. - type: subtitle
  226. name: command_description
  227. label: Basic form demonstrating some of the features of form.yaml
  228. - type: string-input
  229. placeholder: "ex: pilsner"
  230. label: Required Field A
  231. required: true
  232. variable: field_a
  233. - type: string-input
  234. placeholder: "ex: sapporo"
  235. required: true
  236. label: Required Field B
  237. variable: field_b
  238. - type: subtitle
  239. label: "Note: Hidden required fields aren't supported yet (global only)"
  240. - name: controlled-by-external
  241. show_if: checkbox_a
  242. contents:
  243. - type: heading
  244. label: Conditional Display (A)
  245. - type: subtitle
  246. label: This section can be externally controlled by the value of checkbox_a
  247. - type: string-input
  248. variable: input_a
  249. placeholder: "Override w/ input_a"
  250. - name: domain_name
  251. show_if: ingress.custom_domain
  252. contents:
  253. - type: array-input
  254. variable: ingress.hosts
  255. label: Domain Name
  256. - name: env
  257. label: Environment
  258. sections:
  259. - name: env_vars
  260. contents:
  261. - type: heading
  262. label: Environment Variables
  263. - type: subtitle
  264. label: Set environment variables for your secrets and environment-specific configuration.
  265. - type: env-key-value-array
  266. label:
  267. variable: container.env.normal
  268. - name: advanced
  269. label: Advanced
  270. sections:
  271. - name: advanced
  272. contents:
  273. - type: heading
  274. label: Some Header
  275. - type: subtitle
  276. label: Some helper text
  277. `;