Skip to content

Commit 72cc9ef

Browse files
Merge pull request #1559 from pie-framework/feat/PD-597
Feat/pd 597
2 parents ab842a7 + b7640d2 commit 72cc9ef

10 files changed

Lines changed: 325 additions & 82 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { Group } from 'react-konva';
4+
import { faDelete } from './icons';
5+
import Image from './image';
6+
import { calculate } from './utils';
7+
8+
const DeleteWidget = ({ height, id, width, x, y, points, outlineColor, handleWidgetClick }) => {
9+
let positionX, positionY;
10+
// if points exist we have an irregular form (polygon) and position should be computed
11+
if (points) {
12+
const { x, y } = calculate(points);
13+
positionX = x;
14+
positionY = y;
15+
} else {
16+
positionX = x + width - 20; // 10 pixels to the left
17+
positionY = y + height - 20; // 10 pixels above
18+
}
19+
20+
return (
21+
<Group onClick={() => handleWidgetClick(id)}>
22+
<Image width={20} height={20} x={positionX} y={positionY} src={faDelete} />
23+
</Group>
24+
);
25+
};
26+
27+
DeleteWidget.propTypes = {
28+
id: PropTypes.string.isRequired,
29+
height: PropTypes.number,
30+
width: PropTypes.number,
31+
x: PropTypes.number.isRequired,
32+
y: PropTypes.number.isRequired,
33+
handleWidgetClick: PropTypes.func.isRequired,
34+
points: PropTypes.arrayOf(
35+
PropTypes.shape({
36+
x: PropTypes.number,
37+
y: PropTypes.number,
38+
}),
39+
),
40+
outlineColor: PropTypes.string.isRequired,
41+
};
42+
43+
export default DeleteWidget;

packages/hotspot/configure/src/__tests__/__snapshots__/hotspot-container.test.js.snap

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ exports[`HotspotContainer render renders 1`] = `
1616
onInputClick={[Function]}
1717
setRef={[Function]}
1818
/>
19-
<WithStyles(RawButton)
20-
disabled={false}
21-
label="Undo"
22-
onClick={[Function]}
23-
/>
2419
<WithStyles(RawButton)
2520
disabled={false}
2621
label="Clear all"
@@ -40,6 +35,7 @@ exports[`HotspotContainer render renders 1`] = `
4035
hotspotColor="rgba(137, 183, 244, 0.65)"
4136
imageUrl="https://cdn.fluence.net/image/0240eb1455ce4c4bb6180232347b6aef_W"
4237
multipleCorrect={true}
38+
onDeleteShape={[Function]}
4339
onUpdateImageDimension={[MockFunction]}
4440
onUpdateShapes={[Function]}
4541
outlineColor="blue"

packages/hotspot/configure/src/__tests__/hotspot-container.test.js

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ describe('HotspotContainer', () => {
7878
let w,
7979
onImageUpload = jest.fn(),
8080
onUpdateImageDimension = jest.fn(),
81+
onDeleteShape = jest.fn(),
8182
onUpdateShapes = jest.fn(),
8283
initialModel = model();
8384
beforeEach(() => {
@@ -91,6 +92,7 @@ describe('HotspotContainer', () => {
9192
outlineColor: initialModel.outlineColor,
9293
onUpdateImageDimension: onUpdateImageDimension,
9394
onUpdateShapes: onUpdateShapes,
95+
onDeleteShape: onDeleteShape,
9496
onImageUpload: onImageUpload,
9597
shapes: initialModel.shapes,
9698
...extras,
@@ -210,6 +212,54 @@ describe('HotspotContainer', () => {
210212
});
211213
});
212214

215+
it('onDeleteShape by id', () => {
216+
console.log('wrapper', wrapper.instance());
217+
wrapper.instance().onDeleteShape('7');
218+
expect(onUpdateShapes).toHaveBeenCalledWith(
219+
groupShapes([
220+
{ correct: true, group: 'rectangles', height: 140, id: '0', index: 0, width: 130, x: 1, y: 1 },
221+
{ group: 'rectangles', height: 140, id: '1', index: 1, width: 130, x: 140, y: 1 },
222+
{ group: 'rectangles', height: 140, id: '2', index: 2, width: 130, x: 280, y: 1 },
223+
{
224+
correct: true,
225+
group: 'polygons',
226+
id: '3',
227+
index: 3,
228+
points: [
229+
{ x: 1, y: 148 },
230+
{ x: 1, y: 288 },
231+
{ x: 129, y: 288 },
232+
{ x: 129, y: 148 },
233+
],
234+
},
235+
{
236+
correct: false,
237+
group: 'polygons',
238+
id: '4',
239+
index: 4,
240+
points: [
241+
{ x: 141, y: 151 },
242+
{ x: 141, y: 289 },
243+
{ x: 269, y: 289 },
244+
{ x: 269, y: 151 },
245+
],
246+
},
247+
{
248+
correct: false,
249+
group: 'polygons',
250+
id: '5',
251+
index: 5,
252+
points: [
253+
{ x: 279, y: 150 },
254+
{ x: 279, y: 289 },
255+
{ x: 407, y: 289 },
256+
{ x: 407, y: 150 },
257+
],
258+
},
259+
]),
260+
);
261+
});
262+
213263
it('onUpdateShapes with no shapes', () => {
214264
wrapper.instance().onUpdateShapes([]);
215265

@@ -219,33 +269,6 @@ describe('HotspotContainer', () => {
219269
});
220270
});
221271

222-
it('handleUndo if no new shape was added', () => {
223-
wrapper.instance().handleUndo();
224-
expect(onUpdateShapes).toHaveBeenLastCalledWith({
225-
...initialModel.shapes,
226-
polygons: initialModel.shapes.polygons.slice(0, -1),
227-
});
228-
});
229-
230-
it('handleUndo if new shape was added', () => {
231-
const newShape = {
232-
id: '7',
233-
height: 140,
234-
width: 130,
235-
x: 280,
236-
y: 1,
237-
index: 6,
238-
};
239-
240-
// first, add a new shape
241-
wrapper.instance().state.shapes = getAllShapes({
242-
...initialModel.shapes,
243-
rectangles: [...initialModel.shapes.rectangles, newShape],
244-
});
245-
wrapper.instance().handleUndo();
246-
expect(onUpdateShapes).toBeCalledWith(initialModel.shapes);
247-
});
248-
249272
it('handleClearAll', () => {
250273
wrapper.instance().handleClearAll();
251274
expect(onUpdateShapes).toHaveBeenLastCalledWith({

packages/hotspot/configure/src/hotspot-container.jsx

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@ export class Container extends Component {
3333
shapes: getAllShapes(props.shapes),
3434
};
3535
this.fakeImageHandler = {
36-
cancel: () => {
37-
},
36+
cancel: () => {},
3837
done: (a, url) => this.props.onImageUpload(url),
39-
fileChosen: () => {
40-
},
41-
progress: () => {
42-
}
38+
fileChosen: () => {},
39+
progress: () => {},
4340
};
4441
}
4542

@@ -55,7 +52,7 @@ export class Container extends Component {
5552
insertImage({
5653
...this.fakeImageHandler,
5754
getChosenFile: () => file,
58-
isPasted: true
55+
isPasted: true,
5956
});
6057
}
6158
}
@@ -108,23 +105,18 @@ export class Container extends Component {
108105

109106
onUpdateShapes = (newShapes) => {
110107
const { onUpdateShapes } = this.props;
111-
112108
this.setState(
113109
{ shapes: newShapes },
114110
// always transform shapes array back into shapes map when saving changes
115-
() => onUpdateShapes(groupShapes(newShapes))
111+
() => onUpdateShapes(groupShapes(newShapes)),
116112
);
117113
};
118114

119-
handleUndo = () => {
115+
onDeleteShape = (id) => {
120116
const { shapes } = this.state;
121-
122117
if (shapes && shapes.length) {
123-
// sort by index value
124-
let newShapes = shapes.sort((a, b) => parseInt(a.index) - parseInt(b.index));
125-
126-
newShapes = newShapes ? newShapes.slice(0, newShapes.length - 1) : [];
127-
118+
// filter the deleted shape out
119+
let newShapes = shapes.filter((shape) => shape.id !== id);
128120
this.onUpdateShapes(newShapes);
129121
}
130122
};
@@ -170,12 +162,12 @@ export class Container extends Component {
170162
})}
171163
{...(dragEnabled
172164
? {
173-
onDragExit: this.handleOnDragExit,
174-
onDragLeave: this.handleOnDragExit,
175-
onDragOver: this.handleOnDragOver,
176-
onDrop: this.handleOnDrop,
177-
onPaste: this.handleOnPaste,
178-
}
165+
onDragExit: this.handleOnDragExit,
166+
onDragLeave: this.handleOnDragExit,
167+
onDragOver: this.handleOnDragOver,
168+
onDrop: this.handleOnDrop,
169+
onPaste: this.handleOnPaste,
170+
}
179171
: {})}
180172
>
181173
<div className={classes.toolbar}>
@@ -190,9 +182,7 @@ export class Container extends Component {
190182
}}
191183
/>
192184
)}
193-
194-
<Button disabled={!(shapes && shapes.length)} onClick={this.handleUndo} label="Undo"/>
195-
<Button disabled={!(shapes && shapes.length)} onClick={this.handleClearAll} label="Clear all"/>
185+
<Button disabled={!(shapes && shapes.length)} onClick={this.handleClearAll} label="Clear all" />
196186
</div>
197187

198188
<div
@@ -211,6 +201,7 @@ export class Container extends Component {
211201
multipleCorrect={multipleCorrect}
212202
onUpdateImageDimension={onUpdateImageDimension}
213203
onUpdateShapes={this.onUpdateShapes}
204+
onDeleteShape={this.onDeleteShape}
214205
outlineColor={outlineColor}
215206
shapes={shapes}
216207
strokeWidth={strokeWidth}
@@ -219,7 +210,7 @@ export class Container extends Component {
219210
) : (
220211
<div className={classNames(classes.drawableHeight, classes.centered)}>
221212
<label>Drag and drop or upload image from computer</label>
222-
<br/>
213+
<br />
223214
<UploadControl
224215
label="Upload Image"
225216
onInputClick={this.handleInputClick}
@@ -238,11 +229,11 @@ export class Container extends Component {
238229
<label>
239230
Click and drag to create a hotspot. Click the hotspot to mark correct. Click again to unmark.
240231
</label>
241-
<div className={classes.tooltipArrow}/>
232+
<div className={classes.tooltipArrow} />
242233
</div>
243234
)}
244235

245-
<Help className={classes.icon} onMouseOut={this.toggleTooltip} onMouseOver={this.toggleTooltip}/>
236+
<Help className={classes.icon} onMouseOut={this.toggleTooltip} onMouseOver={this.toggleTooltip} />
246237
</div>
247238
)}
248239
</div>

packages/hotspot/configure/src/hotspot-drawable.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ export class Drawable extends React.Component {
102102
x: currShape.x,
103103
y: currShape.y,
104104
};
105-
106105
// On mouse move don't trigger any event. Put the shapes on this state instead.
107106
this.setState({ stateShapes: newShapesList });
108107
}
@@ -254,6 +253,7 @@ export class Drawable extends React.Component {
254253
outlineColor,
255254
shapes,
256255
strokeWidth,
256+
onDeleteShape,
257257
} = this.props;
258258
const {
259259
stateShapes,
@@ -293,19 +293,19 @@ export class Drawable extends React.Component {
293293
onMouseMove={this.handleMouseMove}
294294
>
295295
<Layer>
296-
{shapesToUse.map((shape, index) => {
296+
{shapesToUse.map((shape, i) => {
297297
const Tag = shape.group === 'polygons' ? Polygon : Rectangle;
298-
299298
return (
300299
<Tag
301300
correct={shape.correct}
302301
isDrawing={isDrawing}
303302
height={shape.height}
304303
hotspotColor={hotspotColor}
305304
id={shape.id}
306-
key={index}
305+
key={i}
307306
onClick={() => this.handleOnSetAsCorrect(shape)}
308307
onDragEnd={this.handleOnDragEnd}
308+
onDeleteShape={onDeleteShape}
309309
outlineColor={outlineColor}
310310
width={shape.width}
311311
x={shape.x}
@@ -364,6 +364,7 @@ Drawable.propTypes = {
364364
multipleCorrect: PropTypes.bool.isRequired,
365365
onUpdateImageDimension: PropTypes.func.isRequired,
366366
onUpdateShapes: PropTypes.func.isRequired,
367+
onDeleteShape: PropTypes.func.isRequired,
367368
outlineColor: PropTypes.string.isRequired,
368369
shapes: PropTypes.array.isRequired,
369370
strokeWidth: PropTypes.number,

0 commit comments

Comments
 (0)