Characters now start with a slot for a base. New characters start on the character tab with the build dialog open.
This commit is contained in:
@@ -4,6 +4,7 @@ import SimpleSchema from 'simpl-schema';
|
||||
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 CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import {assertEditPermission} from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js';
|
||||
|
||||
@@ -160,11 +161,25 @@ const insertCreature = new ValidatedMethod({
|
||||
assertUserHasPaidBenefits(this.userId);
|
||||
|
||||
// Create the creature document
|
||||
let charId = Creatures.insert({
|
||||
let creatureId = Creatures.insert({
|
||||
owner: this.userId,
|
||||
});
|
||||
CreatureProperties.insert({
|
||||
slotTags: ['base'],
|
||||
quantityExpected: 1,
|
||||
type: 'propertySlot',
|
||||
name: 'Base',
|
||||
description: 'Choose a starting point for your character, this will define the basic setup of your character sheet. Without a base, your sheet will be empty.',
|
||||
hideWhenFull: true,
|
||||
parent: {collection: 'creatures', id: creatureId},
|
||||
ancestors: [{collection: 'creatures', id: creatureId}],
|
||||
order: 0,
|
||||
tags: [],
|
||||
spaceLeft: 1,
|
||||
totalFilled: 0,
|
||||
});
|
||||
this.unblock();
|
||||
return charId;
|
||||
return creatureId;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
@@ -35,7 +35,11 @@
|
||||
class="fill-height"
|
||||
>
|
||||
<v-tabs-items
|
||||
v-model="activeTab"
|
||||
:value="$store.state.characterSheetTabs[$route.params.id]"
|
||||
@change="e => $store.commit(
|
||||
'setTabForCharacterSheet',
|
||||
{id: $route.params.id, tab: e}
|
||||
)"
|
||||
>
|
||||
<v-tab-item>
|
||||
<stats-tab :creature-id="creatureId" />
|
||||
@@ -87,10 +91,6 @@
|
||||
creatureId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tabs: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
reactiveProvide: {
|
||||
|
||||
@@ -78,11 +78,14 @@
|
||||
<v-tabs
|
||||
v-if="creature"
|
||||
slot="extension"
|
||||
:value="value"
|
||||
centered
|
||||
grow
|
||||
max="100px"
|
||||
@change="e => $emit('input', e)"
|
||||
:value="$store.state.characterSheetTabs[$route.params.id]"
|
||||
@change="e => $store.commit(
|
||||
'setTabForCharacterSheet',
|
||||
{id: $route.params.id, tab: e}
|
||||
)"
|
||||
>
|
||||
<v-tab>
|
||||
Stats
|
||||
@@ -118,12 +121,6 @@ import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
|
||||
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data(){return {
|
||||
theme,
|
||||
}},
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<template lang="html">
|
||||
<v-tabs
|
||||
v-if="creature"
|
||||
slot="extension"
|
||||
color="secondary"
|
||||
:value="value"
|
||||
centered
|
||||
grow
|
||||
max="100px"
|
||||
@change="e => $emit('input', e)"
|
||||
>
|
||||
<v-tab>
|
||||
Stats
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Features
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Inventory
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Spells
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Character
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Tree
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
creature(){
|
||||
return Creatures.findOne(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.v-tabs__container--grow .v-tabs__div {
|
||||
max-width: 120px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,159 +0,0 @@
|
||||
<template lang="html">
|
||||
<v-toolbar-items v-if="creature">
|
||||
<v-btn
|
||||
v-if="editPermission"
|
||||
flat
|
||||
icon
|
||||
@click="recompute(creature._id)"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-menu
|
||||
bottom
|
||||
left
|
||||
transition="slide-y-transition"
|
||||
data-id="creature-menu"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
icon
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list v-if="editPermission">
|
||||
<v-list-tile @click="deleteCharacter">
|
||||
<v-list-tile-title>
|
||||
<v-icon>delete</v-icon> Delete
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showCharacterForm">
|
||||
<v-list-tile-title>
|
||||
<v-icon>create</v-icon> Edit details
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showShareDialog">
|
||||
<v-list-tile-title>
|
||||
<v-icon>share</v-icon> Sharing
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
<v-list v-else>
|
||||
<v-list-tile @click="unshareWithMe">
|
||||
<v-list-tile-title>
|
||||
<v-icon>delete</v-icon> Unshare with me
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-toolbar-items>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import removeCreature from '/imports/api/creature/removeCreature.js';
|
||||
import { mapMutations } from 'vuex';
|
||||
import { theme } from '/imports/ui/theme.js';
|
||||
import { recomputeCreature } from '/imports/api/creature/computation/recomputeCreature.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||
import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
|
||||
|
||||
export default {
|
||||
data(){return {
|
||||
theme,
|
||||
}},
|
||||
computed: {
|
||||
creatureId(){
|
||||
return this.$route.params.id;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([
|
||||
'toggleDrawer',
|
||||
]),
|
||||
recompute(charId){
|
||||
recomputeCreature.call({charId});
|
||||
},
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
showShareDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'share-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
docRef: {
|
||||
id: this.creatureId,
|
||||
collection: 'creatures',
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
deleteCharacter(){
|
||||
let that = this;
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'delete-confirmation-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
name: this.creature.name,
|
||||
typeName: 'Character'
|
||||
},
|
||||
callback(confirmation){
|
||||
if(!confirmation) return;
|
||||
removeCreature.call({charId: that.creatureId}, (error) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
that.$router.push('/characterList');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
unshareWithMe(){
|
||||
updateUserSharePermissions.call({
|
||||
docRef: {
|
||||
collection: 'creatures',
|
||||
id: this.creatureId,
|
||||
},
|
||||
userId: Meteor.userId(),
|
||||
role: 'none',
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
this.$router.push('/characterList');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'singleCharacter'(){
|
||||
return [this.creatureId];
|
||||
},
|
||||
},
|
||||
creature(){
|
||||
return Creatures.findOne(this.creatureId);
|
||||
},
|
||||
editPermission(){
|
||||
try {
|
||||
assertEditPermission(this.creature, Meteor.userId());
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -119,38 +119,18 @@ import Slots from '/imports/ui/creature/slots/Slots.vue';
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ColumnLayout,
|
||||
NoteCard,
|
||||
components: {
|
||||
ColumnLayout,
|
||||
NoteCard,
|
||||
Slots,
|
||||
ToolbarCard,
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
notes(){
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'note',
|
||||
removed: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
});
|
||||
},
|
||||
creature(){
|
||||
return Creatures.findOne(this.creatureId);
|
||||
},
|
||||
classLevels(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {type: 'classLevel'},
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
highestClassLevels(){
|
||||
let highestLevels = {};
|
||||
@@ -171,48 +151,74 @@ export default {
|
||||
return highestLevelsList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'creature-summary',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
mounted(){
|
||||
if (this.$store.state.showBuildDialog){
|
||||
this.$store.commit('setShowBuildDialog', false);
|
||||
this.showSlotDialog();
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
notes(){
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'note',
|
||||
removed: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
});
|
||||
},
|
||||
creature(){
|
||||
return Creatures.findOne(this.creatureId);
|
||||
},
|
||||
classLevels(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {type: 'classLevel'},
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'creature-summary',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
addExperience(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'experience-insert-dialog',
|
||||
elementId: 'experience-add-button',
|
||||
data: {
|
||||
creatureIds: [this.creatureId],
|
||||
component: 'experience-insert-dialog',
|
||||
elementId: 'experience-add-button',
|
||||
data: {
|
||||
creatureIds: [this.creatureId],
|
||||
startAsMilestone: this.creature.variables.milestoneLevels &&
|
||||
!!this.creature.variables.milestoneLevels.value,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
showExperienceList(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'experience-list-dialog',
|
||||
elementId: 'experience-info-button',
|
||||
data: {
|
||||
creatureId: this.creatureId,
|
||||
component: 'experience-list-dialog',
|
||||
elementId: 'experience-info-button',
|
||||
data: {
|
||||
creatureId: this.creatureId,
|
||||
startAsMilestone: this.creature.variables.milestoneLevels &&
|
||||
!!this.creature.variables.milestoneLevels.value,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
showSlotDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'slot-details-dialog',
|
||||
elementId: 'slot-card',
|
||||
data: {
|
||||
creatureId: this.creatureId,
|
||||
},
|
||||
});
|
||||
component: 'slot-details-dialog',
|
||||
elementId: 'slot-card',
|
||||
data: {
|
||||
creatureId: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
v-if="!slot.quantityExpected || slot.spaceLeft"
|
||||
icon
|
||||
:data-id="`slot-add-button-${slot._id}`"
|
||||
class="slot-add-button"
|
||||
style="background-color: inherit;"
|
||||
@click="fillSlot(slot)"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<Sidebar />
|
||||
</v-navigation-drawer>
|
||||
<router-view
|
||||
v-model="tabs"
|
||||
name="toolbar"
|
||||
/>
|
||||
<v-toolbar
|
||||
@@ -50,7 +49,6 @@
|
||||
style="width: 100%"
|
||||
>
|
||||
<router-view
|
||||
v-model="tabs"
|
||||
name="toolbarExtension"
|
||||
/>
|
||||
</div>
|
||||
@@ -60,7 +58,7 @@
|
||||
<v-fade-transition
|
||||
mode="out-in"
|
||||
>
|
||||
<router-view :tabs.sync="tabs" />
|
||||
<router-view />
|
||||
</v-fade-transition>
|
||||
</v-content>
|
||||
<router-view
|
||||
|
||||
@@ -141,7 +141,12 @@
|
||||
if (error){
|
||||
console.error(error);
|
||||
} else {
|
||||
this.$router.push({ path: `/character/${result}`})
|
||||
this.$store.commit(
|
||||
'setTabForCharacterSheet',
|
||||
{id: result, tab: 4}
|
||||
);
|
||||
this.$store.commit('setShowBuildDialog', true);
|
||||
this.$router.push({ path: `/character/${result}`});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<character-sheet
|
||||
show-menu-button
|
||||
:creature-id="$route.params.id"
|
||||
:tabs.sync="activeTab"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -12,21 +11,5 @@ export default {
|
||||
components: {
|
||||
CharacterSheet,
|
||||
},
|
||||
props: {
|
||||
tabs: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
activeTab: {
|
||||
get(){
|
||||
return this.tabs;
|
||||
},
|
||||
set(newTab){
|
||||
this.$emit('update:tabs', newTab);
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -14,6 +14,8 @@ const store = new Vuex.Store({
|
||||
drawer: undefined,
|
||||
rightDrawer: undefined,
|
||||
pageTitle: undefined,
|
||||
characterSheetTabs: {},
|
||||
showBuildDialog: false,
|
||||
},
|
||||
mutations: {
|
||||
toggleDrawer (state) {
|
||||
@@ -32,6 +34,12 @@ const store = new Vuex.Store({
|
||||
state.pageTitle = value;
|
||||
document.title = value;
|
||||
},
|
||||
setTabForCharacterSheet(state, {tab, id}){
|
||||
Vue.set(state.characterSheetTabs, id, tab);
|
||||
},
|
||||
setShowBuildDialog(state, value){
|
||||
state.showBuildDialog = value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user