Files
lootalot/lootalot_front/src/components/Chest.vue

167 lines
5.2 KiB
Vue

<template>
<article>
<p class="control has-icons-left">
<input type="text" class="input" v-model="searchText">
<span class="icon is-small is-left"><i class="fas fa-search"></i></span>
</p>
<table class="table is-fullwidth is-striped">
<thead>
<tr>
<th width="100%">Objets</th>
<th>Valeur</th>
<th>
<div v-if="perms.canSell" class="buttons" :class="{'has-addons': is_selling}">
<button class="button"
:class="is_selling ? 'is-danger' : 'is-warning'"
@click="sellSelectedItems"
>
<span class="icon">
<i class="fas fa-coins"></i>
</span>
<p v-if="!is_selling">Vendre</p>
<p v-else>{{ selected_items.length > 0 ? `${totalSelectedValue} po` : 'Annuler' }}</p>
</button>
<PercentInput v-show="is_selling" v-model="global_mod"></PercentInput>
</div>
<div v-else-if="perms.canBuy">
<button class="button is-danger is-fullwidth"
:disabled="selected_items.length == 0"
@click="buySelectedItems"
>Acheter ({{ totalSelectedValue}}po)</button>
</div>
<div v-else-if="perms.canGrab">
<button class="button is-static is-fullwidth">Demander</button>
</div>
</th>
</tr>
</thead>
<tbody>
<template v-for="(item, idx) in shownItems">
<tr :key="`row-${idx}`">
<td>
<strong>{{item.name}}</strong>
</td>
<td>
{{ is_selling ? item.base_price / 2 : item.base_price }}po
</td>
<td>
<Request
v-if="perms.canGrab"
:id="player"
:claims="claims"
:item="item.id"
@claim="(data) => $emit('claim', data)"
@unclaim="(data) => $emit('unclaim', data)"
></Request>
<Selector
v-else-if="showSelectors"
:id="item.id"
v-model="selected_items"
></Selector>
</td>
</tr>
</template>
</tbody>
</table>
</article>
</template>
<script>
import Request from './Request.vue'
import PercentInput from './PercentInput.vue'
import Selector from './Selector.vue'
import { api } from '../lootalot.js'
/*
The chest displays a collection of items.
A set of permissions is passed as props, to update
the possible actions of active user upon these items.
*/
export default {
props: {
player: {
type: Number,
required: true,
},
items: {
type: Array,
required: true,
},
perms: {
type: Object,
required: true,
},
claims: {
type: Object,
required: true,
},
},
components: {
Request,
PercentInput,
Selector,
},
data () {
return {
is_selling: false,
selected_items: [],
global_mod: 0,
searchText: "",
};
},
methods: {
buySelectedItems () {
this.$emit("buy", this.selected_items);
this.selected_items = [];
},
sellSelectedItems () {
if (!this.is_selling) {
this.is_selling = true;
} else {
this.is_selling = false;
if (this.selected_items.length > 0) {
this.$emit("sell", this.selected_items);
this.selected_items = [];
}
}
},
},
computed: {
shownItems () {
if (this.searchText != "") {
const searchText = this.searchText.toUpperCase();
return this.items.filter(item => item.name.toUpperCase().includes(searchText));
} else {
return this.items;
}
},
showSelectors () {
return !this.perms.canGrab
&& (this.is_selling || this.perms.canBuy);
},
totalSelectedValue () {
var total = this.selected_items
.map(([id, mod]) => {
const item = this.items.find(item => item.id == id);
var price = item.base_price * mod;
if (this.is_selling) {
price = price / 2;
}
return price;
})
.reduce((total,value) => total + value, 0);
return (1 + this.global_mod / 100) * total;
},
},
}
</script>
<style scoped>
.table td, .table th { vertical-align: middle; }
.buttons { flex-wrap: nowrap; }
label.is-checkbox {
background-color: #eee;
}
</style>