@@ -10,47 +10,47 @@ import Course from '../components/Course.vue'
1010import Wrapper from ' ../components/Wrapper.vue'
1111import PanelWrapper from ' ../components/PanelWrapper.vue'
1212import LabelSwitch from ' ../components/LabelSwitch.vue'
13+ import Fuse from ' fuse.js'
14+ import { courseFuseOptions , flattenCourseData , fuzzyQuery } from ' ../utils/fuzz.js'
1315import { useRouter , useRoute } from ' vue-router'
1416const router = useRouter ()
1517const route = useRoute ()
1618log (' web/course' )
1719
18- let loading = $ref (true ), list = $ref (null ), hideList = $ref ({}), showSub = $ref ({}), subjects = $ref ([] )
19- let quarters = $ref ([]), focus = $ref (' ' )
20+ let loading = $ref (true ), list = $ref (null ), showCourses = $ref ({})
21+ let quarters = $ref ([]), focus = $ref (' ' ), flatCourses = [], fuse = null
2022const query = reactive ({
2123 search: ' ' , college: ' ' , GE : {}
2224})
2325const showFocus = $computed (() => Object .keys (state .course .focus ).filter (x => state .course .focus [x]).length )
2426
25- function isHide (k , v , key , ges ) {
26- const genames = v[1 ].split (' ,' )
27- for (const g of ges) {
28- if (! genames .includes (g)) return true
29- }
30- if (! k .includes (key) && ! v[0 ].includes (key)) return true
31- }
32-
3327const computeResult = debounce (() => {
34- hideList = {}
35- showSub = {}
3628 const key = query .search .replaceAll (' ' , ' ' ).toUpperCase ()
3729 const ges = Object .keys (query .GE ).filter (x => query .GE [x]).map (x => query .college + ' -' + x)
38- for (const sub in list) {
39- let hasOne = false
40- for (const k in list[sub]) {
41- hideList[k] = isHide (k, list[sub][k], key, ges)
42- if (! hideList[k]) hasOne = true
30+ const res = fuzzyQuery (key, fuse, flatCourses)
31+ showCourses = res .reduce ((acc , course ) => {
32+ const key = course .subject
33+ if (ges .length == 0 ) {
34+ if (! acc[key]) acc[key] = []
35+ acc[key].push (course)
36+ return acc
4337 }
44- if (hasOne) showSub[sub] = 0
45- }
46- if (Object .keys (showSub).length === 1 ) showSub[Object .keys (showSub)[0 ]] = 1
38+ for (const ge of ges) {
39+ if (list[key][course .id ][1 ].includes (ge)) {
40+ if (! acc[key]) acc[key] = []
41+ acc[key].push (course)
42+ }
43+ }
44+ return acc
45+ }, {})
4746})
4847watch (query, computeResult)
4948
5049async function fetchList () {
5150 loading = true
5251 list = await get (' cache/course.' + state .course .quarter ).then (data => JSON .parse (data .data ))
53- subjects = Object .keys (list).sort ()
52+ flatCourses = flattenCourseData (list)
53+ fuse = fuse ? (fuse .setCollection (flatCourses), fuse) : new Fuse (flatCourses, courseFuseOptions)
5454 computeResult ()
5555 loading = false
5656}
@@ -131,12 +131,12 @@ watch(() => route.query.quarter, v => {
131131 </div >
132132 <div class =" flex items-start" v-if =" !loading" >
133133 <div class =" w-full md:w-80 md:mr-6 shadow-md" style =" min-width : 20rem ;" ><!-- course list -->
134- <template v-for =" sub in subjects " ><!-- subject -->
135- <PanelWrapper v-if = " showSub [ sub ] > - 1 " :title =" sub + ' : ' + lookup .subjects [sub ] " v-model = " showSub [ sub ]" >
136- <template v-for =" ( v , k ) in list [ sub ] " >
134+ <template v-for =" ( courses , subject ) in showCourses " ><!-- subject -->
135+ <PanelWrapper :title =" subject + ' : ' + lookup .subjects [subject ]" >
136+ <template v-for =" course in courses " >
137137 <!-- course -->
138- <div class =" bg-white border p-2 cursor-pointer" v-if = " !hideList[k] " @click =" focus = k " >
139- <h3 class =" pl-2" >{{ k }}: {{ v[0] }}</h3 >
138+ <div class =" bg-white border p-2 cursor-pointer" @click =" focus = course.id " >
139+ <h3 class =" pl-2" >{{ course.id }}: {{ course.name }}</h3 >
140140 </div >
141141 </template >
142142 </PanelWrapper >
0 commit comments