diff options
Diffstat (limited to 'frontend/src/views')
-rw-r--r-- | frontend/src/views/Services.js | 142 | ||||
-rw-r--r-- | frontend/src/views/Services.scss | 20 |
2 files changed, 122 insertions, 40 deletions
diff --git a/frontend/src/views/Services.js b/frontend/src/views/Services.js index 1b3789d..66d99c6 100644 --- a/frontend/src/views/Services.js +++ b/frontend/src/views/Services.js @@ -8,59 +8,131 @@ class Services extends Component { constructor(props) { super(props); + this.alphabet = 'abcdefghijklmnopqrstuvwxyz'; + this.colors = ["#E53935", "#D81B60", "#8E24AA", "#5E35B1", "#3949AB", "#1E88E5", "#039BE5", "#00ACC1", + "#00897B", "#43A047", "#7CB342", "#9E9D24", "#F9A825", "#FB8C00", "#F4511E", "#6D4C41"]; + this.state = { services: {}, - port: "", - portValid: false - } + port: 0, + portValid: false, + name: "", + nameValid: false, + color: this.colors[0], + colorValid: false, + notes: "" + }; this.portChanged = this.portChanged.bind(this); + this.nameChanged = this.nameChanged.bind(this); + this.notesChanged = this.notesChanged.bind(this); + this.newService = this.newService.bind(this); + this.editService = this.editService.bind(this); + this.saveService = this.saveService.bind(this); + this.loadServices = this.loadServices.bind(this); } componentDidMount() { - axios.get("/api/services").then(res => this.setState({services: res.data})) + this.loadServices(); } portChanged(event) { - let value = event.target.value.replace(/[^\d]/gi, '') - let intValue = parseInt(value) - this.setState({port: value, portValid: intValue > 0 && intValue <= 65565}) + let value = event.target.value.replace(/[^\d]/gi, ''); + let port = 0; + if (value !== "") { + port = parseInt(value); + } + this.setState({port: port}); + } + nameChanged(event) { + let value = event.target.value.replace(/[\s]/gi, '_').replace(/[^\w]/gi, '').toLowerCase(); + this.setState({name: value}); + } + notesChanged(event) { + this.setState({notes: event.target.value}); } + newService() { + this.setState({name: "", port: 0, notes: ""}); + } - render() { - let curl = createCurlCommand("/services", { - "port": this.state.port, - "name": "aaaaa", - "color": "#fff", - "notes": "aaa" - }) + editService(service) { + this.setState({name: service.name, port: service.port, color: service.color, notes: service.notes}); + } + + saveService() { + if (this.state.portValid && this.state.nameValid) { + axios.put("/api/services", { + name: this.state.name, + port: this.state.port, + color: this.state.color, + notes: this.state.notes + }); + + this.newService(); + this.loadServices(); + } + } + + loadServices() { + axios.get("/api/services").then(res => this.setState({services: res.data})); + } + + componentDidUpdate(prevProps, prevState, snapshot) { + if (this.state.name != null && prevState.name !== this.state.name) { + this.setState({ + nameValid: this.state.name.length >= 3 + }); + } + if (prevState.port !== this.state.port) { + this.setState({ + portValid: this.state.port > 0 && this.state.port <= 65565 + }); + } + } + render() { + let output = ""; + if (!this.state.portValid) { + output += "assert(1 <= port <= 65565)\n"; + } + if (!this.state.nameValid) { + output += "assert(len(name) >= 3)\n"; + } + if (output === "") { + output = createCurlCommand("/services", { + "port": this.state.port, + "name": this.state.name, + "color": this.state.color, + "notes": this.state.notes + }); + } let rows = Object.values(this.state.services).map(s => <tr> - <td><Button size="sm" style={{ - "backgroundColor": s.color - }}>edit</Button></td> + <td><Button variant="btn-edit" size="sm" + onClick={() => this.editService(s)} style={{ "backgroundColor": s.color }}>edit</Button></td> <td>{s.port}</td> <td>{s.name}</td> </tr> - ) - - + ); + let colorButtons = this.colors.map((color, i) => + <Button size="sm" className="btn-color" key={"button" + this.alphabet[i]} + style={{"backgroundColor": color, "borderColor": this.state.color === color ? "#fff" : color}} + onClick={() => this.setState({color: color})}>{this.alphabet[i]}</Button>); return ( <Modal {...this.props} show="true" size="lg" - aria-labelledby="contained-modal-title-vcenter" + aria-labelledby="services-dialog" centered > <Modal.Header> - <Modal.Title id="contained-modal-title-vcenter"> + <Modal.Title id="services-dialog"> ~/services </Modal.Title> </Modal.Header> @@ -71,9 +143,9 @@ class Services extends Component { <Table borderless size="sm" className="services-list"> <thead> <tr> - <th><Button size="sm">new</Button></th> - <th>name</th> + <th><Button size="sm" onClick={this.newService}>new</Button></th> <th>port</th> + <th>name</th> </tr> </thead> <tbody> @@ -86,31 +158,26 @@ class Services extends Component { <Form.Group controlId="servicePort"> <Form.Label>port:</Form.Label> <Form.Control type="text" onChange={this.portChanged} value={this.state.port} /> - <Form.Text className="text-muted"> - {!this.state.portValid ? "assert(1 <= port <= 65565)" : ""} - </Form.Text> </Form.Group> <Form.Group controlId="serviceName"> <Form.Label>name:</Form.Label> - <Form.Control type="text" required min={3} max={16} /> - <Form.Text className="text-muted"> - {"assert(len(name) >= 3)"} - </Form.Text> + <Form.Control type="text" onChange={this.nameChanged} value={this.state.name}/> </Form.Group> <Form.Group controlId="serviceColor"> <Form.Label>color:</Form.Label> <ButtonGroup aria-label="Basic example"> - <Button variant="secondary">Left</Button> - <Button variant="secondary">Middle</Button> - <Button variant="secondary">Right</Button> + {colorButtons.slice(0,8)} + </ButtonGroup> + <ButtonGroup aria-label="Basic example"> + {colorButtons.slice(8,18)} </ButtonGroup> </Form.Group> <Form.Group controlId="serviceNotes"> <Form.Label>notes:</Form.Label> - <Form.Control type="textarea" /> + <Form.Control as="textarea" rows={3} onChange={this.notesChanged} value={this.state.notes} /> </Form.Group> </Form> @@ -122,8 +189,7 @@ class Services extends Component { <Row> <Col md={12}> <InputGroup> - <FormControl as="textarea" rows={9} className="curl-output" readOnly={true}>{curl} - </FormControl> + <FormControl as="textarea" rows={4} className="curl-output" readOnly={true} value={output}/> </InputGroup> </Col> @@ -131,7 +197,7 @@ class Services extends Component { </Container> </Modal.Body> <Modal.Footer className="dialog-footer"> - <Button variant="green" onClick={this.props.onHide}>save</Button> + <Button variant="green" onClick={this.saveService}>save</Button> <Button variant="red" onClick={this.props.onHide}>close</Button> </Modal.Footer> </Modal> diff --git a/frontend/src/views/Services.scss b/frontend/src/views/Services.scss index fd65beb..2abb55e 100644 --- a/frontend/src/views/Services.scss +++ b/frontend/src/views/Services.scss @@ -1,3 +1,5 @@ +@import '../colors.scss'; + .curl-output { width: 100%; font-size: 13px; @@ -5,12 +7,26 @@ .services-list { .btn { - width: 150px; + width: 70px; + } + + td { + background-color: $color-primary-2; + border-top: 2px solid $color-primary-0; + vertical-align: middle; + } + + th { + background-color: $color-primary-1; } } +.btn-color { + border: 3px solid #fff; +} + .dialog-footer { .btn { width: 80px; } -}
\ No newline at end of file +} |