Added delete option for pictures

This commit is contained in:
dbroqua 2018-12-02 17:40:23 +01:00
parent 50992176fb
commit b6790f6926
3 changed files with 150 additions and 73 deletions

View file

@ -36,3 +36,10 @@ top: 33%;
.carousel-inner img { .carousel-inner img {
max-width: 100%; max-width: 100%;
} }
.deletePicture {
position: absolute;
right: 16px;
top: 16px;
}

View file

@ -17,15 +17,15 @@ import {
} from 'react-icons/fa'; } from 'react-icons/fa';
import { import {
NotificationContainer, NotificationContainer,
NotificationManager NotificationManager,
} from 'react-notifications'; } from 'react-notifications';
import Navigation from './Navigation'; import Navigation from './Navigation';
import Header from './Header'; import Header from './Header';
import API from './Api'; import API from './Api';
import VegetableMain from './Vegetable/Main' import VegetableMain from './Vegetable/Main';
import VegetableCarousel from './Vegetable/Carousel' import VegetableCarousel from './Vegetable/Carousel';
import VegetableMap from './Vegetable/Map' import VegetableMap from './Vegetable/Map';
import VegetablesProperties from './Vegetable/Properties' import VegetablesProperties from './Vegetable/Properties';
import './Vegetable.css'; import './Vegetable.css';
import 'react-notifications/lib/notifications.css'; import 'react-notifications/lib/notifications.css';
@ -42,10 +42,12 @@ class Vegetable extends Component {
description: '', description: '',
Pictures: [], Pictures: [],
}, },
uploadPictures: 0,
uploadedPictures: 0,
imagePreviewUrl: '', imagePreviewUrl: '',
imagesPreviewUrls: [], imagesPreviewUrls: [],
activeTab: '1', activeTab: '1',
availableProperties: [] availableProperties: [],
}; };
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this);
@ -53,8 +55,8 @@ class Vegetable extends Component {
this.updateVegetable = this.updateVegetable.bind(this); this.updateVegetable = this.updateVegetable.bind(this);
this.changeMainPicture = this.changeMainPicture.bind(this); this.changeMainPicture = this.changeMainPicture.bind(this);
this.addPicture = this.addPicture.bind(this); this.addPicture = this.addPicture.bind(this);
this.deletePicture = this.deletePicture.bind(this);
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this);
this.postPicture = this.postPicture.bind(this);
this.updateValueFromChild = this.updateValueFromChild.bind(this); this.updateValueFromChild = this.updateValueFromChild.bind(this);
this.getVegetable(props.match.params.categoryId, props.match.params.vegetableId); this.getVegetable(props.match.params.categoryId, props.match.params.vegetableId);
@ -102,21 +104,73 @@ class Vegetable extends Component {
addPicture(file, reader) { addPicture(file, reader) {
this.setState(prevState => ({ this.setState(prevState => ({
Vegetable: { uploadPictures: prevState.uploadPictures + 1,
...prevState.Vegetable, }), () => {
Pictures: [ const fd = new FormData();
...prevState.Vegetable.Pictures, NotificationManager.info('Sauvegarde de l\'image en cours...');
file
]
},
imagesPreviewUrls: [
...prevState.imagesPreviewUrls,
reader.result
],
activeIndex: prevState.imagesPreviewUrls.length
}));
this.postPicture(file); fd.append('picture', file);
API.post(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures`, fd)
.then((res) => {
const picture = res.data;
this.setState(prevState => ({
uploadedPictures: prevState.uploadedPictures + 1,
Vegetable: {
...prevState.Vegetable,
Pictures: [
...prevState.Vegetable.Pictures,
picture,
],
},
imagesPreviewUrls: [
...prevState.imagesPreviewUrls,
picture.url,
],
activeIndex: prevState.imagesPreviewUrls.length,
}));
NotificationManager.success('Image sauvegardée');
})
.catch(() => {
NotificationManager.error('Impossible d\'ajouter cette image');
});
});
}
deletePicture(id) {
API.delete(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures/${id}`)
.then(() => {
NotificationManager.success('Image supprimée');
const Pictures = this.state.Vegetable.Pictures;
const urls = this.state.imagesPreviewUrls;
let url = null;
for (let i = 0; i < Pictures.length; i++) {
if (Pictures[i].id === id) {
url = Pictures[i].url;
Pictures.splice(i, 1);
break;
}
}
for (let i = 0; i < urls.length; i++) {
if (urls[i] === url) {
urls.splice(i, 1);
break;
}
}
this.setState(prevState => ({
...prevState,
imagesPreviewUrls: urls,
Vegetable: {
...prevState.Vegetable,
Pictures,
},
}));
})
.catch(() => {
NotificationManager.error('Impossible de supprimer cette image');
});
} }
updateVegetable(event) { updateVegetable(event) {
@ -126,12 +180,12 @@ class Vegetable extends Component {
const requests = 1 + this.state.Vegetable.Properties.length; const requests = 1 + this.state.Vegetable.Properties.length;
let requestsDone = 0; let requestsDone = 0;
let isDone = () => { const isDone = () => {
if (requests === requestsDone) { if (requests === requestsDone) {
NotificationManager.success('Sauvegarde terminée'); NotificationManager.success('Sauvegarde terminée');
this.getVegetable(this.props.match.params.categoryId, this.props.match.params.vegetableId); this.getVegetable(this.props.match.params.categoryId, this.props.match.params.vegetableId);
} }
} };
// Patch Vegetable // Patch Vegetable
const fd = new FormData(); const fd = new FormData();
@ -158,7 +212,7 @@ class Vegetable extends Component {
}); });
// Patch or create Properties // Patch or create Properties
this.state.Vegetable.Properties.forEach(propertyItem => { this.state.Vegetable.Properties.forEach((propertyItem) => {
if (propertyItem.id) { if (propertyItem.id) {
API.patch(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/properties/${propertyItem.id}`, propertyItem) API.patch(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/properties/${propertyItem.id}`, propertyItem)
.then((res) => { .then((res) => {
@ -178,35 +232,20 @@ class Vegetable extends Component {
NotificationManager.error(`Impossile de sauvegarder la propriété ayant pour valeur ${propertyItem.value}`); NotificationManager.error(`Impossile de sauvegarder la propriété ayant pour valeur ${propertyItem.value}`);
}); });
} }
}) });
}
postPicture(picture) {
const fd = new FormData();
fd.append('picture', picture);
API.post(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures`, fd)
.then((res) => {
// this.setState({ Category: res.data });
})
.catch(() => {
NotificationManager.error(`Impossible d'ajouter cette image`);
});
} }
getVegetable(categoryId, vegetableId) { getVegetable(categoryId, vegetableId) {
API.get('properties') API.get('properties')
.then(res => { .then((res) => {
//availableProperties // availableProperties
if (res.status === 200) { if (res.status === 200) {
this.setState({ this.setState({
availableProperties: res.data.rows availableProperties: res.data.rows,
}); });
} }
}) })
.catch(e => { .catch((e) => {
NotificationManager.error('Erreur lors de la récupération des types de propriétés'); NotificationManager.error('Erreur lors de la récupération des types de propriétés');
}); });
@ -214,7 +253,7 @@ class Vegetable extends Component {
.then((res) => { .then((res) => {
if (res.status === 200) { if (res.status === 200) {
const item = res.data; const item = res.data;
let images = []; const images = [];
if (item.description === null) { if (item.description === null) {
item.description = ' '; item.description = ' ';
@ -229,7 +268,7 @@ class Vegetable extends Component {
this.setState(prevState => ({ this.setState(prevState => ({
...prevState, ...prevState,
Vegetable: item, Vegetable: item,
imagesPreviewUrls: images imagesPreviewUrls: images,
})); }));
} }
}) })
@ -241,7 +280,7 @@ class Vegetable extends Component {
render() { render() {
return ( return (
<div> <div>
<NotificationContainer/> <NotificationContainer />
<Header /> <Header />
<Container className="Vegetable"> <Container className="Vegetable">
<Navigation categoryId={this.state.Vegetable.Type ? this.state.Vegetable.Type.id : 1} categoryName={this.state.Vegetable.Type ? this.state.Vegetable.Type.name : null} vegetableId={this.state.Vegetable.id || 1} vegetableName={this.state.Vegetable.name} /> <Navigation categoryId={this.state.Vegetable.Type ? this.state.Vegetable.Type.id : 1} categoryName={this.state.Vegetable.Type ? this.state.Vegetable.Type.name : null} vegetableId={this.state.Vegetable.id || 1} vegetableName={this.state.Vegetable.name} />
@ -306,18 +345,21 @@ class Vegetable extends Component {
<TabPane tabId="4"> <TabPane tabId="4">
<VegetableCarousel <VegetableCarousel
addPicture={this.addPicture} addPicture={this.addPicture}
deletePicture={this.deletePicture}
imagesPreviewUrls={this.state.imagesPreviewUrls} imagesPreviewUrls={this.state.imagesPreviewUrls}
activeIndex={this.state.activeIndex} activeIndex={this.state.activeIndex}
pictures={this.state.Vegetable.Pictures}
/> />
</TabPane> </TabPane>
</TabContent> </TabContent>
<Button color="primary" style={{ marginTop: '16px' }} className={this.state.activeTab === '3' ? 'd-none' : ''}> {this.state.uploadPictures === this.state.uploadedPictures ? (
<FaEdit /> <Button color="primary" style={{ marginTop: '16px' }} className={this.state.activeTab === '3' ? 'd-none' : ''}>
{' '} <FaEdit />
Mettre à jour {' '}
</Button> Mettre à jour
</Button>
) : (null)}
</Form> </Form>
</Container> </Container>
</div> </div>

View file

@ -11,18 +11,25 @@ import {
CarouselItem, CarouselItem,
CarouselControl, CarouselControl,
CarouselIndicators, CarouselIndicators,
ListGroup,
ListGroupItem,
Button,
} from 'reactstrap'; } from 'reactstrap';
import { import {
FaFileImage, FaFileImage,
FaTrash,
} from 'react-icons/fa'; } from 'react-icons/fa';
import '../Vegetable.css';
class VegetableCarousel extends Component { class VegetableCarousel extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
imagesPreviewUrls: this.props.imagesPreviewUrls, imagesPreviewUrls: this.props.imagesPreviewUrls,
activeIndex: 0 pictures: this.props.pictures,
activeIndex: 0,
}; };
this.onPictureChange = this.onPictureChange.bind(this); this.onPictureChange = this.onPictureChange.bind(this);
@ -34,14 +41,19 @@ class VegetableCarousel extends Component {
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if ( nextProps.imagesPreviewUrls) { if (nextProps.imagesPreviewUrls) {
this.setState({ this.setState({
imagesPreviewUrls: nextProps.imagesPreviewUrls imagesPreviewUrls: nextProps.imagesPreviewUrls,
}); });
} }
if ( nextProps.activeIndex) { if (nextProps.activeIndex) {
this.setState({ this.setState({
activeIndex: nextProps.activeIndex activeIndex: nextProps.activeIndex,
});
}
if (nextProps.pictures) {
this.setState({
pictures: nextProps.pictures,
}); });
} }
} }
@ -110,35 +122,51 @@ class VegetableCarousel extends Component {
id="Pictures" id="Pictures"
onChange={e => this.onPictureChange(e)} onChange={e => this.onPictureChange(e)}
/> />
<ListGroup>
{this.state.pictures.map((item, key) => (
<ListGroupItem key={key}>
<Button
onClick={() => this.props.deletePicture(item.id)}
color="danger"
className="deletePicture"
>
<FaTrash />
</Button>
<img className="img-thumbnail" src={item.url} alt={item.url} />
</ListGroupItem>
))}
</ListGroup>
</Col> </Col>
</FormGroup> </FormGroup>
</Col> </Col>
<Col xs={12} sm={8}> <Col xs={12} sm={8}>
{this.state.imagesPreviewUrls {this.state.imagesPreviewUrls
&& this.state.imagesPreviewUrls.length > 0 && this.state.imagesPreviewUrls.length > 0
? (<Carousel ? (
<Carousel
activeIndex={activeIndex} activeIndex={activeIndex}
next={this.next} next={this.next}
previous={this.previous} previous={this.previous}
> >
<CarouselIndicators items={this.state.imagesPreviewUrls} activeIndex={activeIndex} onClickHandler={this.goToIndex} /> <CarouselIndicators items={this.state.imagesPreviewUrls} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{this.state.imagesPreviewUrls.map( (item, key) => ( {this.state.imagesPreviewUrls.map((item, key) => (
<CarouselItem <CarouselItem
onExiting={this.onExiting} onExiting={this.onExiting}
onExited={this.onExited} onExited={this.onExited}
key={`Carousel_${key}`} key={`Carousel_${key}`}
> >
<img src={item} alt="Carousel" /> <img src={item} alt="Carousel" />
</CarouselItem> </CarouselItem>
))} ))}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} /> <CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} /> <CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>) </Carousel>
)
: (null) : (null)
} }
</Col> </Col>
</Row> </Row>
) );
} }
} }