From d999fb46a72bc2bbf1a3d1c61e3854902ec80985 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 9 Aug 2021 17:57:35 +0200 Subject: [PATCH 1/7] Fixed a warning about source map failure when trying to define a scss variable --- .../ui/properties/components/skills/SkillListTile.vue | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/imports/ui/properties/components/skills/SkillListTile.vue b/app/imports/ui/properties/components/skills/SkillListTile.vue index 847fc56f..dacfb26b 100644 --- a/app/imports/ui/properties/components/skills/SkillListTile.vue +++ b/app/imports/ui/properties/components/skills/SkillListTile.vue @@ -80,12 +80,6 @@ export default { - - From 6364549d508eed9f055f4d5338c3771a6649488e Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 9 Aug 2021 18:00:55 +0200 Subject: [PATCH 2/7] Added pretty url's from v1 --- .../creature/creatures/getCreatureUrlName.js | 5 ++++ app/imports/ui/layouts/Sidebar.vue | 3 ++- app/imports/ui/pages/CharacterList.vue | 3 ++- app/imports/ui/router.js | 11 +-------- app/package-lock.json | 23 +++++++++++-------- app/package.json | 1 + 6 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 app/imports/api/creature/creatures/getCreatureUrlName.js diff --git a/app/imports/api/creature/creatures/getCreatureUrlName.js b/app/imports/api/creature/creatures/getCreatureUrlName.js new file mode 100644 index 00000000..de8c1b7c --- /dev/null +++ b/app/imports/api/creature/creatures/getCreatureUrlName.js @@ -0,0 +1,5 @@ +import getSlug from 'speakingurl'; + +export default function getCreatureUrlName({name}){ + return getSlug(name, {maintainCase: true}) || '-'; +} diff --git a/app/imports/ui/layouts/Sidebar.vue b/app/imports/ui/layouts/Sidebar.vue index 66777361..fdd4fcb9 100644 --- a/app/imports/ui/layouts/Sidebar.vue +++ b/app/imports/ui/layouts/Sidebar.vue @@ -66,9 +66,10 @@ import Creatures from '/imports/api/creature/creatures/Creatures.js'; import CreatureFolders from '/imports/api/creature/creatureFolders/CreatureFolders.js'; import CreatureFolderList from '/imports/ui/creature/creatureList/CreatureFolderList.vue'; + import getCreatureUrlName from '/imports/api/creature/creatures/getCreatureUrlName.js'; const characterTransform = function(char){ - char.url = `/character/${char._id}/${char.urlName || '-'}`; + char.url = `/character/${char._id}/${getCreatureUrlName(char)}`; char.initial = char.name && char.name[0] || '?'; return char; }; diff --git a/app/imports/ui/pages/CharacterList.vue b/app/imports/ui/pages/CharacterList.vue index 7ebb9cb4..953530a5 100644 --- a/app/imports/ui/pages/CharacterList.vue +++ b/app/imports/ui/pages/CharacterList.vue @@ -82,9 +82,10 @@ import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js'; import CreatureFolderList from '/imports/ui/creature/creatureList/CreatureFolderList.vue'; import ArchiveButton from '/imports/ui/creature/creatureList/ArchiveButton.vue'; + import getCreatureUrlName from '/imports/api/creature/creatures/getCreatureUrlName.js'; const characterTransform = function(char){ - char.url = `/character/${char._id}/${char.urlName || '-'}`; + char.url = `/character/${char._id}/${getCreatureUrlName(char)}`; char.initial = char.name && char.name[0] || '?'; return char; }; diff --git a/app/imports/ui/router.js b/app/imports/ui/router.js index 8590f16c..0bda3df6 100644 --- a/app/imports/ui/router.js +++ b/app/imports/ui/router.js @@ -130,18 +130,9 @@ RouterFactory.configure(factory => { meta: { title: 'Library', }, - },{ - path: '/character/:id/:urlName', - components: { - default: CharacterSheetPage, - toolbar: CharacterSheetToolbar, - rightDrawer: CharacterSheetRightDrawer, - }, - meta: { - title: 'Character Sheet', - }, },{ path: '/character/:id', + alias: '/character/:id/:urlName', components: { default: CharacterSheetPage, toolbar: CharacterSheetToolbar, diff --git a/app/package-lock.json b/app/package-lock.json index 00b8aabf..68d9f103 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -2330,6 +2330,11 @@ "yallist": "^4.0.0" } }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, "mongo-object": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/mongo-object/-/mongo-object-0.1.4.tgz", @@ -2805,6 +2810,11 @@ "source-map": "^0.6.0" } }, + "speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==" + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -2956,9 +2966,9 @@ } }, "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -2966,13 +2976,6 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } } }, "text-table": { diff --git a/app/package.json b/app/package.json index 8da6b16a..36bfacf1 100644 --- a/app/package.json +++ b/app/package.json @@ -39,6 +39,7 @@ "request": "^2.88.2", "simpl-schema": "^1.12.0", "source-map-support": "^0.5.16", + "speakingurl": "^14.0.1", "styles": "^0.2.1", "underscore": "^1.13.1", "vue": "2.6.10", From a35f9221a2c901759d7bf53602cee740a7ab3b1a Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 9 Aug 2021 18:06:04 +0200 Subject: [PATCH 3/7] Fixed granting XP being accidentally locked behind patreon paid benefits --- .../api/creature/experience/Experiences.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/app/imports/api/creature/experience/Experiences.js b/app/imports/api/creature/experience/Experiences.js index fe16563f..8b6bb22e 100644 --- a/app/imports/api/creature/experience/Experiences.js +++ b/app/imports/api/creature/experience/Experiences.js @@ -90,11 +90,6 @@ const insertExperience = new ValidatedMethod({ throw new Meteor.Error('Experiences.methods.insert.denied', 'You need to be logged in to insert an experience'); } - let tier = getUserTier(this.userId); - if (!tier.paidBenefits){ - throw new Meteor.Error('Experiences.methods.insert.denied', - `The ${tier.name} tier does not allow you to grant experience`); - } let insertedIds = []; creatureIds.forEach(creatureId => { let id = insertExperienceForCreature({experience, creatureId, userId}); @@ -123,11 +118,6 @@ const removeExperience = new ValidatedMethod({ throw new Meteor.Error('Experiences.methods.remove.denied', 'You need to be logged in to remove an experience'); } - let tier = getUserTier(this.userId); - if (!tier.paidBenefits){ - throw new Meteor.Error('Experiences.methods.remove.denied', - `The ${tier.name} tier does not allow you to remove an experience`); - } let experience = Experiences.findOne(experienceId); if (!experience) return; let creatureId = experience.creatureId @@ -168,11 +158,6 @@ const recomputeExperiences = new ValidatedMethod({ throw new Meteor.Error('Experiences.methods.recompute.denied', 'You need to be logged in to recompute a creature\'s experiences'); } - let tier = getUserTier(this.userId); - if (!tier.paidBenefits){ - throw new Meteor.Error('Experiences.methods.recompute.denied', - `The ${tier.name} tier does not allow you to recompute a creature's experiences`); - } assertEditPermission(creatureId, userId); let xp = 0; From 16e2b1249f03f2649b2940d8c57ce18abdfe8623 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 9 Aug 2021 20:54:29 +0200 Subject: [PATCH 4/7] Increased slot filler publication load quantity to 50 --- app/imports/server/publications/slotFillers.js | 2 +- app/imports/ui/creature/slots/SlotFillDialog.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/imports/server/publications/slotFillers.js b/app/imports/server/publications/slotFillers.js index ca1d23b5..a22b8a65 100644 --- a/app/imports/server/publications/slotFillers.js +++ b/app/imports/server/publications/slotFillers.js @@ -50,7 +50,7 @@ Meteor.publish('slotFillers', function(slotId){ } this.autorun(function(){ // Get the limit of the documents the user can fetch - var limit = self.data('limit') || 20; + var limit = self.data('limit') || 50; check(limit, Number); // Get the search term diff --git a/app/imports/ui/creature/slots/SlotFillDialog.vue b/app/imports/ui/creature/slots/SlotFillDialog.vue index 660f83d5..86ce48a5 100644 --- a/app/imports/ui/creature/slots/SlotFillDialog.vue +++ b/app/imports/ui/creature/slots/SlotFillDialog.vue @@ -212,7 +212,7 @@ export default { }, loadMore(){ if (this.currentLimit >= this.countAll) return; - this._subs['slotFillers'].setData('limit', this.currentLimit + 20); + this._subs['slotFillers'].setData('limit', this.currentLimit + 50); }, insert(){ if (!this.selectedNode) return; @@ -232,7 +232,7 @@ export default { return Creatures.findOne(this.creatureId); }, currentLimit(){ - return this._subs['slotFillers'].data('limit') || 20; + return this._subs['slotFillers'].data('limit') || 50; }, countAll(){ return this._subs['slotFillers'].data('countAll'); From 9f62a78eb0a7a30c9d83f2478599c43b9df7ae65 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 9 Aug 2021 22:34:04 +0200 Subject: [PATCH 5/7] Began work on implementing string and array storage limits --- app/imports/api/properties/Actions.js | 20 +++++++++++++++++--- app/imports/constants/STORAGE_LIMITS.js | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 app/imports/constants/STORAGE_LIMITS.js diff --git a/app/imports/api/properties/Actions.js b/app/imports/api/properties/Actions.js index 0cd20fc6..2f9f3997 100644 --- a/app/imports/api/properties/Actions.js +++ b/app/imports/api/properties/Actions.js @@ -1,7 +1,9 @@ import SimpleSchema from 'simpl-schema'; import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js'; import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js'; -import { storedIconsSchema } from '/imports/api/icons/Icons.js' +import { storedIconsSchema } from '/imports/api/icons/Icons.js'; +import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js'; + /* * Actions are things a character can do * Any rolls that are children of actions will be rolled when taking the action @@ -12,14 +14,17 @@ let ActionSchema = new SimpleSchema({ name: { type: String, optional: true, + max: STORAGE_LIMITS.name, }, summary: { type: String, optional: true, + max: STORAGE_LIMITS.summary, }, description: { type: String, optional: true, + max: STORAGE_LIMITS.description, }, // What time-resource is used to take the action in combat // long actions take longer than 1 round to cast @@ -41,9 +46,11 @@ let ActionSchema = new SimpleSchema({ tags: { type: Array, defaultValue: [], + maxCount: STORAGE_LIMITS.tagCount, }, 'tags.$': { type: String, + max: STORAGE_LIMITS.tagLength, }, // Duplicate the ResourceSchema here so we can extend it elegantly. resources: { @@ -53,6 +60,7 @@ let ActionSchema = new SimpleSchema({ 'resources.itemsConsumed': { type: Array, defaultValue: [], + maxCount: STORAGE_LIMITS.resourcesCount, }, 'resources.itemsConsumed.$': { type: Object, @@ -79,6 +87,7 @@ let ActionSchema = new SimpleSchema({ 'resources.attributesConsumed': { type: Array, defaultValue: [], + maxCount: STORAGE_LIMITS.resourcesCount, }, 'resources.attributesConsumed.$': { type: Object, @@ -102,6 +111,7 @@ let ActionSchema = new SimpleSchema({ uses: { type: String, optional: true, + max: STORAGE_LIMITS.calculation, }, // Integer of how many times it has already been used usesUsed: { @@ -120,14 +130,14 @@ const ComputedOnlyActionSchema = new SimpleSchema({ summaryCalculations: { type: Array, defaultValue: [], - maxCount: 32, + maxCount: STORAGE_LIMITS.inlineCalculationCount, }, 'summaryCalculations.$': InlineComputationSchema, descriptionCalculations: { type: Array, defaultValue: [], - maxCount: 32, + maxCount: STORAGE_LIMITS.inlineCalculationCount, }, 'descriptionCalculations.$': InlineComputationSchema, @@ -138,6 +148,7 @@ const ComputedOnlyActionSchema = new SimpleSchema({ usesErrors: { type: Array, optional: true, + maxCount: STORAGE_LIMITS.errorCount, }, 'usesErrors.$':{ type: ErrorSchema, @@ -158,6 +169,7 @@ const ComputedOnlyActionSchema = new SimpleSchema({ }, 'resources.itemsConsumed.$.itemName': { type: String, + max: STORAGE_LIMITS.name, optional: true, }, 'resources.itemsConsumed.$.itemIcon': { @@ -167,6 +179,7 @@ const ComputedOnlyActionSchema = new SimpleSchema({ 'resources.itemsConsumed.$.itemColor': { type: String, optional: true, + max: STORAGE_LIMITS.color, }, 'resources.attributesConsumed': Array, 'resources.attributesConsumed.$': Object, @@ -182,6 +195,7 @@ const ComputedOnlyActionSchema = new SimpleSchema({ 'resources.attributesConsumed.$.statName': { type: String, optional: true, + max: STORAGE_LIMITS.name, }, // True if the uses left is zero, or any item or attribute consumed is // insufficient diff --git a/app/imports/constants/STORAGE_LIMITS.js b/app/imports/constants/STORAGE_LIMITS.js new file mode 100644 index 00000000..86c38731 --- /dev/null +++ b/app/imports/constants/STORAGE_LIMITS.js @@ -0,0 +1,14 @@ +const STORAGE_LIMITS = Object.freeze({ + name: 140, + color: 10000, + summary: 10000, + description: 49473, //the length of the Bee Movie script + inlineCalculationCount: 32, + errorCount: 32, + tagCount: 64, + tagLength: 140, + resourcesCount: 32, + calculation: 280, +}); + +export default STORAGE_LIMITS; From 8ecefb03ad1628662affd1a415b71b8bab49d688 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Tue, 10 Aug 2021 10:32:56 +0200 Subject: [PATCH 6/7] Started re-implementing slot fill dialog with different design pattern --- .../creatureProperties/CreatureProperties.js | 6 + .../methods/getSlotFillFilter.js | 44 +++ .../methods/insertPropertyFromLibraryNode.js | 10 + .../methods/pushToProperty.js | 20 +- app/imports/api/properties/Slots.js | 39 ++- .../server/publications/slotFillers.js | 27 +- .../ui/creature/slots/OldSlotFillDialog.vue | 310 ++++++++++++++++++ .../ui/creature/slots/SlotFillDialog.vue | 302 ++++++++--------- .../library/LibraryNodeExpansionContent.vue | 1 + app/imports/ui/properties/forms/SlotForm.vue | 116 ++++++- 10 files changed, 674 insertions(+), 201 deletions(-) create mode 100644 app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js create mode 100644 app/imports/ui/creature/slots/OldSlotFillDialog.vue diff --git a/app/imports/api/creature/creatureProperties/CreatureProperties.js b/app/imports/api/creature/creatureProperties/CreatureProperties.js index 87b5f072..e8522fae 100644 --- a/app/imports/api/creature/creatureProperties/CreatureProperties.js +++ b/app/imports/api/creature/creatureProperties/CreatureProperties.js @@ -28,6 +28,12 @@ let CreaturePropertySchema = new SimpleSchema({ type: storedIconsSchema, optional: true, }, + // Reference to the library node that this property was copied from + libraryNodeId: { + type: String, + regEx: SimpleSchema.RegEx.Id, + optional: true, + }, // Denormalised flag if this property is inactive on the sheet for any reason // Including being disabled, or a decendent of a disabled property inactive: { diff --git a/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js b/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js new file mode 100644 index 00000000..1bba9421 --- /dev/null +++ b/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js @@ -0,0 +1,44 @@ +export default function getSlotFillFilter({slot, libraryIds}){ + let filter = { + removed: {$ne: true}, + $and: [] + }; + if (libraryIds){ + filter['ancestors.id'] = {$in: libraryIds}; + } + if (slot.slotType){ + filter.$and.push({ + $or: [{ + type: slot.slotType + },{ + type: 'slotFiller', + slotFillerType: slot.slotType, + }] + }); + } + let tagsOr = []; + let tagsNor = []; + if (slot.slotTags && slot.slotTags.length){ + tagsOr.push({tags: {$all: slot.slotTags}}); + } + if (slot.extraTags && slot.extraTags.length){ + slot.extraTags.forEach(extra => { + if (!extra.tags || !extra.tags.length) return; + if (extra.operation === 'OR'){ + tagsOr.push({tags: {$all: extra.tags}}); + } else if (extra.operation === 'NOT'){ + tagsNor.push({tags: {$all: extra.tags}}); + } + }); + } + if (tagsOr.length){ + filter.$and.push({$or: tagsOr}); + } + if (tagsNor.length){ + filter.$and.push({$nor: tagsNor}); + } + if (!filter.$and.length){ + delete filter.$and; + } + return filter; +} diff --git a/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js b/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js index a507d01f..0d05f29d 100644 --- a/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js +++ b/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js @@ -107,6 +107,9 @@ function insertPropertyFromNode(nodeId, ancestors, order){ // It must get the first generated ID to prevent flickering nodes = [node, ...nodes]; + // set libraryNodeIds + storeLibraryNodeReferences(nodes, nodeId); + // re-map all the ancestors setLineageOfDocs({ docArray: nodes, @@ -135,6 +138,13 @@ function insertPropertyFromNode(nodeId, ancestors, order){ return node; } + +function storeLibraryNodeReferences(nodes){ + nodes.forEach(node => { + node.libraryNodeId = node._id; + }); +} + // Covert node references into actual nodes // TODO: check permissions for each library a reference node references function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0){ diff --git a/app/imports/api/creature/creatureProperties/methods/pushToProperty.js b/app/imports/api/creature/creatureProperties/methods/pushToProperty.js index 4228eca0..c1054490 100644 --- a/app/imports/api/creature/creatureProperties/methods/pushToProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/pushToProperty.js @@ -4,6 +4,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { get } from 'lodash'; const pushToProperty = new ValidatedMethod({ name: 'creatureProperties.push', @@ -19,9 +20,26 @@ const pushToProperty = new ValidatedMethod({ let rootCreature = getRootCreatureAncestor(property); assertEditPermission(rootCreature, this.userId); + let joinedPath = path.join('.'); + + // Respect maxCount + let schema = CreatureProperties.simpleSchema(property); + let maxCount = schema.get(joinedPath, 'maxCount'); + + if (Number.isFinite(maxCount)){ + let array = get(property, path); + let currentCount = array ? array.length : 0; + if (currentCount >= maxCount){ + throw new Meteor.Error( + 'Array is full', + `Cannot have more than ${maxCount} values` + ); + } + } + // Do work CreatureProperties.update(_id, { - $push: {[path.join('.')]: value}, + $push: {[joinedPath]: value}, }, { selector: {type: property.type}, }); diff --git a/app/imports/api/properties/Slots.js b/app/imports/api/properties/Slots.js index 872d6171..dd25fd41 100644 --- a/app/imports/api/properties/Slots.js +++ b/app/imports/api/properties/Slots.js @@ -21,6 +21,31 @@ let SlotSchema = new SimpleSchema({ 'slotTags.$': { type: String, }, + extraTags: { + type: Array, + defaultValue: [], + maxCount: 5, + }, + 'extraTags.$': { + type: Object, + }, + 'extraTags.$._id': { + type: String, + regEx: SimpleSchema.RegEx.Id, + autoValue(){ + if (!this.isSet) return Random.id(); + } + }, + 'extraTags.$.operation': { + type: String, + allowedValues: ['OR', 'NOT'], + }, + 'extraTags.$.tags': { + type: Array, + }, + 'extraTags.$.tags.$': { + type: String, + }, quantityExpected: { type: String, optional: true, @@ -37,7 +62,19 @@ let SlotSchema = new SimpleSchema({ hideWhenFull: { type: Boolean, optional: true, - } + defaultValue: true, + }, + unique: { + type: String, + allowedValues: [ + // Can't choose the same slot filler twice in this slot + 'uniqueInSlot', + // Can't choose the same slot filler twice accross the whole creature + 'uniqueInCreature' + ], + optional: true, + defaultValue: 'uniqueInSlot', + }, }); const ComputedOnlySlotSchema = new SimpleSchema({ diff --git a/app/imports/server/publications/slotFillers.js b/app/imports/server/publications/slotFillers.js index a22b8a65..94dbf7fc 100644 --- a/app/imports/server/publications/slotFillers.js +++ b/app/imports/server/publications/slotFillers.js @@ -2,6 +2,7 @@ import { check } from 'meteor/check'; import Libraries from '/imports/api/library/Libraries.js'; import LibraryNodes from '/imports/api/library/LibraryNodes.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; +import getSlotFillFilter from '/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js' Meteor.publish('slotFillers', function(slotId){ let self = this; @@ -21,7 +22,7 @@ Meteor.publish('slotFillers', function(slotId){ fields: {subscribedLibraries: 1} }); const subs = user && user.subscribedLibraries || []; - let libraryIds = Libraries.find({ + let libraries = Libraries.find({ $or: [ {owner: this.userId}, {writers: this.userId}, @@ -29,25 +30,13 @@ Meteor.publish('slotFillers', function(slotId){ {_id: {$in: subs}}, ] }, { - fields: {_id: 1}, - }).map(lib => lib._id); + fields: {_id: 1, name: 1}, + }); + let libraryIds = libraries.map(lib => lib._id); // Build a filter for nodes in those libraries that match the slot - let filter = { - 'ancestors.id': {$in: libraryIds}, - removed: {$ne: true}, - }; - if (slot.slotTags && slot.slotTags.length){ - filter.tags = {$all: slot.slotTags}; - } - if (slot.slotType){ - filter.$or = [{ - type: slot.slotType - },{ - type: 'slotFiller', - slotFillerType: slot.slotType, - }]; - } + let filter = getSlotFillFilter({slot, libraryIds}); + this.autorun(function(){ // Get the limit of the documents the user can fetch var limit = self.data('limit') || 50; @@ -85,7 +74,7 @@ Meteor.publish('slotFillers', function(slotId){ self.setData('countAll', LibraryNodes.find(filter).count()); }); self.autorun(function () { - return LibraryNodes.find(filter, options); + return [LibraryNodes.find(filter, options), libraries]; }); }); }); diff --git a/app/imports/ui/creature/slots/OldSlotFillDialog.vue b/app/imports/ui/creature/slots/OldSlotFillDialog.vue new file mode 100644 index 00000000..949460ab --- /dev/null +++ b/app/imports/ui/creature/slots/OldSlotFillDialog.vue @@ -0,0 +1,310 @@ + + + + + diff --git a/app/imports/ui/creature/slots/SlotFillDialog.vue b/app/imports/ui/creature/slots/SlotFillDialog.vue index 86ce48a5..31d3571d 100644 --- a/app/imports/ui/creature/slots/SlotFillDialog.vue +++ b/app/imports/ui/creature/slots/SlotFillDialog.vue @@ -18,134 +18,97 @@ @keyup.enter="insert" /> -
+ - -
-
- - + + + + + @@ -153,21 +116,32 @@ diff --git a/app/imports/ui/library/LibraryNodeExpansionContent.vue b/app/imports/ui/library/LibraryNodeExpansionContent.vue index 19b3199b..aac0f104 100644 --- a/app/imports/ui/library/LibraryNodeExpansionContent.vue +++ b/app/imports/ui/library/LibraryNodeExpansionContent.vue @@ -6,6 +6,7 @@ class="property-viewer" /> - + + + + mdi-plus + + + + + +
+ + + + mdi-delete + +
+
+ = maxCount; + } + }, + methods: { + acknowledgeAddResult(){ + this.addExtraTagsLoading = false; + }, + addExtraTags(){ + this.addExtraTagsLoading = true; + this.$emit('push', { + path: ['extraTags'], + value: { + _id: Random.id(), + operation: 'OR', + tags: [], + }, + ack: this.acknowledgeAddResult, + }); + }, + }, }; From a465e2ce870b482bd684b4fd2416c56a4130b292 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Tue, 10 Aug 2021 13:29:11 +0200 Subject: [PATCH 7/7] Continued implementing new slot dialog --- .../ui/creature/slots/SlotFillDialog.vue | 179 +++++++++++++++--- app/imports/ui/properties/forms/SlotForm.vue | 6 +- .../viewers/shared/PropertyTags.vue | 30 +-- 3 files changed, 177 insertions(+), 38 deletions(-) diff --git a/app/imports/ui/creature/slots/SlotFillDialog.vue b/app/imports/ui/creature/slots/SlotFillDialog.vue index 31d3571d..f0ba749f 100644 --- a/app/imports/ui/creature/slots/SlotFillDialog.vue +++ b/app/imports/ui/creature/slots/SlotFillDialog.vue @@ -21,6 +21,23 @@ +

+ {{ slotPropertyTypeName }} with tags: + + +