Added error alert to stat tab for dependency loops
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
if<template>
|
<template>
|
||||||
<div class="character-sheet fill-height">
|
<div class="character-sheet fill-height">
|
||||||
<v-fade-transition mode="out-in">
|
<v-fade-transition mode="out-in">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
<div
|
<div
|
||||||
class="stats-tab ma-2"
|
class="stats-tab ma-2"
|
||||||
>
|
>
|
||||||
|
<character-errors
|
||||||
|
class="mx-2 mt-4"
|
||||||
|
:creature-id="creatureId"
|
||||||
|
/>
|
||||||
|
|
||||||
<health-bar-card-container :creature-id="creatureId" />
|
<health-bar-card-container :creature-id="creatureId" />
|
||||||
|
|
||||||
<column-layout>
|
<column-layout>
|
||||||
@@ -369,6 +374,7 @@
|
|||||||
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||||
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
||||||
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||||
|
import CharacterErrors from '/imports/ui/creature/character/errors/CharacterErrors.vue';
|
||||||
|
|
||||||
const getProperties = function(creature, filter, options = {
|
const getProperties = function(creature, filter, options = {
|
||||||
sort: {order: 1}
|
sort: {order: 1}
|
||||||
@@ -413,6 +419,7 @@
|
|||||||
SpellSlotListTile,
|
SpellSlotListTile,
|
||||||
ActionCard,
|
ActionCard,
|
||||||
ToggleCard,
|
ToggleCard,
|
||||||
|
CharacterErrors,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
creatureId: {
|
creatureId: {
|
||||||
|
|||||||
60
app/imports/ui/creature/character/errors/CharacterErrors.vue
Normal file
60
app/imports/ui/creature/character/errors/CharacterErrors.vue
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="creature && creature.computeErrors"
|
||||||
|
class="character-sheet-errors"
|
||||||
|
>
|
||||||
|
<template v-for="(error, index) in creature.computeErrors">
|
||||||
|
<dependency-loop-error
|
||||||
|
v-if="error.type === 'dependencyLoop'"
|
||||||
|
:key="index + 'dependencyLoopError'"
|
||||||
|
:model="error"
|
||||||
|
/>
|
||||||
|
<v-alert
|
||||||
|
v-else
|
||||||
|
:key="index + 'otherError'"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
type="error"
|
||||||
|
>
|
||||||
|
{{ error.type }}
|
||||||
|
</v-alert>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
|
import DependencyLoopError from '/imports/ui/creature/character/errors/DependencyLoopError.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
DependencyLoopError,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
default: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
creature() {
|
||||||
|
if (!this.creatureId) return;
|
||||||
|
return Creatures.findOne(this.creatureId, {fields: {computeErrors: 1}});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
errors() {
|
||||||
|
if (!this.creature || !this.creature.computeErrors) return;
|
||||||
|
return this.creature.computeErrors.map(error => {
|
||||||
|
error.text = error.type;
|
||||||
|
if (error.type === 'dependencyLoop') {
|
||||||
|
error.text = 'Dependency Loop Detected';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<v-alert
|
||||||
|
v-if="model"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
type="warning"
|
||||||
|
class="dependency-loop-error"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
The character contains a dependency loop.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
A set of properties may have been calculated incorrectly, because they form an infinite loop:
|
||||||
|
</p>
|
||||||
|
<div class="d-flex align-center flex-wrap">
|
||||||
|
<template
|
||||||
|
v-for="(prop, index) in loopProperties"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
v-if="index !== 0"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
mdi-chevron-right
|
||||||
|
</v-icon>
|
||||||
|
<a
|
||||||
|
v-if="prop.type"
|
||||||
|
:key="index + 'link'"
|
||||||
|
:data-id="`breadcrumb-${prop._id}`"
|
||||||
|
@click="click(prop._id)"
|
||||||
|
>
|
||||||
|
<tree-node-view
|
||||||
|
:model="prop"
|
||||||
|
class="breadcrumb-tree-node-view"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
:key="index + 'variable'"
|
||||||
|
style="font-family: monospace !important;"
|
||||||
|
>
|
||||||
|
{{ prop.name }} {{ prop.path }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</v-alert>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import TreeNodeView from '/imports/ui/properties/treeNodeViews/TreeNodeView.vue';
|
||||||
|
import { reverse } from 'lodash';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
TreeNodeView,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
default: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
loopProperties() {
|
||||||
|
if (!this.model) return;
|
||||||
|
const propAddresses = this.model.details?.nodes || [];
|
||||||
|
const props = propAddresses.map(propAddress => {
|
||||||
|
const [id, ...path] = propAddress.split('.');
|
||||||
|
const prop = CreatureProperties.findOne(id);
|
||||||
|
if (prop) {
|
||||||
|
prop.path = path && path.join('.');
|
||||||
|
if (prop.name && prop.path) prop.name += ` [${prop.path}]`;
|
||||||
|
return prop;
|
||||||
|
} else {
|
||||||
|
return { name: propAddress };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return reverse(props);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
click(id){
|
||||||
|
// Otherwise open it as a new dialog
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'creature-property-dialog',
|
||||||
|
elementId: `breadcrumb-${id}`,
|
||||||
|
data: {_id: id},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
@@ -3,7 +3,15 @@
|
|||||||
class="breadcrumbs layout align-center wrap"
|
class="breadcrumbs layout align-center wrap"
|
||||||
:class="{'no-icons': noIcons}"
|
:class="{'no-icons': noIcons}"
|
||||||
>
|
>
|
||||||
|
<span
|
||||||
|
v-if="noLinks"
|
||||||
|
>
|
||||||
|
<v-icon>
|
||||||
|
mdi-account
|
||||||
|
</v-icon>
|
||||||
|
</span>
|
||||||
<a
|
<a
|
||||||
|
v-else
|
||||||
data-id="breadcrumb-root"
|
data-id="breadcrumb-root"
|
||||||
@click="clickRootCreature"
|
@click="clickRootCreature"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -101,12 +101,13 @@
|
|||||||
case 'mul': return 'Multiply';
|
case 'mul': return 'Multiply';
|
||||||
case 'min': return 'Minimum';
|
case 'min': return 'Minimum';
|
||||||
case 'max': return 'Maximum';
|
case 'max': return 'Maximum';
|
||||||
|
case 'set': return 'Set';
|
||||||
case 'advantage': return 'Advantage';
|
case 'advantage': return 'Advantage';
|
||||||
case 'disadvantage': return 'Disadvantage';
|
case 'disadvantage': return 'Disadvantage';
|
||||||
case 'passiveAdd': return 'Passive bonus';
|
case 'passiveAdd': return 'Passive bonus';
|
||||||
case 'fail': return 'Always fail';
|
case 'fail': return 'Always fail';
|
||||||
case 'conditional': return 'Conditional benefit' ;
|
case 'conditional': return 'Conditional benefit' ;
|
||||||
default: return '';
|
default: return this.model.operation;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
displayedValue(){
|
displayedValue(){
|
||||||
|
|||||||
Reference in New Issue
Block a user