diff --git a/server/helpers/albums.helpers.ts b/server/helpers/albums.helpers.ts
index 1b12ff76e..1d086d351 100644
--- a/server/helpers/albums.helpers.ts
+++ b/server/helpers/albums.helpers.ts
@@ -99,6 +99,21 @@ export type AdvancedFilterGroup = {
uniqueId: string;
};
+const operatorMap = {
+ '!=': 'not',
+ '!~': 'contains',
+ $: 'endsWith',
+ '<': 'lt',
+ '<=': 'lte',
+ '=': 'equals',
+ '>': 'gt',
+ '>=': 'gte',
+ '^': 'startsWith',
+ '~': 'contains',
+};
+
+const insensitiveFields = ['name'];
+
const advancedFilterGroup = (
groups: AdvancedFilterGroup[],
user: AuthUser,
@@ -119,57 +134,65 @@ const advancedFilterGroup = (
for (const rule of group.rules) {
if (rule.field && rule.operator) {
const [table, field, relationField] = rule.field.split('.');
+ const condition = rule.operator === '!~' ? 'none' : 'some';
+ const op = operatorMap[rule.operator as keyof typeof operatorMap];
+
+ switch (table) {
+ case 'albums':
+ if (field === 'ratings') {
+ query[rootType].push({
+ [field]: {
+ [condition]: {
+ [relationField]: {
+ [op]: rule.value,
+ },
+ userId: user.id,
+ },
+ },
+ });
+ break;
+ }
- if (field === 'ratings') {
- if (table === 'albums') {
query[rootType].push({
[field]: {
- some: {
- [relationField]: {
- [rule.operator]: rule.value,
- },
- userId: user.id,
- },
+ mode: insensitiveFields.includes(field)
+ ? 'insensitive'
+ : undefined,
+ [op]: rule.value,
},
});
- } else {
- query[rootType].push({
- [table]: {
- some: {
- [field]: {
- some: {
- [relationField]: {
- [rule.operator]: rule.value,
+ break;
+
+ default:
+ if (field === 'ratings') {
+ query[rootType].push({
+ [table]: {
+ some: {
+ [field]: {
+ some: {
+ [relationField]: {
+ [op]: rule.value,
+ },
+ userId: user.id,
},
- userId: user.id,
},
},
},
- },
- });
- }
- } else if (table === 'albums') {
- const obj = {
- [field]: {
- [rule.operator]: rule.value,
- mode: 'insensitive',
- },
- };
+ });
+ break;
+ }
- query[rootType].push(obj);
- } else {
- const obj = {
- [table]: {
- some: {
- [field]: {
- [rule.operator]: rule.value,
- mode: 'insensitive',
+ query[rootType].push({
+ [table]: {
+ [condition]: {
+ [field]: {
+ mode: 'insensitive',
+ [op]: rule.value,
+ },
},
},
- },
- };
-
- query[rootType].push(obj);
+ });
+ break;
}
}
}
@@ -192,19 +215,6 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
[rootQueryType]: [] as any[],
};
- const operatorMap = {
- '!=': 'not',
- '!~': 'contains',
- $: 'endsWith',
- '<': 'lt',
- '<=': 'lte',
- '=': 'equals',
- '>': 'gt',
- '>=': 'gte',
- '^': 'startsWith',
- '~': 'contains',
- };
-
for (const rule of filter.rules) {
if (rule.field && rule.operator) {
let [table, field, relationField] = rule.field.split('.');
@@ -226,9 +236,12 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
});
break;
}
+
rootQuery[rootQueryType].push({
[field]: {
- mode: 'insensitive',
+ mode: insensitiveFields.includes(field)
+ ? 'insensitive'
+ : undefined,
[op]: rule.value,
},
});
diff --git a/src/renderer/features/albums/components/advanced-filters.tsx b/src/renderer/features/albums/components/advanced-filters.tsx
index e41afeb18..6500629a7 100644
--- a/src/renderer/features/albums/components/advanced-filters.tsx
+++ b/src/renderer/features/albums/components/advanced-filters.tsx
@@ -1,4 +1,4 @@
-import { Box, Stack, Group } from '@mantine/core';
+import { Stack, Group } from '@mantine/core';
import dayjs from 'dayjs';
import get from 'lodash/get';
import set from 'lodash/set';
@@ -75,7 +75,7 @@ const FILTER_GROUP_OPTIONS_DATA = [
const FILTER_OPTIONS_DATA = [
{
- label: 'Artist Name',
+ label: 'Artist Title',
value: 'artists.name',
},
{
@@ -87,7 +87,7 @@ const FILTER_OPTIONS_DATA = [
value: 'artists.genre',
},
{
- label: 'Album Artist Name',
+ label: 'Album Artist Title',
value: 'albumArtists.name',
},
{
@@ -99,7 +99,7 @@ const FILTER_OPTIONS_DATA = [
value: 'albumArtists.genre',
},
{
- label: 'Album Name',
+ label: 'Album Title',
value: 'albums.name',
},
{
@@ -112,7 +112,7 @@ const FILTER_OPTIONS_DATA = [
},
{
label: 'Album Year',
- value: 'albums.year',
+ value: 'albums.releaseYear',
},
{
label: 'Album Release Date',
@@ -127,7 +127,7 @@ const FILTER_OPTIONS_DATA = [
value: 'albums.dateAdded',
},
{
- label: 'Track Name',
+ label: 'Track Title',
value: 'songs.name',
},
{
@@ -171,7 +171,7 @@ const OPTIONS_MAP = {
'albums.releaseDate': {
type: 'date',
},
- 'albums.year': {
+ 'albums.releaseYear': {
type: 'number',
},
'artists.genre': {
@@ -194,10 +194,47 @@ const OPTIONS_MAP = {
},
};
+export const formatAdvancedFiltersGroups = (groups: AdvancedFilterGroup[]) => {
+ const filterGroups: any[] = [];
+
+ for (const group of groups) {
+ const rules = group.rules
+ .filter((rule) => rule.field && rule.operator && rule.value)
+ .map((rule) => ({ ...rule, uniqueId: undefined }));
+
+ const updatedGroup = { ...group, rules, uniqueId: undefined };
+
+ if (group.group.length > 0) {
+ const nestedRuleGroup = formatAdvancedFiltersGroups(group.group);
+ nestedRuleGroup.forEach((group) => groups.push(group));
+ }
+
+ if (updatedGroup.rules.length > 0) {
+ filterGroups.push(updatedGroup);
+ }
+ }
+
+ return filterGroups;
+};
+
+// Prevent query key from constantly changing due to empty rules or groups
+export const formatAdvancedFiltersQuery = (filter: AdvancedFilterGroup) => {
+ const updatedFilter = {
+ ...filter,
+ group: formatAdvancedFiltersGroups(filter.group),
+ rules: filter.rules
+ .filter((rule) => rule.field && rule.operator && rule.value)
+ .map((rule) => ({ ...rule, uniqueId: undefined })),
+ };
+
+ return updatedFilter;
+};
+
interface FilterOptionProps {
data: AdvancedFilterRule;
groupIndex: number[];
level: number;
+ noRemove: boolean;
onChangeField: (args: any) => void;
onChangeOperator: (args: any) => void;
onChangeValue: (args: any) => void;
@@ -209,6 +246,7 @@ const FilterOption = ({
level,
onDeleteRule,
groupIndex,
+ noRemove,
onChangeField,
onChangeOperator,
onChangeValue,
@@ -254,37 +292,45 @@ const FilterOption = ({
const filterOperatorMap = {
date: (
),
id: (
),
number: (
),
string: (
),
@@ -295,27 +341,30 @@ const FilterOption = ({
),
'albumArtists.name': (
),
'albumArtists.ratings.value': (
),
@@ -323,10 +372,11 @@ const FilterOption = ({
),
@@ -334,36 +384,40 @@ const FilterOption = ({
),
'albums.name': (
),
'albums.playCount': (
handleChangeValue(e)}
/>
),
'albums.ratings.value': (
),
@@ -371,19 +425,21 @@ const FilterOption = ({
),
- 'albums.year': (
+ 'albums.releaseYear': (
),
@@ -391,60 +447,75 @@ const FilterOption = ({
),
'artists.name': (
),
'artists.ratings.value': (
),
'songs.name': (
-
+
),
'songs.playCount': (
),
'songs.ratings.value': (
),
};
+ const ml = (level + 1) * 10 - level * 5;
+
return (
-
+
{field ? (
@@ -453,14 +524,15 @@ const FilterOption = ({
.type as keyof typeof filterOperatorMap
]
) : (
-
+
)}
{field ? (
filterInputValueMap[field as keyof typeof filterInputValueMap]
) : (
-
+
)}