diff --git a/app/imports/api/creature/CreatureProperties.js b/app/imports/api/creature/CreatureProperties.js
index de3027b3..8ba1f6a2 100644
--- a/app/imports/api/creature/CreatureProperties.js
+++ b/app/imports/api/creature/CreatureProperties.js
@@ -9,7 +9,7 @@ import { recomputeCreature } from '/imports/api/creature/computation/recomputeCr
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
import Creatures from '/imports/api/creature/Creatures.js';
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
-import { softRemove } from '/imports/api/parenting/softRemove.js';
+import { softRemove, restore } from '/imports/api/parenting/softRemove.js';
import SoftRemovableSchema from '/imports/api/parenting/SoftRemovableSchema.js';
import propertySchemasIndex from '/imports/api/properties/computedPropertySchemasIndex.js';
import {
@@ -443,6 +443,23 @@ const softRemoveProperty = new ValidatedMethod({
}
});
+const restoreProperty = new ValidatedMethod({
+ name: 'creatureProperties.restore',
+ validate: new SimpleSchema({
+ _id: SimpleSchema.RegEx.Id
+ }).validator(),
+ mixins: [RateLimiterMixin],
+ rateLimit: {
+ numRequests: 5,
+ timeInterval: 5000,
+ },
+ run({_id}){
+ let property = CreatureProperties.findOne(_id);
+ assertPropertyEditPermission(property, this.userId);
+ restore({_id, collection: CreatureProperties});
+ recomputeCreatures(property);
+ }
+});
export default CreatureProperties;
export {
@@ -456,5 +473,6 @@ export {
selectAmmoItem,
pushToProperty,
pullFromProperty,
- softRemoveProperty,
+ softRemoveProperty,
+ restoreProperty,
};
diff --git a/app/imports/api/parenting/softRemove.js b/app/imports/api/parenting/softRemove.js
index 1b53d348..9ef16f8c 100644
--- a/app/imports/api/parenting/softRemove.js
+++ b/app/imports/api/parenting/softRemove.js
@@ -41,16 +41,21 @@ const restoreError = function(){
};
export function restore({_id, collection}){
- collection = getCollectionByName(collection);
+ if (typeof collection === 'string') {
+ collection = getCollectionByName(collection);
+ }
let numUpdated = collection.update({
_id,
removedWith: {$exists: false}
}, { $unset: {
removed: 1,
removedAt: 1,
- }});
+ }}, {
+ selector: {type: 'any'},
+ },);
if (numUpdated === 0) restoreError();
updateDescendants({
+ collection,
ancestorId: _id,
filter: {
removedWith: _id,
diff --git a/app/imports/ui/components/snackbars/Snackbars.vue b/app/imports/ui/components/snackbars/Snackbars.vue
index 6f3907fb..b6c57603 100644
--- a/app/imports/ui/components/snackbars/Snackbars.vue
+++ b/app/imports/ui/components/snackbars/Snackbars.vue
@@ -10,11 +10,12 @@
{{ snackbar.text }}
- {{ snackbar.callbackName }}
+ {{ snackbar.callbackName }}
diff --git a/app/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue b/app/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue
index 905c13f4..df8f118b 100644
--- a/app/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue
+++ b/app/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue
@@ -66,6 +66,7 @@ import CreatureProperties, {
pushToProperty,
pullFromProperty,
softRemoveProperty,
+ restoreProperty,
} from '/imports/api/creature/CreatureProperties.js';
import Creatures from '/imports/api/creature/Creatures.js';
import PropertyToolbar from '/imports/ui/components/propertyToolbar.vue';
@@ -75,6 +76,7 @@ import PropertyIcon from '/imports/ui/properties/shared/PropertyIcon.vue';
import propertyFormIndex from '/imports/ui/properties/forms/shared/propertyFormIndex.js';
import propertyViewerIndex from '/imports/ui/properties/viewers/shared/propertyViewerIndex.js';
import CreaturePropertiesTree from '/imports/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
+import getPropertyTitle from '/imports/ui/properties/shared/getPropertyTitle.js';
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
import { get, findLast } from 'lodash';
@@ -174,12 +176,20 @@ export default {
});
},
remove(){
- softRemoveProperty.call({_id: this._id});
+ const _id = this._id;
+ softRemoveProperty.call({_id});
if (this.embedded){
this.$emit('removed');
} else {
this.$store.dispatch('popDialogStack');
}
+ this.$store.dispatch('snackbar', {
+ text: `Deleted ${getPropertyTitle(this.model)}`,
+ callbackName: 'undo',
+ callback(){
+ restoreProperty.call({_id});
+ },
+ });
},
selectSubProperty(_id){
this.$store.commit('pushDialogStack', {
diff --git a/app/imports/ui/creature/slots/Slots.vue b/app/imports/ui/creature/slots/Slots.vue
index c4719f0e..695d68bb 100644
--- a/app/imports/ui/creature/slots/Slots.vue
+++ b/app/imports/ui/creature/slots/Slots.vue
@@ -27,7 +27,7 @@
icon
flat
small
- @click="remove(child._id)"
+ @click="remove(child)"
>
delete
@@ -48,8 +48,14 @@