From 3f4cb8e26b6ed063e89874a51e7ca8405a614e5f Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Sat, 17 Oct 2020 19:10:37 +0200 Subject: [PATCH] Added undo buttons for deleting properties off a creature --- .../api/creature/CreatureProperties.js | 22 +++++++++++++++++-- app/imports/api/parenting/softRemove.js | 9 ++++++-- .../ui/components/snackbars/Snackbars.vue | 11 ++++++++-- .../CreaturePropertyDialog.vue | 12 +++++++++- app/imports/ui/creature/slots/Slots.vue | 21 ++++++++++++++---- .../ui/properties/shared/getPropertyTitle.js | 6 +++++ 6 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 app/imports/ui/properties/shared/getPropertyTitle.js 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 @@