mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
Add default ops, handle releaseDate
This commit is contained in:
@@ -26,13 +26,12 @@ const getList = async (
|
|||||||
const { serverId } = req.params;
|
const { serverId } = req.params;
|
||||||
const { take, skip, serverUrlId, advancedFilters } = req.query;
|
const { take, skip, serverUrlId, advancedFilters } = req.query;
|
||||||
|
|
||||||
const decodedAdvancedFilters = advancedFilters && decodeURI(advancedFilters);
|
const decodedAdvancedFilters =
|
||||||
const jsonAdvancedFilters =
|
advancedFilters && JSON.parse(decodeURI(advancedFilters));
|
||||||
decodedAdvancedFilters && JSON.parse(decodedAdvancedFilters);
|
|
||||||
|
|
||||||
const albums = await service.albums.findMany({
|
const albums = await service.albums.findMany({
|
||||||
...req.query,
|
...req.query,
|
||||||
advancedFilters: jsonAdvancedFilters,
|
advancedFilters: decodedAdvancedFilters,
|
||||||
serverId,
|
serverId,
|
||||||
skip: Number(skip),
|
skip: Number(skip),
|
||||||
take: Number(take),
|
take: Number(take),
|
||||||
|
|||||||
@@ -134,8 +134,11 @@ const advancedFilterGroup = (
|
|||||||
for (const rule of group.rules) {
|
for (const rule of group.rules) {
|
||||||
if (rule.field && rule.operator) {
|
if (rule.field && rule.operator) {
|
||||||
const [table, field, relationField] = rule.field.split('.');
|
const [table, field, relationField] = rule.field.split('.');
|
||||||
const condition = rule.operator === '!~' ? 'none' : 'some';
|
const condition =
|
||||||
|
rule.operator === '!~' || rule.operator === '!=' ? 'none' : 'some';
|
||||||
const op = operatorMap[rule.operator as keyof typeof operatorMap];
|
const op = operatorMap[rule.operator as keyof typeof operatorMap];
|
||||||
|
const value =
|
||||||
|
field !== 'releaseDate' ? rule.value : new Date(rule.value);
|
||||||
|
|
||||||
switch (table) {
|
switch (table) {
|
||||||
case 'albums':
|
case 'albums':
|
||||||
@@ -144,7 +147,7 @@ const advancedFilterGroup = (
|
|||||||
[field]: {
|
[field]: {
|
||||||
[condition]: {
|
[condition]: {
|
||||||
[relationField]: {
|
[relationField]: {
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
@@ -152,13 +155,24 @@ const advancedFilterGroup = (
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (field === 'genres') {
|
||||||
|
query[rootType].push({
|
||||||
|
[field]: {
|
||||||
|
[condition]: {
|
||||||
|
[relationField]: {
|
||||||
|
equals: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
query[rootType].push({
|
query[rootType].push({
|
||||||
[field]: {
|
[field]: {
|
||||||
mode: insensitiveFields.includes(field)
|
mode: insensitiveFields.includes(field)
|
||||||
? 'insensitive'
|
? 'insensitive'
|
||||||
: undefined,
|
: undefined,
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -171,7 +185,7 @@ const advancedFilterGroup = (
|
|||||||
[field]: {
|
[field]: {
|
||||||
some: {
|
some: {
|
||||||
[relationField]: {
|
[relationField]: {
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
@@ -181,13 +195,29 @@ const advancedFilterGroup = (
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (field === 'genres') {
|
||||||
|
query[rootType].push({
|
||||||
|
[table]: {
|
||||||
|
some: {
|
||||||
|
[field]: {
|
||||||
|
[condition]: {
|
||||||
|
[relationField]: {
|
||||||
|
equals: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
query[rootType].push({
|
query[rootType].push({
|
||||||
[table]: {
|
[table]: {
|
||||||
[condition]: {
|
[condition]: {
|
||||||
[field]: {
|
[field]: {
|
||||||
mode: 'insensitive',
|
mode: 'insensitive',
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -218,8 +248,10 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
|
|||||||
for (const rule of filter.rules) {
|
for (const rule of filter.rules) {
|
||||||
if (rule.field && rule.operator) {
|
if (rule.field && rule.operator) {
|
||||||
let [table, field, relationField] = rule.field.split('.');
|
let [table, field, relationField] = rule.field.split('.');
|
||||||
const condition = rule.operator === '!~' ? 'none' : 'some';
|
const condition =
|
||||||
|
rule.operator === '!~' || rule.operator === '!=' ? 'none' : 'some';
|
||||||
const op = operatorMap[rule.operator as keyof typeof operatorMap];
|
const op = operatorMap[rule.operator as keyof typeof operatorMap];
|
||||||
|
const value = field !== 'releaseDate' ? rule.value : new Date(rule.value);
|
||||||
|
|
||||||
switch (table) {
|
switch (table) {
|
||||||
case 'albums':
|
case 'albums':
|
||||||
@@ -228,7 +260,7 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
|
|||||||
[field]: {
|
[field]: {
|
||||||
[condition]: {
|
[condition]: {
|
||||||
[relationField]: {
|
[relationField]: {
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
@@ -236,13 +268,24 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (field === 'genres') {
|
||||||
|
rootQuery[rootQueryType].push({
|
||||||
|
[field]: {
|
||||||
|
[condition]: {
|
||||||
|
[relationField]: {
|
||||||
|
equals: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
rootQuery[rootQueryType].push({
|
rootQuery[rootQueryType].push({
|
||||||
[field]: {
|
[field]: {
|
||||||
mode: insensitiveFields.includes(field)
|
mode: insensitiveFields.includes(field)
|
||||||
? 'insensitive'
|
? 'insensitive'
|
||||||
: undefined,
|
: undefined,
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -255,7 +298,7 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
|
|||||||
[field]: {
|
[field]: {
|
||||||
some: {
|
some: {
|
||||||
[relationField]: {
|
[relationField]: {
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
@@ -265,13 +308,29 @@ const advancedFilter = (filter: AdvancedFilterGroup, user: AuthUser) => {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (field === 'genres') {
|
||||||
|
rootQuery[rootQueryType].push({
|
||||||
|
[table]: {
|
||||||
|
some: {
|
||||||
|
[field]: {
|
||||||
|
[condition]: {
|
||||||
|
[relationField]: {
|
||||||
|
equals: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rootQuery[rootQueryType].push({
|
rootQuery[rootQueryType].push({
|
||||||
[table]: {
|
[table]: {
|
||||||
[condition]: {
|
[condition]: {
|
||||||
[field]: {
|
[field]: {
|
||||||
mode: 'insensitive',
|
mode: 'insensitive',
|
||||||
[op]: rule.value,
|
[op]: value,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import { Stack, Group } from '@mantine/core';
|
import { Stack, Group } from '@mantine/core';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import { nanoid } from 'nanoid/non-secure';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
@@ -12,6 +14,7 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from '@/renderer/components';
|
} from '@/renderer/components';
|
||||||
|
import { useGenreList } from '@/renderer/features/genres';
|
||||||
|
|
||||||
export enum FilterGroupType {
|
export enum FilterGroupType {
|
||||||
AND = 'AND',
|
AND = 'AND',
|
||||||
@@ -19,10 +22,10 @@ export enum FilterGroupType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type AdvancedFilterRule = {
|
export type AdvancedFilterRule = {
|
||||||
field: string | null;
|
field?: string | null;
|
||||||
operator: string | null;
|
operator?: string | null;
|
||||||
uniqueId: string;
|
uniqueId: string;
|
||||||
value: string | number | Date | undefined | null | any;
|
value?: string | number | Date | undefined | null | any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AdvancedFilterGroup = {
|
export type AdvancedFilterGroup = {
|
||||||
@@ -58,8 +61,8 @@ const NUMBER_FILTER_OPTIONS_DATA = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const ID_FILTER_OPTIONS_DATA = [
|
const ID_FILTER_OPTIONS_DATA = [
|
||||||
{ label: 'is', value: 'equals' },
|
{ label: 'is', value: '=' },
|
||||||
{ label: 'is not', value: 'not' },
|
{ label: 'is not', value: '!=' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const FILTER_GROUP_OPTIONS_DATA = [
|
const FILTER_GROUP_OPTIONS_DATA = [
|
||||||
@@ -75,73 +78,96 @@ const FILTER_GROUP_OPTIONS_DATA = [
|
|||||||
|
|
||||||
const FILTER_OPTIONS_DATA = [
|
const FILTER_OPTIONS_DATA = [
|
||||||
{
|
{
|
||||||
|
default: '~',
|
||||||
label: 'Artist Title',
|
label: 'Artist Title',
|
||||||
value: 'artists.name',
|
value: 'artists.name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '=',
|
||||||
label: 'Artist Rating',
|
label: 'Artist Rating',
|
||||||
value: 'artists.ratings.value',
|
value: 'artists.ratings.value',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '=',
|
||||||
label: 'Artist Genre',
|
label: 'Artist Genre',
|
||||||
value: 'artists.genre',
|
value: 'artists.genres.id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '~',
|
||||||
label: 'Album Artist Title',
|
label: 'Album Artist Title',
|
||||||
value: 'albumArtists.name',
|
value: 'albumArtists.name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '=',
|
||||||
label: 'Album Artist Rating',
|
label: 'Album Artist Rating',
|
||||||
value: 'albumArtists.ratings.value',
|
value: 'albumArtists.ratings.value',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '=',
|
||||||
label: 'Album Artist Genre',
|
label: 'Album Artist Genre',
|
||||||
value: 'albumArtists.genre',
|
value: 'albumArtists.genres.id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '~',
|
||||||
label: 'Album Title',
|
label: 'Album Title',
|
||||||
value: 'albums.name',
|
value: 'albums.name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Album Genre',
|
default: '=',
|
||||||
value: 'albums.genre',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Album Rating',
|
label: 'Album Rating',
|
||||||
value: 'albums.ratings.value',
|
value: 'albums.ratings.value',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '=',
|
||||||
|
label: 'Album Genre',
|
||||||
|
value: 'albums.genres.id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: '=',
|
||||||
label: 'Album Year',
|
label: 'Album Year',
|
||||||
value: 'albums.releaseYear',
|
value: 'albums.releaseYear',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '<',
|
||||||
label: 'Album Release Date',
|
label: 'Album Release Date',
|
||||||
value: 'albums.releaseDate',
|
value: 'albums.releaseDate',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Album Plays',
|
default: '=',
|
||||||
|
disabled: true,
|
||||||
|
label: 'Album Play Count',
|
||||||
value: 'albums.playCount',
|
value: 'albums.playCount',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '<',
|
||||||
label: 'Album Date Added',
|
label: 'Album Date Added',
|
||||||
value: 'albums.dateAdded',
|
value: 'albums.dateAdded',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
default: '~',
|
||||||
label: 'Track Title',
|
label: 'Track Title',
|
||||||
value: 'songs.name',
|
value: 'songs.name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Track Plays',
|
default: '=',
|
||||||
value: 'songs.playCount',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Track Rating',
|
label: 'Track Rating',
|
||||||
value: 'songs.ratings.value',
|
value: 'songs.ratings.value',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
default: '=',
|
||||||
|
label: 'Track Genre',
|
||||||
|
value: 'songs.genres.id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: '=',
|
||||||
|
disabled: true,
|
||||||
|
label: 'Track Play Count',
|
||||||
|
value: 'songs.playCount',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const OPTIONS_MAP = {
|
const OPTIONS_MAP = {
|
||||||
'albumArtists.genre': {
|
'albumArtists.genres.id': {
|
||||||
type: 'id',
|
type: 'id',
|
||||||
},
|
},
|
||||||
'albumArtists.name': {
|
'albumArtists.name': {
|
||||||
@@ -156,7 +182,7 @@ const OPTIONS_MAP = {
|
|||||||
'albums.favorite': {
|
'albums.favorite': {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
'albums.genre': {
|
'albums.genres.id': {
|
||||||
type: 'id',
|
type: 'id',
|
||||||
},
|
},
|
||||||
'albums.name': {
|
'albums.name': {
|
||||||
@@ -174,7 +200,7 @@ const OPTIONS_MAP = {
|
|||||||
'albums.releaseYear': {
|
'albums.releaseYear': {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
'artists.genre': {
|
'artists.genres.id': {
|
||||||
type: 'id',
|
type: 'id',
|
||||||
},
|
},
|
||||||
'artists.name': {
|
'artists.name': {
|
||||||
@@ -183,6 +209,9 @@ const OPTIONS_MAP = {
|
|||||||
'artists.ratings.value': {
|
'artists.ratings.value': {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
|
'songs.genres.id': {
|
||||||
|
type: 'id',
|
||||||
|
},
|
||||||
'songs.name': {
|
'songs.name': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
@@ -218,7 +247,7 @@ export const formatAdvancedFiltersGroups = (groups: AdvancedFilterGroup[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Prevent query key from constantly changing due to empty rules or groups
|
// Prevent query key from constantly changing due to empty rules or groups
|
||||||
export const formatAdvancedFiltersQuery = (filter: AdvancedFilterGroup) => {
|
export const encodeAdvancedFiltersQuery = (filter: AdvancedFilterGroup) => {
|
||||||
const updatedFilter = {
|
const updatedFilter = {
|
||||||
...filter,
|
...filter,
|
||||||
group: formatAdvancedFiltersGroups(filter.group),
|
group: formatAdvancedFiltersGroups(filter.group),
|
||||||
@@ -227,7 +256,7 @@ export const formatAdvancedFiltersQuery = (filter: AdvancedFilterGroup) => {
|
|||||||
.map((rule) => ({ ...rule, uniqueId: undefined })),
|
.map((rule) => ({ ...rule, uniqueId: undefined })),
|
||||||
};
|
};
|
||||||
|
|
||||||
return updatedFilter;
|
return encodeURI(JSON.stringify(updatedFilter));
|
||||||
};
|
};
|
||||||
|
|
||||||
interface FilterOptionProps {
|
interface FilterOptionProps {
|
||||||
@@ -252,6 +281,48 @@ const FilterOption = ({
|
|||||||
onChangeValue,
|
onChangeValue,
|
||||||
}: FilterOptionProps) => {
|
}: FilterOptionProps) => {
|
||||||
const { field, operator, uniqueId, value } = data;
|
const { field, operator, uniqueId, value } = data;
|
||||||
|
const { data: genres } = useGenreList();
|
||||||
|
|
||||||
|
const genresData = useMemo(() => {
|
||||||
|
if (!genres?.data) return null;
|
||||||
|
|
||||||
|
const album = [];
|
||||||
|
const song = [];
|
||||||
|
const albumArtist = [];
|
||||||
|
const artist = [];
|
||||||
|
|
||||||
|
for (const genre of genres.data) {
|
||||||
|
if (genre.albumCount > 0) {
|
||||||
|
album.push({
|
||||||
|
label: `${genre.name} (${genre.albumCount})`,
|
||||||
|
value: genre.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genre.songCount > 0) {
|
||||||
|
song.push({
|
||||||
|
label: `${genre.name} (${genre.songCount})`,
|
||||||
|
value: genre.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genre.albumArtistCount > 0) {
|
||||||
|
albumArtist.push({
|
||||||
|
label: `${genre.name} (${genre.albumArtistCount})`,
|
||||||
|
value: genre.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genre.artistCount > 0) {
|
||||||
|
artist.push({
|
||||||
|
label: `${genre.name} (${genre.artistCount})`,
|
||||||
|
value: genre.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { album, albumArtist, artist, song };
|
||||||
|
}, [genres]);
|
||||||
|
|
||||||
const handleDeleteRule = () => {
|
const handleDeleteRule = () => {
|
||||||
onDeleteRule({ groupIndex, level, uniqueId });
|
onDeleteRule({ groupIndex, level, uniqueId });
|
||||||
@@ -281,6 +352,17 @@ const FilterOption = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDate = e instanceof Date;
|
||||||
|
|
||||||
|
if (isDate) {
|
||||||
|
return onChangeValue({
|
||||||
|
groupIndex,
|
||||||
|
level,
|
||||||
|
uniqueId,
|
||||||
|
value: dayjs(e).format('YYYY-MM-DD'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return onChangeValue({
|
return onChangeValue({
|
||||||
groupIndex,
|
groupIndex,
|
||||||
level,
|
level,
|
||||||
@@ -337,10 +419,10 @@ const FilterOption = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filterInputValueMap = {
|
const filterInputValueMap = {
|
||||||
'albumArtists.genre': (
|
'albumArtists.genres.id': (
|
||||||
<Select
|
<Select
|
||||||
searchable
|
searchable
|
||||||
data={[]}
|
data={genresData?.albumArtist || []}
|
||||||
maxWidth={175}
|
maxWidth={175}
|
||||||
size="xs"
|
size="xs"
|
||||||
value={value}
|
value={value}
|
||||||
@@ -380,10 +462,10 @@ const FilterOption = ({
|
|||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
'albums.genre': (
|
'albums.genres.id': (
|
||||||
<Select
|
<Select
|
||||||
searchable
|
searchable
|
||||||
data={[]}
|
data={genresData?.album || []}
|
||||||
maxWidth={175}
|
maxWidth={175}
|
||||||
size="xs"
|
size="xs"
|
||||||
value={value}
|
value={value}
|
||||||
@@ -443,10 +525,10 @@ const FilterOption = ({
|
|||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
'artists.genre': (
|
'artists.genres.id': (
|
||||||
<Select
|
<Select
|
||||||
searchable
|
searchable
|
||||||
data={[]}
|
data={genresData?.artist || []}
|
||||||
maxWidth={175}
|
maxWidth={175}
|
||||||
size="xs"
|
size="xs"
|
||||||
value={value}
|
value={value}
|
||||||
@@ -474,6 +556,17 @@ const FilterOption = ({
|
|||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
'songs.genres.id': (
|
||||||
|
<Select
|
||||||
|
searchable
|
||||||
|
data={genresData?.song || []}
|
||||||
|
maxWidth={175}
|
||||||
|
size="xs"
|
||||||
|
value={value}
|
||||||
|
width="20%"
|
||||||
|
onChange={handleChangeValue}
|
||||||
|
/>
|
||||||
|
),
|
||||||
'songs.name': (
|
'songs.name': (
|
||||||
<TextInput
|
<TextInput
|
||||||
maxWidth={175}
|
maxWidth={175}
|
||||||
@@ -640,39 +733,55 @@ const FilterGroup = ({
|
|||||||
</DropdownMenu.Dropdown>
|
</DropdownMenu.Dropdown>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Group>
|
</Group>
|
||||||
{data.rules.map((rule: AdvancedFilterRule) => (
|
<AnimatePresence key="advanced-filter-option" initial={false}>
|
||||||
<FilterOption
|
{data.rules.map((rule: AdvancedFilterRule) => (
|
||||||
key={rule.uniqueId}
|
<motion.div
|
||||||
data={rule}
|
key={rule.uniqueId}
|
||||||
groupIndex={groupIndex || []}
|
animate={{ opacity: 1, x: 0 }}
|
||||||
level={level}
|
exit={{ opacity: 0, x: -25 }}
|
||||||
noRemove={data.rules.length === 1}
|
initial={{ opacity: 0, x: -25 }}
|
||||||
onChangeField={onChangeField}
|
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
||||||
onChangeOperator={onChangeOperator}
|
>
|
||||||
onChangeValue={onChangeValue}
|
<FilterOption
|
||||||
onDeleteRule={onDeleteRule}
|
data={rule}
|
||||||
/>
|
groupIndex={groupIndex || []}
|
||||||
))}
|
level={level}
|
||||||
{data.group && (
|
noRemove={data.rules.length === 1}
|
||||||
<>
|
|
||||||
{data.group.map((group: AdvancedFilterGroup, index: number) => (
|
|
||||||
<FilterGroup
|
|
||||||
key={group.uniqueId}
|
|
||||||
data={group}
|
|
||||||
groupIndex={[...(groupIndex || []), index]}
|
|
||||||
level={level + 1}
|
|
||||||
uniqueId={group.uniqueId}
|
|
||||||
onAddRule={onAddRule}
|
|
||||||
onAddRuleGroup={onAddRuleGroup}
|
|
||||||
onChangeField={onChangeField}
|
onChangeField={onChangeField}
|
||||||
onChangeOperator={onChangeOperator}
|
onChangeOperator={onChangeOperator}
|
||||||
onChangeType={onChangeType}
|
|
||||||
onChangeValue={onChangeValue}
|
onChangeValue={onChangeValue}
|
||||||
onDeleteRule={onDeleteRule}
|
onDeleteRule={onDeleteRule}
|
||||||
onDeleteRuleGroup={onDeleteRuleGroup}
|
|
||||||
/>
|
/>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</AnimatePresence>
|
||||||
|
{data.group && (
|
||||||
|
<AnimatePresence key="advanced-filter-group" initial={false}>
|
||||||
|
{data.group.map((group: AdvancedFilterGroup, index: number) => (
|
||||||
|
<motion.div
|
||||||
|
key={group.uniqueId}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
exit={{ opacity: 0, x: -25 }}
|
||||||
|
initial={{ opacity: 0, x: -25 }}
|
||||||
|
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
||||||
|
>
|
||||||
|
<FilterGroup
|
||||||
|
data={group}
|
||||||
|
groupIndex={[...(groupIndex || []), index]}
|
||||||
|
level={level + 1}
|
||||||
|
uniqueId={group.uniqueId}
|
||||||
|
onAddRule={onAddRule}
|
||||||
|
onAddRuleGroup={onAddRuleGroup}
|
||||||
|
onChangeField={onChangeField}
|
||||||
|
onChangeOperator={onChangeOperator}
|
||||||
|
onChangeType={onChangeType}
|
||||||
|
onChangeValue={onChangeValue}
|
||||||
|
onDeleteRule={onDeleteRule}
|
||||||
|
onDeleteRuleGroup={onDeleteRuleGroup}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</>
|
</AnimatePresence>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
@@ -701,10 +810,10 @@ export const AdvancedFilters = ({ filters, setFilters }: any) => {
|
|||||||
group: [],
|
group: [],
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
field: undefined,
|
field: '',
|
||||||
operator: undefined,
|
operator: '',
|
||||||
uniqueId: nanoid(),
|
uniqueId: nanoid(),
|
||||||
value: undefined,
|
value: '',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
type: FilterGroupType.AND,
|
type: FilterGroupType.AND,
|
||||||
@@ -800,11 +909,15 @@ export const AdvancedFilters = ({ filters, setFilters }: any) => {
|
|||||||
path,
|
path,
|
||||||
get(filtersCopy, path).map((rule: AdvancedFilterRule) => {
|
get(filtersCopy, path).map((rule: AdvancedFilterRule) => {
|
||||||
if (rule.uniqueId !== uniqueId) return rule;
|
if (rule.uniqueId !== uniqueId) return rule;
|
||||||
|
const defaultOperator = FILTER_OPTIONS_DATA.find(
|
||||||
|
(option) => option.value === value
|
||||||
|
)?.default;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...rule,
|
...rule,
|
||||||
field: value,
|
field: value,
|
||||||
operator: null,
|
operator: defaultOperator || '',
|
||||||
value: null,
|
value: '',
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user