Inventory now uses filtered tree views to display items in containers
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
|
||||
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
|
||||
import { flatten } from 'lodash';
|
||||
import { flatten, findLast } from 'lodash';
|
||||
|
||||
const generalParents = [
|
||||
'attribute',
|
||||
@@ -32,6 +32,9 @@ export function getAllowedParents({childType}){
|
||||
}
|
||||
|
||||
export function isParentAllowed({parentType = 'root', childType}){
|
||||
return true;
|
||||
//TODO until there is a good reason to disallow certain parenting options,
|
||||
// this should just let the user do whatever
|
||||
if (!childType) throw 'childType is required';
|
||||
let allowedParents = getAllowedParents({childType});
|
||||
return allowedParents.includes(parentType);
|
||||
@@ -205,13 +208,14 @@ export function getName(doc){
|
||||
}
|
||||
}
|
||||
|
||||
export function nodesToTree({collection, ancestorId}){
|
||||
export function nodesToTree({collection, ancestorId, filter}){
|
||||
// Store a dict of all the nodes
|
||||
let nodeIndex = {};
|
||||
let nodeList = [];
|
||||
collection.find({
|
||||
'ancestors.id': ancestorId,
|
||||
removed: {$ne: true},
|
||||
...filter,
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
}).forEach( node => {
|
||||
@@ -224,12 +228,16 @@ export function nodesToTree({collection, ancestorId}){
|
||||
});
|
||||
// Create a forest of trees
|
||||
let forest = [];
|
||||
// Either the node is a child of another node, or in the forest as a root
|
||||
nodeList.forEach(node => {
|
||||
if (nodeIndex[node.node.parent.id]){
|
||||
nodeIndex[node.node.parent.id].children.push(node);
|
||||
// Either the node is a child of its nearest found ancestor, or in the forest as a root
|
||||
nodeList.forEach(treeNode => {
|
||||
let ancestorInForest = findLast(
|
||||
treeNode.node.ancestors,
|
||||
ancestor => !!nodeIndex[ancestor.id]
|
||||
);
|
||||
if (ancestorInForest){
|
||||
nodeIndex[ancestorInForest.id].children.push(treeNode);
|
||||
} else {
|
||||
forest.push(node);
|
||||
forest.push(treeNode);
|
||||
}
|
||||
});
|
||||
return forest;
|
||||
|
||||
@@ -52,6 +52,11 @@ ItemSchema = new SimpleSchema({
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Unequipped items shouldn't affect creature stats
|
||||
equipped: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
export { ItemSchema };
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<style lang="css" scoped>
|
||||
.rotate-90 {
|
||||
transform: rotate(90deg);
|
||||
transform: rotate(90deg) translateZ(0);
|
||||
}
|
||||
.drag-area {
|
||||
box-shadow: -2px 0px 0px 0px #808080;
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
<template lang="html">
|
||||
<div class="inventory">
|
||||
<column-layout>
|
||||
<v-card>
|
||||
<v-card-actions>
|
||||
<v-switch v-model="organize" label="Organize"/>
|
||||
</v-card-actions>
|
||||
<!-- Equipping things isn't implemented yet
|
||||
<creature-properties-tree
|
||||
:root="{collection: 'creatures', id: creatureId}"
|
||||
:filter="{
|
||||
equipped: true,
|
||||
type: {$in: ['item']},
|
||||
'ancestors.id': {$nin: containerIds}
|
||||
}"
|
||||
@selected="e => clickProperty(e)"
|
||||
:organize="organize"
|
||||
group="inventory"
|
||||
/>
|
||||
<v-divider/>
|
||||
-->
|
||||
<creature-properties-tree
|
||||
:root="{collection: 'creatures', id: creatureId}"
|
||||
:filter="{
|
||||
equipped: {$ne: true},
|
||||
type: {$in: ['item']},
|
||||
'ancestors.id': {$nin: containerIds}
|
||||
}"
|
||||
@selected="e => clickProperty(e)"
|
||||
:organize="organize"
|
||||
group="inventory"
|
||||
/>
|
||||
</v-card>
|
||||
<div v-for="container in containers" :key="container._id">
|
||||
<container-card
|
||||
:model="container"
|
||||
:organize="organize"
|
||||
/>
|
||||
</div>
|
||||
</column-layout>
|
||||
@@ -13,14 +44,19 @@
|
||||
<script>
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||
import CreaturePropertiesTree from '/imports/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
|
||||
import ContainerCard from '/imports/ui/properties/components/inventory/ContainerCard.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
creatureId: String,
|
||||
},
|
||||
data(){ return {
|
||||
organize: false,
|
||||
}},
|
||||
components: {
|
||||
ColumnLayout,
|
||||
CreaturePropertiesTree,
|
||||
ContainerCard,
|
||||
},
|
||||
meteor: {
|
||||
@@ -31,14 +67,20 @@ export default {
|
||||
removed: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
}).map(container => {
|
||||
container.items = CreatureProperties.find({
|
||||
'parent.id': container._id,
|
||||
removed: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
}).fetch();
|
||||
return container;
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
containerIds(){
|
||||
return this.containers.map(container => container._id);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clickProperty(_id){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: `tree-node-${_id}`,
|
||||
data: {_id},
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
:organize="organize"
|
||||
@selected="e => selected = e"
|
||||
:selected-node-id="selected"
|
||||
style="min-width: 320px;"
|
||||
/>
|
||||
</div>
|
||||
<v-divider vertical/>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template lang="html">
|
||||
<v-card-text style="width: initial; max-width: 100%; min-width: 320px;">
|
||||
<v-card-text style="width: initial; max-width: 100%;">
|
||||
<tree-node-list
|
||||
v-if="root"
|
||||
:children="children"
|
||||
:group="root.id"
|
||||
:group="group"
|
||||
:organize="organize"
|
||||
:selected-node-id="selectedNodeId"
|
||||
@selected="e => $emit('selected', e)"
|
||||
@@ -27,10 +27,19 @@
|
||||
root: Object,
|
||||
organize: Boolean,
|
||||
selectedNodeId: String,
|
||||
filter: Object,
|
||||
group: {
|
||||
type: String,
|
||||
default: 'creatureProperties'
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
children(){
|
||||
return nodesToTree({collection: CreatureProperties, ancestorId: this.root.id});
|
||||
return nodesToTree({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: this.root.id,
|
||||
filter: this.filter,
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
<template lang="html">
|
||||
<toolbar-card :color="model.color" @toolbarclick="clickProperty(model._id)" :data-id="model._id">
|
||||
<toolbar-card :color="model.color" @toolbarclick="clickContainer(model._id)" :data-id="model._id">
|
||||
<template slot="toolbar">
|
||||
<span>
|
||||
{{model.name}}
|
||||
</span>
|
||||
<v-spacer/>
|
||||
</template>
|
||||
<v-list>
|
||||
<item-list-tile
|
||||
v-for="item in model.items"
|
||||
:model="item"
|
||||
:key="item._id"
|
||||
:data-id="item._id"
|
||||
@click="clickProperty(item._id)"
|
||||
/>
|
||||
</v-list>
|
||||
<creature-properties-tree
|
||||
:root="{collection: 'creatureProperties', id: model._id}"
|
||||
:filter="{type: {$in: ['container', 'item', 'folder']}}"
|
||||
@selected="e => clickProperty(e)"
|
||||
:organize="organize"
|
||||
group="inventory"
|
||||
/>
|
||||
</toolbar-card>
|
||||
</template>
|
||||
|
||||
@@ -22,23 +20,33 @@
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
import ItemListTile from '/imports/ui/properties/components/inventory/ItemListTile.vue';
|
||||
import CreaturePropertiesTree from '/imports/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
model: Object,
|
||||
organize: Boolean,
|
||||
},
|
||||
components: {
|
||||
ToolbarCard,
|
||||
ItemListTile,
|
||||
CreaturePropertiesTree,
|
||||
},
|
||||
methods: {
|
||||
clickProperty(_id){
|
||||
clickContainer(_id){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: `${_id}`,
|
||||
data: {_id},
|
||||
});
|
||||
},
|
||||
clickProperty(_id){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: `tree-node-${_id}`,
|
||||
data: {_id},
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user