Refactored all forms for updated code style

This commit is contained in:
Thaum Rystra
2020-04-04 18:40:08 +02:00
parent 1856e90d12
commit e77513110b
30 changed files with 1561 additions and 1517 deletions

View File

@@ -1,198 +1,201 @@
<template lang="html">
<div :class="attackForm ? 'attack-form' : 'action-form'">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<smart-select
label="Action type"
:items="actionTypes"
:value="model.actionType"
:error-messages="errors.actionType"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['actionType'], value, ack})"
:hint="actionTypeHints[model.actionType]"
:debounce-time="debounceTime"
/>
<text-field
label="Roll bonus"
v-if="attackForm"
:value="model.rollBonus"
@change="(value, ack) => $emit('change', {path: ['rollBonus'], value, ack})"
:error-messages="errors.rollBonus"
:debounce-time="debounceTime"
/>
<form-sections>
<form-section name="Results">
<results-form
:model="model.results"
:parent-target="model.target"
@change="({path, value, ack}) => $emit('change', {path: ['results', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['results', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['results', ...path], ack})"
/>
</form-section>
<form-section name="Advanced">
<text-field
label="Ammunition"
hint="The variable name of the item used as ammunition"
v-if="attackForm"
:value="model.ammunition"
@change="(value, ack) => $emit('change', {path: ['ammunition'], value, ack})"
:error-messages="errors.ammunition"
:debounce-time="debounceTime"
/>
<v-combobox
label="Tags"
multiple
chips
deletable-chips
box
:value="model.tags"
@change="(value) => $emit('change', {path: ['tags'], value})"
/>
<smart-select
label="Target"
style="flex-basis: 300px;"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<text-field
label="Uses"
hint="How many times this action can be used before needing to be reset"
style="flex-basis: 300px;"
:value="model.uses"
@change="(value, ack) => $emit('change', {path: ['uses'], value, ack})"
:error-messages="errors.uses"
:debounce-time="debounceTime"
/>
<text-field
label="Uses used"
type="number"
hint="How many times this action has already been used"
style="flex-basis: 300px;"
:value="model.usesUsed"
@change="(value, ack) => $emit('change', {path: ['usesUsed'], value, ack})"
:error-messages="errors.uses"
:debounce-time="debounceTime"
/>
</div>
<smart-select
label="Reset"
clearable
style="flex-basis: 300px;"
:items="resetOptions"
:value="model.reset"
:error-messages="errors.reset"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['reset'], value, ack})"
:debounce-time="debounceTime"
/>
</form-section>
</form-sections>
<text-field
label="Name"
:value="model.name"
:debounce-time="debounceTime"
:error-messages="errors.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<smart-select
label="Action type"
:items="actionTypes"
:value="model.actionType"
:error-messages="errors.actionType"
:menu-props="{auto: true, lazy: true}"
:hint="actionTypeHints[model.actionType]"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['actionType'], value, ack})"
/>
<text-field
v-if="attackForm"
label="Roll bonus"
:value="model.rollBonus"
:error-messages="errors.rollBonus"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['rollBonus'], value, ack})"
/>
<form-sections>
<form-section name="Results">
<results-form
:model="model.results"
:parent-target="model.target"
@change="({path, value, ack}) => $emit('change', {path: ['results', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['results', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['results', ...path], ack})"
/>
</form-section>
<form-section name="Advanced">
<text-field
v-if="attackForm"
label="Ammunition"
hint="The variable name of the item used as ammunition"
:value="model.ammunition"
:error-messages="errors.ammunition"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['ammunition'], value, ack})"
/>
<v-combobox
label="Tags"
multiple
chips
deletable-chips
box
:value="model.tags"
@change="(value) => $emit('change', {path: ['tags'], value})"
/>
<smart-select
label="Target"
style="flex-basis: 300px;"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
/>
<div class="layout row wrap">
<text-field
label="Uses"
hint="How many times this action can be used before needing to be reset"
style="flex-basis: 300px;"
:value="model.uses"
:error-messages="errors.uses"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['uses'], value, ack})"
/>
<text-field
label="Uses used"
type="number"
hint="How many times this action has already been used"
style="flex-basis: 300px;"
:value="model.usesUsed"
:error-messages="errors.uses"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['usesUsed'], value, ack})"
/>
</div>
<smart-select
label="Reset"
clearable
style="flex-basis: 300px;"
:items="resetOptions"
:value="model.reset"
:error-messages="errors.reset"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['reset'], value, ack})"
/>
</form-section>
</form-sections>
</div>
</template>
<script>
import FormSection, {FormSections} from '/imports/ui/properties/forms/shared/FormSection.vue';
import ResultsForm from '/imports/ui/properties/forms/ResultsForm.vue';
import FormSection, {FormSections} from '/imports/ui/properties/forms/shared/FormSection.vue';
import ResultsForm from '/imports/ui/properties/forms/ResultsForm.vue';
export default {
components: {
FormSection,
FormSections,
ResultsForm,
},
props: {
stored: {
type: Boolean,
},
model: {
type: Object,
default: () => ({}),
},
errors: {
type: Object,
default: () => ({}),
},
attackForm: {
type: Boolean,
},
debounceTime: Number,
},
data(){
let data = {
actionTypes: [
{
text: 'Action',
value: 'action',
}, {
text: 'Bonus action',
value: 'bonus',
}, {
text: 'Attack action',
value: 'attack',
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
}, {
text: 'Reaction',
value: 'reaction',
}, {
text: 'Free action',
value: 'free',
help: 'You can take one free action on your turn without using an action or bonus action'
}, {
text: 'Long action',
value: 'long',
help: 'Long actions take longer than one turn to complete'
},
],
targetOptions: [
{
text: 'Self',
value: 'self',
}, {
text: 'Single target',
value: 'singleTarget',
}, {
text: 'Multiple targets',
value: 'multipleTargets',
},
],
resetOptions: [
{
text: 'Short rest',
value: 'shortRest',
}, {
text: 'Long rest',
value: 'longRest',
}
],
};
data.actionTypeHints = {};
data.actionTypes.forEach(type => {
data.actionTypeHints[type.value] = type.help;
});
return data;
},
};
export default {
components: {
FormSection,
FormSections,
ResultsForm,
},
props: {
stored: {
type: Boolean,
},
model: {
type: Object,
default: () => ({}),
},
errors: {
type: Object,
default: () => ({}),
},
attackForm: {
type: Boolean,
},
debounceTime: {
type: Number,
default: undefined,
},
},
data(){
let data = {
actionTypes: [
{
text: 'Action',
value: 'action',
}, {
text: 'Bonus action',
value: 'bonus',
}, {
text: 'Attack action',
value: 'attack',
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
}, {
text: 'Reaction',
value: 'reaction',
}, {
text: 'Free action',
value: 'free',
help: 'You can take one free action on your turn without using an action or bonus action'
}, {
text: 'Long action',
value: 'long',
help: 'Long actions take longer than one turn to complete'
},
],
targetOptions: [
{
text: 'Self',
value: 'self',
}, {
text: 'Single target',
value: 'singleTarget',
}, {
text: 'Multiple targets',
value: 'multipleTargets',
},
],
resetOptions: [
{
text: 'Short rest',
value: 'shortRest',
}, {
text: 'Long rest',
value: 'longRest',
}
],
};
data.actionTypeHints = {};
data.actionTypes.forEach(type => {
data.actionTypeHints[type.value] = type.help;
});
return data;
},
};
</script>
<style lang="css" scoped>
.no-flex {
flex: initial;
}
.layout.row.wrap {
margin-right: -8px;
}
.layout.row.wrap > *{
margin-right: 8px;
}
.no-flex {
flex: initial;
}
.layout.row.wrap {
margin-right: -8px;
}
.layout.row.wrap > *{
margin-right: 8px;
}
</style>

View File

@@ -1,37 +1,37 @@
<template lang="html">
<div>
<div class="layout row">
<text-field
label="Attribute"
hint="The attribute this adjustment will apply to"
style="flex-basis: 300px;"
:value="model.stat"
@change="(value, ack) => $emit('change', {path: ['stat'], value, ack})"
:error-messages="errors.stat"
:debounce-time="debounceTime"
/>
<text-field
label="Damage"
hint="The amount of damage to apply to the selected stat, can be a calculation or roll"
style="flex-basis: 300px;"
:value="model.damage"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
:error-messages="errors.damage"
:debounce-time="debounceTime"
/>
</div>
<smart-select
v-if="parentTarget !== 'self'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
:debounce-time="debounceTime"
/>
</div>
<div>
<div class="layout row">
<text-field
label="Attribute"
hint="The attribute this adjustment will apply to"
style="flex-basis: 300px;"
:value="model.stat"
:error-messages="errors.stat"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['stat'], value, ack})"
/>
<text-field
label="Damage"
hint="The amount of damage to apply to the selected stat, can be a calculation or roll"
style="flex-basis: 300px;"
:value="model.damage"
:error-messages="errors.damage"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
/>
</div>
<smart-select
v-if="parentTarget !== 'self'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
/>
</div>
</template>
<script>
@@ -47,8 +47,12 @@ export default {
},
parentTarget: {
type: String,
required: true,
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
computed: {
targetOptions(){

View File

@@ -1,37 +1,43 @@
<template lang="html">
<div>
<v-slide-x-transition group>
<div
v-for="(adjustment, i) in model"
:key="adjustment._id || i"
>
<v-divider v-if="i !== 0"/>
<div class="layout row align-center">
<div style="flex-grow: 1;">
<adjustment-form
class="mt-4"
:model="adjustment"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
/>
</div>
<v-btn outline icon large class="ma-3" @click="$emit('pull', {path: [i]})">
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addAdjustmentLoading"
:disabled="addAdjustmentLoading"
outline
icon
@click="addAdjustment"
>
<v-icon>add</v-icon>
</v-btn>
</div>
<v-slide-x-transition group>
<div
v-for="(adjustment, i) in model"
:key="adjustment._id || i"
>
<v-divider v-if="i !== 0" />
<div class="layout row align-center">
<div style="flex-grow: 1;">
<adjustment-form
class="mt-4"
:model="adjustment"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
/>
</div>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: [i]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addAdjustmentLoading"
:disabled="addAdjustmentLoading"
outline
icon
@click="addAdjustment"
>
<v-icon>add</v-icon>
</v-btn>
</div>
</div>
</template>
@@ -43,6 +49,20 @@
components: {
AdjustmentForm,
},
props: {
model: {
type: Array,
default: () => ([]),
},
parentTarget: {
type: String,
required: true,
},
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
addAdjustmentLoading: false,
}},
@@ -59,16 +79,6 @@
});
},
},
props: {
model: {
type: Array,
default: () => ([]),
},
parentTarget: {
type: String,
},
debounceTime: Number,
},
}
</script>

View File

@@ -1,5 +1,9 @@
<template lang="html">
<action-form attack-form v-bind="$attrs" v-on="$listeners"/>
<action-form
attack-form
v-bind="$attrs"
v-on="$listeners"
/>
</template>
<script>

View File

@@ -1,99 +1,105 @@
<template lang="html">
<div class="attribute-form">
<div class="layout column align-center">
<text-field
label="Base Value"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.baseValue"
@change="(value, ack) => $emit('change', {path: ['baseValue'], value, ack})"
hint="This is the value of the attribute before effects are applied"
:error-messages="errors.baseValue"
:debounce-time="debounceTime"
/>
</div>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
/>
</div>
<smart-select
label="Type"
:items="attributeTypes"
:value="model.attributeType"
:error-messages="errors.attributeType"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['attributeType'], value, ack})"
:hint="attributeTypeHints[model.attributeType]"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<form-section name="Advanced" standalone>
<div class="layout column align-center">
<v-switch
label="Allow decimal values"
class="no-flex"
:input-value="model.decimal"
:error-messages="errors.decimal"
@change="e => $emit('change', {path: ['decimal'], value: !!e})"
/>
<div class="layout row justify-center" style="align-self: stretch;">
<text-field
label="Damage"
type="number"
class="damage-field text-xs-center"
style="max-width: 300px;"
hint="The attribute's final value is reduced by this amount"
:value="model.damage"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
:error-messages="errors.damage"
:debounce-time="debounceTime"
/>
</div>
</div>
<div class="layout row wrap">
<smart-select
label="Reset"
clearable
style="flex-basis: 300px;"
:items="resetOptions"
:value="model.reset"
:error-messages="errors.reset"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['reset'], value: value || '', ack})"
:debounce-time="debounceTime"
/>
<text-field
label="Reset Multiplier"
type="number"
style="flex-basis: 400px;"
:value="model.resetMultiplier"
:error-messages="errors.resetMultiplier"
@change="(value, ack) => $emit('change', {path: ['resetMultiplier'], value, ack})"
hint="Some attributes, like hit dice, only reset by half their total on a long rest"
:debounce-time="debounceTime"
/>
</div>
</form-section>
<div class="layout column align-center">
<text-field
label="Base Value"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.baseValue"
hint="This is the value of the attribute before effects are applied"
:error-messages="errors.baseValue"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['baseValue'], value, ack})"
/>
</div>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
/>
</div>
<smart-select
label="Type"
:items="attributeTypes"
:value="model.attributeType"
:error-messages="errors.attributeType"
:menu-props="{auto: true, lazy: true}"
:hint="attributeTypeHints[model.attributeType]"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['attributeType'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<form-section
name="Advanced"
standalone
>
<div class="layout column align-center">
<v-switch
label="Allow decimal values"
class="no-flex"
:input-value="model.decimal"
:error-messages="errors.decimal"
@change="e => $emit('change', {path: ['decimal'], value: !!e})"
/>
<div
class="layout row justify-center"
style="align-self: stretch;"
>
<text-field
label="Damage"
type="number"
class="damage-field text-xs-center"
style="max-width: 300px;"
hint="The attribute's final value is reduced by this amount"
:value="model.damage"
:error-messages="errors.damage"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
/>
</div>
</div>
<div class="layout row wrap">
<smart-select
label="Reset"
clearable
style="flex-basis: 300px;"
:items="resetOptions"
:value="model.reset"
:error-messages="errors.reset"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['reset'], value: value || '', ack})"
/>
<text-field
label="Reset Multiplier"
type="number"
style="flex-basis: 400px;"
:value="model.resetMultiplier"
:error-messages="errors.resetMultiplier"
hint="Some attributes, like hit dice, only reset by half their total on a long rest"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['resetMultiplier'], value, ack})"
/>
</div>
</form-section>
</div>
</template>
@@ -113,7 +119,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){
let data = {

View File

@@ -1,52 +1,55 @@
<template lang="html">
<div class="buff-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:error-messages="errors.description"
:debounce-time="debounceTime"
/>
<text-field
label="Duration"
hint="How long the buff lasts"
:value="model.duration"
@change="(value, ack) => $emit('change', {path: ['duration'], value, ack})"
:error-messages="errors.duration"
:debounce-time="debounceTime"
/>
<div v-if="stored">
<smart-select
v-if="parentTarget !== 'self'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
:debounce-time="debounceTime"
/>
<effect-list-form
:model="model.effects"
@change="({path, value, ack}) => $emit('change', {path: ['effects', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['effects', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['effects', ...path], ack})"
/>
</div>
</div>
<div class="buff-form">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<text-field
label="Duration"
hint="How long the buff lasts"
:value="model.duration"
:error-messages="errors.duration"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['duration'], value, ack})"
/>
<div v-if="stored">
<smart-select
v-if="parentTarget !== 'self'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
/>
<effect-list-form
:model="model.effects"
@change="({path, value, ack}) => $emit('change', {path: ['effects', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['effects', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['effects', ...path], ack})"
/>
</div>
</div>
</template>
<script>
import EffectListForm from '/imports/ui/properties/forms/EffectListForm.vue';
export default {
components: {
EffectListForm,
},
props: {
stored: Boolean,
model: {
@@ -59,11 +62,12 @@
},
parentTarget: {
type: String,
required: true,
},
debounceTime: Number,
},
components: {
EffectListForm,
debounceTime: {
type: Number,
default: undefined,
},
},
computed: {
targetOptions(){

View File

@@ -1,40 +1,46 @@
<template lang="html">
<div>
<v-slide-x-transition group>
<div
v-for="(buff, i) in model"
:key="buff._id || i"
>
<v-divider v-if="i !== 0"/>
<div class="layout row align-center">
<div style="flex-grow: 1;">
<buff-form
class="mt-4"
:model="buff"
:parent-target="parentTarget"
:stored="true"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: [i, ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: [i, ...path], ack})"
/>
</div>
<v-btn outline icon large class="ma-3" @click="$emit('pull', {path: [i]})">
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addBuffLoading"
:disabled="addBuffLoading"
outline
icon
@click="addBuff"
>
<v-icon>add</v-icon>
</v-btn>
</div>
<v-slide-x-transition group>
<div
v-for="(buff, i) in model"
:key="buff._id || i"
>
<v-divider v-if="i !== 0" />
<div class="layout row align-center">
<div style="flex-grow: 1;">
<buff-form
class="mt-4"
:model="buff"
:parent-target="parentTarget"
:stored="true"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: [i, ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: [i, ...path], ack})"
/>
</div>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: [i]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addBuffLoading"
:disabled="addBuffLoading"
outline
icon
@click="addBuff"
>
<v-icon>add</v-icon>
</v-btn>
</div>
</div>
</template>
@@ -53,8 +59,12 @@
},
parentTarget: {
type: String,
required: true,
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
addBuffLoading: false,

View File

@@ -1,53 +1,49 @@
<template lang="html">
<div class="class-form">
<div class="layout column align-center">
<text-field
label="Level"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.level"
@change="(value, ack) => $emit('change', {path: ['level'], value, ack})"
:error-messages="errors.level"
:debounce-time="debounceTime"
/>
</div>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
hint="Use this name in formulae to reference this class"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
/>
<text-field
label="Base Class Variable name"
:value="model.baseClass"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['baseClass'], value, ack})"
hint="This is the name of the class this class level belongs to"
:error-messages="errors.baseClass"
:debounce-time="debounceTime"
/>
</div>
<div class="layout column align-center">
<text-field
label="Level"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.level"
:error-messages="errors.level"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['level'], value, ack})"
/>
</div>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
hint="Use this name in formulae to reference this class"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
/>
<text-field
label="Base Class Variable name"
:value="model.baseClass"
style="flex-basis: 300px;"
hint="This is the name of the class this class level belongs to"
:error-messages="errors.baseClass"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['baseClass'], value, ack})"
/>
</div>
</div>
</template>
<script>
import FormSection from '/imports/ui/properties/forms/shared/FormSection.vue';
export default {
components: {
FormSection,
},
props: {
model: {
type: Object,
@@ -57,7 +53,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,60 +1,63 @@
<template lang="html">
<div class="attribute-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<text-field
label="Value"
suffix="gp"
type="number"
min="0"
hint="The value of the item in gold pieces, using decimals for values less than 1 gp"
class="mx-1"
style="flex-basis: 300px;"
:value="model.value"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
:error-messages="errors.value"
:debounce-time="debounceTime"
/>
<text-field
label="Weight"
suffix="lbs"
type="number"
min="0"
class="mx-1"
style="flex-basis: 300px;"
:value="model.weight"
@change="(value, ack) => $emit('change', {path: ['weight'], value, ack})"
:error-messages="errors.weight"
:debounce-time="debounceTime"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<form-section name="Advanced" standalone>
<v-switch
label="Carried"
:input-value="model.carried"
:error-messages="errors.carried"
@change="e => $emit('change', {path: ['carried'], value})"
/>
<v-switch
label="Contents are weightless"
:input-value="model.contentsWeightless"
:error-messages="errors.contentsWeightless"
@change="e => $emit('change', {path: ['contentsWeightless'], value})"
/>
</form-section>
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<div class="layout row wrap">
<text-field
label="Value"
suffix="gp"
type="number"
min="0"
hint="The value of the item in gold pieces, using decimals for values less than 1 gp"
class="mx-1"
style="flex-basis: 300px;"
:value="model.value"
:error-messages="errors.value"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
<text-field
label="Weight"
suffix="lbs"
type="number"
min="0"
class="mx-1"
style="flex-basis: 300px;"
:value="model.weight"
:error-messages="errors.weight"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['weight'], value, ack})"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<form-section
name="Advanced"
standalone
>
<v-switch
label="Carried"
:input-value="model.carried"
:error-messages="errors.carried"
@change="e => $emit('change', {path: ['carried'], value})"
/>
<v-switch
label="Contents are weightless"
:input-value="model.contentsWeightless"
:error-messages="errors.contentsWeightless"
@change="e => $emit('change', {path: ['contentsWeightless'], value})"
/>
</form-section>
</div>
</template>
@@ -74,7 +77,10 @@ export default {
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
}
</script>

View File

@@ -1,46 +1,43 @@
<template lang="html">
<div>
<div class="layout row">
<text-field
label="Damage"
style="flex-basis: 300px;"
:value="model.damage"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
:error-messages="errors.damage"
:debounce-time="debounceTime"
/>
<smart-select
label="Damage Type"
style="flex-basis: 200px;"
:items="DAMAGE_TYPES"
:value="model.damageType"
:error-messages="errors.damageType"
:menu-props="{auto: true}"
@change="(value, ack) => $emit('change', {path: ['damageType'], value, ack})"
:debounce-time="debounceTime"
/>
</div>
<smart-select
v-if="parentTarget == 'multipleTargets'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
:debounce-time="debounceTime"
/>
</div>
<div>
<div class="layout row">
<text-field
label="Damage"
style="flex-basis: 300px;"
:value="model.damage"
:error-messages="errors.damage"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['damage'], value, ack})"
/>
<smart-select
label="Damage Type"
style="flex-basis: 200px;"
:items="DAMAGE_TYPES"
:value="model.damageType"
:error-messages="errors.damageType"
:menu-props="{auto: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['damageType'], value, ack})"
/>
</div>
<smart-select
v-if="parentTarget == 'multipleTargets'"
label="Target"
:hint="targetOptionHint"
:items="targetOptions"
:value="model.target"
:error-messages="errors.target"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['target'], value, ack})"
/>
</div>
</template>
<script>
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
export default {
data(){return{
DAMAGE_TYPES,
}},
props: {
model: {
type: Object,
@@ -52,9 +49,16 @@ export default {
},
parentTarget: {
type: String,
required: true,
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return{
DAMAGE_TYPES,
}},
computed: {
targetOptions(){
return [

View File

@@ -1,49 +1,68 @@
<template lang="html">
<div>
<v-slide-x-transition group>
<div
v-for="(damage, i) in model"
:key="damage._id || i"
>
<v-divider v-if="i !== 0"/>
<div class="layout row align-center">
<div style="flex-grow: 1;">
<damage-form
class="mt-4"
:model="damage"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
/>
</div>
<v-btn outline icon large class="ma-3" @click="$emit('pull', {path: [i]})">
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addDamageLoading"
:disabled="addDamageLoading"
outline
icon
@click="addDamage"
>
<v-icon>add</v-icon>
</v-btn>
</div>
<v-slide-x-transition group>
<div
v-for="(damage, i) in model"
:key="damage._id || i"
>
<v-divider v-if="i !== 0" />
<div class="layout row align-center">
<div style="flex-grow: 1;">
<damage-form
class="mt-4"
:model="damage"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
/>
</div>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: [i]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addDamageLoading"
:disabled="addDamageLoading"
outline
icon
@click="addDamage"
>
<v-icon>add</v-icon>
</v-btn>
</div>
</div>
</template>
<script>
import DamageForm from '/imports/ui/properties/forms/DamageForm.vue';
import DamageSchema from '/imports/api/properties/subSchemas/DamageSchema.js';
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
export default {
components: {
DamageForm,
},
props: {
model: {
type: Array,
default: () => ([]),
},
parentTarget: {
type: String,
required: true,
},
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
addDamageLoading: false,
}},
@@ -60,16 +79,6 @@
});
},
},
props: {
model: {
type: Array,
default: () => ([]),
},
parentTarget: {
type: String,
},
debounceTime: Number,
},
}
</script>

View File

@@ -1,46 +1,39 @@
<template lang="html">
<div class="attribute-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<smart-select
label="Damage Type"
style="flex-basis: 300px;"
:items="damageTypes"
:value="model.damageType"
:error-messages="errors.damageType"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['damageType'], value, ack})"
:debounce-time="debounceTime"
/>
<smart-select
label="Value"
style="flex-basis: 300px;"
:items="values"
:value="model.value"
:error-messages="errors.value"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
:debounce-time="debounceTime"
/>
</div>
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<div class="layout row wrap">
<smart-select
label="Damage Type"
style="flex-basis: 300px;"
:items="damageTypes"
:value="model.damageType"
:error-messages="errors.damageType"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['damageType'], value, ack})"
/>
<smart-select
label="Value"
style="flex-basis: 300px;"
:items="values"
:value="model.value"
:error-messages="errors.value"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
</div>
</div>
</template>
<script>
import FormSection from '/imports/ui/properties/forms/shared/FormSection.vue';
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
export default {
components: {
FormSection,
},
props: {
model: {
type: Object,
@@ -50,70 +43,73 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
damageTypes: [
{
value: "bludgeoning",
text: "Bludgeoning",
{
value: 'bludgeoning',
text: 'Bludgeoning',
}, {
value: "piercing",
text: "Piercing",
value: 'piercing',
text: 'Piercing',
}, {
value: "slashing",
text: "Slashing",
value: 'slashing',
text: 'Slashing',
}, {
value: "magicalBludgeoning",
text: "Magical Bludgeoning",
value: 'magicalBludgeoning',
text: 'Magical Bludgeoning',
}, {
value: "magicalPiercing",
text: "Magical Piercing",
value: 'magicalPiercing',
text: 'Magical Piercing',
}, {
value: "magicalSlashing",
text: "Magical Slashing",
value: 'magicalSlashing',
text: 'Magical Slashing',
}, {
value: "acid",
text: "Acid",
value: 'acid',
text: 'Acid',
}, {
value: "cold",
text: "Cold",
value: 'cold',
text: 'Cold',
}, {
value: "fire",
text: "Fire",
value: 'fire',
text: 'Fire',
}, {
value: "force",
text: "Force",
value: 'force',
text: 'Force',
}, {
value: "lightning",
text: "Lightning",
value: 'lightning',
text: 'Lightning',
}, {
value: "necrotic",
text: "Necrotic",
value: 'necrotic',
text: 'Necrotic',
}, {
value: "poison",
text: "Poison",
value: 'poison',
text: 'Poison',
}, {
value: "psychic",
text: "Psychic",
value: 'psychic',
text: 'Psychic',
}, {
value: "radiant",
text: "Radiant",
value: 'radiant',
text: 'Radiant',
}, {
value: "thunder",
text: "Thunder",
value: 'thunder',
text: 'Thunder',
},
],
values: [
{
{
value: 0,
text: "Immunity",
text: 'Immunity',
}, {
value: 0.5,
text: "Resistance",
text: 'Resistance',
}, {
value: 2,
text: "Vulnerability",
text: 'Vulnerability',
},
],
};},

View File

@@ -1,59 +1,66 @@
<template lang="html">
<div class="effect-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<div class="layout row wrap justify-start">
<smart-select
label="Operation"
append-icon="arrow_drop_down"
class="mx-2"
:error-messages="errors.operation"
:menu-props="{transition: 'slide-y-transition', lazy: true}"
:items="operations"
:value="model.operation"
@change="(value, ack) => $emit('change', {path: ['operation'], value, ack})"
>
<v-icon
class="icon"
slot="prepend"
:class="iconClass"
>{{displayedIcon}}</v-icon>
<template slot="item" slot-scope="item">
<v-icon
class="icon mr-2"
>{{getEffectIcon(item.item.value, 1)}}</v-icon>
{{item.item.text}}
</template>
</smart-select>
<div class="effect-form">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<div class="layout row wrap justify-start">
<smart-select
label="Operation"
append-icon="arrow_drop_down"
class="mx-2"
:error-messages="errors.operation"
:menu-props="{transition: 'slide-y-transition', lazy: true}"
:items="operations"
:value="model.operation"
@change="(value, ack) => $emit('change', {path: ['operation'], value, ack})"
>
<v-icon
slot="prepend"
class="icon"
:class="iconClass"
>
{{ displayedIcon }}
</v-icon>
<template
slot="item"
slot-scope="item"
>
<v-icon
class="icon mr-2"
>
{{ getEffectIcon(item.item.value, 1) }}
</v-icon>
{{ item.item.text }}
</template>
</smart-select>
<text-field
label="Value"
class="mr-2"
:persistent-hint="needsValue"
:value="needsValue ? (model.calculation) : ' '"
:disabled="!needsValue"
:error-messages="errors.calculation"
:hint="!isFinite(model.calculation) && model.result ? model.result + '' : '' "
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['calculation'], value, ack})"
/>
<text-field
label="Value"
class="mr-2"
:persistent-hint="needsValue"
:value="needsValue ? (model.calculation) : ' '"
:disabled="!needsValue"
:error-messages="errors.calculation"
:hint="!isFinite(model.calculation) && model.result ? model.result + '' : '' "
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['calculation'], value, ack})"
/>
<text-field
label="Stat"
class="mr-2"
:value="model.stats[0]"
:items="stats"
:error-messages="errors.stats"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['stats'], value: [value], ack})"
/>
</div>
</div>
<text-field
label="Stat"
class="mr-2"
:value="model.stats[0]"
:items="stats"
:error-messages="errors.stats"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['stats'], value: [value], ack})"
/>
</div>
</div>
</template>
<script>
@@ -72,8 +79,12 @@
},
stats: {
type: Array,
default: () => [],
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){ return {
displayedIcon: 'add',
@@ -104,32 +115,33 @@
case 'passiveAdd': return true;
case 'fail': return false;
case 'conditional': return true;
default: return true;
}
},
},
methods: {
getEffectIcon,
},
watch: {
'model.operation': {
immediate: true,
handler(newValue, oldValue, e){
handler(newValue, oldValue){
let newIcon = getEffectIcon(newValue, 1);
if (!oldValue){
// Skip animation
this.displayedIcon = newIcon;
} else {
this.iconClass="leaving";
this.iconClass='leaving';
setTimeout(() => {
this.displayedIcon = newIcon;
this.iconClass="arriving";
this.iconClass='arriving';
requestAnimationFrame(() => {
this.iconClass="";
this.iconClass='';
});
}, ICON_SPIN_DURATION / 2);
}
},
},
},
methods: {
getEffectIcon,
}
};
</script>

View File

@@ -1,39 +1,45 @@
<template lang="html">
<div>
<v-slide-x-transition group>
<div
v-for="(effect, i) in model"
:key="effect._id || i"
>
<v-divider v-if="i !== 0"/>
<div class="layout row align-center">
<div style="flex-grow: 1;">
<effect-form
class="mt-4"
:model="effect"
:parent-target="parentTarget"
:stored="stored"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
@pull="(ack) => $emit('pull', {path: [i], ack})"
/>
</div>
<v-btn outline icon large class="ma-3" @click="$emit('pull', {path: [i]})">
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-end">
<v-btn
:loading="addEffectLoading"
:disabled="addEffectLoading"
outline
@click="addEffect"
>
<v-icon>add</v-icon>
Add Effect
</v-btn>
</div>
<v-slide-x-transition group>
<div
v-for="(effect, i) in model"
:key="effect._id || i"
>
<v-divider v-if="i !== 0" />
<div class="layout row align-center">
<div style="flex-grow: 1;">
<effect-form
class="mt-4"
:model="effect"
:parent-target="parentTarget"
:stored="stored"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
@pull="(ack) => $emit('pull', {path: [i], ack})"
/>
</div>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: [i]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-end">
<v-btn
:loading="addEffectLoading"
:disabled="addEffectLoading"
outline
@click="addEffect"
>
<v-icon>add</v-icon>
Add Effect
</v-btn>
</div>
</div>
</template>
@@ -53,80 +59,12 @@
},
parentTarget: {
type: String,
required: true,
},
debounceTime: Number,
},
data(){return {
addEffectLoading: false,
}},
methods: {
acknowledgeAddEffect(){
this.addEffectLoading = false;
},
addEffect(){
this.addEffectLoading = true;
this.$emit('push', {
path: [],
value: EffectSchema.clean({}),
ack: this.acknowledgeAddEffect,
});
},
},
}
</script>
<style lang="css" scoped>
</style>
<template lang="html">
<div>
<v-slide-x-transition group>
<div
v-for="(effect, i) in model"
:key="effect._id || i"
>
<v-divider v-if="i !== 0"/>
<div class="layout row align-center">
<div style="flex-grow: 1;">
<effect-form
class="mt-4"
:model="effect"
@change="({path, value, ack}) => $emit('change', {path: [i, ...path], value, ack})"
/>
</div>
<v-btn outline icon large class="ma-3" @click="$emit('pull', {path: [i]})">
<v-icon>delete</v-icon>
</v-btn>
</div>
</div>
</v-slide-x-transition>
<div class="layout row justify-end">
<v-btn
:loading="addEffectLoading"
:disabled="addEffectLoading"
outline
@click="addEffect"
>
<v-icon>add</v-icon>
Add Effect
</v-btn>
</div>
</div>
</template>
<script>
import EffectForm from '/imports/ui/properties/forms/EffectForm.vue';
import { EffectSchema } from '/imports/api/properties/Effects.js';
export default {
components: {
EffectForm,
},
props: {
model: {
type: Array,
default: () => ([]),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
addEffectLoading: false,

View File

@@ -1,61 +1,56 @@
<template lang="html">
<div class="class-form">
<div class="layout column align-center">
<text-field
label="XP"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.value"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
:error-messages="errors.value"
:debounce-time="debounceTime"
/>
</div>
<div class="layout row wrap">
<text-field
label="Title"
style="flex-basis: 300px;"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="In-World date"
:value="model.worldDate"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['worldDate'], value, ack})"
hint="The date in-game that the experience occured"
:error-messages="errors.worldDate"
:debounce-time="debounceTime"
/>
<date-picker
label="Real date"
:value="model.date"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['date'], value, ack})"
hint="Real life date"
:error-messages="errors.date"
:debounce-time="debounceTime"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<div class="layout column align-center">
<text-field
label="XP"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.value"
:error-messages="errors.value"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
</div>
<div class="layout row wrap">
<text-field
label="Title"
style="flex-basis: 300px;"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="In-World date"
:value="model.worldDate"
style="flex-basis: 300px;"
hint="The date in-game that the experience occured"
:error-messages="errors.worldDate"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['worldDate'], value, ack})"
/>
<date-picker
label="Real date"
:value="model.date"
style="flex-basis: 300px;"
hint="Real life date"
:error-messages="errors.date"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['date'], value, ack})"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
</div>
</template>
<script>
import FormSection from '/imports/ui/properties/forms/shared/FormSection.vue';
export default {
components: {
FormSection,
},
props: {
model: {
type: Object,
@@ -65,7 +60,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,13 +1,13 @@
<template lang="html">
<div class="feature-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<!--
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<!--
<smart-select
label="Enabled"
:items="enabledOptions"
@@ -17,13 +17,13 @@
@change="changeEnabled"
:debounce-time="debounceTime"
/>-->
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
</div>
</template>
@@ -38,7 +38,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){ return{
enabledOptions: [

View File

@@ -1,15 +1,15 @@
<template lang="html">
<div class="folder-form">
<div class="layout row wrap">
<text-field
label="Name"
style="flex-basis: 300px;"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
</div>
<div class="layout row wrap">
<text-field
label="Name"
style="flex-basis: 300px;"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
</div>
</div>
</template>
@@ -24,7 +24,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,87 +1,90 @@
<template lang="html">
<div class="item-form">
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
/>
</div>
<text-field
label="Plural name"
:value="model.plural"
@change="(value, ack) => $emit('change', {path: ['plural'], value, ack})"
:error-messages="errors.plural"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<text-field
label="Value"
suffix="gp"
type="number"
min="0"
hint="The value of the item in gold pieces, using decimals for values less than 1 gp"
class="mx-1"
style="flex-basis: 300px;"
:value="model.value"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
:error-messages="errors.value"
:debounce-time="debounceTime"
/>
<text-field
label="Weight"
suffix="lbs"
type="number"
min="0"
class="mx-1"
style="flex-basis: 300px;"
:value="model.weight"
@change="(value, ack) => $emit('change', {path: ['weight'], value, ack})"
:error-messages="errors.weight"
:debounce-time="debounceTime"
/>
</div>
<text-field
label="Quantity"
type="number"
min="0"
:value="model.quantity"
@change="(value, ack) => $emit('change', {path: ['quantity'], value, ack})"
:error-messages="errors.quantity"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<form-section name="Advanced" standalone>
<v-switch
label="Requires attunement"
:input-value="model.requiresAttunement"
:error-messages="errors.requiresAttunement"
@change="e => $emit('change', {path: ['requiresAttunement'], value})"
/>
<v-switch
label="Show increment buttons"
:input-value="model.showIncrement"
:error-messages="errors.showIncrement"
@change="e => $emit('change', {path: ['showIncrement'], value})"
/>
</form-section>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
/>
</div>
<text-field
label="Plural name"
:value="model.plural"
:error-messages="errors.plural"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['plural'], value, ack})"
/>
<div class="layout row wrap">
<text-field
label="Value"
suffix="gp"
type="number"
min="0"
hint="The value of the item in gold pieces, using decimals for values less than 1 gp"
class="mx-1"
style="flex-basis: 300px;"
:value="model.value"
:error-messages="errors.value"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
<text-field
label="Weight"
suffix="lbs"
type="number"
min="0"
class="mx-1"
style="flex-basis: 300px;"
:value="model.weight"
:error-messages="errors.weight"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['weight'], value, ack})"
/>
</div>
<text-field
label="Quantity"
type="number"
min="0"
:value="model.quantity"
:error-messages="errors.quantity"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['quantity'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<form-section
name="Advanced"
standalone
>
<v-switch
label="Requires attunement"
:input-value="model.requiresAttunement"
:error-messages="errors.requiresAttunement"
@change="e => $emit('change', {path: ['requiresAttunement'], value})"
/>
<v-switch
label="Show increment buttons"
:input-value="model.showIncrement"
:error-messages="errors.showIncrement"
@change="e => $emit('change', {path: ['showIncrement'], value})"
/>
</form-section>
</div>
</template>
@@ -101,7 +104,10 @@ export default {
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
}
</script>

View File

@@ -1,19 +1,19 @@
<template lang="html">
<div class="feature-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
</div>
</template>
@@ -28,7 +28,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,30 +1,30 @@
<template lang="html">
<div>
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<div class="layout row wrap justify-start proficiency-form">
<text-field
label="Skill"
class="mr-2"
:value="model.stats[0]"
:items="stats"
:error-messages="errors.stats"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['stats'], value: [value], ack})"
/>
<proficiency-select
label="Proficiency"
style="flex-basis: 300px;"
:value="model.value"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
</div>
</div>
<div>
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<div class="layout row wrap justify-start proficiency-form">
<text-field
label="Skill"
class="mr-2"
:value="model.stats[0]"
:items="stats"
:error-messages="errors.stats"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['stats'], value: [value], ack})"
/>
<proficiency-select
label="Proficiency"
style="flex-basis: 300px;"
:value="model.value"
@change="(value, ack) => $emit('change', {path: ['value'], value, ack})"
/>
</div>
</div>
</template>
<script>
@@ -41,6 +41,7 @@
},
stats: {
type: Array,
default: () => [],
},
},
};

View File

@@ -1,85 +1,69 @@
<template lang="html">
<div class="results-form">
<div class="subheading">
Damage
</div>
<damage-list-form
:model="model.damages"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: ['damages', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['damages', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['damages', ...path], ack})"
/>
<div class="subheading">
Adjustments
</div>
<adjustment-list-form
:model="model.adjustments"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: ['adjustments', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['adjustments', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['adjustments', ...path], ack})"
/>
<div class="subheading">
Buffs
</div>
<buff-list-form
:model="model.buffs"
:parent-target="parentTarget"
:stored="buffsStored"
@change="({path, value, ack}) => $emit('change', {path: ['buffs', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['buffs', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['buffs', ...path], ack})"
/>
</div>
<div class="results-form">
<div class="subheading">
Damage
</div>
<damage-list-form
:model="model.damages"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: ['damages', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['damages', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['damages', ...path], ack})"
/>
<div class="subheading">
Adjustments
</div>
<adjustment-list-form
:model="model.adjustments"
:parent-target="parentTarget"
@change="({path, value, ack}) => $emit('change', {path: ['adjustments', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['adjustments', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['adjustments', ...path], ack})"
/>
<div class="subheading">
Buffs
</div>
<buff-list-form
:model="model.buffs"
:parent-target="parentTarget"
:stored="buffsStored"
@change="({path, value, ack}) => $emit('change', {path: ['buffs', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['buffs', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['buffs', ...path], ack})"
/>
</div>
</template>
<script>
import FormSection, {FormSections} from '/imports/ui/properties/forms/shared/FormSection.vue';
import AdjustmentListForm from '/imports/ui/properties/forms/AdjustmentListForm.vue';
import DamageListForm from '/imports/ui/properties/forms/DamageListForm.vue';
import BuffListForm from '/imports/ui/properties/forms/BuffListForm.vue';
import ResultsSchema from '/imports/api/properties/subSchemas/ResultsSchema.js';
import AdjustmentListForm from '/imports/ui/properties/forms/AdjustmentListForm.vue';
import DamageListForm from '/imports/ui/properties/forms/DamageListForm.vue';
import BuffListForm from '/imports/ui/properties/forms/BuffListForm.vue';
import ResultsSchema from '/imports/api/properties/subSchemas/ResultsSchema.js';
export default {
components: {
FormSection,
FormSections,
AdjustmentListForm,
DamageListForm,
BuffListForm,
},
data(){return {
addDamageLoading: false,
showAddToolbar: false,
}},
props: {
model: {
type: Object,
default: () => (ResultsSchema.clean({})),
},
parentTarget: {
type: String,
},
buffsStored: {
type: Boolean,
},
debounceTime: Number,
},
methods: {
acknowledgeAddDamage(){
this.addDamageLoading = false;
},
addDamage(){
this.addDamageLoading = true;
this.$emit('push', {
path: [],
value: DamageSchema.clean({}),
ack: this.acknowledgeAddDamage,
});
},
},
}
export default {
components: {
AdjustmentListForm,
DamageListForm,
BuffListForm,
},
props: {
model: {
type: Object,
default: () => (ResultsSchema.clean({})),
},
parentTarget: {
type: String,
required: true,
},
buffsStored: {
type: Boolean,
},
debounceTime: {
type: Number,
default: undefined,
},
},
}
</script>
<style lang="css" scoped>

View File

@@ -1,84 +1,84 @@
<template lang="html">
<div class="roll-form">
<text-field
label="Roll"
:value="model.roll"
@change="(value, ack) => $emit('change', {path: ['roll'], value, ack})"
:error-messages="errors.roll"
:debounce-time="debounceTime"
/>
<form-sections>
<form-section name="Results">
<v-slide-x-transition group>
<div
v-for="(rollResult, index) in model.rollResults"
:key="rollResult._id || index"
>
<div class="layout row align-center">
<text-field
label="Comparison"
style="flex-grow: 1;"
hint="If the comparison is true, the results below will be applied"
:value="rollResult.comparison"
@change="(value, ack) => $emit('change', {path: ['rollResults', index, 'comparison'], value, ack})"
:error-messages="errors.rollResults && errors.rollResults[index] && errors.rollResults[index].comparison"
:debounce-time="debounceTime"
/>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: ['rollResults', index]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
<results-form
:model="rollResult.results"
:parent-target="model.target"
@change="({path, value, ack}) => $emit('change', {
path: ['rollResults', index, 'results', ...path],
value,
ack
})"
@push="({path, value, ack}) => $emit('push', {
path: ['rollResults', index, 'results', ...path],
value,
ack
})"
@pull="({path, ack}) => $emit('pull', {
path: ['rollResults', index, 'results', ...path],
ack
})"
/>
<v-divider class="my-4"/>
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addResultLoading"
:disabled="addResultLoading"
outline
@click="addResult"
>
<v-icon>add</v-icon>
Add Result
</v-btn>
</div>
</form-section>
<form-section name="Advanced">
<v-combobox
label="Tags"
multiple
chips
deletable-chips
box
:value="model.tags"
@change="(value) => $emit('change', {path: ['tags'], value})"
/>
</form-section>
</form-sections>
<text-field
label="Roll"
:value="model.roll"
:error-messages="errors.roll"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['roll'], value, ack})"
/>
<form-sections>
<form-section name="Results">
<v-slide-x-transition group>
<div
v-for="(rollResult, index) in model.rollResults"
:key="rollResult._id || index"
>
<div class="layout row align-center">
<text-field
label="Comparison"
style="flex-grow: 1;"
hint="If the comparison is true, the results below will be applied"
:value="rollResult.comparison"
:error-messages="errors.rollResults && errors.rollResults[index] && errors.rollResults[index].comparison"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['rollResults', index, 'comparison'], value, ack})"
/>
<v-btn
outline
icon
large
class="ma-3"
@click="$emit('pull', {path: ['rollResults', index]})"
>
<v-icon>delete</v-icon>
</v-btn>
</div>
<results-form
:model="rollResult.results"
:parent-target="model.target"
@change="({path, value, ack}) => $emit('change', {
path: ['rollResults', index, 'results', ...path],
value,
ack
})"
@push="({path, value, ack}) => $emit('push', {
path: ['rollResults', index, 'results', ...path],
value,
ack
})"
@pull="({path, ack}) => $emit('pull', {
path: ['rollResults', index, 'results', ...path],
ack
})"
/>
<v-divider class="my-4" />
</div>
</v-slide-x-transition>
<div class="layout row justify-center">
<v-btn
:loading="addResultLoading"
:disabled="addResultLoading"
outline
@click="addResult"
>
<v-icon>add</v-icon>
Add Result
</v-btn>
</div>
</form-section>
<form-section name="Advanced">
<v-combobox
label="Tags"
multiple
chips
deletable-chips
box
:value="model.tags"
@change="(value) => $emit('change', {path: ['tags'], value})"
/>
</form-section>
</form-sections>
</div>
</template>
@@ -93,9 +93,6 @@
FormSections,
ResultsForm,
},
data(){return {
addResultLoading: false,
}},
props: {
stored: {
type: Boolean,
@@ -108,8 +105,14 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
addResultLoading: false,
}},
methods: {
acknowledgeAddResult(){
this.addResultLoading = false;

View File

@@ -1,38 +1,38 @@
<template lang="html">
<div class="saving-throw-form">
<text-field
label="DC"
:value="model.dc"
@change="(value, ack) => $emit('change', {path: ['dc'], value, ack})"
:error-messages="errors.dc"
:debounce-time="debounceTime"
/>
<text-field
label="Ability"
hint="Which ability the saving throw targets"
:value="model.ability"
@change="(value, ack) => $emit('change', {path: ['ability'], value, ack})"
:error-messages="errors.ability"
:debounce-time="debounceTime"
/>
<form-sections>
<form-section name="Results on successful save">
<results-form
:model="model.passResults"
@change="({path, value, ack}) => $emit('change', {path: ['passResults', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['passResults', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['passResults', ...path], ack})"
/>
</form-section>
<form-section name="Results on failed save">
<results-form
:model="model.failResults"
@change="({path, value, ack}) => $emit('change', {path: ['failResults', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['failResults', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['failResults', ...path], ack})"
/>
</form-section>
</form-sections>
<text-field
label="DC"
:value="model.dc"
:error-messages="errors.dc"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['dc'], value, ack})"
/>
<text-field
label="Ability"
hint="Which ability the saving throw targets"
:value="model.ability"
:error-messages="errors.ability"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['ability'], value, ack})"
/>
<form-sections>
<form-section name="Results on successful save">
<results-form
:model="model.passResults"
@change="({path, value, ack}) => $emit('change', {path: ['passResults', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['passResults', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['passResults', ...path], ack})"
/>
</form-section>
<form-section name="Results on failed save">
<results-form
:model="model.failResults"
@change="({path, value, ack}) => $emit('change', {path: ['failResults', ...path], value, ack})"
@push="({path, value, ack}) => $emit('push', {path: ['failResults', ...path], value, ack})"
@pull="({path, ack}) => $emit('pull', {path: ['failResults', ...path], ack})"
/>
</form-section>
</form-sections>
</div>
</template>
@@ -55,7 +55,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,70 +1,73 @@
<template lang="html">
<div class="skill-form">
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
hint="Use this name in formulae to reference this skill"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
/>
<text-field
label="Ability"
:value="model.ability"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['ability'], value, ack})"
hint="Which ability is this skill based off of"
:error-messages="errors.ability"
:debounce-time="debounceTime"
/>
</div>
<smart-select
label="Type"
:items="skillTypes"
:value="model.skillType"
:error-messages="errors.skillType"
:menu-props="{auto: true, lazy: true}"
@change="(value, ack) => $emit('change', {path: ['skillType'], value, ack})"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<form-section name="Advanced" standalone>
<div class="layout row justify-center">
<text-field
label="Base Value"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.baseValue"
@change="(value, ack) => $emit('change', {path: ['baseValue'], value, ack})"
hint="This is the value of the skill before effects are applied"
:error-messages="errors.baseValue"
:debounce-time="debounceTime"
/>
<proficiency-select
style="flex-basis: 300px;"
label="Base Proficiency"
clearable
:value="model.baseProficiency"
:error-messages="errors.baseProficiency"
@change="(value, ack) => {$emit('change', {path: ['baseProficiency'], value: value || '', ack}); log({value, ack})}"
/>
</div>
</form-section>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
hint="Use this name in formulae to reference this skill"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
/>
<text-field
label="Ability"
:value="model.ability"
style="flex-basis: 300px;"
hint="Which ability is this skill based off of"
:error-messages="errors.ability"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['ability'], value, ack})"
/>
</div>
<smart-select
label="Type"
:items="skillTypes"
:value="model.skillType"
:error-messages="errors.skillType"
:menu-props="{auto: true, lazy: true}"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['skillType'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<form-section
name="Advanced"
standalone
>
<div class="layout row justify-center">
<text-field
label="Base Value"
type="number"
class="base-value-field text-xs-center large-format no-flex"
:value="model.baseValue"
hint="This is the value of the skill before effects are applied"
:error-messages="errors.baseValue"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['baseValue'], value, ack})"
/>
<proficiency-select
style="flex-basis: 300px;"
label="Base Proficiency"
clearable
:value="model.baseProficiency"
:error-messages="errors.baseProficiency"
@change="(value, ack) => {$emit('change', {path: ['baseProficiency'], value: value || '', ack}); log({value, ack})}"
/>
</div>
</form-section>
</div>
</template>
@@ -86,7 +89,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return{
skillTypes: [

View File

@@ -1,117 +1,120 @@
<template lang="html">
<div class="attribute-form">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<smart-select
label="Level"
class="mx-1"
style="flex-basis: 300px;"
:items="spellLevels"
:value="model.level"
:error-messages="errors.level"
@change="(value, ack) => $emit('change', {path: ['level'], value, ack})"
:debounce-time="debounceTime"
/>
<smart-select
label="School"
class="mx-1"
style="flex-basis: 300px;"
:items="magicSchools"
:value="model.school"
:error-messages="errors.school"
@change="(value, ack) => $emit('change', {path: ['school'], value, ack})"
:debounce-time="debounceTime"
/>
</div>
<div class="layout row wrap">
<v-switch
label="Always prepared"
style="width: 200px; flex-grow: 0;"
class="ml-2"
:input-value="model.alwaysPrepared"
:error-messages="errors.alwaysPrepared"
@change="e => $emit('change', {path: ['alwaysPrepared'], value: !!e})"
/>
</div>
<text-field
label="Casting Time"
:value="model.castingTime"
@change="(value, ack) => $emit('change', {path: ['castingTime'], value, ack})"
:error-messages="errors.castingTime"
:debounce-time="debounceTime"
/>
<text-field
label="Range"
:value="model.range"
@change="(value, ack) => $emit('change', {path: ['range'], value, ack})"
:error-messages="errors.range"
:debounce-time="debounceTime"
/>
<div class="layout row wrap justify-space-between">
<v-checkbox
label="Verbal"
:value="model.verbal"
:error-messages="errors.verbal"
@change="(value) => $emit('change', {path: ['verbal'], value})"
/>
<v-checkbox
label="Somatic"
:value="model.somatic"
:error-messages="errors.somatic"
@change="(value) => $emit('change', {path: ['somatic'], value})"
/>
<v-checkbox
label="Concentration"
:value="model.concentration"
:error-messages="errors.concentration"
@change="(value) => $emit('change', {path: ['concentration'], value})"
/>
<v-checkbox
label="Ritual"
:value="model.ritual"
:error-messages="errors.ritual"
@change="(value) => $emit('change', {path: ['ritual'], value})"
/>
</div>
<text-field
label="Material"
:value="model.material"
@change="(value, ack) => $emit('change', {path: ['material'], value, ack})"
:error-messages="errors.material"
:debounce-time="debounceTime"
/>
<text-field
label="Duration"
:value="model.duration"
@change="(value, ack) => $emit('change', {path: ['duration'], value, ack})"
:error-messages="errors.duration"
:debounce-time="debounceTime"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<form-section name="Advanced" standalone>
<v-combobox
label="Spell lists"
multiple
chips
deletable-chips
box
:value="model.spellLists"
@change="(value) => $emit('change', {path: ['spellLists'], value})"
:error-messages="errors.spellLists"
/>
</form-section>
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<div class="layout row wrap">
<smart-select
label="Level"
class="mx-1"
style="flex-basis: 300px;"
:items="spellLevels"
:value="model.level"
:error-messages="errors.level"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['level'], value, ack})"
/>
<smart-select
label="School"
class="mx-1"
style="flex-basis: 300px;"
:items="magicSchools"
:value="model.school"
:error-messages="errors.school"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['school'], value, ack})"
/>
</div>
<div class="layout row wrap">
<v-switch
label="Always prepared"
style="width: 200px; flex-grow: 0;"
class="ml-2"
:input-value="model.alwaysPrepared"
:error-messages="errors.alwaysPrepared"
@change="e => $emit('change', {path: ['alwaysPrepared'], value: !!e})"
/>
</div>
<text-field
label="Casting Time"
:value="model.castingTime"
:error-messages="errors.castingTime"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['castingTime'], value, ack})"
/>
<text-field
label="Range"
:value="model.range"
:error-messages="errors.range"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['range'], value, ack})"
/>
<div class="layout row wrap justify-space-between">
<v-checkbox
label="Verbal"
:value="model.verbal"
:error-messages="errors.verbal"
@change="(value) => $emit('change', {path: ['verbal'], value})"
/>
<v-checkbox
label="Somatic"
:value="model.somatic"
:error-messages="errors.somatic"
@change="(value) => $emit('change', {path: ['somatic'], value})"
/>
<v-checkbox
label="Concentration"
:value="model.concentration"
:error-messages="errors.concentration"
@change="(value) => $emit('change', {path: ['concentration'], value})"
/>
<v-checkbox
label="Ritual"
:value="model.ritual"
:error-messages="errors.ritual"
@change="(value) => $emit('change', {path: ['ritual'], value})"
/>
</div>
<text-field
label="Material"
:value="model.material"
:error-messages="errors.material"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['material'], value, ack})"
/>
<text-field
label="Duration"
:value="model.duration"
:error-messages="errors.duration"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['duration'], value, ack})"
/>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<form-section
name="Advanced"
standalone
>
<v-combobox
label="Spell lists"
multiple
chips
deletable-chips
box
:value="model.spellLists"
:error-messages="errors.spellLists"
@change="(value) => $emit('change', {path: ['spellLists'], value})"
/>
</form-section>
</div>
</template>
@@ -131,7 +134,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
data(){return {
magicSchools: [

View File

@@ -1,38 +1,38 @@
<template lang="html">
<div class="attribute-form">
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
:error-messages="errors.name"
:debounce-time="debounceTime"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
:debounce-time="debounceTime"
/>
<text-field
label="Maximum prepared spells"
:value="model.maxPrepared"
@change="(value, ack) => $emit('change', {path: ['maxPrepared'], value, ack})"
hint="How many spells can be prepared"
:error-messages="errors.maxPrepared"
:debounce-time="debounceTime"
/>
<div class="layout row wrap">
<text-field
label="Name"
:value="model.name"
:error-messages="errors.name"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
/>
<text-field
label="Variable name"
:value="model.variableName"
style="flex-basis: 300px;"
hint="Use this name in formulae to reference this attribute"
:error-messages="errors.variableName"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['variableName'], value, ack})"
/>
</div>
<text-area
label="Description"
:value="model.description"
:error-messages="errors.description"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['description'], value, ack})"
/>
<text-field
label="Maximum prepared spells"
:value="model.maxPrepared"
hint="How many spells can be prepared"
:error-messages="errors.maxPrepared"
:debounce-time="debounceTime"
@change="(value, ack) => $emit('change', {path: ['maxPrepared'], value, ack})"
/>
</div>
</template>
@@ -47,7 +47,10 @@
type: Object,
default: () => ({}),
},
debounceTime: Number,
debounceTime: {
type: Number,
default: undefined,
},
},
};
</script>

View File

@@ -1,22 +1,28 @@
<template lang="html">
<form-sections v-if="standalone">
<v-expansion-panel-content>
<div slot="header" class="subheading">
{{name}}
</div>
<v-card-text>
<slot/>
</v-card-text>
</v-expansion-panel-content>
</form-sections>
<v-expansion-panel-content v-else>
<div slot="header" class="subheading">
{{name}}
</div>
<v-card-text>
<slot/>
</v-card-text>
</v-expansion-panel-content>
<form-sections v-if="standalone">
<v-expansion-panel-content>
<div
slot="header"
class="subheading"
>
{{ name }}
</div>
<v-card-text>
<slot />
</v-card-text>
</v-expansion-panel-content>
</form-sections>
<v-expansion-panel-content v-else>
<div
slot="header"
class="subheading"
>
{{ name }}
</div>
<v-card-text>
<slot />
</v-card-text>
</v-expansion-panel-content>
</template>
<script>
@@ -26,7 +32,10 @@ export default {
FormSections,
},
props: {
name: String,
name: {
type: String,
default: '',
},
standalone: Boolean,
},
}

View File

@@ -1,7 +1,10 @@
<template lang="html">
<v-expansion-panel popout expand>
<slot/>
</v-expansion-panel>
<v-expansion-panel
popout
expand
>
<slot />
</v-expansion-panel>
</template>
<script>

View File

@@ -1,19 +1,21 @@
<template lang="html">
<smart-select
append-icon="arrow_drop_down"
class="ml-3"
v-bind="$attrs"
:menu-props="{transition: 'slide-y-transition', lazy: true}"
:items="values"
:value="value"
@change="(value, ack) => $emit('change', value, ack)"
>
<v-icon
class="icon"
slot="prepend"
:class="iconClass"
>{{displayedIcon}}</v-icon>
</smart-select>
<smart-select
append-icon="arrow_drop_down"
class="ml-3"
v-bind="$attrs"
:menu-props="{transition: 'slide-y-transition', lazy: true}"
:items="values"
:value="value"
@change="(value, ack) => $emit('change', value, ack)"
>
<v-icon
slot="prepend"
class="icon"
:class="iconClass"
>
{{ displayedIcon }}
</v-icon>
</smart-select>
</template>
<script>
@@ -32,7 +34,10 @@
export default {
props: {
value: Number,
value: {
type: Number,
default: 1,
},
},
data(){ return {
displayedIcon: 'radio_button_unchecked',
@@ -46,18 +51,18 @@
watch: {
'value': {
immediate: true,
handler(newValue, oldValue, e){
handler(newValue, oldValue){
let newIcon = proficiencyIcon(newValue);
if (!oldValue){
// Skip animation
this.displayedIcon = newIcon;
} else {
this.iconClass="leaving";
this.iconClass='leaving';
setTimeout(() => {
this.displayedIcon = newIcon;
this.iconClass="arriving";
this.iconClass='arriving';
requestAnimationFrame(() => {
this.iconClass="";
this.iconClass='';
});
}, ICON_SPIN_DURATION / 2);
}

View File

@@ -13,7 +13,7 @@ function resolvePath(model, path){
let key = arrayPath.slice(-1);
let object = get(model, objectPath);
return {object, key};
};
}
const schemaFormMixin = {
data(){ return {
@@ -23,7 +23,7 @@ const schemaFormMixin = {
errors(){
this.valid = true;
if (!this.model){
throw new Error("this.model must be set");
throw new Error('this.model must be set');
}
if (!this.validationContext) return {};
let cleanModel = this.validationContext.clean(this.model, {