Skip to content

Commit 5e0d522

Browse files
authored
Merge pull request #1480 from andrewn/bugfix/deleted-collection-sketch
Allow deleted sketches in collections to be removed (fixes #1465)
2 parents 6f1ac99 + 0e1bb3b commit 5e0d522

File tree

5 files changed

+55
-29
lines changed

5 files changed

+55
-29
lines changed

client/modules/User/components/Collection.jsx

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,41 +71,50 @@ ShareURL.propTypes = {
7171
value: PropTypes.string.isRequired,
7272
};
7373

74-
class CollectionItemRowBase extends React.Component {
75-
handleSketchRemove = () => {
76-
if (window.confirm(`Are you sure you want to remove "${this.props.item.project.name}" from this collection?`)) {
77-
this.props.removeFromCollection(this.props.collection.id, this.props.item.project.id);
74+
const CollectionItemRowBase = ({
75+
collection, item, isOwner, removeFromCollection
76+
}) => {
77+
const projectIsDeleted = item.isDeleted;
78+
79+
const handleSketchRemove = () => {
80+
const name = projectIsDeleted ? 'deleted sketch' : item.project.name;
81+
82+
if (window.confirm(`Are you sure you want to remove "${name}" from this collection?`)) {
83+
removeFromCollection(collection.id, item.projectId);
7884
}
79-
}
85+
};
8086

81-
render() {
82-
const { item } = this.props;
83-
const sketchOwnerUsername = item.project.user.username;
84-
const sketchUrl = `/${item.project.user.username}/sketches/${item.project.id}`;
87+
const name = projectIsDeleted ? <span>Sketch was deleted</span> : (
88+
<Link to={`/${item.project.user.username}/sketches/${item.projectId}`}>
89+
{item.project.name}
90+
</Link>
91+
);
8592

86-
return (
87-
<tr
88-
className="sketches-table__row"
89-
>
90-
<th scope="row">
91-
<Link to={sketchUrl}>
92-
{item.project.name}
93-
</Link>
94-
</th>
95-
<td>{format(new Date(item.createdAt), 'MMM D, YYYY h:mm A')}</td>
96-
<td>{sketchOwnerUsername}</td>
97-
<td className="collection-row__action-column ">
93+
const sketchOwnerUsername = projectIsDeleted ? null : item.project.user.username;
94+
95+
return (
96+
<tr
97+
className={`sketches-table__row ${projectIsDeleted ? 'is-deleted' : ''}`}
98+
>
99+
<th scope="row">
100+
{name}
101+
</th>
102+
<td>{format(new Date(item.createdAt), 'MMM D, YYYY h:mm A')}</td>
103+
<td>{sketchOwnerUsername}</td>
104+
<td className="collection-row__action-column ">
105+
{isOwner &&
98106
<button
99107
className="collection-row__remove-button"
100-
onClick={this.handleSketchRemove}
108+
onClick={handleSketchRemove}
101109
aria-label="Remove sketch from collection"
102110
>
103111
<RemoveIcon focusable="false" aria-hidden="true" />
104112
</button>
105-
</td>
106-
</tr>);
107-
}
108-
}
113+
}
114+
</td>
115+
</tr>);
116+
};
117+
109118

110119
CollectionItemRowBase.propTypes = {
111120
collection: PropTypes.shape({
@@ -114,14 +123,17 @@ CollectionItemRowBase.propTypes = {
114123
}).isRequired,
115124
item: PropTypes.shape({
116125
createdAt: PropTypes.string.isRequired,
126+
projectId: PropTypes.string.isRequired,
127+
isDeleted: PropTypes.bool.isRequired,
117128
project: PropTypes.shape({
118129
id: PropTypes.string.isRequired,
119130
name: PropTypes.string.isRequired,
120131
user: PropTypes.shape({
121132
username: PropTypes.string.isRequired
122-
})
133+
}),
123134
}).isRequired,
124135
}).isRequired,
136+
isOwner: PropTypes.bool.isRequired,
125137
user: PropTypes.shape({
126138
username: PropTypes.string,
127139
authenticated: PropTypes.bool.isRequired
@@ -342,6 +354,7 @@ class Collection extends React.Component {
342354

343355
render() {
344356
const title = this.hasCollection() ? this.getCollectionName() : null;
357+
const isOwner = this.isOwner();
345358

346359
return (
347360
<main className="collection-container" data-has-items={this.hasCollectionItems() ? 'true' : 'false'}>
@@ -372,6 +385,7 @@ class Collection extends React.Component {
372385
user={this.props.user}
373386
username={this.getUsername()}
374387
collection={this.props.collection}
388+
isOwner={isOwner}
375389
/>))}
376390
</tbody>
377391
</table>

client/styles/components/_sketch-list.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@
8585
}
8686
}
8787

88+
.sketches-table__row.is-deleted > * {
89+
font-style: italic;
90+
}
91+
8892
.sketches-table thead {
8993
font-size: #{12 / $base-font-size}rem;
9094
@include themify() {

server/controllers/collection.controller/addProjectToCollection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export default function addProjectToCollection(req, res) {
3232
return null;
3333
}
3434

35-
const projectInCollection = collection.items.find(p => p.project._id === project._id);
35+
const projectInCollection = collection.items.find(p => p.projectId === project._id);
3636

3737
if (projectInCollection) {
3838
sendFailure(404, 'Project already in collection');

server/controllers/collection.controller/removeProjectFromCollection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default function addProjectToCollection(req, res) {
2323
return null;
2424
}
2525

26-
const project = collection.items.find(p => p.project._id === projectId);
26+
const project = collection.items.find(p => p.projectId === projectId);
2727

2828
if (project != null) {
2929
project.remove();

server/models/collection.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ collectedProjectSchema.virtual('id').get(function getId() {
1515
return this._id.toHexString();
1616
});
1717

18+
collectedProjectSchema.virtual('projectId').get(function projectId() {
19+
return this.populated('project');
20+
});
21+
22+
collectedProjectSchema.virtual('isDeleted').get(function isDeleted() {
23+
return this.project == null;
24+
});
25+
1826
collectedProjectSchema.set('toJSON', {
1927
virtuals: true
2028
});

0 commit comments

Comments
 (0)