From df4f05b14ccc407df09aab005e4eec3a935a9628 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Thu, 5 Jan 2023 02:27:29 -0800 Subject: [PATCH] Finalize base features for smart playlist editor --- src/renderer/api/navidrome.types.ts | 102 ++- .../components/query-builder/index.tsx | 48 +- .../query-builder/query-builder-option.tsx | 363 +++------ .../playlist-detail-song-list-header.tsx | 32 +- .../components/playlist-query-builder.tsx | 692 ++++++++++-------- .../playlist-detail-song-list-route.tsx | 126 +++- 6 files changed, 739 insertions(+), 624 deletions(-) diff --git a/src/renderer/api/navidrome.types.ts b/src/renderer/api/navidrome.types.ts index 33e5de18..79d61295 100644 --- a/src/renderer/api/navidrome.types.ts +++ b/src/renderer/api/navidrome.types.ts @@ -353,40 +353,74 @@ export type NDPlaylistSongList = { }; export const NDSongQueryFields = [ - { label: 'Title', value: 'title' }, - { label: 'Album', value: 'album' }, - { label: 'Artist', value: 'artist' }, - { label: 'Album artist', value: 'albumartist' }, - { label: 'Has cover art', value: 'hascoverart' }, - { label: 'Track number', value: 'tracknumber' }, - { label: 'Disc number', value: 'discnumber' }, - { label: 'Year', value: 'year' }, - { label: 'Size', value: 'size' }, - { label: 'Is compilation', value: 'compilation' }, - { label: 'Date added', value: 'dateadded' }, - { label: 'Date modified', value: 'datemodified' }, - { label: 'Disc subtitle', value: 'discsubtitle' }, - { label: 'Comment', value: 'comment' }, - { label: 'Lyrics', value: 'lyrics' }, - { label: 'Sort title', value: 'sorttitle' }, - { label: 'Sort album', value: 'sortalbum' }, - { label: 'Sort artist', value: 'sortartist' }, - { label: 'Sort album artist', value: 'sortalbumartist' }, - { label: 'Album type', value: 'albumtype' }, - { label: 'Album comment', value: 'albumcomment' }, - { label: 'Catalog number', value: 'catalognumber' }, - { label: 'File path', value: 'filepath' }, - { label: 'File type', value: 'filetype' }, - { label: 'Duration', value: 'duration' }, - { label: 'Bitrate', value: 'bitrate' }, - { label: 'BPM', value: 'bpm' }, - { label: 'Channels', value: 'channels' }, - { label: 'Genre', value: 'genre' }, - { label: 'Is favorite', value: 'loved' }, - { label: 'Date favorited', value: 'dateloved' }, - { label: 'Last played', value: 'lastplayed' }, - { label: 'Play count', value: 'playcount' }, - { label: 'Rating', value: 'rating' }, + { label: 'Album', type: 'string', value: 'album' }, + { label: 'Album Artist', type: 'string', value: 'albumartist' }, + { label: 'Album Comment', type: 'string', value: 'albumcomment' }, + { label: 'Album Type', type: 'string', value: 'albumtype' }, + { label: 'Artist', type: 'string', value: 'artist' }, + { label: 'Bitrate', type: 'number', value: 'bitrate' }, + { label: 'BPM', type: 'number', value: 'bpm' }, + { label: 'Catalog Number', type: 'string', value: 'catalognumber' }, + { label: 'Channels', type: 'number', value: 'channels' }, + { label: 'Comment', type: 'string', value: 'comment' }, + { label: 'Date Added', type: 'date', value: 'dateadded' }, + { label: 'Date Favorited', type: 'date', value: 'dateloved' }, + { label: 'Date Last Played', type: 'date', value: 'lastplayed' }, + { label: 'Date Modified', type: 'date', value: 'datemodified' }, + { label: 'Disc Subtitle', type: 'string', value: 'discsubtitle' }, + { label: 'Disc Number', type: 'number', value: 'discnumber' }, + { label: 'Duration', type: 'number', value: 'duration' }, + { label: 'File Path', type: 'string', value: 'filepath' }, + { label: 'File Type', type: 'string', value: 'filetype' }, + { label: 'Genre', type: 'string', value: 'genre' }, + { label: 'Has CoverArt', type: 'boolean', value: 'hascoverart' }, + { label: 'Is Compilation', type: 'boolean', value: 'compilation' }, + { label: 'Is Favorite', type: 'boolean', value: 'loved' }, + { label: 'Lyrics', type: 'string', value: 'lyrics' }, + { label: 'Name', type: 'string', value: 'title' }, + { label: 'Play Count', type: 'number', value: 'playcount' }, + { label: 'Rating', type: 'number', value: 'rating' }, + { label: 'Size', type: 'number', value: 'size' }, + { label: 'Sort Album', type: 'string', value: 'sortalbum' }, + { label: 'Sort Album Artist', type: 'string', value: 'sortalbumartist' }, + { label: 'Sort Artist', type: 'string', value: 'sortartist' }, + { label: 'Sort Name', type: 'string', value: 'sorttitle' }, + { label: 'Track Number', type: 'number', value: 'tracknumber' }, + { label: 'Year', type: 'number', value: 'year' }, +]; + +export const NDSongQueryDateOperators = [ + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'is before', value: 'before' }, + { label: 'is after', value: 'after' }, + { label: 'is in the last', value: 'inTheLast' }, + { label: 'is not in the last', value: 'notInTheLast' }, + { label: 'is in the range', value: 'inTheRange' }, +]; + +export const NDSongQueryStringOperators = [ + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'contains', value: 'contains' }, + { label: 'does not contain', value: 'notContains' }, + { label: 'starts with', value: 'startsWith' }, + { label: 'ends with', value: 'endsWith' }, +]; + +export const NDSongQueryBooleanOperators = [ + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, +]; + +export const NDSongQueryNumberOperators = [ + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'contains', value: 'contains' }, + { label: 'does not contain', value: 'notContains' }, + { label: 'is greater than', value: 'gt' }, + { label: 'is less than', value: 'lt' }, + { label: 'is in the range', value: 'inTheRange' }, ]; export type NDUserListParams = { diff --git a/src/renderer/components/query-builder/index.tsx b/src/renderer/components/query-builder/index.tsx index 82b59567..f12cb424 100644 --- a/src/renderer/components/query-builder/index.tsx +++ b/src/renderer/components/query-builder/index.tsx @@ -30,7 +30,7 @@ type DeleteArgs = { }; interface QueryBuilderProps { data: Record; - filters: { label: string; value: string }[]; + filters: { label: string; type: string; value: string }[]; groupIndex: number[]; level: number; onAddRule: (args: AddArgs) => void; @@ -39,8 +39,16 @@ interface QueryBuilderProps { onChangeOperator: (args: any) => void; onChangeType: (args: any) => void; onChangeValue: (args: any) => void; + onClearFilters: () => void; onDeleteRule: (args: DeleteArgs) => void; onDeleteRuleGroup: (args: DeleteArgs) => void; + onResetFilters: () => void; + operators: { + boolean: { label: string; value: string }[]; + date: { label: string; value: string }[]; + number: { label: string; value: string }[]; + string: { label: string; value: string }[]; + }; uniqueId: string; } @@ -53,8 +61,11 @@ export const QueryBuilder = ({ onAddRuleGroup, onChangeType, onChangeField, + operators, onChangeOperator, onChangeValue, + onClearFilters, + onResetFilters, groupIndex, uniqueId, filters, @@ -95,7 +106,7 @@ export const QueryBuilder = ({ > - +