|
4 | 4 | import { PUBLIC_APP_ASSETS, PUBLIC_ORIGIN } from "$env/static/public"; |
5 | 5 | import { isHuggingChat } from "$lib/utils/isHuggingChat"; |
6 | 6 |
|
| 7 | + import { tick } from "svelte"; |
7 | 8 | import { goto } from "$app/navigation"; |
8 | 9 | import { base } from "$app/paths"; |
9 | 10 | import { page } from "$app/stores"; |
|
14 | 15 | import CarbonArrowUpRight from "~icons/carbon/arrow-up-right"; |
15 | 16 | import CarbonEarthAmerica from "~icons/carbon/earth-americas-filled"; |
16 | 17 | import CarbonUserMultiple from "~icons/carbon/user-multiple"; |
| 18 | + import CarbonSearch from "~icons/carbon/search"; |
17 | 19 | import Pagination from "$lib/components/Pagination.svelte"; |
18 | 20 | import { formatUserCount } from "$lib/utils/formatUserCount"; |
19 | 21 | import { getHref } from "$lib/utils/getHref"; |
| 22 | + import { debounce } from "$lib/utils/debounce"; |
20 | 23 | import { useSettingsStore } from "$lib/stores/settings"; |
21 | 24 |
|
22 | 25 | export let data: PageData; |
23 | 26 |
|
24 | 27 | $: assistantsCreator = $page.url.searchParams.get("user"); |
25 | 28 | $: createdByMe = data.user?.username && data.user.username === assistantsCreator; |
26 | 29 |
|
| 30 | + const SEARCH_DEBOUNCE_DELAY = 400; |
| 31 | + let filterInputEl: HTMLInputElement; |
| 32 | + let searchDisabled = false; |
| 33 | +
|
27 | 34 | const onModelChange = (e: Event) => { |
28 | 35 | const newUrl = getHref($page.url, { |
29 | 36 | newKeys: { modelId: (e.target as HTMLSelectElement).value }, |
|
32 | 39 | goto(newUrl); |
33 | 40 | }; |
34 | 41 |
|
| 42 | + const filterOnName = debounce(async (e: Event) => { |
| 43 | + searchDisabled = true; |
| 44 | + const value = (e.target as HTMLInputElement).value; |
| 45 | + const newUrl = getHref($page.url, { newKeys: { q: value } }); |
| 46 | + await goto(newUrl); |
| 47 | + setTimeout(async () => { |
| 48 | + searchDisabled = false; |
| 49 | + await tick(); |
| 50 | + filterInputEl.focus(); |
| 51 | + }, 0); |
| 52 | + }, SEARCH_DEBOUNCE_DELAY); |
| 53 | +
|
35 | 54 | const settings = useSettingsStore(); |
36 | 55 | </script> |
37 | 56 |
|
|
99 | 118 | {assistantsCreator}'s Assistants |
100 | 119 | <a |
101 | 120 | href={getHref($page.url, { |
102 | | - existingKeys: { behaviour: "delete", keys: ["user", "modelId", "p"] }, |
| 121 | + existingKeys: { behaviour: "delete", keys: ["user", "modelId", "p", "q"] }, |
103 | 122 | })} |
104 | 123 | class="group" |
105 | 124 | ><CarbonClose |
|
119 | 138 | {:else} |
120 | 139 | <a |
121 | 140 | href={getHref($page.url, { |
122 | | - existingKeys: { behaviour: "delete", keys: ["user", "modelId", "p"] }, |
| 141 | + existingKeys: { behaviour: "delete", keys: ["user", "modelId", "p", "q"] }, |
123 | 142 | })} |
124 | 143 | class="flex items-center gap-1.5 rounded-full border px-3 py-1 {!assistantsCreator |
125 | 144 | ? 'border-gray-300 bg-gray-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white' |
|
132 | 151 | <a |
133 | 152 | href={getHref($page.url, { |
134 | 153 | newKeys: { user: data.user.username }, |
135 | | - existingKeys: { behaviour: "delete", keys: ["modelId", "p"] }, |
| 154 | + existingKeys: { behaviour: "delete", keys: ["modelId", "p", "q"] }, |
136 | 155 | })} |
137 | | - class="flex items-center gap-1.5 rounded-full border px-3 py-1 {assistantsCreator && |
| 156 | + class="flex items-center gap-1.5 truncate rounded-full border px-3 py-1 {assistantsCreator && |
138 | 157 | createdByMe |
139 | 158 | ? 'border-gray-300 bg-gray-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white' |
140 | 159 | : 'border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-300'}" |
141 | 160 | >{data.user.username} |
142 | 161 | </a> |
143 | 162 | {/if} |
144 | 163 | {/if} |
| 164 | + <div |
| 165 | + class="relative ml-auto flex hidden h-[30px] w-40 items-center rounded-full border px-2 has-[:focus]:border-gray-400 sm:w-64 dark:border-gray-600" |
| 166 | + > |
| 167 | + <CarbonSearch class="pointer-events-none absolute left-2 text-xs text-gray-400" /> |
| 168 | + <input |
| 169 | + class="h-[30px] w-full bg-transparent pl-5 focus:outline-none" |
| 170 | + placeholder="Filter by name" |
| 171 | + value={data.query} |
| 172 | + on:input={filterOnName} |
| 173 | + bind:this={filterInputEl} |
| 174 | + maxlength="150" |
| 175 | + type="search" |
| 176 | + disabled={searchDisabled} |
| 177 | + /> |
| 178 | + </div> |
145 | 179 | </div> |
146 | 180 |
|
147 | 181 | <div class="mt-8 grid grid-cols-2 gap-3 sm:gap-5 md:grid-cols-3 lg:grid-cols-4"> |
|
0 commit comments