Skip to content

Commit 1e6604c

Browse files
authored
Merge pull request #266 from traPtitech/feat/make_searchList_better
検索をいい感じに
2 parents 49d121f + 9baecaa commit 1e6604c

File tree

6 files changed

+36
-13
lines changed

6 files changed

+36
-13
lines changed

src/components/Contest/ContestTeams.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface Props {
1515
const props = defineProps<Props>()
1616
const searchQuery = ref('')
1717
const filteredContestTeams = computed(() =>
18-
searchListCaseInsensitive(props.contestTeams, searchQuery.value, 'name')
18+
searchListCaseInsensitive(props.contestTeams, searchQuery.value, v => v.name)
1919
)
2020
</script>
2121

src/components/UI/MemberInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const limit = ref(10)
2222
const search = ref('')
2323
2424
const filtered = computed(() =>
25-
searchListCaseInsensitive(props.users, search.value, 'name')
25+
searchListCaseInsensitive(props.users, search.value, v => v.name)
2626
)
2727
const options = computed(() => filtered.value.slice(0, limit.value))
2828
const hasNextPage = computed(() => filtered.value.length > options.value.length)

src/lib/search.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1-
export const searchListCaseInsensitive = <
2-
K extends string,
3-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Index signature for type 'string' is missing in type を回避
4-
T extends Record<K, string> & Record<PropertyKey, any>
5-
>(
6-
list: T[],
1+
// https://github.com/traPtitech/traQ_S-UI/blob/983c6f89f3246509011f8ca4d76e2ba24e0beb2b/src/lib/basic/array.ts
2+
3+
/**
4+
* 一致するキーの一覧を返す
5+
* priorityが0のとき完全一致
6+
* 1のとき前方一致
7+
* 2のとき部分一致
8+
*
9+
* @param arr 検索対象のキーの配列
10+
* @param query lowercaseになっているクエリ
11+
* @param f キーから検索対象の文字列を取得する関数
12+
*/
13+
export const searchListCaseInsensitive = <T>(
14+
arr: readonly T[],
715
_query: string,
8-
key: K
16+
f: (v: T) => string
917
): T[] => {
1018
const query = _query.toLowerCase()
11-
return list.filter(item => item[key].toLowerCase().includes(query))
19+
const result: Array<{ value: T; priority: number }> = []
20+
21+
for (const val of arr) {
22+
const valLower = f(val).toLowerCase()
23+
if (valLower === query) {
24+
result.push({ value: val, priority: 0 })
25+
} else if (valLower.startsWith(query)) {
26+
result.push({ value: val, priority: 1 })
27+
} else if (valLower.includes(query)) {
28+
result.push({ value: val, priority: 2 })
29+
}
30+
}
31+
32+
return result
33+
.toSorted((a, b) => a.priority - b.priority)
34+
.map(({ value }) => value)
1235
}

src/pages/Contests.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const contests = await contestStore.fetchContests()
1515
1616
const searchQuery = ref('')
1717
const filteredContests = computed(() =>
18-
searchListCaseInsensitive(contests, searchQuery.value, 'name')
18+
searchListCaseInsensitive(contests, searchQuery.value, v => v.name)
1919
)
2020
</script>
2121

src/pages/Events.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const filteredEventsBySearch = computed(() =>
3232
searchListCaseInsensitive(
3333
filteredEventsByLevel.value,
3434
searchQuery.value,
35-
'name'
35+
v => v.name
3636
)
3737
)
3838
</script>

src/pages/Projects.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const projects = await projectStore.fetchProjects()
1515
1616
const searchQuery = ref('')
1717
const filteredProjects = computed(() =>
18-
searchListCaseInsensitive(projects, searchQuery.value, 'name')
18+
searchListCaseInsensitive(projects, searchQuery.value, v => v.name)
1919
)
2020
</script>
2121

0 commit comments

Comments
 (0)