@@ -19,6 +19,7 @@ import {
1919 ChevronDown ,
2020 ChevronRight ,
2121 FileType ,
22+ Heading ,
2223 Link ,
2324 PlusCircle ,
2425 Rss ,
@@ -28,21 +29,26 @@ import {
2829} from "lucide-react" ;
2930import { useTranslation } from "react-i18next" ;
3031
31- import type { RuleEngineCondition } from "@karakeep/shared/types/rules" ;
32+ import type {
33+ RuleEngineCondition ,
34+ RuleEngineEvent ,
35+ } from "@karakeep/shared/types/rules" ;
3236
3337import { FeedSelector } from "../feeds/FeedSelector" ;
3438import { TagAutocomplete } from "../tags/TagAutocomplete" ;
3539
3640interface ConditionBuilderProps {
3741 value : RuleEngineCondition ;
3842 onChange : ( condition : RuleEngineCondition ) => void ;
43+ eventType : RuleEngineEvent [ "type" ] ;
3944 level ?: number ;
4045 onRemove ?: ( ) => void ;
4146}
4247
4348export function ConditionBuilder ( {
4449 value,
4550 onChange,
51+ eventType,
4652 level = 0 ,
4753 onRemove,
4854} : ConditionBuilderProps ) {
@@ -57,6 +63,12 @@ export function ConditionBuilder({
5763 case "urlDoesNotContain" :
5864 onChange ( { type : "urlDoesNotContain" , str : "" } ) ;
5965 break ;
66+ case "titleContains" :
67+ onChange ( { type : "titleContains" , str : "" } ) ;
68+ break ;
69+ case "titleDoesNotContain" :
70+ onChange ( { type : "titleDoesNotContain" , str : "" } ) ;
71+ break ;
6072 case "importedFromFeed" :
6173 onChange ( { type : "importedFromFeed" , feedId : "" } ) ;
6274 break ;
@@ -93,6 +105,9 @@ export function ConditionBuilder({
93105 case "urlContains" :
94106 case "urlDoesNotContain" :
95107 return < Link className = "h-4 w-4" /> ;
108+ case "titleContains" :
109+ case "titleDoesNotContain" :
110+ return < Heading className = "h-4 w-4" /> ;
96111 case "importedFromFeed" :
97112 return < Rss className = "h-4 w-4" /> ;
98113 case "bookmarkTypeIs" :
@@ -134,6 +149,30 @@ export function ConditionBuilder({
134149 </ div >
135150 ) ;
136151
152+ case "titleContains" :
153+ return (
154+ < div className = "mt-2" >
155+ < Input
156+ value = { value . str }
157+ onChange = { ( e ) => onChange ( { ...value , str : e . target . value } ) }
158+ placeholder = "Title contains..."
159+ className = "w-full"
160+ />
161+ </ div >
162+ ) ;
163+
164+ case "titleDoesNotContain" :
165+ return (
166+ < div className = "mt-2" >
167+ < Input
168+ value = { value . str }
169+ onChange = { ( e ) => onChange ( { ...value , str : e . target . value } ) }
170+ placeholder = "Title does not contain..."
171+ className = "w-full"
172+ />
173+ </ div >
174+ ) ;
175+
137176 case "importedFromFeed" :
138177 return (
139178 < div className = "mt-2" >
@@ -198,6 +237,7 @@ export function ConditionBuilder({
198237 newConditions [ index ] = newCondition ;
199238 onChange ( { ...value , conditions : newConditions } ) ;
200239 } }
240+ eventType = { eventType }
201241 level = { level + 1 }
202242 onRemove = { ( ) => {
203243 const newConditions = [ ...value . conditions ] ;
@@ -233,6 +273,10 @@ export function ConditionBuilder({
233273 }
234274 } ;
235275
276+ // Title conditions are hidden for "bookmarkAdded" event because
277+ // titles are not available at bookmark creation time (they're fetched during crawling)
278+ const showTitleConditions = eventType !== "bookmarkAdded" ;
279+
236280 const ConditionSelector = ( ) => (
237281 < Select value = { value . type } onValueChange = { handleTypeChange } >
238282 < SelectTrigger className = "ml-2 h-8 border-none bg-transparent px-2" >
@@ -254,6 +298,16 @@ export function ConditionBuilder({
254298 < SelectItem value = "urlDoesNotContain" >
255299 { t ( "settings.rules.conditions_types.url_does_not_contain" ) }
256300 </ SelectItem >
301+ { showTitleConditions && (
302+ < SelectItem value = "titleContains" >
303+ { t ( "settings.rules.conditions_types.title_contains" ) }
304+ </ SelectItem >
305+ ) }
306+ { showTitleConditions && (
307+ < SelectItem value = "titleDoesNotContain" >
308+ { t ( "settings.rules.conditions_types.title_does_not_contain" ) }
309+ </ SelectItem >
310+ ) }
257311 < SelectItem value = "importedFromFeed" >
258312 { t ( "settings.rules.conditions_types.imported_from_feed" ) }
259313 </ SelectItem >
0 commit comments