aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/views
diff options
context:
space:
mode:
authorEmiliano Ciavatta2020-05-07 10:25:41 +0000
committerEmiliano Ciavatta2020-05-07 10:25:41 +0000
commitdee7d7dfcbec7ef4475896935873f04d4df0d40f (patch)
tree78b77cd829b77e1efc9bd27e5d79941d8c14404d /frontend/src/views
parent8db3b3b43bec6170a7f1db21772c48c5e270c97b (diff)
Add colors to services dialog
Diffstat (limited to 'frontend/src/views')
-rw-r--r--frontend/src/views/Services.js142
-rw-r--r--frontend/src/views/Services.scss20
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
+}