github.com/replicatedhq/ship@v0.55.0/web/init/src/components/config_render/ConfigGroup.jsx (about) 1 import React from "react"; 2 import ReactDOM from "react-dom" 3 import Markdown from "react-remarkable"; 4 import each from "lodash/each"; 5 import some from "lodash/some"; 6 import isEmpty from "lodash/isEmpty"; 7 import { ConfigService } from "../../services/ConfigService"; 8 9 import ConfigInput from "./ConfigInput"; 10 import ConfigTextarea from "./ConfigTextarea"; 11 import ConfigSelectOne from "./ConfigSelectOne"; 12 import ConfigItemTitle from "./ConfigItemTitle"; 13 import ConfigCheckbox from "./ConfigCheckbox"; 14 import ConfigFileInput from "./ConfigFileInput"; 15 16 export default class ConfigGroup extends React.Component { 17 18 handleItemChange = (itemName, value, data) => { 19 if (this.props.handleChange) { 20 this.props.handleChange(itemName, value, data); 21 } 22 } 23 24 renderConfigItems = (items, readonly) => { 25 if (!items) return null; 26 return items.map((item, i) => { 27 switch (item.type) { 28 case "text": 29 return ( 30 <ConfigInput 31 key={`${i}-${item.name}`} 32 handleOnChange={this.handleItemChange} 33 inputType="text" 34 hidden={item.hidden} 35 when={item.when} 36 {...item} 37 readonly={readonly} 38 /> 39 ); 40 case "textarea": 41 return ( 42 <ConfigTextarea 43 key={`${i}-${item.name}`} 44 handleOnChange={this.handleItemChange} 45 hidden={item.hidden} 46 when={item.when} 47 {...item} 48 readonly={readonly} 49 /> 50 ); 51 case "bool": 52 return ( 53 <ConfigCheckbox 54 key={`${i}-${item.name}`} 55 handleOnChange={this.handleItemChange} 56 hidden={item.hidden} 57 when={item.when} 58 {...item} 59 readonly={readonly} 60 /> 61 ); 62 case "label": 63 return ( 64 <div key={`${i}-${item.name}`} className="field field-type-label u-marginTop--15"> 65 <ConfigItemTitle 66 title={item.title} 67 recommended={item.recommended} 68 required={item.required} 69 hidden={item.hidden} 70 when={item.when} 71 name={item.name} 72 error={item.error} 73 readonly={readonly} 74 /> 75 </div> 76 ); 77 case "file": 78 return ( 79 <div key={`${i}-${item.name}`}> 80 <ConfigFileInput 81 {...item} 82 title={item.title} 83 recommended={item.recommended} 84 required={item.required} 85 handleChange={this.handleItemChange} 86 hidden={item.hidden} 87 when={item.when} 88 readonly={readonly} 89 /> 90 </div> 91 ); 92 case "select_one": 93 return ( 94 <ConfigSelectOne 95 key={`${i}-${item.name}`} 96 handleOnChange={this.handleItemChange} 97 hidden={item.hidden} 98 when={item.when} 99 {...item} 100 readonly={readonly} 101 /> 102 ); 103 case "heading": 104 return ( 105 <div key={`${i}-${item.name}`} className={`u-marginTop--40 u-marginBottom--15 ${item.hidden || item.when === "false" ? "hidden" : ""}`}> 106 <h3 className="header-color field-section-header">{item.title}</h3> 107 </div> 108 ); 109 case "password": 110 return ( 111 <ConfigInput 112 key={`${i}-${item.name}`} 113 handleOnChange={this.handleItemChange} 114 hidden={item.hidden} 115 when={item.when} 116 inputType="password" 117 {...item} 118 readonly={readonly} 119 /> 120 ); 121 default: 122 return ( 123 <div key={`${i}-${item.name}`}>Unsupported config type <a href="https://help.replicated.com/docs/config-screen/config-yaml/" target="_blank" rel="noopener noreferrer">Check out our docs</a> to see all the support config types.</div> 124 ); 125 } 126 }) 127 } 128 129 addLinkAttributes = () => { 130 if (this.refs.markdown) { 131 each(ReactDOM.findDOMNode(this.refs.markdown).getElementsByTagName("a"), (el) => { 132 el.setAttribute("target", "_blank"); 133 }); 134 } 135 } 136 137 isAtLeastOneItemVisible = () => { 138 const { item } = this.props; 139 if (!item) return false; 140 return some(this.props.item.items, (item) => { 141 if (!isEmpty(item)) { 142 return ConfigService.isVisible(this.props.items, item); 143 } 144 }); 145 } 146 147 componentDidMount() { 148 this.addLinkAttributes(); 149 } 150 151 render() { 152 const { item, readonly } = this.props; 153 const hidden = item && (item.when === "false"); 154 if (hidden || !this.isAtLeastOneItemVisible()) return null; 155 return ( 156 <div className="flex-column flex-auto"> 157 {item && 158 <div id={item.name} className={`flex-auto config-item-wrapper ${this.isAtLeastOneItemVisible() ? "u-marginBottom--40" : ""}`}> 159 <h3 className="header-color field-section-header">{item.title}</h3> 160 {item.description !== "" ? 161 <Markdown 162 options={{ 163 linkTarget: "_blank", 164 linkify: true, 165 }}> 166 {item.description} 167 </Markdown> 168 : null} 169 <div className="config-item"> 170 {this.renderConfigItems(item.items, readonly)} 171 </div> 172 </div> 173 } 174 </div> 175 ); 176 } 177 }