Apply filters to nodes list.

This commit is contained in:
baldo 2022-06-12 14:10:00 +02:00
parent 5b703917b5
commit cce665d149
6 changed files with 96 additions and 77 deletions
frontend/src

View file

@ -1,37 +1,24 @@
<script setup lang="ts">
import {computed, defineProps} from "vue";
import type {NodesFilter} from "@/types";
const props = defineProps({
title: {
type: String,
required: true,
},
icon: {
type: String,
required: true,
},
variant: {
type: String,
required: true,
},
value: {
type: Number,
required: true,
},
link: {
type: String,
required: true,
},
filter: {
type: Object,
required: false,
},
});
interface Props {
title: string;
icon: string;
variant: string;
value: number;
link: string;
filter?: NodesFilter;
}
const props = defineProps<Props>();
const linkTarget = computed(() => {
if (props.filter) {
const json = JSON.stringify(props.filter);
return `${props.link}?search=${encodeURIComponent(json)}`;
return {
path: props.link,
query: props.filter,
}
} else {
return props.link;
}

View file

@ -1,7 +1,8 @@
import { createRouter, createWebHistory } from "vue-router";
import {createRouter, createWebHistory} from "vue-router";
import AdminDashboardView from "@/views/AdminDashboardView.vue";
import AdminNodesView from "@/views/AdminNodesView.vue";
import HomeView from "@/views/HomeView.vue";
import {isNodesFilter} from "@/types";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -20,6 +21,9 @@ const router = createRouter({
path: "/admin/nodes",
name: "admin-nodes",
component: AdminNodesView,
props: route => ({
filter: isNodesFilter(route.query) ? route.query : {}
})
},
],
});

View file

@ -1,5 +1,5 @@
import {defineStore} from "pinia";
import {isEnhancedNode, type EnhancedNode} from "@/types";
import {type EnhancedNode, isEnhancedNode, type NodesFilter} from "@/types";
import {internalApi} from "@/utils/Api";
interface NodesStoreState {
@ -37,12 +37,13 @@ export const useNodesStore = defineStore({
},
},
actions: {
async refresh(page: number, nodesPerPage: number): Promise<void> {
async refresh(page: number, nodesPerPage: number, filter: NodesFilter): Promise<void> {
const result = await internalApi.getPagedList<EnhancedNode>(
"nodes",
isEnhancedNode,
page,
nodesPerPage,
filter,
);
this.nodes = result.entries;
this.totalNodes = result.total;

View file

@ -1,5 +1,4 @@
import type {TypeGuard} from "@/types/shared";
import {toIsArray} from "@/types/shared";
import {toIsArray, type TypeGuard} from "@/types";
import type {Headers} from "request";
import {parseInteger} from "@/utils/Numbers";
@ -63,10 +62,12 @@ class Api {
isT: TypeGuard<T>,
page: number,
itemsPerPage: number,
filter?: object,
): Promise<PagedListResult<T>> {
const response = await this.doGet(path, toIsArray(isT), {
_page: page,
_perPage: itemsPerPage,
...filter,
});
const totalStr = response.headers.get("x-total-count");
const total = parseInteger(totalStr, 10);

View file

@ -1,12 +1,18 @@
<script setup lang="ts">
import {useNodesStore} from "@/stores/nodes";
import {onMounted, ref} from "vue";
import type {EnhancedNode, MAC} from "@/types";
import type {EnhancedNode, MAC, NodesFilter} from "@/types";
import Pager from "@/components/Pager.vue";
import LoadingContainer from "@/components/LoadingContainer.vue";
const NODE_PER_PAGE = 50;
interface Props {
filter: NodesFilter;
}
const props = defineProps<Props>();
type NodeRedactField = "nickname" | "email" | "token";
type NodeRedactFieldsMap = Partial<Record<NodeRedactField, boolean>>;
@ -21,7 +27,7 @@ async function refresh(page: number): Promise<void> {
loading.value = true;
redactAllFields(true);
try {
await nodes.refresh(page, NODE_PER_PAGE);
await nodes.refresh(page, NODE_PER_PAGE, props.filter);
} finally {
loading.value = false;
}