diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-12-30 13:29:03 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-30 11:29:03 +0000 |
| commit | b20ba9cfccd22159bf8263165cca76aab3147d9c (patch) | |
| tree | 166f5c477d1c368a5017aae9f726b692d655fc0e /apps | |
| parent | a0b4a26ad398137e13c35f3fe0dad99154537d91 (diff) | |
| download | karakeep-b20ba9cfccd22159bf8263165cca76aab3147d9c.tar.zst | |
feat: add "URL Does Not Contain" condition to rule engine (#2280)
* feat: add "URL Does Not Contain" condition to rule engine
Add a new condition type `urlDoesNotContain` that allows users to create
rules based on URLs that do NOT contain specific strings. This enables
more flexible rule configurations, such as:
- Automatically adding bookmarks to a "Read Later" list if the URL
does not contain "reddit.com" or "youtube.com"
Changes:
- Added `urlDoesNotContain` condition type to Zod schema
- Implemented evaluation logic in RuleEngine
- Added UI support in ConditionBuilder component
- Added translation key for new condition type
- Added test coverage for the new condition
Fixes #2259
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Mohamed Bassem <MohamedBassem@users.noreply.github.com>
* fix type link
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Mohamed Bassem <MohamedBassem@users.noreply.github.com>
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/web/components/dashboard/rules/RuleEngineConditionBuilder.tsx | 19 | ||||
| -rw-r--r-- | apps/web/lib/i18n/locales/en/translation.json | 1 |
2 files changed, 20 insertions, 0 deletions
diff --git a/apps/web/components/dashboard/rules/RuleEngineConditionBuilder.tsx b/apps/web/components/dashboard/rules/RuleEngineConditionBuilder.tsx index 8faca013..a859a4cc 100644 --- a/apps/web/components/dashboard/rules/RuleEngineConditionBuilder.tsx +++ b/apps/web/components/dashboard/rules/RuleEngineConditionBuilder.tsx @@ -54,6 +54,9 @@ export function ConditionBuilder({ case "urlContains": onChange({ type: "urlContains", str: "" }); break; + case "urlDoesNotContain": + onChange({ type: "urlDoesNotContain", str: "" }); + break; case "importedFromFeed": onChange({ type: "importedFromFeed", feedId: "" }); break; @@ -88,6 +91,7 @@ export function ConditionBuilder({ const renderConditionIcon = (type: RuleEngineCondition["type"]) => { switch (type) { case "urlContains": + case "urlDoesNotContain": return <Link className="h-4 w-4" />; case "importedFromFeed": return <Rss className="h-4 w-4" />; @@ -118,6 +122,18 @@ export function ConditionBuilder({ </div> ); + case "urlDoesNotContain": + return ( + <div className="mt-2"> + <Input + value={value.str} + onChange={(e) => onChange({ ...value, str: e.target.value })} + placeholder="URL does not contain..." + className="w-full" + /> + </div> + ); + case "importedFromFeed": return ( <div className="mt-2"> @@ -235,6 +251,9 @@ export function ConditionBuilder({ <SelectItem value="urlContains"> {t("settings.rules.conditions_types.url_contains")} </SelectItem> + <SelectItem value="urlDoesNotContain"> + {t("settings.rules.conditions_types.url_does_not_contain")} + </SelectItem> <SelectItem value="importedFromFeed"> {t("settings.rules.conditions_types.imported_from_feed")} </SelectItem> diff --git a/apps/web/lib/i18n/locales/en/translation.json b/apps/web/lib/i18n/locales/en/translation.json index 58e1af09..87851324 100644 --- a/apps/web/lib/i18n/locales/en/translation.json +++ b/apps/web/lib/i18n/locales/en/translation.json @@ -348,6 +348,7 @@ "conditions_types": { "always": "Always", "url_contains": "URL Contains", + "url_does_not_contain": "URL Does Not Contain", "imported_from_feed": "Imported From Feed", "bookmark_type_is": "Bookmark Type Is", "has_tag": "Has Tag", |
