|
162 | 162 | margin-left: 10px; |
163 | 163 | } |
164 | 164 |
|
| 165 | + .speaker-name-link { |
| 166 | + cursor: pointer; |
| 167 | + text-decoration: underline; |
| 168 | + color: var(--link-fg, #417690); |
| 169 | + } |
| 170 | + |
| 171 | + .speaker-name-link:hover { |
| 172 | + color: var(--link-hover-color, #036); |
| 173 | + } |
| 174 | + |
| 175 | + .clear-filter-btn { |
| 176 | + background: none; |
| 177 | + border: 1px solid #ccc; |
| 178 | + border-radius: 3px; |
| 179 | + cursor: pointer; |
| 180 | + padding: 2px 8px; |
| 181 | + font-size: 12px; |
| 182 | + color: #666; |
| 183 | + margin-left: 6px; |
| 184 | + vertical-align: middle; |
| 185 | + } |
| 186 | + |
| 187 | + .clear-filter-btn:hover { |
| 188 | + background-color: #eee; |
| 189 | + border-color: #999; |
| 190 | + color: #333; |
| 191 | + } |
| 192 | + |
165 | 193 | tr:nth-of-type(odd) { |
166 | 194 | background-color: var(--body-bg); |
167 | 195 | } |
|
261 | 289 | const filterWithReviewsSelect = document.querySelector('#filter-with-n-reviews'); |
262 | 290 | const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')]; |
263 | 291 | const filterByTypeInputs = [...document.querySelectorAll('input[name="filter-by-type"]')]; |
| 292 | + const filterBySpeakerInput = document.querySelector('#filter-by-speaker'); |
264 | 293 |
|
265 | 294 | const applyFilters = () => { |
266 | 295 | const reviewFilterValue = filterWithReviewsSelect.value; |
267 | 296 | const visibleStatuses = filterByStatusInputs.filter(input => input.checked).map(input => input.value); |
268 | 297 | const visibleTypes = filterByTypeInputs.filter(input => input.checked).map(input => input.value); |
| 298 | + const speakerFilter = filterBySpeakerInput.value.toLowerCase().trim(); |
269 | 299 |
|
270 | 300 | document.querySelectorAll('.proposal-item').forEach(proposalRow => { |
271 | 301 | const proposalId = parseInt(proposalRow.id.split('-')[1], 10); |
|
274 | 304 | const matchesReviews = reviewFilterValue === 'all' || proposalData.numOfVotes === parseInt(reviewFilterValue, 10); |
275 | 305 | const matchesStatus = visibleStatuses.includes(proposalData.originalStatus); |
276 | 306 | const matchesType = visibleTypes.includes(proposalData.submissionType); |
| 307 | + const matchesSpeaker = !speakerFilter || proposalData.speakerName.toLowerCase().includes(speakerFilter); |
277 | 308 |
|
278 | | - if (matchesReviews && matchesStatus && matchesType) { |
| 309 | + if (matchesReviews && matchesStatus && matchesType && matchesSpeaker) { |
279 | 310 | proposalRow.classList.remove('hidden'); |
280 | 311 | } else { |
281 | 312 | proposalRow.classList.add('hidden'); |
|
286 | 317 | filterWithReviewsSelect.addEventListener('change', applyFilters); |
287 | 318 | filterByStatusInputs.forEach(input => input.addEventListener('change', applyFilters)); |
288 | 319 | filterByTypeInputs.forEach(input => input.addEventListener('change', applyFilters)); |
| 320 | + filterBySpeakerInput.addEventListener('input', () => { |
| 321 | + applyFilters(); |
| 322 | + const hasFilter = filterBySpeakerInput.value.trim() !== ''; |
| 323 | + document.getElementById('clear-speaker-filter').style.display = hasFilter ? 'inline' : 'none'; |
| 324 | + document.querySelectorAll('.speaker-row-clear-btn').forEach(btn => { |
| 325 | + btn.style.display = hasFilter ? 'inline' : 'none'; |
| 326 | + }); |
| 327 | + }); |
289 | 328 | }); |
290 | 329 |
|
291 | 330 | const updateBottomBarUI = () => { |
|
353 | 392 | ); |
354 | 393 | }; |
355 | 394 |
|
| 395 | + // Filter by speaker name (called when clicking a speaker name link) |
| 396 | + const filterBySpeakerName = (name) => { |
| 397 | + const input = document.querySelector('#filter-by-speaker'); |
| 398 | + input.value = name; |
| 399 | + input.dispatchEvent(new Event('input')); |
| 400 | + input.scrollIntoView({ behavior: 'smooth', block: 'center' }); |
| 401 | + }; |
| 402 | + |
| 403 | + // Clear speaker name filter |
| 404 | + const clearSpeakerFilter = () => { |
| 405 | + const input = document.querySelector('#filter-by-speaker'); |
| 406 | + input.value = ''; |
| 407 | + input.dispatchEvent(new Event('input')); |
| 408 | + }; |
| 409 | + |
356 | 410 | // Toggle bottom bar visibility |
357 | 411 | const toggleBottomBar = () => { |
358 | 412 | const bottomBar = document.querySelector('.reviews-bottom-bar'); |
@@ -405,6 +459,13 @@ <h3>Show proposals with pending status:</h3> |
405 | 459 | {% endfor %} |
406 | 460 | </div> |
407 | 461 | </div> |
| 462 | + <div class="opt-filter"> |
| 463 | + <h3>Filter by speaker name:</h3> |
| 464 | + <div style="display: flex;"> |
| 465 | + <input type="text" id="filter-by-speaker" placeholder="Type speaker name..." style="flex: 1;" /> |
| 466 | + <button type="button" class="clear-filter-btn" id="clear-speaker-filter" onclick="clearSpeakerFilter()" style="display: none;">Clear</button> |
| 467 | + </div> |
| 468 | + </div> |
408 | 469 | <div class="opt-filter"> |
409 | 470 | <h3>Show proposals of type:</h3> |
410 | 471 | <div> |
@@ -464,6 +525,7 @@ <h3>Show proposals of type:</h3> |
464 | 525 | languages: [{% for language in item.languages.all %}"{{language.code}}",{% endfor %}], |
465 | 526 | numOfVotes: {{item.userreview_set.count}}, |
466 | 527 | submissionType: "{{ item.type.name }}", |
| 528 | + speakerName: "{{ item.speaker.fullname|escapejs }}", |
467 | 529 | }; |
468 | 530 | </script> |
469 | 531 | <tr class="proposal-item" id="submission-{{item.id}}" data-original-status="{{ item.current_or_pending_status }}"> |
@@ -494,7 +556,8 @@ <h3>Show proposals of type:</h3> |
494 | 556 | {% with speaker_id=item.speaker_id|stringformat:"i" %} |
495 | 557 | <li> |
496 | 558 | <strong>Speaker Name</strong> |
497 | | - <span>{{ item.speaker.fullname }}</span> |
| 559 | + <span class="speaker-name-link" onclick="filterBySpeakerName('{{ item.speaker.fullname|escapejs }}')">{{ item.speaker.fullname }}</span> |
| 560 | + <button type="button" class="clear-filter-btn speaker-row-clear-btn" onclick="event.stopPropagation(); clearSpeakerFilter();" style="display: none;">Clear filter</button> |
498 | 561 | </li> |
499 | 562 | <li> |
500 | 563 | <strong>Speaker Country</strong> |
|
0 commit comments