diff options
author | Rémy Raes <contact@remyraes.com> | 2023-01-14 01:18:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-14 01:18:48 +0100 |
commit | 20c3880721cd0f0bd0a2b48a1463b49c514a849b (patch) | |
tree | 8bdce436ad295ab550dda3b65f2515c83bec7965 /src-vue/src/views/ThunderstoreModsView.vue | |
parent | bcdab67ee1e0c34dbbf0e6c5d294b8a163ebeeff (diff) | |
download | FlightCore-20c3880721cd0f0bd0a2b48a1463b49c514a849b.tar.gz FlightCore-20c3880721cd0f0bd0a2b48a1463b49c514a849b.zip |
refactor: Mods view (#134)
* feat: add UI skeleton for new mods interface
* fix: only apply app menu style to app menu items
* feat: add menu skeleton
* feat: add thunderstore mods view into mods view
* refactor: remove thunderstore mods view from router + menu bar
* refactor: move search input into mods view
* fix: adjust ts mods container padding
* refactor: center pagination components
* refactor: rework media queries to adapt cards container width
* fix: set mods view navigation min-width
* refactor: compute mods container width with CSS variables
* refactor: remove horizontal padding around ts mods container
This will allow them to take much screen space.
* feat: Thunderstore mods container is larger
* feat: add layouts for 5 to 8 Thunderstore mod columns
* feat: add some space to separate navigation menu subparts
* fix: move search pagination reset in ThunderstoreModsView component
* feat: retrieve Thunderstore mod categories when fetching mods
* feat: add mod categories selector component
* feat: mod categories selector now filters Thunderstore mods
* fix: reset pagination index if needed when selecting mod categories
* fix: first mod does not appear anymore while selecting any mod category
First mod's categories array was used as an accumulator (in a reduce call)
to regroup all mod categories; we now use an empty array as initial value
for the accumulator.
* feat: add a selector component to sort mods
* feat: set sort selector default value on view mount
* fix: set default sorting select value as selected in dropdown list
* feat: add date_updated field to ThunderstoreMod type
* feat: pass sorting value to ThunderstoreModsView as a prop
* feat: mods can be sorted by name and release date
* feat: mods can be sorted by most downloaded and top rated
* fix: don't display sorting select on local mods view
* refactor: remove local mods title
* refactor: export local mods view code in dedicated component
* refactor: export search value in a search-dedicated store
* fix: display "no matching mods" message when no mods match
This message was previously displayed only if no mods matched AND search
input was not empty; now that we have categories selector, we can have no
matching mods with an empty input.
* refactor: remove unused input prop
* fix: mods can be sorted by rating
* refactor: remove unused searchValue computed property
* style: adjust SortOptions import
* refactor: move selected mod categories into search store module
* refactor: move mod sorting into search store module
* refactor: export mods menu component to dedicated file
* fix: remove compare method initialization
* feat: local mods can be filtered with search input
* build: add ES2018 lib to typescript compiler options
* refactor: remove unused variable
* fix: retrieve SortOptions values from string input
* refactor: move Thunderstore mods view into dedicated folder
* style: add missing trailing newline to SortOptions.d.ts
Diffstat (limited to 'src-vue/src/views/ThunderstoreModsView.vue')
-rw-r--r-- | src-vue/src/views/ThunderstoreModsView.vue | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/src-vue/src/views/ThunderstoreModsView.vue b/src-vue/src/views/ThunderstoreModsView.vue deleted file mode 100644 index 5733d30b..00000000 --- a/src-vue/src/views/ThunderstoreModsView.vue +++ /dev/null @@ -1,240 +0,0 @@ -<template> - <div class="fc-container"> - <div v-if="mods.length === 0" class="fc__changelog__container"> - <el-progress :show-text="false" :percentage="50" :indeterminate="true" /> - </div> - <el-scrollbar v-else class="container" ref="scrollbar"> - <div class="card-container"> - <!-- Search filters --> - <div class="filter_container"> - <el-input v-model="input" placeholder="Search" clearable @input="onFilterTextChange" /> - <!-- Message displayed when user is typing in search bar --> - <div v-if="userIsTyping" class="modMessage search"> - Searching mods... - </div> - - <!-- Pagination --> - <el-pagination - v-if="shouldDisplayPagination" - :currentPage="currentPageIndex + 1" - layout="prev, pager, next" - :page-size="modsPerPage" - :total="modsList.length" - @current-change="(e: number) => currentPageIndex = e - 1" - /> - </div> - - <!-- Message displayed if no mod matched searched words --> - <div v-if="filteredMods.length === 0 && input.length !== 0 && !userIsTyping" class="modMessage"> - No matching mod has been found.<br/> - Try another search! - </div> - - <!-- Mod cards --> - <thunderstore-mod-card v-for="mod of currentPageMods" v-bind:key="mod.name" :mod="mod" /> - </div> - - <!-- Bottom pagination --> - <div class="card-container"> - <div class="filter_container"> - <el-pagination - class="fc_bottom__pagination" - v-if="shouldDisplayPagination" - :currentPage="currentPageIndex + 1" - layout="prev, pager, next" - :page-size="modsPerPage" - :total="modsList.length" - @current-change="onBottomPaginationChange" - /> - </div> - </div> - </el-scrollbar> - </div> -</template> - -<script lang="ts"> -import { defineComponent, ref } from 'vue'; -import { ThunderstoreMod } from "../utils/thunderstore/ThunderstoreMod"; -import ThunderstoreModCard from "../components/ThunderstoreModCard.vue"; -import { ElScrollbar, ScrollbarInstance } from "element-plus"; - -export default defineComponent({ - name: "ThunderstoreModsView", - components: {ThunderstoreModCard}, - async mounted() { - this.$store.commit('fetchThunderstoreMods'); - }, - computed: { - mods(): ThunderstoreMod[] { - return this.$store.state.thunderstoreMods; - }, - filteredMods(): ThunderstoreMod[] { - if (this.searchValue.length === 0) { - return this.mods; - } - - return this.mods.filter((mod: ThunderstoreMod) => { - return mod.name.toLowerCase().includes(this.searchValue) - || mod.owner.toLowerCase().includes(this.searchValue) - || mod.versions[0].description.toLowerCase().includes(this.searchValue); - }); - }, - modsList(): ThunderstoreMod[] { - return this.input.length !== 0 || this.userIsTyping ? this.filteredMods : this.mods; - }, - modsPerPage(): number { - return parseInt(this.$store.state.mods_per_page); - }, - currentPageMods(): ThunderstoreMod[] { - // User might want to display all mods on one page. - const perPageValue = this.modsPerPage != 0 ? this.modsPerPage : this.modsList.length; - - const startIndex = this.currentPageIndex * perPageValue; - const endIndexCandidate = startIndex + perPageValue; - const endIndex = endIndexCandidate > this.modsList.length ? this.modsList.length : endIndexCandidate; - return this.modsList.slice(startIndex, endIndex); - }, - shouldDisplayPagination(): boolean { - return this.modsPerPage != 0 && this.modsList.length > this.modsPerPage; - } - }, - data() { - return { - // This is the model for the search input. - input: '', - // This is the treated value of search input - searchValue: '', - - modsBeingInstalled: [] as string[], - userIsTyping: false, - - currentPageIndex: 0 - }; - }, - methods: { - /** - * This method is called each time search input is modified, and - * triggered filtered mods recomputing by updating the `searchValue` - * variable. - * - * This converts research string and all researched fields to - * lower case, to match mods regardless of font case. - */ - onFilterTextChange(value: string) { - this.currentPageIndex = 0; - this.searchValue = value.toLowerCase(); - }, - - /** - * This updates current pagination and scrolls view to the top. - */ - onBottomPaginationChange(index: number) { - this.currentPageIndex = index - 1; - (this.$refs.scrollbar as ScrollbarInstance).scrollTo({ top: 0, behavior: 'smooth' }); - } - } -}); -</script> - -<style scoped> -.fc__changelog__container { - padding: 20px 30px; -} - -.el-timeline-item__timestamp { - color: white !important; - user-select: none !important; -} - -.search { - display: inline-block; - margin: 0 0 0 10px !important; -} - -.modMessage { - color: white; - margin: 20px 5px; -} - -.card-container { - margin: 0 auto; -} - -.fc_bottom__pagination { - padding-bottom: 20px !important; - padding-right: 10px; -} - -/* Card container dynamic size */ -@media (max-width: 1000px) { - .card-container { - width: 752px; - } -} - -@media (max-width: 812px) { - .card-container { - width: 574px; - } - - .el-pagination { - float: none; - margin-top: 5px; - } -} - -@media (max-width: 624px) { - .card-container { - width: 376px; - } -} - -.filter_container { - margin-bottom: 10px; -} - -.el-input { - max-width: 200px; -} - -@media (min-width: 812px) { - .filter_container { - margin: 5px auto; - padding: 0 5px; - max-width: 1000px; - } - - .el-pagination { - float: right; - margin: 0; - } -} - -@media (min-width: 1000px) { - .card-container { - width: 940px; - } - - .el-input { - max-width: 300px; - } -} - -@media (min-width: 1188px) { - .card-container { - width: 1128px; - } -} - -@media (min-width: 1376px) { - .card-container { - width: 1316px; - } -} - -@media (min-width: 1565px) { - .card-container { - width: 1505px; - } -} -</style> |