Added UI backend that can do computations with context

This commit is contained in:
Thaum Rystra
2020-04-23 14:26:05 +02:00
parent 7416101a34
commit 95bfcd79c9
16 changed files with 294 additions and 40 deletions

View File

@@ -0,0 +1,35 @@
<template lang="html">
<div v-html="computedValue" class="computed" :class="expectNumber && 'symbols-are-errors'"/>
</template>
<script>
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
export default {
props: {
value: {
type: String,
},
scope: {
type: Object,
},
expectNumber: {
type: Boolean,
default: true,
}
},
computed: {
computedValue(){
if (!this.value) return;
let {result, errors} = evaluateString(this.value, this.scope);
return result;
}
}
}
</script>
<style lang="css">
.computed.symbols-are-errors .math-symbol {
color: red;
}
</style>

View File

@@ -0,0 +1,29 @@
<template lang="html">
<computed :value="value" :scope="scope"/>
</template>
<script>
import Computed from '/imports/ui/components/computation/Computed.vue';
export default {
inject: ['computationContext'],
components: {
Computed,
},
props: {
value: {
type: String,
},
},
meteor: {
creature(){
return Creatures.findOne(this.creatureId);
},
},
computed: {
scope(){
return this.computationContext.creature && this.computationContext.creature.variables;
}
}
}
</script>

View File

@@ -3,8 +3,8 @@
<v-toolbar
app
clipped-left
:color="character.color || 'secondary'"
:dark="isDarkColor(character.color || theme.primary)"
:color="creature.color || 'secondary'"
:dark="isDarkColor(creature.color || theme.primary)"
>
<v-btn
v-if="showMenuButton"
@@ -15,12 +15,12 @@
<v-icon>menu</v-icon>
</v-btn>
<div class="flex">
{{ character.name }}
{{ creature.name }}
</div>
<v-btn
flat
icon
@click="recompute(character._id)"
@click="recompute(creature._id)"
>
<v-icon>refresh</v-icon>
</v-btn>
@@ -143,6 +143,10 @@
required: true,
},
},
reactiveProvide: {
name: 'computationContext',
include: ['creature'],
},
data(){return {
theme,
tab: 0,
@@ -181,7 +185,7 @@
component: 'delete-confirmation-dialog',
elementId: 'creature-menu',
data: {
name: this.character.name,
name: this.creature.name,
typeName: 'Character'
},
callback(confirmation){
@@ -204,13 +208,10 @@
return [this.creatureId];
},
},
character(){
creature(){
return Creatures.findOne(this.creatureId) || {};
},
},
provide: {
creature: this.character,
}
}
</script>

View File

@@ -162,6 +162,14 @@
:data-id="action._id"
@click="clickProperty({_id: action._id})"
/>
<v-subheader>Attacks</v-subheader>
<attack-list-tile
v-for="attack in attacks"
:key="attack._id"
:model="attack"
:data-id="attack._id"
@click="clickProperty({_id: attack._id})"
/>
</v-list>
</v-card>
</div>
@@ -180,6 +188,7 @@
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
import ActionListTile from '/imports/ui/properties/components/actions/ActionListTile.vue';
import AttackListTile from '/imports/ui/properties/components/actions/AttackListTile.vue';
const getAttributeOfType = function(charId, type){
return CreatureProperties.find({
@@ -215,6 +224,7 @@
ResourceCard,
SpellSlotListTile,
ActionListTile,
AttackListTile,
},
props: {
creatureId: {
@@ -300,6 +310,14 @@
sort: {order: 1},
});
},
attacks(){
return CreatureProperties.find({
'ancestors.id': this.creatureId,
type: 'attack',
}, {
sort: {order: 1},
});
},
},
methods: {
clickProperty({_id}){

View File

@@ -10,7 +10,12 @@
</template>
<script>
import ComputedForCreature from '/imports/ui/components/computation/ComputedForCreature.vue';
export default {
components: {
Computed: ComputedForCreature,
},
props: {
model: {
type: Object,

View File

@@ -0,0 +1,40 @@
<template lang="html">
<v-list-tile
class="ability-list-tile"
v-on="hasClickListener ? {click} : {}"
>
<v-list-tile-content>
<computed :value="model.rollBonus"/>
{{ model.name }}
</v-list-tile-content>
</v-list-tile>
</template>
<script>
import ComputedForCreature from '/imports/ui/components/computation/ComputedForCreature.vue';
export default {
components: {
Computed: ComputedForCreature,
},
props: {
model: {
type: Object,
required: true,
}
},
computed: {
hasClickListener(){
return this.$listeners && this.$listeners.click
},
},
methods: {
click(e){
this.$emit('click', e);
},
}
}
</script>
<style lang="css" scoped>
</style>

View File

@@ -4,6 +4,7 @@ import Vuetify from "vuetify";
import store from "/imports/ui/vuexStore.js";
import VueMeteorTracker from 'vue-meteor-tracker';
import AppLayout from '/imports/ui/layouts/AppLayout.vue';
import ReactiveProvide from 'vue-reactive-provide';
import router from "/imports/ui/router.js";
import { theme } from '/imports/ui/theme.js';
import "vuetify/dist/vuetify.min.css";
@@ -15,6 +16,9 @@ Vue.use(Vuetify, {
theme,
iconfont: "md",
});
Vue.use(ReactiveProvide, {
name: 'reactiveProvide', // default value
})
// App start
Meteor.startup(() => {