FormDebugger.tsx 8.6 KB

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