mirror of
https://github.com/agregarr/agregarr.git
synced 2026-01-09 07:45:17 +08:00
parent
d32c041faf
commit
15d343e8ee
@ -197,7 +197,8 @@ export interface ConditionRule {
|
||||
| 'contains' // string contains
|
||||
| 'regex' // regex match
|
||||
| 'begins' // string begins with
|
||||
| 'ends'; // string ends with
|
||||
| 'ends' // string ends with
|
||||
| 'exists'; // field exists (has non-null/undefined value)
|
||||
value: string | number | boolean | (string | number)[];
|
||||
}
|
||||
|
||||
|
||||
@ -185,6 +185,12 @@ function evaluateRule(
|
||||
if (rule.operator === 'neq') {
|
||||
return conditionValue !== undefined && conditionValue !== null;
|
||||
}
|
||||
// For 'exists', we need to evaluate based on the presence/absence of value
|
||||
if (rule.operator === 'exists') {
|
||||
// value is null/undefined, so field does NOT exist
|
||||
// Return true if conditionValue is false (checking for non-existence)
|
||||
return conditionValue === false;
|
||||
}
|
||||
// For all other operators (eq, gt, gte, lt, lte, contains, in, etc.)
|
||||
// undefined/null means the condition can't be evaluated, so false
|
||||
return false;
|
||||
@ -292,6 +298,14 @@ function evaluateRule(
|
||||
typeof conditionValue === 'string' &&
|
||||
value.toLowerCase().endsWith(conditionValue.toLowerCase())
|
||||
);
|
||||
case 'exists':
|
||||
// Check if field has a non-null/undefined value
|
||||
// conditionValue should be boolean: true = exists, false = not exists
|
||||
if (typeof conditionValue === 'boolean') {
|
||||
const hasValue = value !== undefined && value !== null;
|
||||
return conditionValue ? hasValue : !hasValue;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ const messages = defineMessages({
|
||||
opBegins: 'begins with',
|
||||
opEnds: 'ends with',
|
||||
opIn: 'in',
|
||||
opExists: 'exists',
|
||||
and: 'AND',
|
||||
or: 'OR',
|
||||
});
|
||||
@ -143,6 +144,7 @@ const RuleItem: React.FC<RuleItemProps> = ({
|
||||
const isRadarrTags = field === 'radarrTags';
|
||||
const isSonarrTags = field === 'sonarrTags';
|
||||
const isTagField = isRadarrTags || isSonarrTags;
|
||||
const isExistsOperator = operator === 'exists';
|
||||
|
||||
// Fetch all tags from all Radarr instances
|
||||
const { data: radarrTags } = useSWR<ArrTag[]>(
|
||||
@ -218,14 +220,14 @@ const RuleItem: React.FC<RuleItemProps> = ({
|
||||
const numericOnlyOperators = ['gt', 'gte', 'lt', 'lte'];
|
||||
const isCurrentOperatorInvalid =
|
||||
(!isNewFieldNumeric && numericOnlyOperators.includes(operator)) ||
|
||||
(isNewFieldBoolean && !['eq', 'neq'].includes(operator));
|
||||
(isNewFieldBoolean && !['eq', 'neq', 'exists'].includes(operator));
|
||||
|
||||
// Reset to appropriate defaults when changing field
|
||||
onChange({
|
||||
...rule,
|
||||
field: newField,
|
||||
operator: isCurrentOperatorInvalid ? 'eq' : rule.operator,
|
||||
value: isNewFieldBoolean ? true : '',
|
||||
value: operator === 'exists' || isNewFieldBoolean ? true : '',
|
||||
});
|
||||
}}
|
||||
className="flex-1 select-none rounded border border-stone-600 bg-stone-700 px-2 py-1 text-sm text-white"
|
||||
@ -247,9 +249,12 @@ const RuleItem: React.FC<RuleItemProps> = ({
|
||||
<select
|
||||
value={operator}
|
||||
onChange={(e) => {
|
||||
const newOperator = e.target.value as ConditionRule['operator'];
|
||||
onChange({
|
||||
...rule,
|
||||
operator: e.target.value as ConditionRule['operator'],
|
||||
operator: newOperator,
|
||||
// Set value to true when switching to 'exists' operator
|
||||
value: newOperator === 'exists' ? true : rule.value,
|
||||
});
|
||||
}}
|
||||
className="w-32 rounded border border-stone-600 bg-stone-700 px-2 py-1 text-sm text-white"
|
||||
@ -287,10 +292,11 @@ const RuleItem: React.FC<RuleItemProps> = ({
|
||||
<option value="ends">{intl.formatMessage(messages.opEnds)}</option>
|
||||
</>
|
||||
)}
|
||||
<option value="exists">{intl.formatMessage(messages.opExists)}</option>
|
||||
</select>
|
||||
|
||||
{/* Value Input */}
|
||||
{isBoolean ? (
|
||||
{isBoolean || isExistsOperator ? (
|
||||
<select
|
||||
value={String(value)}
|
||||
onChange={(e) => {
|
||||
|
||||
@ -139,7 +139,8 @@ export interface ConditionRule {
|
||||
| 'contains' // string contains
|
||||
| 'regex' // regex match
|
||||
| 'begins' // string begins with
|
||||
| 'ends'; // string ends with
|
||||
| 'ends' // string ends with
|
||||
| 'exists'; // field exists (has non-null/undefined value)
|
||||
value: string | number | boolean | (string | number)[];
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user