gamebrary/src/components/Lists/AddGameModal.vue

158 lines
3.4 KiB
Vue
Raw Normal View History

2018-10-19 05:15:28 +00:00
<template lang="html">
2020-07-22 15:15:31 +00:00
<div class="add-game-modal">
<b-button
2020-08-11 23:39:11 +00:00
block
variant="light"
2020-08-21 06:12:51 +00:00
v-b-modal="`game-modal-${list.name}`"
:title="$t('list.addGames', { listName: list.name })"
2019-11-21 22:19:49 +00:00
>
2020-08-11 23:39:11 +00:00
<b-icon-plus />
</b-button>
2019-11-08 20:34:06 +00:00
2020-07-22 15:15:31 +00:00
<b-modal
2020-08-21 06:12:51 +00:00
:id="`game-modal-${list.name}`"
:title="$t('list.addGames', { listName: list.name })"
2020-08-15 00:02:34 +00:00
footer-class="p-2 justify-content-center"
2020-07-22 15:15:31 +00:00
@show="clear"
>
2019-11-08 20:34:06 +00:00
2020-08-21 06:12:51 +00:00
<b-form @submit.prevent="search" class="mb-2">
<b-input-group>
<b-form-input
v-model="searchText"
autofocus
debounce="500"
:placeholder="$t('gameSearch.inputPlaceholder')"
/>
<b-input-group-append>
<b-button variant="primary" @click="search">
<b-spinner v-if="loading" small label="Loading..." />
<b-icon-search v-else />
</b-button>
</b-input-group-append>
</b-input-group>
<b-form-text v-if="gamesInList.length">
<strong>{{ gamesInList.length }}</strong>
{{ $t('gameSearch.alreadyInList') }}
</b-form-text>
</b-form>
<b-card
2019-11-08 20:34:06 +00:00
v-if="filteredResults.length > 0"
ref="searchResults"
2020-08-21 06:12:51 +00:00
body-class="p-1 pb-0 search-results"
bg-variant="light"
2019-11-21 22:19:49 +00:00
>
2019-11-08 20:34:06 +00:00
<game-card-search
v-for="{ id } in filteredResults"
:key="id"
:game-id="id"
2020-08-21 06:12:51 +00:00
:list="list"
2019-11-08 20:34:06 +00:00
/>
2020-08-21 06:12:51 +00:00
</b-card>
2019-11-08 20:34:06 +00:00
2020-08-21 06:12:51 +00:00
<b-alert :show="noResults" variant="warning" class="mt-2 mb-0">
2019-11-08 20:34:06 +00:00
{{ $t('gameSearch.noResultsFound') }}
2020-08-21 06:12:51 +00:00
</b-alert>
2020-08-15 00:02:34 +00:00
<template v-slot:modal-footer>
<igdb-logo />
</template>
2020-07-22 15:15:31 +00:00
</b-modal>
</div>
2018-10-19 05:15:28 +00:00
</template>
<script>
import GameCardSearch from '@/components/GameCards/GameCardSearch';
2020-08-15 00:02:34 +00:00
import IgdbLogo from '@/components/IgdbLogo';
2019-10-09 16:30:07 +00:00
import { mapState } from 'vuex';
2018-10-19 05:15:28 +00:00
export default {
2019-11-08 19:56:03 +00:00
components: {
GameCardSearch,
2020-08-15 00:02:34 +00:00
IgdbLogo,
2019-11-08 19:56:03 +00:00
},
props: {
2020-08-21 06:12:51 +00:00
list: {
type: Object,
2019-11-08 19:56:03 +00:00
required: true,
2018-10-19 05:15:28 +00:00
},
2019-11-08 19:56:03 +00:00
},
2018-10-19 05:15:28 +00:00
2019-11-08 19:56:03 +00:00
data() {
return {
searchText: '',
loading: false,
};
},
computed: {
2020-08-21 06:12:51 +00:00
...mapState(['results']),
2019-11-08 19:56:03 +00:00
noResults() {
2019-11-21 22:19:49 +00:00
return !this.loading
&& this.filteredResults.length === 0
2019-11-08 20:34:06 +00:00
&& this.searchText.trim().length > 0;
2018-10-19 05:15:28 +00:00
},
2019-11-08 19:56:03 +00:00
filteredResults() {
return this.results
2020-08-21 06:12:51 +00:00
? this.results.filter(({ id }) => !this.list.games.includes(id))
2019-11-08 19:56:03 +00:00
: [];
},
2019-10-01 03:50:36 +00:00
2019-11-08 19:56:03 +00:00
gamesInList() {
return this.results
2020-08-21 06:12:51 +00:00
? this.results.filter(({ id }) => this.list.games.includes(id))
2019-11-08 19:56:03 +00:00
: [];
2018-10-19 05:15:28 +00:00
},
2019-11-08 19:56:03 +00:00
},
watch: {
searchText(value) {
if (value) {
2019-11-21 22:19:49 +00:00
this.loading = true;
2019-11-08 19:56:03 +00:00
this.search();
}
2018-10-19 05:15:28 +00:00
},
2019-11-08 19:56:03 +00:00
},
methods: {
clear() {
this.searchText = '';
this.$store.commit('CLEAR_SEARCH_RESULTS');
},
2018-10-19 05:15:28 +00:00
async search() {
2020-08-21 06:12:51 +00:00
await this.$store.dispatch('SEARCH_GAMES', this.searchText)
.catch(() => {
2020-08-21 06:49:49 +00:00
// TODO toast error
this.loading = false;
});
this.error = null;
this.loading = false;
if (this.$refs.searchResults) {
this.$refs.searchResults.scrollTop = 0;
}
},
2019-11-08 19:56:03 +00:00
},
2018-10-19 05:15:28 +00:00
};
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
2020-01-22 18:09:16 +00:00
.search-results {
2020-08-21 06:12:51 +00:00
max-height: calc(100vh - 400px);
2020-01-22 18:09:16 +00:00
overflow-y: auto;
display: grid;
2020-07-22 20:44:48 +00:00
@media(max-width: 780px) {
2020-01-22 18:09:16 +00:00
max-height: calc(100vh - 200px);
2018-11-24 20:50:27 +00:00
}
2019-11-08 20:34:06 +00:00
}
2018-10-19 05:15:28 +00:00
</style>