Merge branch 'develop' into feature-tabletop
This commit is contained in:
@@ -18,23 +18,31 @@ export default function getSlotFillFilter({ slot, libraryIds }) {
|
|||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
} else if (slot.type === 'class') {
|
} else if (slot.type === 'class') {
|
||||||
filter.$and.push({
|
const classLevelFilter = {
|
||||||
$or: [{
|
type: 'classLevel',
|
||||||
type: 'classLevel',
|
};
|
||||||
}, {
|
const slotFillerFilter = {
|
||||||
slotFillerType: 'classLevel',
|
slotFillerType: 'classLevel',
|
||||||
}]
|
};
|
||||||
});
|
|
||||||
|
// Match variable name or tags
|
||||||
if (slot.variableName) {
|
if (slot.variableName) {
|
||||||
filter.variableName = slot.variableName;
|
classLevelFilter.variableName = slot.variableName;
|
||||||
|
slotFillerFilter.libraryTags = slot.variableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only search for levels the class needs
|
// Only search for levels the class needs
|
||||||
if (slot.missingLevels && slot.missingLevels.length) {
|
if (slot.missingLevels && slot.missingLevels.length) {
|
||||||
filter.level = { $in: slot.missingLevels };
|
classLevelFilter.level = { $in: slot.missingLevels };
|
||||||
|
slotFillerFilter['cache.node.level'] = { $in: slot.missingLevels };
|
||||||
} else {
|
} else {
|
||||||
filter.level = { $gt: slot.level || 0 };
|
classLevelFilter.level = { $gt: slot.level || 0 };
|
||||||
|
slotFillerFilter['cache.node.level'] = { $gt: slot.level || 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter.$and.push({
|
||||||
|
$or: [classLevelFilter, slotFillerFilter]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let tagsOr = [];
|
let tagsOr = [];
|
||||||
let tagsNin = [];
|
let tagsNin = [];
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ function insertPropertyFromNode(nodeId, ancestors, order) {
|
|||||||
|
|
||||||
// Convert all references into actual nodes
|
// Convert all references into actual nodes
|
||||||
nodes = reifyNodeReferences(nodes);
|
nodes = reifyNodeReferences(nodes);
|
||||||
|
// Refetch the root node, it might have been reified
|
||||||
|
node = nodes[0] || node;
|
||||||
|
|
||||||
// set libraryNodeIds
|
// set libraryNodeIds
|
||||||
storeLibraryNodeReferences(nodes);
|
storeLibraryNodeReferences(nodes);
|
||||||
|
|||||||
@@ -179,11 +179,6 @@ let CreatureSchema = new SimpleSchema({
|
|||||||
blackbox: true,
|
blackbox: true,
|
||||||
defaultValue: {}
|
defaultValue: {}
|
||||||
},
|
},
|
||||||
variables: {
|
|
||||||
type: Object,
|
|
||||||
blackbox: true,
|
|
||||||
defaultValue: {}
|
|
||||||
},
|
|
||||||
computeErrors: {
|
computeErrors: {
|
||||||
type: Array,
|
type: Array,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ import operator from '/imports/parser/parseTree/operator.js';
|
|||||||
import { parse } from '/imports/parser/parser.js';
|
import { parse } from '/imports/parser/parser.js';
|
||||||
import logErrors from './logErrors.js';
|
import logErrors from './logErrors.js';
|
||||||
|
|
||||||
export default function applyEffectsToCalculationParseNode(calcObj, actionContext){
|
export default function applyEffectsToCalculationParseNode(calcObj, actionContext) {
|
||||||
if (!calcObj.effects) return;
|
calcObj.effects?.forEach(effect => {
|
||||||
calcObj.effects.forEach(effect => {
|
|
||||||
if (effect.operation !== 'add') return;
|
if (effect.operation !== 'add') return;
|
||||||
if (!effect.amount) return;
|
if (!effect.amount) return;
|
||||||
if (effect.amount.value === null) return;
|
if (effect.amount.value === null) return;
|
||||||
@@ -17,8 +16,31 @@ export default function applyEffectsToCalculationParseNode(calcObj, actionContex
|
|||||||
operator: '+',
|
operator: '+',
|
||||||
fn: 'add'
|
fn: 'add'
|
||||||
});
|
});
|
||||||
} catch (e){
|
} catch (e) {
|
||||||
logErrors([e], actionContext)
|
logErrors([e], actionContext)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Add the highest proficiency as well
|
||||||
|
let highestProficiency;
|
||||||
|
calcObj.proficiencies?.forEach(proficiency => {
|
||||||
|
if (
|
||||||
|
proficiency.value > highestProficiency
|
||||||
|
|| (highestProficiency === undefined && Number.isFinite(proficiency.value))
|
||||||
|
) {
|
||||||
|
highestProficiency = proficiency.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (highestProficiency) {
|
||||||
|
try {
|
||||||
|
let profParseNode = parse(highestProficiency.toString());
|
||||||
|
calcObj.parseNode = operator.create({
|
||||||
|
left: calcObj.parseNode,
|
||||||
|
right: profParseNode,
|
||||||
|
operator: '+',
|
||||||
|
fn: 'add'
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logErrors([e], actionContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import evaluateCalculation from '/imports/api/engine/computation/utility/evaluat
|
|||||||
import applyEffectsToCalculationParseNode from '/imports/api/engine/actions/applyPropertyByType/shared/applyEffectsToCalculationParseNode.js';
|
import applyEffectsToCalculationParseNode from '/imports/api/engine/actions/applyPropertyByType/shared/applyEffectsToCalculationParseNode.js';
|
||||||
import logErrors from './logErrors.js';
|
import logErrors from './logErrors.js';
|
||||||
|
|
||||||
export default function recalculateCalculation(calc, actionContext, context){
|
export default function recalculateCalculation(calc, actionContext, context) {
|
||||||
if (!calc?.parseNode) return;
|
if (!calc?.parseNode) return;
|
||||||
calc._parseLevel = 'reduce';
|
calc._parseLevel = 'reduce';
|
||||||
applyEffectsToCalculationParseNode(calc, actionContext);
|
applyEffectsToCalculationParseNode(calc, actionContext);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import resolve, { toString } from '/imports/parser/resolve.js';
|
import resolve, { toString } from '/imports/parser/resolve.js';
|
||||||
|
|
||||||
export default function evaluateCalculation(calculation, scope, givenContext){
|
export default function evaluateCalculation(calculation, scope, givenContext) {
|
||||||
const parseNode = calculation.parseNode;
|
const parseNode = calculation.parseNode;
|
||||||
const fn = calculation._parseLevel;
|
const fn = calculation._parseLevel;
|
||||||
const calculationScope = {...calculation._localScope, ...scope};
|
const calculationScope = { ...calculation._localScope, ...scope };
|
||||||
const {result: resultNode, context} = resolve(fn, parseNode, calculationScope, givenContext);
|
const { result: resultNode, context } = resolve(fn, parseNode, calculationScope, givenContext);
|
||||||
calculation.errors = context.errors;
|
calculation.errors = context.errors;
|
||||||
if (resultNode?.parseType === 'constant'){
|
if (resultNode?.parseType === 'constant') {
|
||||||
calculation.value = resultNode.value;
|
calculation.value = resultNode.value;
|
||||||
} else if (resultNode?.parseType === 'error'){
|
} else if (resultNode?.parseType === 'error') {
|
||||||
calculation.value = null;
|
calculation.value = null;
|
||||||
} else {
|
} else {
|
||||||
calculation.value = toString(resultNode);
|
calculation.value = toString(resultNode);
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ const duplicateLibraryNode = new ValidatedMethod({
|
|||||||
}).validator(),
|
}).validator(),
|
||||||
mixins: [RateLimiterMixin],
|
mixins: [RateLimiterMixin],
|
||||||
rateLimit: {
|
rateLimit: {
|
||||||
numRequests: 1,
|
numRequests: 4,
|
||||||
timeInterval: 5000,
|
timeInterval: 6000,
|
||||||
},
|
},
|
||||||
run({ _id }) {
|
run({ _id }) {
|
||||||
let libraryNode = LibraryNodes.findOne(_id);
|
let libraryNode = LibraryNodes.findOne(_id);
|
||||||
|
|||||||
@@ -16,42 +16,27 @@ export default {
|
|||||||
wideColumns: Boolean,
|
wideColumns: Boolean,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Removed to improve chrome layout performance, put it back if there are rendering errors
|
|
||||||
.column-layout>span>div {
|
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css">
|
<style lang="css">
|
||||||
.column-layout {
|
.column-layout {
|
||||||
column-count: 12;
|
column-count: 12;
|
||||||
column-fill: balance;
|
column-fill: balance;
|
||||||
column-gap: 0;
|
column-gap: 8px;
|
||||||
column-width: 240px;
|
column-width: 240px;
|
||||||
transform: translateZ(0);
|
padding: 8px;
|
||||||
padding: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-layout.wide-columns {
|
.column-layout.wide-columns {
|
||||||
column-count: 12;
|
|
||||||
column-fill: balance;
|
|
||||||
column-gap: 0;
|
|
||||||
column-width: 320px;
|
column-width: 320px;
|
||||||
transform: translateZ(0);
|
|
||||||
padding: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-layout>div,
|
.column-layout>*,
|
||||||
.column-layout>span>div {
|
.column-layout>span>div {
|
||||||
width: 100%;
|
display: inline-block;
|
||||||
backface-visibility: hidden;
|
|
||||||
transform: translateX(0);
|
|
||||||
page-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
padding: 4px;
|
page-break-inside: avoid;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
timeout: {
|
timeout: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 6000000,
|
default: 15000,
|
||||||
},
|
},
|
||||||
pause: {
|
pause: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
|||||||
@@ -596,7 +596,6 @@ export default {
|
|||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
margin-left: -30px;
|
margin-left: -30px;
|
||||||
padding-left: 34px;
|
padding-left: 34px;
|
||||||
z-index: -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.number-label .number {
|
.number-label .number {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
:key="libraryNode._id"
|
:key="libraryNode._id"
|
||||||
:model="libraryNode"
|
:model="libraryNode"
|
||||||
:data-id="libraryNode._id"
|
:data-id="libraryNode._id"
|
||||||
:class="{disabled: isDisabled(libraryNode)}"
|
:class="{disabled: isDisabled(libraryNode) || libraryNode._disabledBySlotFillerCondition}"
|
||||||
>
|
>
|
||||||
<v-expansion-panel-header>
|
<v-expansion-panel-header>
|
||||||
<template #default="{ open }">
|
<template #default="{ open }">
|
||||||
@@ -69,6 +69,7 @@
|
|||||||
v-model="selectedNodeIds"
|
v-model="selectedNodeIds"
|
||||||
class="my-0 py-0"
|
class="my-0 py-0"
|
||||||
hide-details
|
hide-details
|
||||||
|
:color="libraryNode._disabledBySlotFillerCondition ? 'error' : ''"
|
||||||
:disabled="isDisabled(libraryNode)"
|
:disabled="isDisabled(libraryNode)"
|
||||||
:value="libraryNode._id"
|
:value="libraryNode._id"
|
||||||
@click.stop
|
@click.stop
|
||||||
@@ -81,7 +82,7 @@
|
|||||||
v-if="libraryNode._disabledBySlotFillerCondition"
|
v-if="libraryNode._disabledBySlotFillerCondition"
|
||||||
class="error--text text-no-wrap text-truncate"
|
class="error--text text-no-wrap text-truncate"
|
||||||
>
|
>
|
||||||
{{ libraryNode.slotFillerCondition }}
|
{{ libraryNode._conditionError }}
|
||||||
</div>
|
</div>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<div class="text-caption text-no-wrap text-truncate">
|
<div class="text-caption text-no-wrap text-truncate">
|
||||||
@@ -110,7 +111,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-expansion-panel-header>
|
</v-expansion-panel-header>
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<library-node-expansion-content :model="libraryNode" />
|
<library-node-expansion-content :id="libraryNode._id" />
|
||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</template>
|
</template>
|
||||||
@@ -120,11 +121,12 @@
|
|||||||
column
|
column
|
||||||
align-center
|
align-center
|
||||||
justify-center
|
justify-center
|
||||||
class="ma-3"
|
class="ma-3 mt-8"
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
:loading="!$subReady.classFillers"
|
:loading="!$subReady.classFillers"
|
||||||
color="accent"
|
color="accent"
|
||||||
|
outlined
|
||||||
@click="loadMore"
|
@click="loadMore"
|
||||||
>
|
>
|
||||||
Load More
|
Load More
|
||||||
@@ -192,7 +194,7 @@ import getSlotFillFilter from '/imports/api/creature/creatureProperties/methods/
|
|||||||
import Libraries from '/imports/api/library/Libraries.js';
|
import Libraries from '/imports/api/library/Libraries.js';
|
||||||
import LibraryNodeExpansionContent from '/imports/client/ui/library/LibraryNodeExpansionContent.vue';
|
import LibraryNodeExpansionContent from '/imports/client/ui/library/LibraryNodeExpansionContent.vue';
|
||||||
import PropertyTags from '/imports/client/ui/properties/viewers/shared/PropertyTags.vue';
|
import PropertyTags from '/imports/client/ui/properties/viewers/shared/PropertyTags.vue';
|
||||||
import { clone, difference } from 'lodash';
|
import { clone, difference, isEqual } from 'lodash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -247,29 +249,69 @@ export default {
|
|||||||
});
|
});
|
||||||
return { or, not };
|
return { or, not };
|
||||||
},
|
},
|
||||||
|
filledLevels() {
|
||||||
|
return LibraryNodes.find({
|
||||||
|
_id: { $in: this.selectedNodeIds }
|
||||||
|
}).map(
|
||||||
|
node => node.level || node.cache?.node?.level || 0
|
||||||
|
).sort((a, b) => a - b);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectedNodeIds(selectedIds, oldSelectedIds) {
|
selectedNodeIds(selectedIds, oldSelectedIds) {
|
||||||
// Skip if we didn't increase the length by adding a new Id
|
// Skip if we increased the length by adding a new Id, see if we need to backfill levels
|
||||||
if (oldSelectedIds.length >= selectedIds.length) return;
|
if (oldSelectedIds.length < selectedIds.length) {
|
||||||
// Find out which library node was added
|
// Find out which library node was added
|
||||||
const addedId = difference(selectedIds, oldSelectedIds)[0];
|
const addedId = difference(selectedIds, oldSelectedIds)[0];
|
||||||
if (!addedId) return;
|
if (!addedId) return;
|
||||||
const addedNode = LibraryNodes.findOne(addedId);
|
const addedNode = LibraryNodes.findOne(addedId);
|
||||||
if (!addedNode) return;
|
if (!addedNode) return;
|
||||||
// Tick any unchecked nodes of a lower level, but only one per level
|
// Check which levels are already backfilled
|
||||||
const backFilledLevels = new Set();
|
const backFilledLevels = new Set();
|
||||||
this.libraryNodes.forEach(node => {
|
const sortedIds = LibraryNodes.find({
|
||||||
if (
|
_id: { $in: selectedIds }
|
||||||
!selectedIds.includes(node._id)
|
}).map(node => backFilledLevels.add(node.level || node.cache?.node?.level || 0));
|
||||||
&& node.level < addedNode.level
|
// Tick any unchecked nodes of a lower level, but only one per level
|
||||||
&& !backFilledLevels.has(node.level)
|
this.libraryNodes.forEach(node => {
|
||||||
) {
|
if (
|
||||||
selectedIds.push(node._id);
|
!selectedIds.includes(node._id)
|
||||||
}
|
&& (node.level < addedNode.level)
|
||||||
});
|
&& !backFilledLevels.has(node.level)
|
||||||
this.selectedNodeIds = selectedIds;
|
&& !this.isDisabled(node)
|
||||||
}
|
&& !node._disabledBySlotFillerCondition
|
||||||
|
) {
|
||||||
|
selectedIds.push(node._id);
|
||||||
|
backFilledLevels.add(node.level)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.selectedNodeIds = sortedIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refetch the library nodes to sort them correctly
|
||||||
|
const sortedIds = LibraryNodes.find({
|
||||||
|
_id: { $in: selectedIds }
|
||||||
|
}, {
|
||||||
|
sort: { level: 1, name: 1, order: 1 }
|
||||||
|
})
|
||||||
|
.fetch()
|
||||||
|
.sort((a, b) => (a.level || a.cache?.node?.level || 0) - (b.level || b.cache?.node?.level || 0))
|
||||||
|
.map(node => node._id);
|
||||||
|
// Only update if the order changed
|
||||||
|
if (!isEqual(this.selectedNodeIds, sortedIds)) {
|
||||||
|
this.selectedNodeIds = sortedIds;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeCount(val) {
|
||||||
|
// Still loading fillers
|
||||||
|
if (!this._subs['classFillers'].ready()) return;
|
||||||
|
// Can load more, and not showing enough active choices, so load more
|
||||||
|
if (
|
||||||
|
this.currentLimit < this.countAll
|
||||||
|
&& val < 20
|
||||||
|
) {
|
||||||
|
this.loadMore();
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadMore() {
|
loadMore() {
|
||||||
@@ -286,12 +328,10 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
isDisabled(node) {
|
isDisabled(node) {
|
||||||
return node._disabledBySlotFillerCondition ||
|
const selected = this.selectedNodeIds.includes(node._id);
|
||||||
node._disabledByAlreadyAdded ||
|
return node._disabledByAlreadyAdded
|
||||||
(
|
|| ( node._disabledByQuantityFilled && !selected )
|
||||||
node._disabledByQuantityFilled &&
|
|| ( this.filledLevels.includes(node.level || node.cache?.node?.level || 0) && !selected )
|
||||||
!this.selectedNodeIds.includes(node._id)
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
meteor: {
|
meteor: {
|
||||||
@@ -324,6 +364,10 @@ export default {
|
|||||||
countAll() {
|
countAll() {
|
||||||
return this._subs['classFillers'].data('countAll');
|
return this._subs['classFillers'].data('countAll');
|
||||||
},
|
},
|
||||||
|
activeCount() {
|
||||||
|
if (!this.libraryNodes) return;
|
||||||
|
return this.libraryNodes.length - (this.disabledNodeCount || 0);
|
||||||
|
},
|
||||||
alreadyAdded() {
|
alreadyAdded() {
|
||||||
let added = new Set();
|
let added = new Set();
|
||||||
if (!this.model.unique) return added;
|
if (!this.model.unique) return added;
|
||||||
@@ -377,12 +421,15 @@ export default {
|
|||||||
if (!this.libraryNodeFilter) return [];
|
if (!this.libraryNodeFilter) return [];
|
||||||
if (!this.$subReady.classFillers) return [];
|
if (!this.$subReady.classFillers) return [];
|
||||||
let nodes = LibraryNodes.find(this.libraryNodeFilter, {
|
let nodes = LibraryNodes.find(this.libraryNodeFilter, {
|
||||||
sort: { name: 1, order: 1 }
|
sort: { level: 1, name: 1, order: 1 }
|
||||||
}).fetch();
|
}).fetch();
|
||||||
let disabledNodeCount = 0;
|
let disabledNodeCount = 0;
|
||||||
// Mark classFillers whose condition isn't met or are too big to fit
|
// Mark classFillers whose condition isn't met or are too big to fit
|
||||||
// the quantity to fill
|
// the quantity to fill
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
|
if (node.cache?.node) {
|
||||||
|
node.level = node.cache.node.level;
|
||||||
|
}
|
||||||
if (node.slotFillerCondition) {
|
if (node.slotFillerCondition) {
|
||||||
try {
|
try {
|
||||||
let parseNode = parse(node.slotFillerCondition);
|
let parseNode = parse(node.slotFillerCondition);
|
||||||
@@ -390,18 +437,19 @@ export default {
|
|||||||
if (resultNode?.parseType === 'constant') {
|
if (resultNode?.parseType === 'constant') {
|
||||||
if (!resultNode.value) {
|
if (!resultNode.value) {
|
||||||
node._disabledBySlotFillerCondition = true;
|
node._disabledBySlotFillerCondition = true;
|
||||||
|
node._conditionError = node.slotFillerConditionNote || node.slotFillerCondition;
|
||||||
disabledNodeCount += 1;
|
disabledNodeCount += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node._disabledBySlotFillerCondition = true;
|
node._disabledBySlotFillerCondition = true;
|
||||||
node._conditionError = toString(resultNode);
|
node._conditionError = node.slotFillerConditionNote || toString(resultNode);
|
||||||
disabledNodeCount += 1;
|
disabledNodeCount += 1;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
let error = prettifyParseError(e);
|
let error = prettifyParseError(e);
|
||||||
node._disabledBySlotFillerCondition = true;
|
node._disabledBySlotFillerCondition = true;
|
||||||
node._conditionError = error;
|
node._conditionError = 'Condition error: ' + error;
|
||||||
disabledNodeCount += 1;
|
disabledNodeCount += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,6 +463,7 @@ export default {
|
|||||||
node._disabledByAlreadyAdded = true;
|
node._disabledByAlreadyAdded = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nodes.sort((a, b) => a.level - b.level);
|
||||||
this.disabledNodeCount = disabledNodeCount;
|
this.disabledNodeCount = disabledNodeCount;
|
||||||
return nodes;
|
return nodes;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
:key="libraryNode._id"
|
:key="libraryNode._id"
|
||||||
:model="libraryNode"
|
:model="libraryNode"
|
||||||
:data-id="libraryNode._id"
|
:data-id="libraryNode._id"
|
||||||
:class="{disabled: isDisabled(libraryNode)}"
|
:class="{disabled: isDisabled(libraryNode) || libraryNode._disabledBySlotFillerCondition}"
|
||||||
>
|
>
|
||||||
<v-expansion-panel-header>
|
<v-expansion-panel-header>
|
||||||
<template #default="{ open }">
|
<template #default="{ open }">
|
||||||
@@ -84,6 +84,7 @@
|
|||||||
v-model="selectedNodeIds"
|
v-model="selectedNodeIds"
|
||||||
class="my-0 py-0"
|
class="my-0 py-0"
|
||||||
hide-details
|
hide-details
|
||||||
|
:color="libraryNode._disabledBySlotFillerCondition ? 'error' : ''"
|
||||||
:disabled="isDisabled(libraryNode)"
|
:disabled="isDisabled(libraryNode)"
|
||||||
:value="libraryNode._id"
|
:value="libraryNode._id"
|
||||||
@click.stop
|
@click.stop
|
||||||
@@ -125,7 +126,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-expansion-panel-header>
|
</v-expansion-panel-header>
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<library-node-expansion-content :model="libraryNode" />
|
<library-node-expansion-content :id="libraryNode._id" />
|
||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</template>
|
</template>
|
||||||
@@ -136,16 +137,38 @@
|
|||||||
column
|
column
|
||||||
align-center
|
align-center
|
||||||
justify-center
|
justify-center
|
||||||
class="ma-3"
|
class="ma-3 mt-8"
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
:loading="!$subReady.slotFillers"
|
:loading="!$subReady.slotFillers"
|
||||||
color="accent"
|
color="accent"
|
||||||
|
outlined
|
||||||
@click="loadMore"
|
@click="loadMore"
|
||||||
>
|
>
|
||||||
Load More
|
Load More
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
<template v-if="!showDisabled && disabledNodeCount">
|
||||||
|
<v-layout
|
||||||
|
column
|
||||||
|
align-center
|
||||||
|
justify-center
|
||||||
|
class="ma-3 mt-8"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
Requirements of {{ disabledNodeCount }} properties were not met
|
||||||
|
</div>
|
||||||
|
<v-btn
|
||||||
|
class="mt-2"
|
||||||
|
elevation="0"
|
||||||
|
color="accent"
|
||||||
|
outlined
|
||||||
|
@click="showDisabled = true"
|
||||||
|
>
|
||||||
|
Show All
|
||||||
|
</v-btn>
|
||||||
|
</v-layout>
|
||||||
|
</template>
|
||||||
<v-layout
|
<v-layout
|
||||||
align-center
|
align-center
|
||||||
justify-center
|
justify-center
|
||||||
@@ -162,6 +185,7 @@
|
|||||||
<v-btn
|
<v-btn
|
||||||
v-if="!dummySlot"
|
v-if="!dummySlot"
|
||||||
text
|
text
|
||||||
|
small
|
||||||
data-id="library-browser-button"
|
data-id="library-browser-button"
|
||||||
:disabled="!model"
|
:disabled="!model"
|
||||||
@click="openLibraryBrowser"
|
@click="openLibraryBrowser"
|
||||||
@@ -171,7 +195,7 @@
|
|||||||
<v-btn
|
<v-btn
|
||||||
v-if="!dummySlot"
|
v-if="!dummySlot"
|
||||||
text
|
text
|
||||||
color="accent"
|
small
|
||||||
:disabled="!model"
|
:disabled="!model"
|
||||||
data-id="custom-button"
|
data-id="custom-button"
|
||||||
@click="insertCustomFiller"
|
@click="insertCustomFiller"
|
||||||
@@ -179,26 +203,7 @@
|
|||||||
Create custom filler
|
Create custom filler
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<template v-if="!showDisabled && disabledNodeCount">
|
|
||||||
<v-layout
|
|
||||||
column
|
|
||||||
align-center
|
|
||||||
justify-center
|
|
||||||
class="ma-3"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
Requirements of {{ disabledNodeCount }} properties were not met
|
|
||||||
</div>
|
|
||||||
<v-btn
|
|
||||||
class="mt-2"
|
|
||||||
elevation="0"
|
|
||||||
color="accent"
|
|
||||||
@click="showDisabled = true"
|
|
||||||
>
|
|
||||||
Show All
|
|
||||||
</v-btn>
|
|
||||||
</v-layout>
|
|
||||||
</template>
|
|
||||||
<template slot="actions">
|
<template slot="actions">
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
@@ -306,6 +311,19 @@ export default {
|
|||||||
return propName;
|
return propName;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
activeCount(val) {
|
||||||
|
// Still loading fillers
|
||||||
|
if (!this._subs['slotFillers'].ready()) return;
|
||||||
|
// Can load more, and not showing enough active choices, so load more
|
||||||
|
if (
|
||||||
|
this.currentLimit < this.countAll
|
||||||
|
&& val < 25
|
||||||
|
) {
|
||||||
|
this.loadMore();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadMore() {
|
loadMore() {
|
||||||
if (this.currentLimit >= this.countAll) return;
|
if (this.currentLimit >= this.countAll) return;
|
||||||
@@ -327,8 +345,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
isDisabled(node) {
|
isDisabled(node) {
|
||||||
return node._disabledBySlotFillerCondition ||
|
return node._disabledByAlreadyAdded ||
|
||||||
node._disabledByAlreadyAdded ||
|
|
||||||
(
|
(
|
||||||
node._disabledByQuantityFilled &&
|
node._disabledByQuantityFilled &&
|
||||||
!this.selectedNodeIds.includes(node._id)
|
!this.selectedNodeIds.includes(node._id)
|
||||||
@@ -408,6 +425,10 @@ export default {
|
|||||||
countAll() {
|
countAll() {
|
||||||
return this._subs['slotFillers'].data('countAll');
|
return this._subs['slotFillers'].data('countAll');
|
||||||
},
|
},
|
||||||
|
activeCount() {
|
||||||
|
if (!this.libraryNodes) return;
|
||||||
|
return this.libraryNodes.length - (this.disabledNodeCount || 0);
|
||||||
|
},
|
||||||
libraryNodeFilter() {
|
libraryNodeFilter() {
|
||||||
const filterString = this._subs['slotFillers'].data('libraryNodeFilter');
|
const filterString = this._subs['slotFillers'].data('libraryNodeFilter');
|
||||||
if (!filterString) return;
|
if (!filterString) return;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<v-list-item
|
<v-list-item
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:class="(isSelected || selectedByCollection) && !disabled && 'primary--text v-list-item--active'"
|
:class="(isSelected || selectedByCollection) && !disabled && 'primary--text v-list-item--active'"
|
||||||
:to="singleSelect ? undefined : to"
|
:to="selection ? undefined : to"
|
||||||
@click="singleSelect && $emit('select')"
|
@click="singleSelect && $emit('select')"
|
||||||
>
|
>
|
||||||
<v-list-item-action
|
<v-list-item-action
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div>
|
<div :key="id">
|
||||||
<v-progress-linear
|
<v-progress-linear
|
||||||
v-if="!subsReady"
|
v-if="!subsReady"
|
||||||
indeterminate
|
indeterminate
|
||||||
@@ -37,8 +37,8 @@ export default {
|
|||||||
...propertyViewerIndex,
|
...propertyViewerIndex,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
model: {
|
id: {
|
||||||
type: Object,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -61,16 +61,19 @@ export default {
|
|||||||
meteor: {
|
meteor: {
|
||||||
$subscribe: {
|
$subscribe: {
|
||||||
libraryNode(){
|
libraryNode(){
|
||||||
return [this.model._id];
|
return [this.id];
|
||||||
},
|
},
|
||||||
descendantLibraryNodes(){
|
descendantLibraryNodes(){
|
||||||
return [this.model._id];
|
return [this.id];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
model() {
|
||||||
|
return LibraryNodes.findOne(this.id);
|
||||||
|
},
|
||||||
propertyChildren(){
|
propertyChildren(){
|
||||||
return nodesToTree({
|
return nodesToTree({
|
||||||
collection: LibraryNodes,
|
collection: LibraryNodes,
|
||||||
ancestorId: this.model._id
|
ancestorId: this.id
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
v-else-if="model.attributeType === 'resource'"
|
v-else-if="model.attributeType === 'resource'"
|
||||||
:model="model"
|
:model="model"
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
@change="({ type, value }) => damageProperty({type, value: -value})"
|
@change="({ type, value, ack }) => damageProperty({type, value: -value, ack})"
|
||||||
@mouseover="hover = true"
|
@mouseover="hover = true"
|
||||||
@mouseleave="hover = false"
|
@mouseleave="hover = false"
|
||||||
/>
|
/>
|
||||||
@@ -96,6 +96,9 @@ export default {
|
|||||||
_id: this.model._id,
|
_id: this.model._id,
|
||||||
operation: change.type,
|
operation: change.type,
|
||||||
value: change.value
|
value: change.value
|
||||||
|
}, e => {
|
||||||
|
console.log(change);
|
||||||
|
change.ack?.(e);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
log({_id}) {
|
log({_id}) {
|
||||||
|
|||||||
@@ -41,16 +41,21 @@ Meteor.publish('slotFillers', function (slotId, searchTerm, isDummySlot) {
|
|||||||
sort: { name: 1 }
|
sort: { name: 1 }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build a filter for nodes in those libraries that match the slot
|
|
||||||
let filter = getSlotFillFilter({ slot, libraryIds });
|
|
||||||
this.autorun(function () {
|
this.autorun(function () {
|
||||||
|
// Build a filter for nodes in those libraries that match the slot
|
||||||
|
let filter = getSlotFillFilter({ slot, libraryIds });
|
||||||
// Get the limit of the documents the user can fetch
|
// Get the limit of the documents the user can fetch
|
||||||
var limit = self.data('limit') || 50;
|
var limit = self.data('limit') || 50;
|
||||||
check(limit, Number);
|
check(limit, Number);
|
||||||
|
|
||||||
let options = undefined;
|
let options = undefined;
|
||||||
if (searchTerm) {
|
if (searchTerm) {
|
||||||
filter.name = { $regex: escapeRegex(searchTerm), '$options': 'i' };
|
filter.$and.push({
|
||||||
|
$or: [
|
||||||
|
{ name: { $regex: escapeRegex(searchTerm), '$options': 'i' } },
|
||||||
|
{ libraryTags: searchTerm }
|
||||||
|
]
|
||||||
|
});
|
||||||
//filter.$text = { $search: searchTerm };
|
//filter.$text = { $search: searchTerm };
|
||||||
options = {
|
options = {
|
||||||
// relevant documents have a higher score.
|
// relevant documents have a higher score.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dicecloud",
|
"name": "dicecloud",
|
||||||
"version": "2.0.53",
|
"version": "2.0.55",
|
||||||
"description": "Unofficial Online Realtime D&D 5e App",
|
"description": "Unofficial Online Realtime D&D 5e App",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
Reference in New Issue
Block a user