Add basic deck builder #12

Merged
hamcha merged 42 commits from feature/deckbuilder into master 2019-09-12 09:11:32 +00:00
5 changed files with 29 additions and 58 deletions
Showing only changes of commit 6dd2c4196e - Show all commits

View file

@ -2,7 +2,7 @@
<section class="cardpicker" :style="grid"> <section class="cardpicker" :style="grid">
<article <article
@click="() => _picked(card.data)" @click="() => _picked(card.data)"
class="ccgcard" :class="cardClass(card)"
v-for="(card, i) in cards" v-for="(card, i) in cards"
:key="i + card.data.ID" :key="i + card.data.ID"
> >
@ -17,9 +17,9 @@ $padding: 10px;
.cardpicker { .cardpicker {
height: 100%; height: 100%;
display: grid; display: grid;
grid-gap: $padding; gap: $padding;
padding: ($padding * 4) $padding; padding: ($padding * 4) $padding;
grid-row-gap: $padding * 4; row-gap: $padding * 4;
.ccgcard { .ccgcard {
display: flex; display: flex;
align-items: center; align-items: center;
@ -61,5 +61,12 @@ export default class CardPicker extends Vue {
private _picked(card: Card) { private _picked(card: Card) {
this.$emit("picked", card); this.$emit("picked", card);
} }
private cardClass(card: CardSlot) {
return {
ccgcard: true,
disabled: card.howmany >= card.limit
};
}
} }
</script> </script>

View file

@ -1,7 +1,7 @@
<template> <template>
<section class="decklist"> <section class="decklist">
<article <article
class="card" class="ccgcard"
@click="() => _drop(card)" @click="() => _drop(card)"
v-for="(card, i) in cards" v-for="(card, i) in cards"
:key="i" :key="i"
@ -25,7 +25,7 @@
flex-direction: column; flex-direction: column;
} }
.card { .ccgcard {
display: flex; display: flex;
align-content: space-between; align-content: space-between;
align-items: center; align-items: center;

View file

@ -16,7 +16,7 @@ describe("components/DeckBuilder/CardPicker", () => {
cards: testSlots cards: testSlots
} }
}); });
const cards = wrapper.findAll(".card"); const cards = wrapper.findAll(".ccgcard");
expect(cards.contains(".fullname")).toBe(true); expect(cards.contains(".fullname")).toBe(true);
for (let index = 0; index < testSlots.length; index++) { for (let index = 0; index < testSlots.length; index++) {
const item = cards.at(index); const item = cards.at(index);

View file

@ -4,36 +4,36 @@
<section class="filters"> <section class="filters">
<div class="row"> <div class="row">
<b-input <b-input
@input="nameChanged" @input="textChanged"
v-model="nameFilter" v-model="nameFilter"
placeholder="Search name" placeholder="Search name"
></b-input> ></b-input>
<div class="colorfilter" v-for="color in colors" :key="color"> <div class="colorfilter" v-for="color in colors" :key="color">
<img <img
@click="toggleElementFilter(color)" @click="toggleFilter(elementFilters, color)"
:class="elementIconClass(color)" :class="filterIconClass(elementFilters, color)"
:src="elementIconURL(color)" :src="elementIconURL(color)"
/> />
</div> </div>
<div class="divider" /> <div class="divider" />
<div class="typefilter" v-for="type in types" :key="type"> <div class="typefilter" v-for="type in types" :key="type">
<img <img
@click="toggleTypeFilter(type)" @click="toggleFilter(typeFilters, type)"
:class="typeIconClass(type)" :class="filterIconClass(typeFilters, type)"
:src="typeIconURL(type)" :src="typeIconURL(type)"
/> />
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<b-input <b-input
@input="ruleChanged" @input="textChanged"
v-model="ruleFilter" v-model="ruleFilter"
placeholder="Search rule text" placeholder="Search rule text"
></b-input> ></b-input>
<div class="setfilter" v-for="set in sets" :key="set"> <div class="setfilter" v-for="set in sets" :key="set">
<img <img
@click="toggleSetFilter(set)" @click="toggleFilter(setFilters, set)"
:class="setIconClass(set)" :class="filterIconClass(setFilters, set)"
:src="setIconURL(set)" :src="setIconURL(set)"
/> />
</div> </div>
@ -411,59 +411,23 @@ export default class DeckBuilder extends Vue {
return require(`../assets/images/cardtypes/${urltype}.webp`); return require(`../assets/images/cardtypes/${urltype}.webp`);
} }
private elementIconClass(element: string) { private filterIconClass(filter: string[], key: string) {
return { return {
selected: this.elementFilters.includes(element) selected: filter.includes(key)
}; };
} }
private setIconClass(set: string) { private toggleFilter(filter: string[], key: string) {
return { const idx = filter.indexOf(key);
selected: this.setFilters.includes(set)
};
}
private typeIconClass(type: string) {
return {
selected: this.typeFilters.includes(type)
};
}
private toggleElementFilter(element: string) {
const idx = this.elementFilters.indexOf(element);
if (idx >= 0) { if (idx >= 0) {
this.elementFilters.splice(idx, 1); filter.splice(idx, 1);
} else { } else {
this.elementFilters.push(element); filter.push(key);
} }
this.applyFilters(); this.applyFilters();
} }
private toggleSetFilter(set: string) { private textChanged() {
const idx = this.setFilters.indexOf(set);
if (idx >= 0) {
this.setFilters.splice(idx, 1);
} else {
this.setFilters.push(set);
}
this.applyFilters();
}
private toggleTypeFilter(set: string) {
const idx = this.typeFilters.indexOf(set);
if (idx >= 0) {
this.typeFilters.splice(idx, 1);
} else {
this.typeFilters.push(set);
}
this.applyFilters();
}
private nameChanged() {
this.applyFilters();
}
private ruleChanged() {
this.applyFilters(); this.applyFilters();
} }

View file

@ -16,7 +16,7 @@
.draftview { .draftview {
display: grid; display: grid;
height: 100vh; height: 100vh;
grid-gap: 10px; gap: 10px;
grid-template-columns: minmax(200px, 1fr) 3fr minmax(250px, 1fr); grid-template-columns: minmax(200px, 1fr) 3fr minmax(250px, 1fr);
section { section {
grid-row: 1; grid-row: 1;