Added delete option for pictures
This commit is contained in:
parent
50992176fb
commit
b6790f6926
3 changed files with 150 additions and 73 deletions
|
@ -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;
|
||||||
|
}
|
118
src/Vegetable.js
118
src/Vegetable.js
|
@ -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 => ({
|
||||||
|
uploadPictures: prevState.uploadPictures + 1,
|
||||||
|
}), () => {
|
||||||
|
const fd = new FormData();
|
||||||
|
NotificationManager.info('Sauvegarde de l\'image en cours...');
|
||||||
|
|
||||||
|
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: {
|
Vegetable: {
|
||||||
...prevState.Vegetable,
|
...prevState.Vegetable,
|
||||||
Pictures: [
|
Pictures: [
|
||||||
...prevState.Vegetable.Pictures,
|
...prevState.Vegetable.Pictures,
|
||||||
file
|
picture,
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
imagesPreviewUrls: [
|
imagesPreviewUrls: [
|
||||||
...prevState.imagesPreviewUrls,
|
...prevState.imagesPreviewUrls,
|
||||||
reader.result
|
picture.url,
|
||||||
],
|
],
|
||||||
activeIndex: prevState.imagesPreviewUrls.length
|
activeIndex: prevState.imagesPreviewUrls.length,
|
||||||
}));
|
}));
|
||||||
|
NotificationManager.success('Image sauvegardée');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
NotificationManager.error('Impossible d\'ajouter cette image');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.postPicture(file);
|
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>
|
||||||
|
|
||||||
|
{this.state.uploadPictures === this.state.uploadedPictures ? (
|
||||||
<Button color="primary" style={{ marginTop: '16px' }} className={this.state.activeTab === '3' ? 'd-none' : ''}>
|
<Button color="primary" style={{ marginTop: '16px' }} className={this.state.activeTab === '3' ? 'd-none' : ''}>
|
||||||
<FaEdit />
|
<FaEdit />
|
||||||
{' '}
|
{' '}
|
||||||
Mettre à jour
|
Mettre à jour
|
||||||
</Button>
|
</Button>
|
||||||
|
) : (null)}
|
||||||
</Form>
|
</Form>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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,19 +122,34 @@ 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}
|
||||||
|
@ -133,12 +160,13 @@ class VegetableCarousel extends Component {
|
||||||
))}
|
))}
|
||||||
<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>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue