Add sorting by column and fix page reload issue.

This commit is contained in:
baldo 2022-06-27 13:51:01 +02:00
parent ed29b96d45
commit 6057ad5a2a
5 changed files with 228 additions and 53 deletions
frontend/src/components

View file

@ -7,12 +7,14 @@ import {
NODES_FILTER_FIELDS,
type NodesFilter,
OnlineState,
type SearchTerm,
type UnixTimestampMilliseconds,
} from "@/types";
import {computed, nextTick, onMounted, ref, watch} from "vue";
import {useConfigStore} from "@/stores/config";
interface Props {
searchTerm: SearchTerm;
filter: NodesFilter;
}
@ -41,7 +43,7 @@ const FILTER_LABELS: Record<string, string | Map<any, any>> = {
}
const emit = defineEmits<{
(e: "updateFilter", filter: NodesFilter, searchTerm?: string): void,
(e: "updateFilter", filter: NodesFilter, searchTerm: SearchTerm): void,
}>();
const props = defineProps<Props>();
@ -204,15 +206,12 @@ function buildNodesFilter(): NodesFilter {
let lastSearchTimestamp: UnixTimestampMilliseconds = 0 as UnixTimestampMilliseconds;
let searchTimeout: NodeJS.Timeout | undefined = undefined;
let lastSearchTerm = "";
let lastSearchTerm: SearchTerm = "" as SearchTerm;
function doSearch(): void {
const nodesFilter = buildNodesFilter();
lastSearchTerm = input.value.value;
let searchTerm: string | undefined = lastSearchTerm.trim();
if (!searchTerm) {
searchTerm = undefined;
}
lastSearchTerm = input.value.value as SearchTerm;
const searchTerm: SearchTerm = lastSearchTerm.trim() as SearchTerm;
emit("updateFilter", nodesFilter, searchTerm);
}
@ -258,6 +257,7 @@ function doThrottledSearch(): void {
@keyup="doThrottledSearch()"
maxlength="64"
type="search"
:value="searchTerm"
placeholder="Knoten durchsuchen..."/>
<i class="fa fa-search search" @click="doSearch()"/>
</div>

View file

@ -0,0 +1,67 @@
<script lang="ts">
import {type Component, defineComponent, type PropType} from "vue";
import {type EnumValue, SortDirection} from "@/types";
type Props<SortField> = {
field: PropType<EnumValue<SortField>>,
currentField: PropType<EnumValue<SortField>>,
currentDirection: PropType<SortDirection>,
};
type SortTH<SortField> = Component<Props<SortField>>;
function defineGenericComponent<SortField>(): SortTH<SortField> {
const props: Props<SortField> = {
field: null as unknown as PropType<EnumValue<SortField>>,
currentField: null as unknown as PropType<EnumValue<SortField>>,
currentDirection: null as unknown as PropType<SortDirection>,
};
return defineComponent({
name: "SortTH",
props,
computed: {
sortDirection: function () {
return this.field === this.currentField ? this.currentDirection : undefined;
},
isAscending: function () {
return this.sortDirection === SortDirection.ASCENDING;
},
},
emits: {
sort: (field: SortField, direction: SortDirection) => true,
},
methods: {
onClick(): void {
this.$emit(
'sort',
this.field,
this.isAscending ? SortDirection.DESCENDING : SortDirection.ASCENDING
);
}
},
});
}
const component = defineGenericComponent<unknown>();
export function SortTH<SortField>(): SortTH<SortField> {
return component as SortTH<SortField>;
}
// noinspection JSUnusedGlobalSymbols
export default component;
</script>
<template>
<th>
<a href="javascript:" title="Sortieren" @click="onClick">
<slot/>
<i v-if="sortDirection && isAscending" class="fa fa-chevron-down" />
<i v-if="sortDirection && !isAscending" class="fa fa-chevron-up" />
</a>
</th>
</template>
<style lang="scss" scoped>
@import "../../scss/variables";
</style>