Added basic creature document editing UI
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import deathSaveSchema from "/imports/api/properties/subSchemas/DeathSavesSchema.js"
|
||||
import ColorSchema from "/imports/api/properties/subSchemas/ColorSchema.js";
|
||||
import deathSaveSchema from '/imports/api/properties/subSchemas/DeathSavesSchema.js'
|
||||
import ColorSchema from '/imports/api/properties/subSchemas/ColorSchema.js';
|
||||
import SharingSchema from '/imports/api/sharing/SharingSchema.js';
|
||||
import {assertEditPermission, assertOwnership} from '/imports/api/sharing/sharingPermissions.js';
|
||||
|
||||
//set up the collection for creatures
|
||||
Creatures = new Mongo.Collection("creatures");
|
||||
Creatures = new Mongo.Collection('creatures');
|
||||
|
||||
let CreatureSettingsSchema = new SimpleSchema({
|
||||
//slowed down by carrying too much?
|
||||
@@ -28,25 +29,25 @@ let CreatureSchema = new SimpleSchema({
|
||||
// Strings
|
||||
name: {
|
||||
type: String,
|
||||
defaultValue: "",
|
||||
defaultValue: '',
|
||||
optional: true,
|
||||
},
|
||||
urlName: {
|
||||
type: String,
|
||||
optional: true,
|
||||
autoValue: function() {
|
||||
return getSlug(this.field("name").value, {maintainCase: true}) || "-";
|
||||
return getSlug(this.field('name').value, {maintainCase: true}) || '-';
|
||||
},
|
||||
},
|
||||
alignment: {
|
||||
type: String,
|
||||
optional: true
|
||||
},
|
||||
gender: {
|
||||
gender: {
|
||||
type: String,
|
||||
optional: true
|
||||
},
|
||||
picture: {
|
||||
picture: {
|
||||
type: String,
|
||||
optional: true
|
||||
},
|
||||
@@ -70,8 +71,8 @@ let CreatureSchema = new SimpleSchema({
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
defaultValue: "pc",
|
||||
allowedValues: ["pc", "npc", "monster"],
|
||||
defaultValue: 'pc',
|
||||
allowedValues: ['pc', 'npc', 'monster'],
|
||||
},
|
||||
variables: {
|
||||
type: Object,
|
||||
@@ -93,14 +94,14 @@ Creatures.attachSchema(CreatureSchema);
|
||||
|
||||
const insertCreature = new ValidatedMethod({
|
||||
|
||||
name: "Creatures.methods.insertCreature",
|
||||
name: 'Creatures.methods.insertCreature',
|
||||
|
||||
validate: null,
|
||||
|
||||
run() {
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error("Creatures.methods.insert.denied",
|
||||
"You need to be logged in to insert a creature");
|
||||
throw new Meteor.Error('Creatures.methods.insert.denied',
|
||||
'You need to be logged in to insert a creature');
|
||||
}
|
||||
|
||||
// Create the creature document
|
||||
@@ -114,15 +115,36 @@ const insertCreature = new ValidatedMethod({
|
||||
});
|
||||
|
||||
const removeCreature = new ValidatedMethod({
|
||||
name: 'Creature.methods.remove',
|
||||
name: 'Creatures.methods.remove',
|
||||
validate: null,
|
||||
run({charId}) {
|
||||
assertCreatureEditPermission(charId, this.userId);
|
||||
let creature = Creatures.findOne(_id);
|
||||
assertOwnership(creature, this.userId);
|
||||
let _id = CreatureProperties.insert(creatureProperty);
|
||||
let property = CreatureProperties.findOne(_id);
|
||||
recomputeCreatures(property);
|
||||
},
|
||||
});
|
||||
|
||||
const updateCreature = new ValidatedMethod({
|
||||
name: 'Creatures.methods.update',
|
||||
validate({_id, path, value, ack}){
|
||||
if (!_id) return false;
|
||||
// Allowed fields
|
||||
let allowedFields = ['name', 'alignment', 'gender', 'picture', 'settings'];
|
||||
if (!allowedFields.includes(path[0])){
|
||||
throw new Meteor.Error('Creatures.methods.update.denied',
|
||||
'This field can\'t be updated using this method');
|
||||
}
|
||||
},
|
||||
run({_id, path, value}) {
|
||||
let creature = Creatures.findOne(_id);
|
||||
assertEditPermission(creature, this.userId);
|
||||
Creatures.update(_id, {
|
||||
$set: {[path.join('.')]: value},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default Creatures;
|
||||
export { CreatureSchema, insertCreature, removeCreature };
|
||||
export { CreatureSchema, insertCreature, removeCreature, updateCreature };
|
||||
|
||||
88
app/imports/ui/creature/CreatureForm.vue
Normal file
88
app/imports/ui/creature/CreatureForm.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template lang="html">
|
||||
<div class="creature-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="Alignment"
|
||||
:value="model.alignment"
|
||||
@change="(value, ack) => $emit('change', {path: ['alignment'], value, ack})"
|
||||
:error-messages="errors.alignment"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Gender"
|
||||
:value="model.gender"
|
||||
@change="(value, ack) => $emit('change', {path: ['gender'], value, ack})"
|
||||
:error-messages="errors.gender"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Picture URL"
|
||||
:value="model.picture"
|
||||
@change="(value, ack) => $emit('change', {path: ['picture'], value, ack})"
|
||||
:error-messages="errors.picture"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<form-sections>
|
||||
<form-section name="settings">
|
||||
<v-switch
|
||||
label="Use variant encumbrance"
|
||||
:input-value="model.settings.useVariantEncumbrance"
|
||||
:error-messages="errors.useVariantEncumbrance"
|
||||
@change="value => $emit('change', {path: ['settings','useVariantEncumbrance'], value})"
|
||||
/>
|
||||
<v-switch
|
||||
label="Hide spells tab"
|
||||
:input-value="model.settings.hideSpellcasting"
|
||||
:error-messages="errors.hideSpellcasting"
|
||||
@change="value => $emit('change', {path: ['settings','hideSpellcasting'], value})"
|
||||
/>
|
||||
<v-switch
|
||||
label="Swap ability scores and modifiers"
|
||||
:input-value="model.settings.swapStatAndModifier"
|
||||
:error-messages="errors.swapStatAndModifier"
|
||||
@change="value => $emit('change', {path: ['settings','swapStatAndModifier'], value})"
|
||||
/>
|
||||
</form-section>
|
||||
</form-sections>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormSection, {FormSections} from '/imports/ui/properties/forms/shared/FormSection.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormSection,
|
||||
FormSections,
|
||||
},
|
||||
props: {
|
||||
stored: {
|
||||
type: Boolean,
|
||||
},
|
||||
model: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
attackForm: {
|
||||
type: Boolean,
|
||||
},
|
||||
debounceTime: Number,
|
||||
},
|
||||
methods: {
|
||||
log: console.log,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
48
app/imports/ui/creature/CreatureFormDialog.vue
Normal file
48
app/imports/ui/creature/CreatureFormDialog.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template lang="html">
|
||||
<dialog-base>
|
||||
<div slot="toolbar">
|
||||
Creature Form Dialog
|
||||
</div>
|
||||
<div>
|
||||
<creature-form :model="model" @change="change"/>
|
||||
</div>
|
||||
<v-spacer slot="actions"/>
|
||||
<v-btn
|
||||
slot="actions"
|
||||
flat
|
||||
@click="$store.dispatch('popDialogStack')"
|
||||
>Done</v-btn>
|
||||
</dialog-base>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {updateCreature} from '/imports/api/creature/Creatures.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
import CreatureForm from '/imports/ui/creature/CreatureForm.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DialogBase,
|
||||
CreatureForm,
|
||||
},
|
||||
props: {
|
||||
_id: String,
|
||||
startInEditTab: Boolean,
|
||||
},
|
||||
meteor: {
|
||||
model(){
|
||||
return Creatures.findOne(this._id);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
change({path, value, ack}){
|
||||
updateCreature.call({_id: this._id, path, value}, (error, result) =>{
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -4,10 +4,14 @@
|
||||
<v-btn v-if="showMenuButton" flat icon @click="toggleDrawer">
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-if="showMenuButton" flat icon @click="recompute(character._id)">
|
||||
<v-btn flat icon @click="recompute(character._id)">
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<span>{{character.name}}</span>
|
||||
<v-spacer/>
|
||||
<v-btn flat icon @click="showCharacterForm" data-id="character-form-button">
|
||||
<v-icon>more</v-icon>
|
||||
</v-btn>
|
||||
<v-tabs
|
||||
slot="extension"
|
||||
v-model="tab"
|
||||
@@ -74,6 +78,15 @@
|
||||
recompute(charId){
|
||||
recomputeCreature.call({charId});
|
||||
},
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'character-form-button',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
isDarkColor,
|
||||
},
|
||||
meteor: {
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<v-btn
|
||||
slot="activator"
|
||||
color="primary"
|
||||
small fab disabled
|
||||
small fab
|
||||
@click="insertCreatureProperty"
|
||||
>
|
||||
<v-icon>edit</v-icon>
|
||||
@@ -116,7 +116,7 @@
|
||||
creatureProperty.parent = {collection: "creatures", id: that.creatureId};
|
||||
creatureProperty.ancestors = [ {collection: "creatures", id: that.creatureId}];
|
||||
setDocToLastOrder({collection: CreatureProperties, doc: creatureProperty});
|
||||
let creaturePropertyId = insertProperty.call(creatureProperty);
|
||||
let creaturePropertyId = insertProperty.call({creatureProperty});
|
||||
return creaturePropertyId;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -105,13 +105,13 @@ export default {
|
||||
change({path, value, ack}){
|
||||
updateProperty.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
push({path, value, ack}){
|
||||
pushToProperty.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
pull({path, ack}){
|
||||
@@ -119,7 +119,7 @@ export default {
|
||||
path.pop();
|
||||
pullFromProperty.call({_id: this._id, path, itemId}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
remove(){
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import AttributeDialog from '/imports/ui/properties/attributes/AttributeDialog.vue';
|
||||
import AttributeDialogContainer from '/imports/ui/properties/attributes/AttributeDialogContainer.vue';
|
||||
import AttributeCreationDialog from '/imports/ui/properties/attributes/AttributeCreationDialog.vue';
|
||||
import CreatureFormDialog from '/imports/ui/creature/CreatureFormDialog.vue';
|
||||
import CreaturePropertyCreationDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyCreationDialog.vue';
|
||||
import CreaturePropertyDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue'
|
||||
import CreaturePropertyFromLibraryDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyFromLibraryDialog.vue'
|
||||
@@ -15,6 +16,7 @@ export default {
|
||||
AttributeDialog,
|
||||
AttributeDialogContainer,
|
||||
AttributeCreationDialog,
|
||||
CreatureFormDialog,
|
||||
CreaturePropertyCreationDialog,
|
||||
CreaturePropertyDialog,
|
||||
CreaturePropertyFromLibraryDialog,
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
change({path, value, ack}){
|
||||
updateLibraryNode.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
push({path, value, ack}){
|
||||
pushToLibraryNode.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
pull({path, ack}){
|
||||
@@ -78,7 +78,7 @@
|
||||
path.pop();
|
||||
pullFromLibraryNode.call({_id: this._id, path, itemId}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
ack && ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
remove(){
|
||||
|
||||
Reference in New Issue
Block a user