Completed folder stat grouping UI
This commit is contained in:
@@ -5,54 +5,19 @@
|
||||
@mouseover="hasClickListener ? hovering = true : undefined"
|
||||
@mouseleave="hasClickListener ? hovering = false : undefined"
|
||||
>
|
||||
<div class="layout align-center">
|
||||
<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>
|
||||
<attribute-card-content :model="model" />
|
||||
<card-highlight :active="hasClickListener && hovering" />
|
||||
</v-card>
|
||||
</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';
|
||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||
import AttributeCardContent from '/imports/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
RollPopup,
|
||||
CardHighlight,
|
||||
},
|
||||
inject: {
|
||||
context: {
|
||||
default: {},
|
||||
},
|
||||
AttributeCardContent,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
@@ -68,41 +33,11 @@
|
||||
hasClickListener(){
|
||||
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: {
|
||||
signed: numberToSignedString,
|
||||
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>
|
||||
|
||||
<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;"
|
||||
:class="{ hover }"
|
||||
class="my-1 health-bar"
|
||||
:data-id="_id"
|
||||
:data-id="model._id"
|
||||
>
|
||||
<div
|
||||
class="subheading text-truncate pa-2 name"
|
||||
@@ -14,14 +14,10 @@
|
||||
@mouseleave="hover = false"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
{{ name }}
|
||||
{{ model.name }}
|
||||
</div>
|
||||
<v-flex
|
||||
style="
|
||||
height: 24px;
|
||||
flex-basis: 300px;
|
||||
flex-grow: 100;
|
||||
"
|
||||
style="height: 24px; flex-basis: 300px; flex-grow: 100;"
|
||||
>
|
||||
<div
|
||||
column
|
||||
@@ -50,8 +46,7 @@
|
||||
'white--text': isTextLight,
|
||||
'black--text': !isTextLight,
|
||||
}"
|
||||
style="
|
||||
font-size: 15px;
|
||||
style="font-size: 15px;
|
||||
line-height: 24px;
|
||||
font-weight: 600;
|
||||
position: absolute;
|
||||
@@ -59,30 +54,30 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
|
||||
"
|
||||
text-align: center;"
|
||||
>
|
||||
{{ value }} / {{ maxValue }}
|
||||
{{ model.value }} / {{ model.total }}
|
||||
</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
|
||||
v-show="editing"
|
||||
:value="value"
|
||||
:value="model.value"
|
||||
:open="editing"
|
||||
@change="changeIncrementMenu"
|
||||
@close="cancelEdit"
|
||||
/>
|
||||
</transition>
|
||||
<transition name="background-transition">
|
||||
<div
|
||||
v-if="editing"
|
||||
class="page-tint"
|
||||
@click="cancelEdit"
|
||||
/>
|
||||
</transition>
|
||||
</v-menu>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</template>
|
||||
@@ -104,31 +99,9 @@ export default {
|
||||
},
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
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,
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
_id: String,
|
||||
},
|
||||
@@ -136,24 +109,29 @@ export default {
|
||||
return {
|
||||
editing: false,
|
||||
hover: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
fillFraction() {
|
||||
let fraction = this.value / this.maxValue;
|
||||
let fraction = this.model.value / this.model.total;
|
||||
if (fraction < 0) fraction = 0;
|
||||
if (fraction > 1) fraction = 1;
|
||||
return fraction;
|
||||
},
|
||||
color() {
|
||||
return this.model.color || this.$vuetify.theme.currentTheme.primary
|
||||
},
|
||||
barColor() {
|
||||
const fraction = this.value / this.maxValue;
|
||||
const fraction = this.model.value / this.model.total;
|
||||
if (!Number.isFinite(fraction)) return this.color;
|
||||
if (fraction > 0.5) {
|
||||
return this.color;
|
||||
} else if (this.midColor && this.lowColor) {
|
||||
return chroma.mix(this.lowColor, this.midColor, fraction * 2).hex();
|
||||
} else if (this.midColor) {
|
||||
return this.midColor;
|
||||
} else if (this.model.healthBarColorMid && this.model.healthBarColorLow) {
|
||||
return chroma.mix(this.model.healthBarColorLow, this.model.healthBarColorMid, fraction * 2).hex();
|
||||
} else if (this.model.healthBarColorMid) {
|
||||
return this.model.healthBarColorMid;
|
||||
}
|
||||
return this.color;
|
||||
},
|
||||
@@ -166,7 +144,7 @@ export default {
|
||||
isTextLight() {
|
||||
return isDarkColor(this.barBackgroundColor);
|
||||
/* Change color at the halfway mark
|
||||
const fraction = this.value / this.maxValue;
|
||||
const fraction = this.model.value / this.model.total;
|
||||
if (fraction >= 0.5){
|
||||
return isDarkColor(this.barColor);
|
||||
} else {
|
||||
@@ -176,8 +154,14 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
edit() {
|
||||
this.editing = true;
|
||||
edit(e) {
|
||||
e.preventDefault()
|
||||
this.editing = false;
|
||||
this.x = e.clientX - 165;
|
||||
this.y = e.clientY - 24;
|
||||
this.$nextTick(() => {
|
||||
this.editing = true
|
||||
});
|
||||
},
|
||||
cancelEdit() {
|
||||
this.editing = false;
|
||||
@@ -199,6 +183,10 @@ export default {
|
||||
z-index: 7;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.no-menu-shadow {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
<health-bar
|
||||
v-for="attribute in attributes"
|
||||
:key="attribute._id"
|
||||
:value="attribute.value"
|
||||
:max-value="attribute.total"
|
||||
:name="attribute.name"
|
||||
:color="attribute.color"
|
||||
:mid-color="attribute.healthBarColorMid"
|
||||
:low-color="attribute.healthBarColorLow"
|
||||
:_id="attribute._id"
|
||||
:model="attribute"
|
||||
@change="e => $emit('change', {_id: attribute._id, change: e})"
|
||||
@click="e => $emit('click', {_id: attribute._id})"
|
||||
/>
|
||||
|
||||
@@ -3,57 +3,26 @@
|
||||
class="resource-card"
|
||||
:class="hover ? 'elevation-8': ''"
|
||||
>
|
||||
<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="hover = true"
|
||||
@mouseleave="hover = false"
|
||||
>
|
||||
<div class="text-truncate ">
|
||||
{{ model.name }}
|
||||
</div>
|
||||
</div>
|
||||
</v-layout>
|
||||
<resource-card-content
|
||||
:model="model"
|
||||
:hover="hover"
|
||||
@mouseover="hover = true"
|
||||
@mouseleave="hover = false"
|
||||
@click="$emit('click')"
|
||||
@change="e => $emit('change', e)"
|
||||
/>
|
||||
<card-highlight :active="hover" />
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||
import ResourceCardContent from '/imports/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CardHighlight,
|
||||
ResourceCardContent,
|
||||
},
|
||||
inject: {
|
||||
context: { default: {} }
|
||||
@@ -69,46 +38,16 @@ export default {
|
||||
hover: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
click(e) {
|
||||
this.$emit('click', e);
|
||||
},
|
||||
increment(value) {
|
||||
this.$emit('change', { type: 'increment', value })
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
<style lang="css">
|
||||
.resource-card {
|
||||
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
|
||||
.resource-card>div {
|
||||
.resource-card > div {
|
||||
padding-top: 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>
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
dark: Boolean,
|
||||
hideCastButton: Boolean,
|
||||
disabled: Boolean,
|
||||
},
|
||||
computed: {
|
||||
|
||||
Reference in New Issue
Block a user