fix: multi-choice filter styles

This commit is contained in:
2025-07-26 14:16:12 -05:00
parent f9ec089f8b
commit 0e13b74b3b
4 changed files with 42 additions and 65 deletions

View File

@@ -166,7 +166,6 @@ export default class DownloadOptionTr extends HTMLTableRowElement {
if (selectedOptions.length === 0 ||
(selectedOptions.length === 1 && selectedOptions[0] === "") ||
(selectedOptions.length === 1 && selectedOptions[0] === "-") ||
(selectedOptions.length === 1 && selectedOptions[0] === "n/a")
) {
return true;

View File

@@ -19,6 +19,8 @@ export default class extends Controller {
"quality": "",
}
defaultOptions = '<option value="">n/a</option><option value="-">-</option>';
static outlets = ['tv-episode-list']
static targets = ['resolution', 'codec', 'language', 'provider', 'season', 'quality', 'selectAll', 'downloadSelected']
static values = {
@@ -65,68 +67,33 @@ export default class extends Controller {
this.languages.push(language);
}
});
this.languageTarget.innerHTML = '<option value="">n/a</option>';
this.languageTarget.innerHTML += this.languages.sort()
.map((language) => {
const preferred = this.languageTarget.dataset.preferred.split(',');
if (preferred.includes(language.toLowerCase())) {
return '<option value="'+language+'" selected>'+language+'</option>';
}
return '<option value="'+language+'">'+language+'</option>';
})
.join();
const preferred = JSON.parse(this.languageTarget.dataset.preferred);
this.languageTarget.innerHTML = this.#serializeSelectOptions(this.languages);
this.languageTarget.tomselect.items = preferred;
}
addProviders(option) {
if (!this.providers.includes(option.provider)) {
this.providers.push(option.provider);
}
const preferred = this.providerTarget.dataset.preferred;
if (preferred) {
this.providerTarget.innerHTML = '<option value="'+preferred+'" selected>'+preferred+'</option>';
this.providerTarget.innerHTML += '<option value="">n/a</option>';
} else {
this.providerTarget.innerHTML = '<option value="">n/a</option>';
}
this.providerTarget.innerHTML += this.providers.sort()
.map((provider) => {
const preferred = this.languageTarget.dataset.preferred;
if (preferred === provider) {
return;
}
return '<option value="' + provider + '">' + provider + '</option>'
})
.join();
const preferred = JSON.parse(this.providerTarget.dataset.preferred);
this.providerTarget.innerHTML = this.#serializeSelectOptions(this.providers);
this.providerTarget.tomselect.items = preferred;
}
addQualities(option) {
if (!this.qualities.includes(option.quality)) {
if (option.quality.toLowerCase() in this.reverseMappedQualitiesValue) {
this.qualities.push(option.quality);
if (option.quality.toLowerCase() in this.reverseMappedQualitiesValue) {
let quality = this.reverseMappedQualitiesValue[option.quality.toLowerCase()];
// converts api returned quality with a value the system recognizes
option.quality = quality;
if (!this.qualities.includes(option.quality)) {
this.qualities.push(quality);
}
}
const preferred = this.qualityTarget.dataset.preferred;
if (preferred) {
this.qualityTarget.innerHTML = '<option value="'+preferred+'" selected>'+preferred+'</option>';
this.qualityTarget.innerHTML += '<option value="">n/a</option>';
} else {
this.qualityTarget.innerHTML = '<option value="">n/a</option>';
}
this.qualityTarget.innerHTML += this.qualities.sort()
.map((quality) => {
const preferred = this.qualityTarget.dataset.preferred;
if (preferred === quality) {
return;
}
return '<option value="' + quality + '">' + quality + '</option>'
})
.join();
const preferred = JSON.parse(this.qualityTarget.dataset.preferred) ?? [];
this.qualityTarget.innerHTML = this.#serializeSelectOptions(this.qualities);
this.qualityTarget.tomselect.items = preferred;
}
async filter() {
@@ -169,7 +136,14 @@ export default class extends Controller {
}
#fetchValuesFromNodeList(nodeList) {
console.log([...nodeList].map(option => option.value))
return [...nodeList].map(option => option.value)
}
#serializeSelectOptions(options) {
return this.defaultOptions + options.sort()
.map((option) => {
return '<option value="' + option + '">' + option + '</option>'
})
.join();
}
}

View File

@@ -173,13 +173,19 @@ dialog[data-dialog-target="dialog"][closing] {
.item[data-ts-item] {
background-image: none !important;
border: none;
@apply bg-orange-500;
box-shadow: none;
text-shadow: none;
@apply bg-orange-500 rounded-ms font-bold;
}
@apply border-b-2 border-b-orange-600 bg-transparent;
}
.ts-wrapper.plugin-remove_button:not(.rtl) .item .remove {
@apply border-l border-l-orange-600 !important;
}
}
.ts-wrapper.plugin-remove_button:not(.rtl) .item .remove {
@apply border-l-orange-800;
.filter-label {
@apply flex flex-col gap-1 justify-between;
}

View File

@@ -6,8 +6,8 @@
data-result-filter-tv-episode-list-outlet=".episode-list"
data-action="change->result-filter#filter action-button:downloadSeason@window->result-filter#downloadSeason"
>
<div class="w-full p-4 flex flex-col md:flex-row gap-4 bg-stone-500 text-md text-gray-500 dark:text-gray-50 rounded-lg">
<label for="resolution" class="flex flex-col gap-1">
<div class="filter-items w-full p-4 flex flex-col md:flex-row gap-4 bg-black/20 border-2 border-orange-500 text-md text-gray-500 dark:text-gray-50 rounded-lg">
<label for="resolution" class="filter-label">
Resolution
<select id="resolution"
multiple="multiple"
@@ -29,7 +29,7 @@
</select>
</label>
<label for="codec" class="flex flex-col gap-1">
<label for="codec" class="filter-label">
Codec
<select id="codec"
multiple="multiple"
@@ -49,7 +49,7 @@
</select>
</label>
<label for="language" class="flex flex-col gap-1">
<label for="language" class="filter-label">
Language
<select id="language"
multiple="multiple"
@@ -68,7 +68,7 @@
</select>
</label>
<label for="provider" class="flex flex-col gap-1">
<label for="provider" class="filter-label">
Provider
<select id="provider"
multiple="multiple"
@@ -87,27 +87,25 @@
</select>
</label>
<label for="quality" class="flex flex-col gap-1">
<label for="quality" class="filter-label">
Quality
<select id="quality"
multiple="multiple"
data-result-filter-target="quality"
class="px-1 py-0.5 bg-stone-100 text-gray-50"
data-preferred="{{ this.userPreferences['quality']|json_encode }}"
{{ stimulus_controller('symfony/ux-autocomplete/autocomplete', {
create: false,
tomSelectOptions: {
highlight: false,
}
}) }}
{% if this.userPreferences['quality'] != null %}
data-preferred="{{ this.userPreferences['quality']|json_encode }}"
{% endif %}
>
</select>
</label>
{% if results.media.mediaType == "tvshows" %}
<label for="season">
<label for="season" class="filter-label">
Season
<select id="season" name="season" value="1" data-result-filter-target="season" class="px-1 py-0.5 bg-stone-100 text-gray-800"
{{ stimulus_action('result_filter', 'setSeason', 'change') }}