-
Notifications
You must be signed in to change notification settings - Fork 1
07 Agregar el componente ListTile
Inicializamos el estado del componente src/components/Board.js, el cual va a tener el nombre del board y sus listas asociadas:
import React, { Component } from 'react';
class Board extends Component {
// ####### Agregar: COMIENZO bloque
constructor(props) {
super(props);
this.state = { name: "", lists: [] };
this.boardId = this.props.match.params.boardId;
}
// ####### Agregar: FIN bloque
render() {
return (
...Luego, obtenemos la información del board desde nuestra API, y actualizamos el estado del componente:
class Board extends Component {
constructor(props) {
super(props);
this.state = { name: "", lists: [] };
this.boardId = this.props.match.params.boardId;
}
+
+ componentDidMount() {
+ fetch(`/boards/${this.boardId}`).then(res => res.json()).then((board) => {
+ this.setState({
+ name: board.name,
+ lists: board.lists
+ });
+ });
+ }
+
render() {
return (
<div className="Board">
<div className="Board-content">
<div className="Board-header">
<span className="Board-header-btn">
- Workshop
+ {this.state.name}
</span>
</div>Editamos el archivo src/components/Board.js, invocando el futuro componente. Para esto, primero debemos importar el componente:
import React, { Component } from 'react';
+ import ListTile from './ListTile';Y luego, lo invocamos, pasándole el nombre de cada board en particular:
<div className="Board-canvas">
<div className="Board-canvas-content">
+ {
+ this.state.lists.map((list) => {
+ return <ListTile id={list.id} name={list.name} key={list.id} boardId={this.boardId} cards={list.cards}/>
+ })
+ }
- <div className="ListTile">
- <div className="ListTile-content">
- <div className="ListTile-header">
- <div className="ListTile-header-title">
- To Do
- </div>
- </div>
- <div className="ListTile-cards">
- <div className="CardTile">
- <div className="CardTile-details">
- <span className="CardTile-title">Create Wiki</span>
- </div>
- </div>
- <div className="CardTile">
- <div className="CardTile-details">
- <span className="CardTile-title">Setup VM</span>
- </div>
- </div>
- </div>
- <a className="ListTile-add-card">Add a card…</a>
- </div>
- </div>
<div className="NewList">
<a className="NewList-placeholder">Add a list…</a>
</div>
</div>
</div>Creamos el archivo src/components/ListTile.js, cuyo contenido debería ser el siguiente:
import React, { Component } from 'react';
class ListTile extends Component {
render() {
return (
<div className="ListTile">
<div className="ListTile-content">
<div className="ListTile-header">
<div className="ListTile-header-title">
{this.props.name}
</div>
</div>
<div className="ListTile-cards">
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Create Wiki</span>
</div>
</div>
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Setup VM</span>
</div>
</div>
</div>
<a className="ListTile-add-card">Add a card…</a>
</div>
</div>
);
}
}
export default ListTile;Probamos en el browser:
A continuación, vamos a agregar un formulario a nuestras listas, que nos permita agregar nuevas tarjetas a cada una de ellas.
Para ello, primero modificaremos nuestro componente para renderizar dicho formulario:
<div className="ListTile">
<div className="ListTile-content">
<div className="ListTile-header">
<div className="ListTile-header-title">
{this.props.name}
</div>
</div>
<div className="ListTile-cards">
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Create Wiki</span>
</div>
</div>
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Setup VM</span>
</div>
</div>
+ <div>
+ <form>
+ <textarea className="ListTile-composer"></textarea>
+ <input className="ListTile-composer-add" type="submit" value="Add"/>
+ <div className="ListTile-composer-close"></div>
+ </form>
+ </div>
</div>
<a className="ListTile-add-card">Add a card…</a>
</div>
</div>Deberíamos ver lo siguiente:
Ahora, vamos a actualizar nuestro componente para que se muestre o el formulario de agregar una nueva tarjeta, o el link que habilitaría dicho formulario. Para esto, definiremos una propiedad en nuestro componente para indicar si se está agregando o no una nueva tarjeta:
class ListTile extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ composing: false,
+ newCardText: ''
+ };
+ }
+
+ toggleComposer = () => {
+ this.setState(prevState => ({
+ composing: !prevState.composing
+ }));
+ }
+
render() {
return (
<div className="ListTile">
<div className="ListTile-content">
<div className="ListTile-header">
<div className="ListTile-header-title">
{this.props.name}
</div>
</div>
<div className="ListTile-cards">
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Create Wiki</span>
</div>
</div>
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Setup VM</span>
</div>
</div>
+ {this.state.composing &&
<div>
<form>
<textarea className="ListTile-composer"></textarea>
<input className="ListTile-composer-add" type="submit" value="Add"/>
- <div className="ListTile-composer-close"></div>
+ <div className="ListTile-composer-close" onClick={this.toggleComposer}></div>
</form>
</div>
+ }
</div>
- <a className="ListTile-add-card">Add a card…</a>
+ {!this.state.composing &&
+ <a className="ListTile-add-card" onClick={this.toggleComposer}>Add a card…</a>
+ }
</div>
</div>
);
}Finalmente, implementamos el método que realmente agrega la nueva tarjeta a nuestra lista, una vez presionado el botón "Add":
class ListTile extends Component {
constructor(props) {
super(props);
this.state = {
+ cards: props.cards,
composing: false,
newCardText: ''
};
}
toggleComposer = () => {
this.setState(prevState => ({
composing: !prevState.composing
}));
}
+ newCardTextChange = (e) => {
+ this.setState({
+ newCardText: e.target.value
+ });
+ }
+
+ handleSubmit = (e) => {
+ e.preventDefault();
+
+ fetch(`/boards/${this.props.boardId}/lists/${this.props.id}/cards`, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ card: {
+ text: this.state.newCardText
+ }
+ }),
+ }).then((response) => {
+ if (!response.ok) {
+ throw Error(response.statusText);
+ }
+ return response;
+ }).then((response) => {
+ return response.json();
+ }).then((card) => {
+ this.toggleComposer();
+ this.setState(prevState => ({
+ cards: [...prevState.cards, card],
+ newCardText: ''
+ }))
+ }).catch((error) => {
+ console.log(error);
+ });
+ }
+
render() {
return (
<div className="ListTile">
<div className="ListTile-content">
<div className="ListTile-header">
<div className="ListTile-header-title">
{this.props.name}
</div>
</div>
<div className="ListTile-cards">
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Create Wiki</span>
</div>
</div>
<div className="CardTile">
<div className="CardTile-details">
<span className="CardTile-title">Setup VM</span>
</div>
</div>
{this.state.composing &&
<div>
- <form>
+ <form onSubmit={this.handleSubmit}>
- <textarea className="ListTile-composer"></textarea>
+ <textarea className="ListTile-composer" value={this.state.newCardText} onChange={this.newCardTextChange}></textarea>
<input className="ListTile-composer-add" type="submit" value="Add"/>
<div className="ListTile-composer-close" onClick={this.toggleComposer}></div>
</form>
</div>
}
</div>
{!this.state.composing &&
<a className="ListTile-add-card" onClick={this.toggleComposer}>Add a card…</a>
}
</div>
</div>
);
}
}Hasta ahora, las tarjetas que vemos en nuestras listas son siempre las mismas. Vamos a modificar nuestro componente para que obtenga las tarjetas del board desde la API.
+ {
+ this.state.cards.map((card) => {
+ return (
+ <div className="CardTile" key={card.id}>
+ <div className="CardTile-details">
+ <span className="CardTile-title">{card.text}</span>
+ </div>
+ </div>
+ )
+ })
+ }
- <div className="CardTile">
- <div className="CardTile-details">
- <span className="CardTile-title">Create Wiki</span>
- </div>
- </div>
- <div className="CardTile">
- <div className="CardTile-details">
- <span className="CardTile-title">Setup VM</span>
- </div>
- </div>git add -A
git commit -m "Componentizar las listas"
