11<script setup lang="ts">
22import { computed , ref , watch } from " vue" ;
33import { storeToRefs } from " pinia" ;
4- import DataTable from " primevue/datatable" ;
4+ import DataTable , {
5+ type DataTableOperatorFilterMetaData ,
6+ } from " primevue/datatable" ;
57import Column from " primevue/column" ;
68import InputText from " primevue/inputtext" ;
79import ProgressSpinner from " primevue/progressspinner" ;
810import Calendar from " primevue/calendar" ;
11+ import TreeSelect from " primevue/treeselect" ;
12+ import type { TreeNode } from " primevue/tree" ;
913import { FilterMatchMode , FilterOperator } from " primevue/api" ;
1014import type { ContestDetails , ProblemSummary } from " luogu-api-docs/luogu-api" ;
1115import { useUserStore } from " @/stores/user" ;
@@ -56,7 +60,7 @@ const problemPrefixLength = computed(() =>
5660
5761const filters = ref ({
5862 global: { value: null , matchMode: FilterMatchMode .CONTAINS },
59- name: { value: null , matchMode: FilterMatchMode . CONTAINS },
63+ name: { operator: FilterOperator . OR , constraints: [] },
6064 startTime: {
6165 operator: FilterOperator .AND ,
6266 constraints: [
@@ -93,6 +97,36 @@ const problemIndexes = computed(() => [
9397 Math .max (... props .contests .map (({ problems }) => problems .length )),
9498 ).keys (),
9599]);
100+
101+ const nodes: TreeNode [] = [
102+ {
103+ key: " 【LGR" ,
104+ label: " 官方比赛" ,
105+ children: [
106+ { key: " Div.1】" , label: " Div.1" },
107+ { key: " Div.2】" , label: " Div.2" },
108+ { key: " Div.3】" , label: " Div.3" },
109+ { key: " Div.4】" , label: " Div.4" },
110+ ],
111+ },
112+ { key: " ICPC" , label: " ICPC" },
113+ ];
114+
115+ type TreeSelectModelValue = Record <
116+ string ,
117+ { checked: boolean ; partialChecked: boolean }
118+ >;
119+
120+ const selectedCategories = ref <TreeSelectModelValue >({});
121+
122+ function applySelectedCategories() {
123+ const f: DataTableOperatorFilterMetaData [" constraints" ] = [];
124+ Object .entries (selectedCategories .value ).forEach ((category ) => {
125+ if (category [1 ].checked )
126+ f .push ({ value: category [0 ], matchMode: FilterMatchMode .CONTAINS });
127+ });
128+ (filters .value .name as DataTableOperatorFilterMetaData ).constraints = f ;
129+ }
96130 </script >
97131
98132<template >
@@ -117,6 +151,13 @@ const problemIndexes = computed(() => [
117151 >
118152 <template #header >
119153 <div style =" display : flex ; flex-wrap : wrap-reverse " >
154+ <TreeSelect
155+ :options =" nodes"
156+ v-model =" selectedCategories"
157+ @hide =" applySelectedCategories"
158+ selectionMode =" checkbox"
159+ placeholder =" Select Item"
160+ />
120161 <span class =" p-input-icon-left" >
121162 <i class =" pi pi-search" />
122163 <InputText
@@ -177,13 +218,6 @@ const problemIndexes = computed(() => [
177218 <span style =" position : absolute ; inset : 0 " />
178219 </a >
179220 </template >
180- <template #filter =" { filterModel } " >
181- <InputText
182- v-model =" filterModel.value"
183- type =" text"
184- placeholder =" Search by name"
185- />
186- </template >
187221 </Column >
188222 <Column
189223 v-for =" i of problemIndexes"
0 commit comments