Skip to content

Commit

Permalink
Merge pull request #266 from traPtitech/feat/make_searchList_better
Browse files Browse the repository at this point in the history
検索をいい感じに
  • Loading branch information
Pugma authored Oct 28, 2024
2 parents 49d121f + 9baecaa commit 1e6604c
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/components/Contest/ContestTeams.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface Props {
const props = defineProps<Props>()
const searchQuery = ref('')
const filteredContestTeams = computed(() =>
searchListCaseInsensitive(props.contestTeams, searchQuery.value, 'name')
searchListCaseInsensitive(props.contestTeams, searchQuery.value, v => v.name)
)
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/components/UI/MemberInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const limit = ref(10)
const search = ref('')
const filtered = computed(() =>
searchListCaseInsensitive(props.users, search.value, 'name')
searchListCaseInsensitive(props.users, search.value, v => v.name)
)
const options = computed(() => filtered.value.slice(0, limit.value))
const hasNextPage = computed(() => filtered.value.length > options.value.length)
Expand Down
39 changes: 31 additions & 8 deletions src/lib/search.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
export const searchListCaseInsensitive = <
K extends string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Index signature for type 'string' is missing in type を回避
T extends Record<K, string> & Record<PropertyKey, any>
>(
list: T[],
// https://github.com/traPtitech/traQ_S-UI/blob/983c6f89f3246509011f8ca4d76e2ba24e0beb2b/src/lib/basic/array.ts

/**
* 一致するキーの一覧を返す
* priorityが0のとき完全一致
* 1のとき前方一致
* 2のとき部分一致
*
* @param arr 検索対象のキーの配列
* @param query lowercaseになっているクエリ
* @param f キーから検索対象の文字列を取得する関数
*/
export const searchListCaseInsensitive = <T>(
arr: readonly T[],
_query: string,
key: K
f: (v: T) => string
): T[] => {
const query = _query.toLowerCase()
return list.filter(item => item[key].toLowerCase().includes(query))
const result: Array<{ value: T; priority: number }> = []

for (const val of arr) {
const valLower = f(val).toLowerCase()
if (valLower === query) {
result.push({ value: val, priority: 0 })
} else if (valLower.startsWith(query)) {
result.push({ value: val, priority: 1 })
} else if (valLower.includes(query)) {
result.push({ value: val, priority: 2 })
}
}

return result
.toSorted((a, b) => a.priority - b.priority)
.map(({ value }) => value)
}
2 changes: 1 addition & 1 deletion src/pages/Contests.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const contests = await contestStore.fetchContests()
const searchQuery = ref('')
const filteredContests = computed(() =>
searchListCaseInsensitive(contests, searchQuery.value, 'name')
searchListCaseInsensitive(contests, searchQuery.value, v => v.name)
)
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/pages/Events.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const filteredEventsBySearch = computed(() =>
searchListCaseInsensitive(
filteredEventsByLevel.value,
searchQuery.value,
'name'
v => v.name
)
)
</script>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Projects.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const projects = await projectStore.fetchProjects()
const searchQuery = ref('')
const filteredProjects = computed(() =>
searchListCaseInsensitive(projects, searchQuery.value, 'name')
searchListCaseInsensitive(projects, searchQuery.value, v => v.name)
)
</script>

Expand Down

0 comments on commit 1e6604c

Please sign in to comment.