From 20c3880721cd0f0bd0a2b48a1463b49c514a849b Mon Sep 17 00:00:00 2001
From: Rémy Raes <contact@remyraes.com>
Date: Sat, 14 Jan 2023 01:18:48 +0100
Subject: 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
---
 src-vue/src/views/ThunderstoreModsView.vue | 240 -----------------------------
 1 file changed, 240 deletions(-)
 delete mode 100644 src-vue/src/views/ThunderstoreModsView.vue

(limited to 'src-vue/src/views/ThunderstoreModsView.vue')

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>
-- 
cgit v1.2.3

