add originalyear to smart playlist filters (#1746)

This commit is contained in:
jeffvli
2026-02-24 00:34:07 -08:00
parent ec12e89653
commit ceef7964af
3 changed files with 34 additions and 33 deletions
@@ -139,7 +139,7 @@ const QueryValueInput = ({
case 'dateRange':
if (operator === 'inTheRangeDate') {
return (
<Group gap="sm" wrap="nowrap">
<Group gap="sm" grow wrap="nowrap">
<DateInput
clearable
defaultLevel="year"
+32 -32
View File
@@ -86,18 +86,9 @@ export const parseQueryBuilderChildren = (groups: QueryBuilderGroup[], data: any
for (const rule of group.rules) {
if (rule.field && rule.operator) {
const [table, field] = rule.field.split('.');
let operator = rule.operator;
const operator = mapDatePickerOperatorToApi(rule.operator);
const value = field !== 'releaseDate' ? rule.value : new Date(rule.value);
// Transform date picker operators back to original operators
if (operator === 'beforeDate') {
operator = 'before';
} else if (operator === 'afterDate') {
operator = 'after';
} else if (operator === 'inTheRangeDate') {
operator = 'inTheRange';
}
switch (table) {
default:
query[rootType].push({
@@ -132,7 +123,7 @@ export const convertQueryGroupToNDQuery = (filter: QueryBuilderGroup) => {
for (const rule of filter.rules) {
if (rule.field && rule.operator) {
const [field] = rule.field.split('.');
let operator = rule.operator;
const operator = mapDatePickerOperatorToApi(rule.operator);
let value = rule.value;
const booleanFields = NDSongQueryFields.filter(
@@ -144,14 +135,6 @@ export const convertQueryGroupToNDQuery = (filter: QueryBuilderGroup) => {
value = value === 'true';
}
if (operator === 'beforeDate') {
operator = 'before';
} else if (operator === 'afterDate') {
operator = 'after';
} else if (operator === 'inTheRangeDate') {
operator = 'inTheRange';
}
switch (field) {
default:
rootQuery[rootQueryType].push({
@@ -200,19 +183,8 @@ export const convertNDQueryToQueryGroup = (query: Record<string, any>) => {
value = value.toString();
}
const dateFields = NDSongQueryFields.filter(
(queryField) => queryField.type === 'date' || queryField.type === 'dateRange',
).map((field) => field.value);
if (dateFields.includes(field)) {
if (operator === 'before') {
operator = 'beforeDate';
} else if (operator === 'after') {
operator = 'afterDate';
} else if (operator === 'inTheRange') {
operator = 'inTheRangeDate';
}
}
// Use date-picker operator in UI when value is date-like (e.g. YYYY-MM-DD); otherwise keep API operator
operator = mapApiOperatorToDatePicker(operator, value);
rootGroup.rules.push({
field,
@@ -225,3 +197,31 @@ export const convertNDQueryToQueryGroup = (query: Record<string, any>) => {
return rootGroup;
};
const DATE_STRING_REGEX = /^\d{4}-\d{2}-\d{2}$/;
function isDateLikeValue(value: unknown): boolean {
if (value instanceof Date) return true;
if (typeof value === 'string') return DATE_STRING_REGEX.test(value.trim());
return false;
}
function isDateRangeValue(value: unknown): value is [null | string, null | string] {
if (!Array.isArray(value) || value.length !== 2) return false;
const [a, b] = value;
return (a == null || isDateLikeValue(a)) && (b == null || isDateLikeValue(b));
}
function mapApiOperatorToDatePicker(operator: string, value: unknown): string {
if (operator === 'before' && isDateLikeValue(value)) return 'beforeDate';
if (operator === 'after' && isDateLikeValue(value)) return 'afterDate';
if (operator === 'inTheRange' && isDateRangeValue(value)) return 'inTheRangeDate';
return operator;
}
function mapDatePickerOperatorToApi(operator: string): string {
if (operator === 'beforeDate') return 'before';
if (operator === 'afterDate') return 'after';
if (operator === 'inTheRangeDate') return 'inTheRange';
return operator;
}
@@ -144,6 +144,7 @@ export const NDSongQueryFields = [
{ label: 'MusicBrainz Work Id', type: 'string', value: 'musicbrainz_workid' },
{ label: 'Name', type: 'string', value: 'title' },
{ label: 'Original Date', type: 'date', value: 'originaldate' },
{ label: 'Original Year', type: 'date', value: 'originalyear' },
{ label: 'Performer', type: 'string', value: 'performer' },
{ label: 'Play Count', type: 'number', value: 'playcount' },
{ label: 'Playlist', type: 'playlist', value: 'id' },