Completed folder stat grouping UI
This commit is contained in:
@@ -28,8 +28,7 @@ let AttributeSchema = createPropertySchema({
|
|||||||
'stat', // Speed, Armor Class
|
'stat', // Speed, Armor Class
|
||||||
'modifier', // Proficiency Bonus, displayed as +x
|
'modifier', // Proficiency Bonus, displayed as +x
|
||||||
'hitDice', // d12 hit dice
|
'hitDice', // d12 hit dice
|
||||||
'healthBar', // Hitpoints, Temporary Hitpoints, can take damage
|
'healthBar', // Hitpoints, Temporary Hitpoints
|
||||||
'bar', // Displayed as a health bar, can't take damage
|
|
||||||
'resource', // Rages, sorcery points
|
'resource', // Rages, sorcery points
|
||||||
'spellSlot', // Level 1, 2, 3... spell slots
|
'spellSlot', // Level 1, 2, 3... spell slots
|
||||||
'utility', // Aren't displayed, Jump height, Carry capacity
|
'utility', // Aren't displayed, Jump height, Carry capacity
|
||||||
|
|||||||
@@ -1,14 +1,29 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div class="stats-tab ma-2">
|
<div class="stats-tab ma-2">
|
||||||
<health-bar-card-container :creature-id="creatureId" />
|
<div
|
||||||
|
v-if="healthBars.length"
|
||||||
|
class="px-2 pt-2"
|
||||||
|
>
|
||||||
|
<v-card class="pa-2">
|
||||||
|
<health-bar
|
||||||
|
v-for="healthBar in healthBars"
|
||||||
|
:key="healthBar._id"
|
||||||
|
:model="healthBar"
|
||||||
|
@change="({ type, value }) => incrementChange(healthBar._id, { type, value: -value })"
|
||||||
|
@click="clickProperty({_id: healthBar._id})"
|
||||||
|
/>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<column-layout>
|
<column-layout>
|
||||||
<div
|
<folder-group-card
|
||||||
v-for="folder in folders"
|
v-for="folder in folders"
|
||||||
:key="folder._id"
|
:key="folder._id"
|
||||||
>
|
:model="folder"
|
||||||
<folder-group-card :model="folder" />
|
@click-property="clickProperty"
|
||||||
</div>
|
@sub-click="_id => clickTreeProperty({_id})"
|
||||||
|
@remove="softRemove"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="!creature.settings.hideRestButtons || (events && events.length)"
|
v-if="!creature.settings.hideRestButtons || (events && events.length)"
|
||||||
class="character-buttons"
|
class="character-buttons"
|
||||||
@@ -50,26 +65,14 @@
|
|||||||
<v-card>
|
<v-card>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-subheader>Buffs and conditions</v-subheader>
|
<v-subheader>Buffs and conditions</v-subheader>
|
||||||
<v-list-item
|
<buff-list-item
|
||||||
v-for="buff in appliedBuffs"
|
v-for="buff in appliedBuffs"
|
||||||
:key="buff._id"
|
:key="buff._id"
|
||||||
:data-id="buff._id"
|
:data-id="buff._id"
|
||||||
|
:model="buff"
|
||||||
@click="clickProperty({_id: buff._id})"
|
@click="clickProperty({_id: buff._id})"
|
||||||
>
|
@remove="softRemove(buff._id)"
|
||||||
<v-list-item-content>
|
/>
|
||||||
<v-list-item-title>
|
|
||||||
{{ buff.name }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
<v-list-item-action v-if="!buff.hideRemoveButton">
|
|
||||||
<v-btn
|
|
||||||
icon
|
|
||||||
@click.stop="softRemove(buff._id)"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-delete</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item-action>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,7 +202,6 @@
|
|||||||
:model="spellSlot"
|
:model="spellSlot"
|
||||||
:data-id="spellSlot._id"
|
:data-id="spellSlot._id"
|
||||||
@click="clickProperty({_id: spellSlot._id})"
|
@click="clickProperty({_id: spellSlot._id})"
|
||||||
@cast="castSpellWithSlot(spellSlot._id)"
|
|
||||||
/>
|
/>
|
||||||
</v-list>
|
</v-list>
|
||||||
<div
|
<div
|
||||||
@@ -355,11 +357,11 @@
|
|||||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
import softRemoveProperty from '/imports/api/creature/creatureProperties/methods/softRemoveProperty.js';
|
import softRemoveProperty from '/imports/api/creature/creatureProperties/methods/softRemoveProperty.js';
|
||||||
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||||
|
import HealthBar from '/imports/ui/properties/components/attributes/HealthBar.vue';
|
||||||
import AttributeCard from '/imports/ui/properties/components/attributes/AttributeCard.vue';
|
import AttributeCard from '/imports/ui/properties/components/attributes/AttributeCard.vue';
|
||||||
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
||||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||||
import DamageMultiplierCard from '/imports/ui/properties/components/damageMultipliers/DamageMultiplierCard.vue';
|
import DamageMultiplierCard from '/imports/ui/properties/components/damageMultipliers/DamageMultiplierCard.vue';
|
||||||
import HealthBarCardContainer from '/imports/ui/properties/components/attributes/HealthBarCardContainer.vue';
|
|
||||||
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
||||||
import SkillListTile from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
import SkillListTile from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
||||||
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
||||||
@@ -368,13 +370,14 @@ import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue
|
|||||||
import RestButton from '/imports/ui/creature/RestButton.vue';
|
import RestButton from '/imports/ui/creature/RestButton.vue';
|
||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||||
|
import BuffListItem from '/imports/ui/properties/components/buffs/BuffListItem.vue';
|
||||||
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
||||||
import EventButton from '/imports/ui/properties/components/actions/EventButton.vue';
|
import EventButton from '/imports/ui/properties/components/actions/EventButton.vue';
|
||||||
import { snackbar } from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
import { snackbar } from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||||
import FolderGroupCard from '/imports/ui/properties/components/folders/FolderGroupCard.vue';
|
import FolderGroupCard from '/imports/ui/properties/components/folders/FolderGroupCard.vue';
|
||||||
import { uniqBy } from 'lodash';
|
import { uniqBy } from 'lodash';
|
||||||
|
|
||||||
const getProperties = function (creature, filter, options = {
|
const getProperties = function (creature, folderIds, filter, options = {
|
||||||
sort: { order: 1 }
|
sort: { order: 1 }
|
||||||
}) {
|
}) {
|
||||||
if (!creature) return;
|
if (!creature) return;
|
||||||
@@ -382,6 +385,7 @@ const getProperties = function (creature, filter, options = {
|
|||||||
filter.hide = { $ne: true };
|
filter.hide = { $ne: true };
|
||||||
}
|
}
|
||||||
filter['ancestors.id'] = creature._id;
|
filter['ancestors.id'] = creature._id;
|
||||||
|
filter['parent.id'] = {$nin: folderIds},
|
||||||
filter.removed = { $ne: true };
|
filter.removed = { $ne: true };
|
||||||
filter.inactive = { $ne: true };
|
filter.inactive = { $ne: true };
|
||||||
filter.overridden = { $ne: true };
|
filter.overridden = { $ne: true };
|
||||||
@@ -393,15 +397,15 @@ const getProperties = function (creature, filter, options = {
|
|||||||
return CreatureProperties.find(filter, options);
|
return CreatureProperties.find(filter, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAttributeOfType = function (creature, type) {
|
const getAttributeOfType = function (creature, folderIds, type) {
|
||||||
return getProperties(creature, {
|
return getProperties(creature, folderIds, {
|
||||||
type: 'attribute',
|
type: 'attribute',
|
||||||
attributeType: type,
|
attributeType: type,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSkillOfType = function (creature, type) {
|
const getSkillOfType = function (creature, folderIds, type) {
|
||||||
return getProperties(creature, {
|
return getProperties(creature, folderIds, {
|
||||||
type: 'skill',
|
type: 'skill',
|
||||||
skillType: type,
|
skillType: type,
|
||||||
});
|
});
|
||||||
@@ -409,12 +413,13 @@ const getSkillOfType = function (creature, type) {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
HealthBar,
|
||||||
RestButton,
|
RestButton,
|
||||||
|
BuffListItem,
|
||||||
AbilityListTile,
|
AbilityListTile,
|
||||||
AttributeCard,
|
AttributeCard,
|
||||||
ColumnLayout,
|
ColumnLayout,
|
||||||
DamageMultiplierCard,
|
DamageMultiplierCard,
|
||||||
HealthBarCardContainer,
|
|
||||||
HitDiceListTile,
|
HitDiceListTile,
|
||||||
SkillListTile,
|
SkillListTile,
|
||||||
ResourceCard,
|
ResourceCard,
|
||||||
@@ -439,16 +444,27 @@ export default {
|
|||||||
creature() {
|
creature() {
|
||||||
return Creatures.findOne(this.creatureId, { fields: { settings: 1 } });
|
return Creatures.findOne(this.creatureId, { fields: { settings: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
folders() {
|
||||||
|
return getProperties(this.creature, [], { type: 'folder', groupStats: true });
|
||||||
|
},
|
||||||
|
folderIds() {
|
||||||
|
return this.folders.map(f => f._id);
|
||||||
|
},
|
||||||
|
healthBars() {
|
||||||
|
return getAttributeOfType(this.creature, this.folderIds, 'healthBar');
|
||||||
|
},
|
||||||
abilities() {
|
abilities() {
|
||||||
return getAttributeOfType(this.creature, 'ability');
|
return getAttributeOfType(this.creature, this.folderIds, 'ability');
|
||||||
},
|
},
|
||||||
stats() {
|
stats() {
|
||||||
return getAttributeOfType(this.creature, 'stat');
|
return getAttributeOfType(this.creature, this.folderIds, 'stat');
|
||||||
},
|
},
|
||||||
toggles() {
|
toggles() {
|
||||||
return CreatureProperties.find({
|
return CreatureProperties.find({
|
||||||
'ancestors.id': this.creatureId,
|
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
'parent.id': { $nin: this.folderIds },
|
||||||
removed: { $ne: true },
|
removed: { $ne: true },
|
||||||
deactivatedByAncestor: { $ne: true },
|
deactivatedByAncestor: { $ne: true },
|
||||||
showUI: true,
|
showUI: true,
|
||||||
@@ -457,64 +473,61 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
modifiers() {
|
modifiers() {
|
||||||
return getAttributeOfType(this.creature, 'modifier');
|
return getAttributeOfType(this.creature, this.folderIds, 'modifier');
|
||||||
},
|
},
|
||||||
resources() {
|
resources() {
|
||||||
return getAttributeOfType(this.creature, 'resource');
|
return getAttributeOfType(this.creature, this.folderIds, 'resource');
|
||||||
},
|
},
|
||||||
spellSlots() {
|
spellSlots() {
|
||||||
return getAttributeOfType(this.creature, 'spellSlot');
|
return getAttributeOfType(this.creature, this.folderIds, 'spellSlot');
|
||||||
},
|
},
|
||||||
hasSpells() {
|
hasSpells() {
|
||||||
const cursor = getProperties(this.creature, {
|
const cursor = getProperties(this.creature, this.folderIds, {
|
||||||
type: 'spell',
|
type: 'spell',
|
||||||
})
|
})
|
||||||
return cursor && cursor.count();
|
return cursor && cursor.count();
|
||||||
},
|
},
|
||||||
hitDice() {
|
hitDice() {
|
||||||
return getAttributeOfType(this.creature, 'hitDice');
|
return getAttributeOfType(this.creature, this.folderIds, 'hitDice');
|
||||||
},
|
},
|
||||||
checks() {
|
checks() {
|
||||||
return getSkillOfType(this.creature, 'check');
|
return getSkillOfType(this.creature, this.folderIds, 'check');
|
||||||
},
|
},
|
||||||
savingThrows() {
|
savingThrows() {
|
||||||
return getSkillOfType(this.creature, 'save');
|
return getSkillOfType(this.creature, this.folderIds, 'save');
|
||||||
},
|
},
|
||||||
skills() {
|
skills() {
|
||||||
return getSkillOfType(this.creature, 'skill');
|
return getSkillOfType(this.creature, this.folderIds, 'skill');
|
||||||
},
|
},
|
||||||
tools() {
|
tools() {
|
||||||
return getSkillOfType(this.creature, 'tool');
|
return getSkillOfType(this.creature, this.folderIds, 'tool');
|
||||||
},
|
},
|
||||||
weapons() {
|
weapons() {
|
||||||
return getSkillOfType(this.creature, 'weapon');
|
return getSkillOfType(this.creature, this.folderIds, 'weapon');
|
||||||
},
|
},
|
||||||
armors() {
|
armors() {
|
||||||
return getSkillOfType(this.creature, 'armor');
|
return getSkillOfType(this.creature, this.folderIds, 'armor');
|
||||||
},
|
},
|
||||||
languages() {
|
languages() {
|
||||||
return getSkillOfType(this.creature, 'language');
|
return getSkillOfType(this.creature, this.folderIds, 'language');
|
||||||
},
|
},
|
||||||
events() {
|
events() {
|
||||||
const events = getProperties(this.creature, { type: 'action', actionType: 'event' });
|
const events = getProperties(this.creature, this.folderIds, { type: 'action', actionType: 'event' });
|
||||||
return uniqBy(events.fetch(), e => e.variableName);
|
return uniqBy(events.fetch(), e => e.variableName);
|
||||||
},
|
},
|
||||||
actions() {
|
actions() {
|
||||||
return getProperties(this.creature, { type: 'action', actionType: { $ne: 'event' } });
|
return getProperties(this.creature, this.folderIds, { type: 'action', actionType: { $ne: 'event' } });
|
||||||
},
|
},
|
||||||
appliedBuffs() {
|
appliedBuffs() {
|
||||||
return getProperties(this.creature, { type: 'buff' });
|
return getProperties(this.creature, this.folderIds, { type: 'buff' });
|
||||||
},
|
},
|
||||||
multipliers() {
|
multipliers() {
|
||||||
return getProperties(this.creature, {
|
return getProperties(this.creature, this.folderIds, {
|
||||||
type: 'damageMultiplier'
|
type: 'damageMultiplier'
|
||||||
}, {
|
}, {
|
||||||
sort: { value: 1, order: 1 }
|
sort: { value: 1, order: 1 }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
folders() {
|
|
||||||
return getProperties(this.creature, { type: 'folder', groupStats: true });
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clickProperty({ _id }) {
|
clickProperty({ _id }) {
|
||||||
@@ -532,13 +545,23 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
incrementChange(_id, { type, value }) {
|
incrementChange(_id, { type, value }) {
|
||||||
if (type === 'increment') {
|
damageProperty.call({
|
||||||
damageProperty.call({ _id, operation: 'increment', value: -value });
|
_id,
|
||||||
}
|
operation: type,
|
||||||
|
value: -value
|
||||||
|
}, error => {
|
||||||
|
if (error) {
|
||||||
|
snackbar({ text: error.reason || error.message || error.toString() });
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
softRemove(_id) {
|
softRemove(_id) {
|
||||||
softRemoveProperty.call({ _id }, error => {
|
softRemoveProperty.call({ _id }, error => {
|
||||||
if (error) console.error(error);
|
if (error) {
|
||||||
|
snackbar({ text: error.reason || error.message || error.toString() });
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
castSpell() {
|
castSpell() {
|
||||||
|
|||||||
@@ -5,54 +5,19 @@
|
|||||||
@mouseover="hasClickListener ? hovering = true : undefined"
|
@mouseover="hasClickListener ? hovering = true : undefined"
|
||||||
@mouseleave="hasClickListener ? hovering = false : undefined"
|
@mouseleave="hasClickListener ? hovering = false : undefined"
|
||||||
>
|
>
|
||||||
<div class="layout align-center">
|
<attribute-card-content :model="model" />
|
||||||
<roll-popup
|
|
||||||
v-if="model.attributeType === 'modifier' || model.type === 'skill'"
|
|
||||||
button-class="px-0"
|
|
||||||
text
|
|
||||||
height="70"
|
|
||||||
min-width="72"
|
|
||||||
:roll-text="computedValue && computedValue.toString()"
|
|
||||||
:name="model.name"
|
|
||||||
:advantage="model.advantage"
|
|
||||||
:loading="checkLoading"
|
|
||||||
:disabled="!context.editPermission"
|
|
||||||
@roll="check"
|
|
||||||
>
|
|
||||||
<v-card-title class="value text-h4 flex-shrink-0">
|
|
||||||
{{ computedValue }}
|
|
||||||
</v-card-title>
|
|
||||||
</roll-popup>
|
|
||||||
<v-card-title
|
|
||||||
v-else
|
|
||||||
class="value text-h4 flex-shrink-0"
|
|
||||||
>
|
|
||||||
{{ computedValue }}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-title class="name text-subtitle-1 text-truncate d-block pl-0">
|
|
||||||
{{ model.name }}
|
|
||||||
</v-card-title>
|
|
||||||
</div>
|
|
||||||
<card-highlight :active="hasClickListener && hovering" />
|
<card-highlight :active="hasClickListener && hovering" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
|
||||||
import RollPopup from '/imports/ui/components/RollPopup.vue';
|
|
||||||
import doCheck from '/imports/api/engine/actions/doCheck.js';
|
|
||||||
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
|
||||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
import AttributeCardContent from '/imports/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
RollPopup,
|
|
||||||
CardHighlight,
|
CardHighlight,
|
||||||
},
|
AttributeCardContent,
|
||||||
inject: {
|
|
||||||
context: {
|
|
||||||
default: {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
model: {
|
model: {
|
||||||
@@ -68,41 +33,11 @@
|
|||||||
hasClickListener(){
|
hasClickListener(){
|
||||||
return this.$listeners && !!this.$listeners.click
|
return this.$listeners && !!this.$listeners.click
|
||||||
},
|
},
|
||||||
computedValue(){
|
|
||||||
if (this.model.attributeType === 'modifier' || this.model.type === 'skill'){
|
|
||||||
return numberToSignedString(this.model.value);
|
|
||||||
} else {
|
|
||||||
return this.model.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
signed: numberToSignedString,
|
|
||||||
click(e){
|
click(e){
|
||||||
this.$emit('click', e);
|
this.$emit('click', e);
|
||||||
},
|
},
|
||||||
check({advantage}){
|
|
||||||
this.checkLoading = true;
|
|
||||||
doCheck.call({
|
|
||||||
propId: this.model._id,
|
|
||||||
scope: {
|
|
||||||
$checkAdvantage: advantage,
|
|
||||||
},
|
|
||||||
}, error => {
|
|
||||||
this.checkLoading = false;
|
|
||||||
if (error){
|
|
||||||
console.error(error);
|
|
||||||
snackbar({text: error.reason});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
|
||||||
.value {
|
|
||||||
min-width: 72px;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="layout align-center"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@mouseover="$emit('mouseover')"
|
||||||
|
@mouseleave="$emit('mouseleave')"
|
||||||
|
>
|
||||||
|
<roll-popup
|
||||||
|
v-if="model.attributeType === 'modifier' || model.type === 'skill'"
|
||||||
|
button-class="px-0"
|
||||||
|
text
|
||||||
|
height="70"
|
||||||
|
min-width="72"
|
||||||
|
:roll-text="computedValue && computedValue.toString()"
|
||||||
|
:name="model.name"
|
||||||
|
:advantage="model.advantage"
|
||||||
|
:loading="checkLoading"
|
||||||
|
:disabled="!context.editPermission"
|
||||||
|
@roll="check"
|
||||||
|
>
|
||||||
|
<v-card-title class="value text-h4 flex-shrink-0">
|
||||||
|
{{ computedValue }}
|
||||||
|
</v-card-title>
|
||||||
|
</roll-popup>
|
||||||
|
<v-card-title
|
||||||
|
v-else
|
||||||
|
class="value text-h4 flex-shrink-0"
|
||||||
|
>
|
||||||
|
{{ computedValue }}
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-title class="name text-subtitle-1 text-truncate d-block pl-0">
|
||||||
|
{{ model.name }}
|
||||||
|
</v-card-title>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import RollPopup from '/imports/ui/components/RollPopup.vue';
|
||||||
|
import doCheck from '/imports/api/engine/actions/doCheck.js';
|
||||||
|
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
RollPopup,
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
context: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data(){return {
|
||||||
|
checkLoading: false,
|
||||||
|
hovering: false,
|
||||||
|
}},
|
||||||
|
computed: {
|
||||||
|
computedValue(){
|
||||||
|
if (this.model.attributeType === 'modifier' || this.model.type === 'skill'){
|
||||||
|
return numberToSignedString(this.model.value);
|
||||||
|
} else {
|
||||||
|
return this.model.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
signed: numberToSignedString,
|
||||||
|
check({advantage}){
|
||||||
|
this.checkLoading = true;
|
||||||
|
doCheck.call({
|
||||||
|
propId: this.model._id,
|
||||||
|
scope: {
|
||||||
|
$checkAdvantage: advantage,
|
||||||
|
},
|
||||||
|
}, error => {
|
||||||
|
this.checkLoading = false;
|
||||||
|
if (error){
|
||||||
|
console.error(error);
|
||||||
|
snackbar({text: error.reason});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.value {
|
||||||
|
min-width: 72px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
style="min-height: 42px;"
|
style="min-height: 42px;"
|
||||||
:class="{ hover }"
|
:class="{ hover }"
|
||||||
class="my-1 health-bar"
|
class="my-1 health-bar"
|
||||||
:data-id="_id"
|
:data-id="model._id"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="subheading text-truncate pa-2 name"
|
class="subheading text-truncate pa-2 name"
|
||||||
@@ -14,14 +14,10 @@
|
|||||||
@mouseleave="hover = false"
|
@mouseleave="hover = false"
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
>
|
>
|
||||||
{{ name }}
|
{{ model.name }}
|
||||||
</div>
|
</div>
|
||||||
<v-flex
|
<v-flex
|
||||||
style="
|
style="height: 24px; flex-basis: 300px; flex-grow: 100;"
|
||||||
height: 24px;
|
|
||||||
flex-basis: 300px;
|
|
||||||
flex-grow: 100;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
column
|
column
|
||||||
@@ -50,8 +46,7 @@
|
|||||||
'white--text': isTextLight,
|
'white--text': isTextLight,
|
||||||
'black--text': !isTextLight,
|
'black--text': !isTextLight,
|
||||||
}"
|
}"
|
||||||
style="
|
style="font-size: 15px;
|
||||||
font-size: 15px;
|
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -59,30 +54,30 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
text-align: center;
|
text-align: center;"
|
||||||
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ value }} / {{ maxValue }}
|
{{ model.value }} / {{ model.total }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition name="transition">
|
<v-menu
|
||||||
|
v-model="editing"
|
||||||
|
absolute
|
||||||
|
transition="scale-transition"
|
||||||
|
origin="center center"
|
||||||
|
content-class="no-menu-shadow"
|
||||||
|
:position-x="x"
|
||||||
|
:position-y="y"
|
||||||
|
:min-width="305"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
>
|
||||||
<increment-menu
|
<increment-menu
|
||||||
v-show="editing"
|
:value="model.value"
|
||||||
:value="value"
|
|
||||||
:open="editing"
|
:open="editing"
|
||||||
@change="changeIncrementMenu"
|
@change="changeIncrementMenu"
|
||||||
@close="cancelEdit"
|
@close="cancelEdit"
|
||||||
/>
|
/>
|
||||||
</transition>
|
</v-menu>
|
||||||
<transition name="background-transition">
|
|
||||||
<div
|
|
||||||
v-if="editing"
|
|
||||||
class="page-tint"
|
|
||||||
@click="cancelEdit"
|
|
||||||
/>
|
|
||||||
</transition>
|
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
@@ -104,31 +99,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
model: {
|
||||||
type: Number,
|
type: Object,
|
||||||
default: undefined,
|
required: true,
|
||||||
},
|
|
||||||
maxValue: {
|
|
||||||
type: Number,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return this.$vuetify.theme.currentTheme.primary
|
|
||||||
},
|
|
||||||
},
|
|
||||||
midColor: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
lowColor: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
},
|
||||||
_id: String,
|
_id: String,
|
||||||
},
|
},
|
||||||
@@ -136,24 +109,29 @@ export default {
|
|||||||
return {
|
return {
|
||||||
editing: false,
|
editing: false,
|
||||||
hover: false,
|
hover: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fillFraction() {
|
fillFraction() {
|
||||||
let fraction = this.value / this.maxValue;
|
let fraction = this.model.value / this.model.total;
|
||||||
if (fraction < 0) fraction = 0;
|
if (fraction < 0) fraction = 0;
|
||||||
if (fraction > 1) fraction = 1;
|
if (fraction > 1) fraction = 1;
|
||||||
return fraction;
|
return fraction;
|
||||||
},
|
},
|
||||||
|
color() {
|
||||||
|
return this.model.color || this.$vuetify.theme.currentTheme.primary
|
||||||
|
},
|
||||||
barColor() {
|
barColor() {
|
||||||
const fraction = this.value / this.maxValue;
|
const fraction = this.model.value / this.model.total;
|
||||||
if (!Number.isFinite(fraction)) return this.color;
|
if (!Number.isFinite(fraction)) return this.color;
|
||||||
if (fraction > 0.5) {
|
if (fraction > 0.5) {
|
||||||
return this.color;
|
return this.color;
|
||||||
} else if (this.midColor && this.lowColor) {
|
} else if (this.model.healthBarColorMid && this.model.healthBarColorLow) {
|
||||||
return chroma.mix(this.lowColor, this.midColor, fraction * 2).hex();
|
return chroma.mix(this.model.healthBarColorLow, this.model.healthBarColorMid, fraction * 2).hex();
|
||||||
} else if (this.midColor) {
|
} else if (this.model.healthBarColorMid) {
|
||||||
return this.midColor;
|
return this.model.healthBarColorMid;
|
||||||
}
|
}
|
||||||
return this.color;
|
return this.color;
|
||||||
},
|
},
|
||||||
@@ -166,7 +144,7 @@ export default {
|
|||||||
isTextLight() {
|
isTextLight() {
|
||||||
return isDarkColor(this.barBackgroundColor);
|
return isDarkColor(this.barBackgroundColor);
|
||||||
/* Change color at the halfway mark
|
/* Change color at the halfway mark
|
||||||
const fraction = this.value / this.maxValue;
|
const fraction = this.model.value / this.model.total;
|
||||||
if (fraction >= 0.5){
|
if (fraction >= 0.5){
|
||||||
return isDarkColor(this.barColor);
|
return isDarkColor(this.barColor);
|
||||||
} else {
|
} else {
|
||||||
@@ -176,8 +154,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
edit() {
|
edit(e) {
|
||||||
this.editing = true;
|
e.preventDefault()
|
||||||
|
this.editing = false;
|
||||||
|
this.x = e.clientX - 165;
|
||||||
|
this.y = e.clientY - 24;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.editing = true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
cancelEdit() {
|
cancelEdit() {
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
@@ -199,6 +183,10 @@ export default {
|
|||||||
z-index: 7;
|
z-index: 7;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-menu-shadow {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -3,13 +3,7 @@
|
|||||||
<health-bar
|
<health-bar
|
||||||
v-for="attribute in attributes"
|
v-for="attribute in attributes"
|
||||||
:key="attribute._id"
|
:key="attribute._id"
|
||||||
:value="attribute.value"
|
:model="attribute"
|
||||||
:max-value="attribute.total"
|
|
||||||
:name="attribute.name"
|
|
||||||
:color="attribute.color"
|
|
||||||
:mid-color="attribute.healthBarColorMid"
|
|
||||||
:low-color="attribute.healthBarColorLow"
|
|
||||||
:_id="attribute._id"
|
|
||||||
@change="e => $emit('change', {_id: attribute._id, change: e})"
|
@change="e => $emit('change', {_id: attribute._id, change: e})"
|
||||||
@click="e => $emit('click', {_id: attribute._id})"
|
@click="e => $emit('click', {_id: attribute._id})"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,57 +3,26 @@
|
|||||||
class="resource-card"
|
class="resource-card"
|
||||||
:class="hover ? 'elevation-8': ''"
|
:class="hover ? 'elevation-8': ''"
|
||||||
>
|
>
|
||||||
<v-layout>
|
<resource-card-content
|
||||||
<div class="buttons layout column justify-center pl-3">
|
:model="model"
|
||||||
<v-btn
|
:hover="hover"
|
||||||
icon
|
@mouseover="hover = true"
|
||||||
small
|
@mouseleave="hover = false"
|
||||||
:disabled="(model.value >= model.total && !model.ignoreUpperLimit) || context.editPermission === false"
|
@click="$emit('click')"
|
||||||
@click="increment(1)"
|
@change="e => $emit('change', e)"
|
||||||
>
|
/>
|
||||||
<v-icon>mdi-chevron-up</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
icon
|
|
||||||
small
|
|
||||||
:disabled="(model.value <= 0 && !model.ignoreLowerLimit) || context.editPermission === false"
|
|
||||||
@click="increment(-1)"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-chevron-down</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
<div class="layout align-center value pl-2 pr-3">
|
|
||||||
<div class="text-h4">
|
|
||||||
{{ model.value }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="model.total !== 0"
|
|
||||||
class="text-h6 ml-2 max-value"
|
|
||||||
>
|
|
||||||
/{{ model.total }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="content layout align-center pr-3"
|
|
||||||
@click="click"
|
|
||||||
@mouseover="hover = true"
|
|
||||||
@mouseleave="hover = false"
|
|
||||||
>
|
|
||||||
<div class="text-truncate ">
|
|
||||||
{{ model.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-layout>
|
|
||||||
<card-highlight :active="hover" />
|
<card-highlight :active="hover" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
import ResourceCardContent from '/imports/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
CardHighlight,
|
CardHighlight,
|
||||||
|
ResourceCardContent,
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
context: { default: {} }
|
context: { default: {} }
|
||||||
@@ -69,46 +38,16 @@ export default {
|
|||||||
hover: false,
|
hover: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
click(e) {
|
|
||||||
this.$emit('click', e);
|
|
||||||
},
|
|
||||||
increment(value) {
|
|
||||||
this.$emit('change', { type: 'increment', value })
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css">
|
||||||
.resource-card {
|
.resource-card {
|
||||||
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-card>div {
|
.resource-card > div {
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons,
|
|
||||||
.value {
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons>.v-btn {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-value {
|
|
||||||
color: rgba(0, 0, 0, .54);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme--dark .max-value {
|
|
||||||
color: rgba(255, 255, 255, 0.54);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<v-layout>
|
||||||
|
<div class="buttons layout column justify-center pl-3">
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
small
|
||||||
|
:disabled="(model.value >= model.total && !model.ignoreUpperLimit) || context.editPermission === false"
|
||||||
|
@click="increment(1)"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-chevron-up</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
small
|
||||||
|
:disabled="(model.value <= 0 && !model.ignoreLowerLimit) || context.editPermission === false"
|
||||||
|
@click="increment(-1)"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
<div class="layout align-center value pl-2 pr-3">
|
||||||
|
<div class="text-h4">
|
||||||
|
{{ model.value }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="model.total !== 0"
|
||||||
|
class="text-h6 ml-2 max-value"
|
||||||
|
>
|
||||||
|
/{{ model.total }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="content layout align-center pr-3"
|
||||||
|
@click="click"
|
||||||
|
@mouseover="$emit('mouseover')"
|
||||||
|
@mouseleave="$emit('mouseleave')"
|
||||||
|
>
|
||||||
|
<div class="text-truncate ">
|
||||||
|
{{ model.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: {
|
||||||
|
context: { default: {} }
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
hover: {
|
||||||
|
type: Boolean,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
click(e) {
|
||||||
|
this.$emit('click', e);
|
||||||
|
},
|
||||||
|
increment(value) {
|
||||||
|
this.$emit('change', { type: 'increment', value })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.buttons,
|
||||||
|
.value {
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
.buttons>.v-btn {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.max-value {
|
||||||
|
color: rgba(0, 0, 0, .54);
|
||||||
|
}
|
||||||
|
.theme--dark .max-value {
|
||||||
|
color: rgba(255, 255, 255, 0.54);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -61,7 +61,6 @@ export default {
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
dark: Boolean,
|
dark: Boolean,
|
||||||
hideCastButton: Boolean,
|
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
30
app/imports/ui/properties/components/buffs/BuffListItem.vue
Normal file
30
app/imports/ui/properties/components/buffs/BuffListItem.vue
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<v-list-item
|
||||||
|
@click="$emit('click')"
|
||||||
|
>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ model.name }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
<v-list-item-action v-if="!model.hideRemoveButton">
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
@click.stop="$emit('remove')"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-delete</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-item-action>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,15 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-card>
|
<div
|
||||||
<v-subheader v-if="model.name">
|
v-if="model.name || (properties && properties.length)"
|
||||||
{{ model.name }}
|
>
|
||||||
</v-subheader>
|
<v-card
|
||||||
<component
|
class="folder-group-card pb-2"
|
||||||
:is="prop.type"
|
>
|
||||||
v-for="prop in properties"
|
<v-subheader v-if="model.name">
|
||||||
:key="prop._id"
|
{{ model.name }}
|
||||||
:model="prop"
|
</v-subheader>
|
||||||
/>
|
<component
|
||||||
</v-card>
|
:is="prop.type"
|
||||||
|
v-for="prop in properties"
|
||||||
|
:key="prop._id"
|
||||||
|
:model="prop"
|
||||||
|
:data-id="prop._id"
|
||||||
|
@click="$emit('click-property', {_id: prop._id})"
|
||||||
|
@sub-click="_id => $emit('sub-click', _id)"
|
||||||
|
@remove="$emit('remove', prop._id)"
|
||||||
|
/>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
@@ -28,12 +38,44 @@ export default {
|
|||||||
},
|
},
|
||||||
meteor: {
|
meteor: {
|
||||||
properties() {
|
properties() {
|
||||||
return CreatureProperties.find({
|
const props = [];
|
||||||
'ancestors.id': this.model._id
|
CreatureProperties.find({
|
||||||
|
'parent.id': this.model._id,
|
||||||
|
removed: { $ne: true },
|
||||||
|
overridden: { $ne: true },
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
showUI: true,
|
||||||
|
deactivatedByAncestor: { $ne: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inactive: { $ne: true }
|
||||||
|
},
|
||||||
|
],
|
||||||
|
$nor: [
|
||||||
|
{ hideWhenTotalZero: true, total: 0 },
|
||||||
|
{ hideWhenValueZero: true, value: 0 },
|
||||||
|
],
|
||||||
}, {
|
}, {
|
||||||
sort: { order: 1 },
|
sort: { order: 1 },
|
||||||
|
}).forEach(prop => {
|
||||||
|
if (this.$options.components[prop.type]) {
|
||||||
|
props.push(prop);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
return props;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.folder-group-card .v-card {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.folder-group-card .drag-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="model.actionType === 'event'"
|
||||||
|
class="d-flex justify-center"
|
||||||
|
>
|
||||||
|
<event-button
|
||||||
|
class="ma-1"
|
||||||
|
:model="model"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<action-card
|
||||||
|
v-else
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@sub-click="_id => $emit('sub-click', _id)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue';
|
||||||
|
import EventButton from '/imports/ui/properties/components/actions/EventButton.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ActionCard,
|
||||||
|
EventButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="attribute">
|
||||||
|
<ability-list-tile
|
||||||
|
v-if="model.attributeType === 'ability'"
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
/>
|
||||||
|
<hit-dice-list-tile
|
||||||
|
v-else-if="model.attributeType === 'hitDice'"
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@change="({ type, value }) => damageProperty({type, value: -value})"
|
||||||
|
/>
|
||||||
|
<health-bar
|
||||||
|
v-else-if="model.attributeType === 'healthBar'"
|
||||||
|
:model="model"
|
||||||
|
@change="damageProperty"
|
||||||
|
@click="$emit('click')"
|
||||||
|
/>
|
||||||
|
<spell-slot-list-tile
|
||||||
|
v-else-if="model.attributeType === 'spellSlot'"
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
/>
|
||||||
|
<resource-card-content
|
||||||
|
v-else-if="model.attributeType === 'resource'"
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@change="({ type, value }) => damageProperty({type, value: -value})"
|
||||||
|
@mouseover="hover = true"
|
||||||
|
@mouseleave="hover = false"
|
||||||
|
/>
|
||||||
|
<attribute-card-content
|
||||||
|
v-else-if="model.attributeType !== 'utility'"
|
||||||
|
class="pointer"
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@mouseover="hover = true"
|
||||||
|
@mouseleave="hover = false"
|
||||||
|
/>
|
||||||
|
<card-highlight :active="hover" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
||||||
|
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
||||||
|
import HealthBar from '/imports/ui/properties/components/attributes/HealthBar.vue';
|
||||||
|
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
||||||
|
import ResourceCardContent from '/imports/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||||
|
import AttributeCardContent from '/imports/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||||
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
|
||||||
|
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AbilityListTile,
|
||||||
|
HitDiceListTile,
|
||||||
|
HealthBar,
|
||||||
|
SpellSlotListTile,
|
||||||
|
ResourceCardContent,
|
||||||
|
AttributeCardContent,
|
||||||
|
CardHighlight,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hover: false,
|
||||||
|
}},
|
||||||
|
methods: {
|
||||||
|
damageProperty(change) {
|
||||||
|
damageProperty.call({
|
||||||
|
_id: this.model._id,
|
||||||
|
operation: change.type,
|
||||||
|
value: change.value
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.attribute {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
import action from '/imports/ui/properties/components/actions/EventButton.vue';
|
import action from '/imports/ui/properties/components/folders/folderGroupComponents/ActionGroupComponent.vue';
|
||||||
//import adjustment from '';
|
//import adjustment from '';
|
||||||
import attribute from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
import attribute from './folderGroupComponents/AttributeGroupComponent.vue';
|
||||||
//import buff from '';
|
import buff from '/imports/ui/properties/components/buffs/BuffListItem.vue';
|
||||||
//import buffRemover from '';
|
//import buffRemover from '';
|
||||||
//import branch from '';
|
//import branch from '';
|
||||||
//import constant from '';
|
//import constant from '';
|
||||||
//import container from '';
|
import container from '/imports/ui/properties/components/inventory/ContainerCard.vue';
|
||||||
//import classComponent from '';
|
//import classComponent from '';
|
||||||
//import classLevel from '';
|
//import classLevel from '';
|
||||||
//import damage from '';
|
//import damage from '';
|
||||||
//import damageMultiplier from '';
|
//import damageMultiplier from '';
|
||||||
//import effect from '';
|
//import effect from '';
|
||||||
//import feature from '';
|
import feature from '/imports/ui/properties/components/features/FeatureCard.vue';
|
||||||
//import folder from '';
|
// import folder from '';
|
||||||
//import item from '';
|
import item from '/imports/ui/properties/components/inventory/ItemListTile.vue';
|
||||||
//import note from '';
|
import note from '/imports/ui/properties/components/persona/NoteCard.vue';
|
||||||
//import pointBuy from '';
|
//import pointBuy from '';
|
||||||
//import proficiency from '';
|
//import proficiency from '';
|
||||||
//import propertySlot from '';
|
//import propertySlot from '';
|
||||||
//import reference from '';
|
//import reference from '';
|
||||||
//import roll from '';
|
//import roll from '';
|
||||||
//import savingThrow from '';
|
//import savingThrow from '';
|
||||||
//import skill from '';
|
import skill from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
||||||
//import slotFiller from '';
|
//import slotFiller from '';
|
||||||
//import spellList from '';
|
//import spellList from '';
|
||||||
//import spell from '';
|
//import spell from '';
|
||||||
@@ -32,27 +32,27 @@ export default {
|
|||||||
action,
|
action,
|
||||||
//adjustment,
|
//adjustment,
|
||||||
attribute,
|
attribute,
|
||||||
//buff,
|
buff,
|
||||||
//buffRemover,
|
//buffRemover,
|
||||||
//branch,
|
//branch,
|
||||||
//constant,
|
//constant,
|
||||||
//container,
|
container,
|
||||||
//class: classComponent,
|
//class: classComponent,
|
||||||
//classLevel,
|
//classLevel,
|
||||||
//damage,
|
//damage,
|
||||||
//damageMultiplier,
|
//damageMultiplier,
|
||||||
//effect,
|
//effect,
|
||||||
//feature,
|
feature,
|
||||||
//folder,
|
//folder,
|
||||||
//item,
|
item,
|
||||||
//note,
|
note,
|
||||||
//pointBuy,
|
//pointBuy,
|
||||||
//proficiency,
|
//proficiency,
|
||||||
//propertySlot,
|
//propertySlot,
|
||||||
//reference,
|
//reference,
|
||||||
//roll,
|
//roll,
|
||||||
//savingThrow,
|
//savingThrow,
|
||||||
//skill,
|
skill,
|
||||||
//slotFiller,
|
//slotFiller,
|
||||||
//spellList,
|
//spellList,
|
||||||
//spell,
|
//spell,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
@change="changeQuantity"
|
@change="changeQuantity"
|
||||||
/>
|
/>
|
||||||
</v-list-item-action>
|
</v-list-item-action>
|
||||||
<v-list-item-action>
|
<v-list-item-action class="drag-handle">
|
||||||
<v-icon
|
<v-icon
|
||||||
:disabled="context.editPermission === false"
|
:disabled="context.editPermission === false"
|
||||||
style="height: 100%; width: 40px; cursor: move;"
|
style="height: 100%; width: 40px; cursor: move;"
|
||||||
|
|||||||
Reference in New Issue
Block a user