|
48 | 48 | } |
49 | 49 |
|
50 | 50 | // Close dropdowns when clicking outside |
51 | | - const handleClickOutside = (event: MouseEvent) => { |
| 51 | + const handleClickOutside = (event: Event) => { |
52 | 52 | const target = event.target as HTMLElement; |
53 | | - if (!target.closest('.custom-dropdown')) { |
| 53 | + const dropdown = target.closest('.custom-dropdown'); |
| 54 | + if (!dropdown) { |
54 | 55 | viewModeOpen = false; |
55 | 56 | filterOpen = false; |
56 | 57 | } |
57 | 58 | }; |
58 | | - document.addEventListener('click', handleClickOutside); |
| 59 | + |
| 60 | + // Use mousedown instead of click for better responsiveness |
| 61 | + document.addEventListener('mousedown', handleClickOutside); |
59 | 62 | |
60 | 63 | return () => { |
61 | | - document.removeEventListener('click', handleClickOutside); |
| 64 | + document.removeEventListener('mousedown', handleClickOutside); |
62 | 65 | }; |
63 | 66 | }); |
64 | 67 |
|
|
68 | 71 | } |
69 | 72 |
|
70 | 73 | $: { |
71 | | - // Apply filters |
| 74 | + // Apply filters - ensure we start with full data when switching views |
72 | 75 | let tempProviders = providers; |
73 | | - let tempEndpoints = endpointColumns; |
| 76 | + let tempEndpoints = endpointColumns.length > 0 ? [...endpointColumns] : []; |
74 | 77 |
|
75 | 78 | // Apply search query |
76 | 79 | if (searchQuery.trim() !== "") { |
|
101 | 104 | filteredEndpoints = tempEndpoints; |
102 | 105 | } |
103 | 106 |
|
104 | | - // Initialize filtered endpoints when endpoint columns are ready |
105 | | - $: if (endpointColumns.length > 0 && filteredEndpoints.length === 0) { |
106 | | - filteredEndpoints = endpointColumns; |
107 | | - } |
108 | | -
|
109 | 107 | function formatEndpointName(endpoint: string): string { |
110 | 108 | // Convert snake_case to /path format |
111 | 109 | const formatted = endpoint.replace(/_/g, "/"); |
|
160 | 158 |
|
161 | 159 | <!-- View Mode Dropdown --> |
162 | 160 | <div class="custom-dropdown"> |
163 | | - <button class="dropdown-trigger" on:click|stopPropagation={() => viewModeOpen = !viewModeOpen} type="button"> |
| 161 | + <button class="dropdown-trigger" on:click={() => viewModeOpen = !viewModeOpen} type="button"> |
164 | 162 | <span>{viewMode === "provider" ? "View by Provider" : "View by Endpoint"}</span> |
165 | 163 | <svg width="12" height="12" viewBox="0 0 12 12" fill="none"> |
166 | 164 | <path d="M2 4L6 8L10 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> |
167 | 165 | </svg> |
168 | 166 | </button> |
169 | 167 | {#if viewModeOpen} |
170 | | - <div class="dropdown-menu" transition:fly={{ y: -10, duration: 150 }}> |
171 | | - <button class="dropdown-option" class:selected={viewMode === "provider"} on:click|stopPropagation={() => { viewMode = "provider"; viewModeOpen = false; }} type="button"> |
| 168 | + <div class="dropdown-menu"> |
| 169 | + <button |
| 170 | + class="dropdown-option" |
| 171 | + class:selected={viewMode === "provider"} |
| 172 | + on:click={() => { |
| 173 | + viewMode = "provider"; |
| 174 | + viewModeOpen = false; |
| 175 | + }} |
| 176 | + type="button" |
| 177 | + > |
172 | 178 | View by Provider |
173 | 179 | </button> |
174 | | - <button class="dropdown-option" class:selected={viewMode === "endpoint"} on:click|stopPropagation={() => { viewMode = "endpoint"; viewModeOpen = false; }} type="button"> |
| 180 | + <button |
| 181 | + class="dropdown-option" |
| 182 | + class:selected={viewMode === "endpoint"} |
| 183 | + on:click={() => { |
| 184 | + viewMode = "endpoint"; |
| 185 | + viewModeOpen = false; |
| 186 | + }} |
| 187 | + type="button" |
| 188 | + > |
175 | 189 | View by Endpoint |
176 | 190 | </button> |
177 | 191 | </div> |
|
180 | 194 |
|
181 | 195 | <!-- Filter Dropdown --> |
182 | 196 | <div class="custom-dropdown"> |
183 | | - <button class="dropdown-trigger" on:click|stopPropagation={() => filterOpen = !filterOpen} type="button"> |
| 197 | + <button class="dropdown-trigger" on:click={() => filterOpen = !filterOpen} type="button"> |
184 | 198 | <span>{selectedFilter ? (viewMode === "provider" ? providers.find(p => p.provider === selectedFilter)?.display_name.replace(/\s*\(.*?\)\s*$/, '') : formatEndpointName(selectedFilter)) : `All ${viewMode === "provider" ? "Providers" : "Endpoints"}`}</span> |
185 | 199 | <svg width="12" height="12" viewBox="0 0 12 12" fill="none"> |
186 | 200 | <path d="M2 4L6 8L10 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> |
187 | 201 | </svg> |
188 | 202 | </button> |
189 | 203 | {#if filterOpen} |
190 | | - <div class="dropdown-menu scrollable" transition:fly={{ y: -10, duration: 150 }}> |
191 | | - <button class="dropdown-option" class:selected={!selectedFilter} on:click|stopPropagation={() => { selectedFilter = ""; filterOpen = false; }} type="button"> |
| 204 | + <div class="dropdown-menu scrollable"> |
| 205 | + <button class="dropdown-option" class:selected={!selectedFilter} on:click={() => { selectedFilter = ""; filterOpen = false; }} type="button"> |
192 | 206 | All {viewMode === "provider" ? "Providers" : "Endpoints"} |
193 | 207 | </button> |
194 | 208 | {#if viewMode === "provider"} |
195 | 209 | {#each providers as { provider, display_name }} |
196 | | - <button class="dropdown-option" class:selected={selectedFilter === provider} on:click|stopPropagation={() => { selectedFilter = provider; filterOpen = false; }} type="button"> |
| 210 | + <button class="dropdown-option" class:selected={selectedFilter === provider} on:click={() => { selectedFilter = provider; filterOpen = false; }} type="button"> |
197 | 211 | {display_name.replace(/\s*\(.*?\)\s*$/, '')} |
198 | 212 | </button> |
199 | 213 | {/each} |
200 | 214 | {:else} |
201 | 215 | {#each endpointColumns as endpoint} |
202 | | - <button class="dropdown-option" class:selected={selectedFilter === endpoint} on:click|stopPropagation={() => { selectedFilter = endpoint; filterOpen = false; }} type="button"> |
| 216 | + <button class="dropdown-option" class:selected={selectedFilter === endpoint} on:click={() => { selectedFilter = endpoint; filterOpen = false; }} type="button"> |
203 | 217 | {formatEndpointName(endpoint)} |
204 | 218 | </button> |
205 | 219 | {/each} |
|
0 commit comments