mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
Merge pull request #2933 from rommapp/none-filter-support
Add NONE support for filter logic operators
This commit is contained in:
@@ -351,55 +351,55 @@ def get_roms(
|
||||
genres_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for genres filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for genres filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
franchises_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for franchises filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for franchises filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
collections_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for collections filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for collections filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
companies_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for companies filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for companies filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
age_ratings_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for age ratings filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for age ratings filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
regions_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for regions filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for regions filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
languages_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for languages filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for languages filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
statuses_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for statuses filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for statuses filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
player_counts_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for player counts filter: 'any' (OR) or 'all' (AND).",
|
||||
description="Logic operator for player counts filter: 'any' (OR), 'all' (AND) or 'none' (NOT).",
|
||||
),
|
||||
] = "any",
|
||||
order_by: Annotated[
|
||||
|
||||
@@ -372,9 +372,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(RomMetadata.genres, values, session=session))
|
||||
condition = op(RomMetadata.genres, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_franchises(
|
||||
self,
|
||||
@@ -383,9 +385,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(RomMetadata.franchises, values, session=session))
|
||||
condition = op(RomMetadata.franchises, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_collections(
|
||||
self,
|
||||
@@ -394,9 +398,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(RomMetadata.collections, values, session=session))
|
||||
condition = op(RomMetadata.collections, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_companies(
|
||||
self,
|
||||
@@ -405,9 +411,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(RomMetadata.companies, values, session=session))
|
||||
condition = op(RomMetadata.companies, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_age_ratings(
|
||||
self,
|
||||
@@ -416,9 +424,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(RomMetadata.age_ratings, values, session=session))
|
||||
condition = op(RomMetadata.age_ratings, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_status(self, query: Query, statuses: Sequence[str]):
|
||||
"""Filter by one or more user statuses using OR logic."""
|
||||
@@ -449,9 +459,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(Rom.regions, values, session=session))
|
||||
condition = op(Rom.regions, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_languages(
|
||||
self,
|
||||
@@ -460,9 +472,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(Rom.languages, values, session=session))
|
||||
condition = op(Rom.languages, values, session=session)
|
||||
return query.filter(~condition) if match_none else query.filter(condition)
|
||||
|
||||
def _filter_by_player_counts(
|
||||
self,
|
||||
@@ -471,8 +485,12 @@ class DBRomsHandler(DBBaseHandler):
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
match_none: bool = False,
|
||||
) -> Query:
|
||||
return query.filter(RomMetadata.player_count.in_(values))
|
||||
condition = RomMetadata.player_count.in_(values)
|
||||
if match_none:
|
||||
return query.filter(not_(condition))
|
||||
return query.filter(condition)
|
||||
|
||||
@begin_session
|
||||
def filter_roms(
|
||||
@@ -695,7 +713,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
for values, logic, filter_func in filters_to_apply:
|
||||
if values:
|
||||
query = filter_func(
|
||||
query, session=session, values=values, match_all=(logic == "all")
|
||||
query,
|
||||
session=session,
|
||||
values=values,
|
||||
match_all=(logic == "all"),
|
||||
match_none=(logic == "none"),
|
||||
)
|
||||
|
||||
# The RomUser table is already joined if user_id is set
|
||||
|
||||
@@ -15,7 +15,9 @@ import FilterPlatformBtn from "@/components/Gallery/AppBar/common/FilterDrawer/F
|
||||
import FilterPlayablesBtn from "@/components/Gallery/AppBar/common/FilterDrawer/FilterPlayablesBtn.vue";
|
||||
import FilterRaBtn from "@/components/Gallery/AppBar/common/FilterDrawer/FilterRaBtn.vue";
|
||||
import FilterVerifiedBtn from "@/components/Gallery/AppBar/common/FilterDrawer/FilterVerifiedBtn.vue";
|
||||
import storeGalleryFilter from "@/stores/galleryFilter";
|
||||
import storeGalleryFilter, {
|
||||
type FilterLogicOperator,
|
||||
} from "@/stores/galleryFilter";
|
||||
import storePlatforms from "@/stores/platforms";
|
||||
import storeRoms from "@/stores/roms";
|
||||
import type { Events } from "@/types/emitter";
|
||||
@@ -112,49 +114,49 @@ const onFilterChange = debounce(
|
||||
: null,
|
||||
genres:
|
||||
selectedGenres.value.length > 0 ? selectedGenres.value.join(",") : null,
|
||||
genresLogic: selectedGenres.value.length > 1 ? genresLogic.value : null,
|
||||
genresLogic: selectedGenres.value.length > 0 ? genresLogic.value : null,
|
||||
franchises:
|
||||
selectedFranchises.value.length > 0
|
||||
? selectedFranchises.value.join(",")
|
||||
: null,
|
||||
franchisesLogic:
|
||||
selectedFranchises.value.length > 1 ? franchisesLogic.value : null,
|
||||
selectedFranchises.value.length > 0 ? franchisesLogic.value : null,
|
||||
collections:
|
||||
selectedCollections.value.length > 0
|
||||
? selectedCollections.value.join(",")
|
||||
: null,
|
||||
collectionsLogic:
|
||||
selectedCollections.value.length > 1 ? collectionsLogic.value : null,
|
||||
selectedCollections.value.length > 0 ? collectionsLogic.value : null,
|
||||
companies:
|
||||
selectedCompanies.value.length > 0
|
||||
? selectedCompanies.value.join(",")
|
||||
: null,
|
||||
companiesLogic:
|
||||
selectedCompanies.value.length > 1 ? companiesLogic.value : null,
|
||||
selectedCompanies.value.length > 0 ? companiesLogic.value : null,
|
||||
ageRatings:
|
||||
selectedAgeRatings.value.length > 0
|
||||
? selectedAgeRatings.value.join(",")
|
||||
: null,
|
||||
ageRatingsLogic:
|
||||
selectedAgeRatings.value.length > 1 ? ageRatingsLogic.value : null,
|
||||
selectedAgeRatings.value.length > 0 ? ageRatingsLogic.value : null,
|
||||
regions:
|
||||
selectedRegions.value.length > 0
|
||||
? selectedRegions.value.join(",")
|
||||
: null,
|
||||
regionsLogic:
|
||||
selectedRegions.value.length > 1 ? regionsLogic.value : null,
|
||||
selectedRegions.value.length > 0 ? regionsLogic.value : null,
|
||||
languages:
|
||||
selectedLanguages.value.length > 0
|
||||
? selectedLanguages.value.join(",")
|
||||
: null,
|
||||
languagesLogic:
|
||||
selectedLanguages.value.length > 1 ? languagesLogic.value : null,
|
||||
selectedLanguages.value.length > 0 ? languagesLogic.value : null,
|
||||
statuses:
|
||||
selectedStatuses.value.length > 0
|
||||
? selectedStatuses.value.join(",")
|
||||
: null,
|
||||
statusesLogic:
|
||||
selectedStatuses.value.length > 1 ? statusesLogic.value : null,
|
||||
selectedStatuses.value.length > 0 ? statusesLogic.value : null,
|
||||
playerCounts:
|
||||
selectedPlayerCounts.value.length > 0
|
||||
? selectedPlayerCounts.value.join(",")
|
||||
@@ -184,7 +186,7 @@ const filters = [
|
||||
selected: selectedGenres,
|
||||
items: filterGenres,
|
||||
logic: genresLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setGenresLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -192,7 +194,7 @@ const filters = [
|
||||
selected: selectedFranchises,
|
||||
items: filterFranchises,
|
||||
logic: franchisesLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setFranchisesLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -200,7 +202,7 @@ const filters = [
|
||||
selected: selectedCollections,
|
||||
items: filterCollections,
|
||||
logic: collectionsLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setCollectionsLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -208,7 +210,7 @@ const filters = [
|
||||
selected: selectedCompanies,
|
||||
items: filterCompanies,
|
||||
logic: companiesLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setCompaniesLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -216,7 +218,7 @@ const filters = [
|
||||
selected: selectedAgeRatings,
|
||||
items: filterAgeRatings,
|
||||
logic: ageRatingsLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setAgeRatingsLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -224,7 +226,7 @@ const filters = [
|
||||
selected: selectedRegions,
|
||||
items: filterRegions,
|
||||
logic: regionsLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setRegionsLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -232,7 +234,7 @@ const filters = [
|
||||
selected: selectedLanguages,
|
||||
items: filterLanguages,
|
||||
logic: languagesLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setLanguagesLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -240,7 +242,7 @@ const filters = [
|
||||
selected: selectedPlayerCounts,
|
||||
items: filterPlayerCounts,
|
||||
logic: playerCountsLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setPlayerCountsLogic(logic),
|
||||
},
|
||||
{
|
||||
@@ -248,7 +250,7 @@ const filters = [
|
||||
selected: selectedStatuses,
|
||||
items: filterStatuses,
|
||||
logic: statusesLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
setLogic: (logic: FilterLogicOperator) =>
|
||||
galleryFilterStore.setStatusesLogic(logic),
|
||||
},
|
||||
];
|
||||
@@ -377,7 +379,7 @@ onMounted(async () => {
|
||||
const genres = (urlGenres as string).split(",").filter((g) => g.trim());
|
||||
galleryFilterStore.setSelectedFilterGenres(genres);
|
||||
if (urlGenresLogic !== undefined) {
|
||||
galleryFilterStore.setGenresLogic(urlGenresLogic as "any" | "all");
|
||||
galleryFilterStore.setGenresLogic(urlGenresLogic as FilterLogicOperator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +390,7 @@ onMounted(async () => {
|
||||
galleryFilterStore.setSelectedFilterFranchises(franchises);
|
||||
if (urlFranchisesLogic !== undefined) {
|
||||
galleryFilterStore.setFranchisesLogic(
|
||||
urlFranchisesLogic as "any" | "all",
|
||||
urlFranchisesLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -400,7 +402,7 @@ onMounted(async () => {
|
||||
galleryFilterStore.setSelectedFilterCollections(collections);
|
||||
if (urlCollectionsLogic !== undefined) {
|
||||
galleryFilterStore.setCollectionsLogic(
|
||||
urlCollectionsLogic as "any" | "all",
|
||||
urlCollectionsLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -411,7 +413,9 @@ onMounted(async () => {
|
||||
.filter((c) => c.trim());
|
||||
galleryFilterStore.setSelectedFilterCompanies(companies);
|
||||
if (urlCompaniesLogic !== undefined) {
|
||||
galleryFilterStore.setCompaniesLogic(urlCompaniesLogic as "any" | "all");
|
||||
galleryFilterStore.setCompaniesLogic(
|
||||
urlCompaniesLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,7 +426,7 @@ onMounted(async () => {
|
||||
galleryFilterStore.setSelectedFilterAgeRatings(ageRatings);
|
||||
if (urlAgeRatingsLogic !== undefined) {
|
||||
galleryFilterStore.setAgeRatingsLogic(
|
||||
urlAgeRatingsLogic as "any" | "all",
|
||||
urlAgeRatingsLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -431,7 +435,9 @@ onMounted(async () => {
|
||||
const regions = (urlRegions as string).split(",").filter((r) => r.trim());
|
||||
galleryFilterStore.setSelectedFilterRegions(regions);
|
||||
if (urlRegionsLogic !== undefined) {
|
||||
galleryFilterStore.setRegionsLogic(urlRegionsLogic as "any" | "all");
|
||||
galleryFilterStore.setRegionsLogic(
|
||||
urlRegionsLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +447,9 @@ onMounted(async () => {
|
||||
.filter((l) => l.trim());
|
||||
galleryFilterStore.setSelectedFilterLanguages(languages);
|
||||
if (urlLanguagesLogic !== undefined) {
|
||||
galleryFilterStore.setLanguagesLogic(urlLanguagesLogic as "any" | "all");
|
||||
galleryFilterStore.setLanguagesLogic(
|
||||
urlLanguagesLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,7 +457,9 @@ onMounted(async () => {
|
||||
const statuses = (urlStatuses as string).split(",").filter((s) => s.trim());
|
||||
galleryFilterStore.setSelectedFilterStatuses(statuses);
|
||||
if (urlStatusesLogic !== undefined) {
|
||||
galleryFilterStore.setStatusesLogic(urlStatusesLogic as "any" | "all");
|
||||
galleryFilterStore.setStatusesLogic(
|
||||
urlStatusesLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +470,7 @@ onMounted(async () => {
|
||||
galleryFilterStore.setSelectedFilterPlayerCounts(playerCounts);
|
||||
if (urlPlayerCountsLogic !== undefined) {
|
||||
galleryFilterStore.setPlayerCountsLogic(
|
||||
urlPlayerCountsLogic as "any" | "all",
|
||||
urlPlayerCountsLogic as FilterLogicOperator,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -568,7 +578,7 @@ onMounted(async () => {
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn value="any" size="small" v-bind="props">
|
||||
<v-icon size="x-large">mdi-set-none</v-icon>
|
||||
<v-icon size="x-large">mdi-set-all</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
@@ -579,7 +589,18 @@ onMounted(async () => {
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn value="all" size="small" v-bind="props">
|
||||
<v-icon size="x-large">mdi-set-all</v-icon>
|
||||
<v-icon size="x-large">mdi-set-center</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip
|
||||
:text="t('platform.match-none-logic')"
|
||||
location="bottom"
|
||||
open-delay="500"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn value="none" size="small" v-bind="props">
|
||||
<v-icon size="x-large">mdi-set-none</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
|
||||
@@ -11,12 +11,14 @@ import { ROUTES } from "@/plugins/router";
|
||||
import collectionApi from "@/services/api/collection";
|
||||
import storeCollections from "@/stores/collections";
|
||||
import storeGalleryFilter from "@/stores/galleryFilter";
|
||||
import storeRoms from "@/stores/roms";
|
||||
import type { Events } from "@/types/emitter";
|
||||
import { getStatusKeyForText } from "@/utils";
|
||||
|
||||
const { t } = useI18n();
|
||||
const galleryFilterStore = storeGalleryFilter();
|
||||
const collectionsStore = storeCollections();
|
||||
const romsStore = storeRoms();
|
||||
const { mdAndUp } = useDisplay();
|
||||
const router = useRouter();
|
||||
const show = ref(false);
|
||||
@@ -24,6 +26,7 @@ const name = ref("");
|
||||
const description = ref("");
|
||||
const isPublic = ref(false);
|
||||
|
||||
const { currentPlatform } = storeToRefs(romsStore);
|
||||
const {
|
||||
searchTerm,
|
||||
filterMatched,
|
||||
@@ -70,10 +73,13 @@ const filterSummary = computed(() => {
|
||||
const filters = [];
|
||||
|
||||
if (searchTerm.value) filters.push(`Search: "${searchTerm.value}"`);
|
||||
if (selectedPlatforms.value && selectedPlatforms.value.length > 0)
|
||||
if (selectedPlatforms.value && selectedPlatforms.value.length > 0) {
|
||||
filters.push(
|
||||
`Platforms: ${selectedPlatforms.value.map((p) => p.name).join(", ")}`,
|
||||
`Platforms: ${selectedPlatforms.value.map((p) => p.display_name).join(", ")}`,
|
||||
);
|
||||
} else if (currentPlatform.value) {
|
||||
filters.push(`Platform: ${currentPlatform.value.display_name}`);
|
||||
}
|
||||
if (filterMatched.value) filters.push("Matched only");
|
||||
if (filterFavorites.value) filters.push("Favorites");
|
||||
if (filterDuplicates.value) filters.push("Duplicates");
|
||||
@@ -125,14 +131,14 @@ async function createSmartCollection() {
|
||||
emitter?.emit("showLoadingDialog", { loading: true, scrim: true });
|
||||
|
||||
try {
|
||||
const filterCriteria: Record<
|
||||
string,
|
||||
number | boolean | string | string[] | number[] | (string | null)[] | null
|
||||
> = {};
|
||||
const filterCriteria: Record<string, any> = {};
|
||||
|
||||
if (searchTerm.value) filterCriteria.search_term = searchTerm.value;
|
||||
if (selectedPlatforms.value && selectedPlatforms.value.length > 0)
|
||||
if (selectedPlatforms.value && selectedPlatforms.value.length > 0) {
|
||||
filterCriteria.platform_ids = selectedPlatforms.value.map((p) => p.id);
|
||||
} else if (currentPlatform.value) {
|
||||
filterCriteria.platform_ids = [currentPlatform.value.id];
|
||||
}
|
||||
if (filterMatched.value) filterCriteria.matched = true;
|
||||
if (filterFavorites.value) filterCriteria.favorite = true;
|
||||
if (filterDuplicates.value) filterCriteria.duplicate = true;
|
||||
@@ -142,27 +148,27 @@ async function createSmartCollection() {
|
||||
if (filterVerified.value) filterCriteria.verified = true;
|
||||
if (selectedGenres.value && selectedGenres.value.length > 0) {
|
||||
filterCriteria.genres = selectedGenres.value;
|
||||
if (selectedGenres.value.length > 1)
|
||||
if (selectedGenres.value.length > 0)
|
||||
filterCriteria.genres_logic = genresLogic.value;
|
||||
}
|
||||
if (selectedFranchises.value && selectedFranchises.value.length > 0) {
|
||||
filterCriteria.franchises = selectedFranchises.value;
|
||||
if (selectedFranchises.value.length > 1)
|
||||
if (selectedFranchises.value.length > 0)
|
||||
filterCriteria.franchises_logic = franchisesLogic.value;
|
||||
}
|
||||
if (selectedCollections.value && selectedCollections.value.length > 0) {
|
||||
filterCriteria.collections = selectedCollections.value;
|
||||
if (selectedCollections.value.length > 1)
|
||||
if (selectedCollections.value.length > 0)
|
||||
filterCriteria.collections_logic = collectionsLogic.value;
|
||||
}
|
||||
if (selectedCompanies.value && selectedCompanies.value.length > 0) {
|
||||
filterCriteria.companies = selectedCompanies.value;
|
||||
if (selectedCompanies.value.length > 1)
|
||||
if (selectedCompanies.value.length > 0)
|
||||
filterCriteria.companies_logic = companiesLogic.value;
|
||||
}
|
||||
if (selectedAgeRatings.value && selectedAgeRatings.value.length > 0) {
|
||||
filterCriteria.age_ratings = selectedAgeRatings.value;
|
||||
if (selectedAgeRatings.value.length > 1)
|
||||
if (selectedAgeRatings.value.length > 0)
|
||||
filterCriteria.age_ratings_logic = ageRatingsLogic.value;
|
||||
}
|
||||
if (selectedStatuses.value && selectedStatuses.value.length > 0) {
|
||||
@@ -176,12 +182,12 @@ async function createSmartCollection() {
|
||||
}
|
||||
if (selectedRegions.value && selectedRegions.value.length > 0) {
|
||||
filterCriteria.regions = selectedRegions.value;
|
||||
if (selectedRegions.value.length > 1)
|
||||
if (selectedRegions.value.length > 0)
|
||||
filterCriteria.regions_logic = regionsLogic.value;
|
||||
}
|
||||
if (selectedLanguages.value && selectedLanguages.value.length > 0) {
|
||||
filterCriteria.languages = selectedLanguages.value;
|
||||
if (selectedLanguages.value.length > 1)
|
||||
if (selectedLanguages.value.length > 0)
|
||||
filterCriteria.languages_logic = languagesLogic.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,39 +188,39 @@ async function getRoms({
|
||||
: undefined,
|
||||
// Logic operators
|
||||
genres_logic:
|
||||
selectedGenres && selectedGenres.length > 1
|
||||
selectedGenres && selectedGenres.length > 0
|
||||
? genresLogic || "any"
|
||||
: undefined,
|
||||
franchises_logic:
|
||||
selectedFranchises && selectedFranchises.length > 1
|
||||
selectedFranchises && selectedFranchises.length > 0
|
||||
? franchisesLogic || "any"
|
||||
: undefined,
|
||||
collections_logic:
|
||||
selectedCollections && selectedCollections.length > 1
|
||||
selectedCollections && selectedCollections.length > 0
|
||||
? collectionsLogic || "any"
|
||||
: undefined,
|
||||
companies_logic:
|
||||
selectedCompanies && selectedCompanies.length > 1
|
||||
selectedCompanies && selectedCompanies.length > 0
|
||||
? companiesLogic || "any"
|
||||
: undefined,
|
||||
age_ratings_logic:
|
||||
selectedAgeRatings && selectedAgeRatings.length > 1
|
||||
selectedAgeRatings && selectedAgeRatings.length > 0
|
||||
? ageRatingsLogic || "any"
|
||||
: undefined,
|
||||
regions_logic:
|
||||
selectedRegions && selectedRegions.length > 1
|
||||
selectedRegions && selectedRegions.length > 0
|
||||
? regionsLogic || "any"
|
||||
: undefined,
|
||||
languages_logic:
|
||||
selectedLanguages && selectedLanguages.length > 1
|
||||
selectedLanguages && selectedLanguages.length > 0
|
||||
? languagesLogic || "any"
|
||||
: undefined,
|
||||
statuses_logic:
|
||||
selectedStatuses && selectedStatuses.length > 1
|
||||
selectedStatuses && selectedStatuses.length > 0
|
||||
? statusesLogic || "any"
|
||||
: undefined,
|
||||
player_counts_logic:
|
||||
selectedPlayerCounts && selectedPlayerCounts.length > 1
|
||||
selectedPlayerCounts && selectedPlayerCounts.length > 0
|
||||
? playerCountsLogic || "any"
|
||||
: undefined,
|
||||
...(filterMatched !== null ? { matched: filterMatched } : {}),
|
||||
|
||||
18
frontend/src/services/cache/api.ts
vendored
18
frontend/src/services/cache/api.ts
vendored
@@ -80,39 +80,39 @@ class CachedApiService {
|
||||
: undefined,
|
||||
// Logic operators
|
||||
genres_logic:
|
||||
params.selectedGenres && params.selectedGenres.length > 1
|
||||
params.selectedGenres && params.selectedGenres.length > 0
|
||||
? params.genresLogic || "any"
|
||||
: undefined,
|
||||
franchises_logic:
|
||||
params.selectedFranchises && params.selectedFranchises.length > 1
|
||||
params.selectedFranchises && params.selectedFranchises.length > 0
|
||||
? params.franchisesLogic || "any"
|
||||
: undefined,
|
||||
collections_logic:
|
||||
params.selectedCollections && params.selectedCollections.length > 1
|
||||
params.selectedCollections && params.selectedCollections.length > 0
|
||||
? params.collectionsLogic || "any"
|
||||
: undefined,
|
||||
companies_logic:
|
||||
params.selectedCompanies && params.selectedCompanies.length > 1
|
||||
params.selectedCompanies && params.selectedCompanies.length > 0
|
||||
? params.companiesLogic || "any"
|
||||
: undefined,
|
||||
age_ratings_logic:
|
||||
params.selectedAgeRatings && params.selectedAgeRatings.length > 1
|
||||
params.selectedAgeRatings && params.selectedAgeRatings.length > 0
|
||||
? params.ageRatingsLogic || "any"
|
||||
: undefined,
|
||||
regions_logic:
|
||||
params.selectedRegions && params.selectedRegions.length > 1
|
||||
params.selectedRegions && params.selectedRegions.length > 0
|
||||
? params.regionsLogic || "any"
|
||||
: undefined,
|
||||
languages_logic:
|
||||
params.selectedLanguages && params.selectedLanguages.length > 1
|
||||
params.selectedLanguages && params.selectedLanguages.length > 0
|
||||
? params.languagesLogic || "any"
|
||||
: undefined,
|
||||
statuses_logic:
|
||||
params.selectedStatuses && params.selectedStatuses.length > 1
|
||||
params.selectedStatuses && params.selectedStatuses.length > 0
|
||||
? params.statusesLogic || "any"
|
||||
: undefined,
|
||||
player_counts_logic:
|
||||
params.selectedPlayerCounts && params.selectedPlayerCounts.length > 1
|
||||
params.selectedPlayerCounts && params.selectedPlayerCounts.length > 0
|
||||
? params.playerCountsLogic || "any"
|
||||
: undefined,
|
||||
...(params.filterMatched !== null
|
||||
|
||||
@@ -15,6 +15,8 @@ export type FilterType =
|
||||
| "language"
|
||||
| "playerCount";
|
||||
|
||||
export type FilterLogicOperator = "any" | "all" | "none";
|
||||
|
||||
const defaultFilterState = {
|
||||
activeFilterDrawer: false,
|
||||
searchTerm: null as string | null,
|
||||
@@ -47,15 +49,15 @@ const defaultFilterState = {
|
||||
selectedPlayerCounts: [] as string[],
|
||||
selectedStatuses: [] as string[],
|
||||
// Logic operators for multi-select filters
|
||||
genresLogic: "any" as "any" | "all",
|
||||
franchisesLogic: "any" as "any" | "all",
|
||||
collectionsLogic: "any" as "any" | "all",
|
||||
companiesLogic: "any" as "any" | "all",
|
||||
ageRatingsLogic: "any" as "any" | "all",
|
||||
regionsLogic: "any" as "any" | "all",
|
||||
languagesLogic: "any" as "any" | "all",
|
||||
statusesLogic: "any" as "any" | "all",
|
||||
playerCountsLogic: "any" as "any" | "all",
|
||||
genresLogic: "any" as FilterLogicOperator,
|
||||
franchisesLogic: "any" as FilterLogicOperator,
|
||||
collectionsLogic: "any" as FilterLogicOperator,
|
||||
companiesLogic: "any" as FilterLogicOperator,
|
||||
ageRatingsLogic: "any" as FilterLogicOperator,
|
||||
regionsLogic: "any" as FilterLogicOperator,
|
||||
languagesLogic: "any" as FilterLogicOperator,
|
||||
statusesLogic: "any" as FilterLogicOperator,
|
||||
playerCountsLogic: "any" as FilterLogicOperator,
|
||||
};
|
||||
|
||||
export default defineStore("galleryFilter", {
|
||||
@@ -105,55 +107,55 @@ export default defineStore("galleryFilter", {
|
||||
setSelectedFilterGenres(genres: string[]) {
|
||||
this.selectedGenres = genres;
|
||||
},
|
||||
setGenresLogic(logic: "any" | "all") {
|
||||
setGenresLogic(logic: FilterLogicOperator) {
|
||||
this.genresLogic = logic;
|
||||
},
|
||||
setSelectedFilterFranchises(franchises: string[]) {
|
||||
this.selectedFranchises = franchises;
|
||||
},
|
||||
setFranchisesLogic(logic: "any" | "all") {
|
||||
setFranchisesLogic(logic: FilterLogicOperator) {
|
||||
this.franchisesLogic = logic;
|
||||
},
|
||||
setSelectedFilterCollections(collections: string[]) {
|
||||
this.selectedCollections = collections;
|
||||
},
|
||||
setCollectionsLogic(logic: "any" | "all") {
|
||||
setCollectionsLogic(logic: FilterLogicOperator) {
|
||||
this.collectionsLogic = logic;
|
||||
},
|
||||
setSelectedFilterCompanies(companies: string[]) {
|
||||
this.selectedCompanies = companies;
|
||||
},
|
||||
setCompaniesLogic(logic: "any" | "all") {
|
||||
setCompaniesLogic(logic: FilterLogicOperator) {
|
||||
this.companiesLogic = logic;
|
||||
},
|
||||
setSelectedFilterAgeRatings(ageRatings: string[]) {
|
||||
this.selectedAgeRatings = ageRatings;
|
||||
},
|
||||
setAgeRatingsLogic(logic: "any" | "all") {
|
||||
setAgeRatingsLogic(logic: FilterLogicOperator) {
|
||||
this.ageRatingsLogic = logic;
|
||||
},
|
||||
setSelectedFilterRegions(regions: string[]) {
|
||||
this.selectedRegions = regions;
|
||||
},
|
||||
setRegionsLogic(logic: "any" | "all") {
|
||||
setRegionsLogic(logic: FilterLogicOperator) {
|
||||
this.regionsLogic = logic;
|
||||
},
|
||||
setSelectedFilterLanguages(languages: string[]) {
|
||||
this.selectedLanguages = languages;
|
||||
},
|
||||
setLanguagesLogic(logic: "any" | "all") {
|
||||
setLanguagesLogic(logic: FilterLogicOperator) {
|
||||
this.languagesLogic = logic;
|
||||
},
|
||||
setSelectedFilterPlayerCounts(playerCounts: string[]) {
|
||||
this.selectedPlayerCounts = playerCounts;
|
||||
},
|
||||
setPlayerCountsLogic(logic: "any" | "all") {
|
||||
setPlayerCountsLogic(logic: FilterLogicOperator) {
|
||||
this.playerCountsLogic = logic;
|
||||
},
|
||||
setSelectedFilterStatuses(statuses: string[]) {
|
||||
this.selectedStatuses = statuses;
|
||||
},
|
||||
setStatusesLogic(logic: "any" | "all") {
|
||||
setStatusesLogic(logic: FilterLogicOperator) {
|
||||
this.statusesLogic = logic;
|
||||
},
|
||||
setFilterMatched(value: boolean | null) {
|
||||
|
||||
Reference in New Issue
Block a user