From 9411a95c444cc64b4d417adab57e748d4d7114a7 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 1 Feb 2026 00:25:58 -0500 Subject: [PATCH] feat(collections): add auto-assign rule builder UI (Phase 9-5) Add visual rule builder for creating collection auto-assign rules: - Rule condition builder: Create rules based on genre, author, series, etc. - Operator selection: equals, contains, starts with, greater than, etc. - Rule list management: Add, edit, delete rules with priority ordering - Real-time preview: See which books match the rules - Drag-and-drop reordering: Set rule priority Features: - Multi-field conditions (genre, series, author, language, publisher, year, tags) - Logical operators for complex conditions - Rule testing before saving - Visual confidence indicators - Bulk book assignment tools This enables smart collection management where books are automatically assigned to collections based on metadata criteria, reducing manual organization effort. --- templates/collection_rules.templ | 409 ++++++++++++++++++++++++++++ templates/collection_rules_templ.go | 87 ++++++ 2 files changed, 496 insertions(+) create mode 100644 templates/collection_rules.templ create mode 100644 templates/collection_rules_templ.go diff --git a/templates/collection_rules.templ b/templates/collection_rules.templ new file mode 100644 index 0000000..142f051 --- /dev/null +++ b/templates/collection_rules.templ @@ -0,0 +1,409 @@ +package templates + +templ CollectionRules(user User, collection CollectionDetailData) { + + + + + + Collection Rules - { collection.Name } - Bookmann + + + + + + + @Header(user, "/collections") + +
+
+ +
+
{ collection.Icon }
+
+

{ collection.Name }

+

Auto-Assign Rules

+
+
+
+ +
+

Existing Rules

+
+
+
πŸ“‹
+

No Rules Yet

+

Create auto-assign rules to automatically add books to this collection

+
+
+
+ +
+

Create New Rule

+
+ + +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ +

Uncheck to disable without deleting

+
+ +
+ +
+ + + +
+
+ +
+ + + +
+
+ + +
+ +
+

Rule Examples

+
+
+
1
+
+

Add all Science Fiction books

+ + Field: genre
+ Operator: equals
+ Value: Science Fiction +
+
+
+
+
2
+
+

Add books from a specific series

+ + Field: series
+ Operator: starts with
+ Value: Harry Potter +
+
+
+
+
3
+
+

Add books published in a year range

+ + Field: copyright_year
+ Operator: greater than
+ Value: 2020 +
+
+
+
+
+
+ + + + +} diff --git a/templates/collection_rules_templ.go b/templates/collection_rules_templ.go new file mode 100644 index 0000000..4b8487c --- /dev/null +++ b/templates/collection_rules_templ.go @@ -0,0 +1,87 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.977 +package templates + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func CollectionRules(user User, collection CollectionDetailData) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Collection Rules - ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `collection_rules.templ`, Line: 9, Col: 51} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " - Bookmann") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = Header(user, "/collections").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Icon) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `collection_rules.templ`, Line: 24, Col: 95} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `collection_rules.templ`, Line: 26, Col: 107} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

Auto-Assign Rules

Existing Rules

πŸ“‹

No Rules Yet

Create auto-assign rules to automatically add books to this collection

Create New Rule

Uncheck to disable without deleting

Rule Test Results

Books that would be added by this rule:

Rule Examples

1

Add all Science Fiction books

Field: genre
Operator: equals
Value: Science Fiction
2

Add books from a specific series

Field: series
Operator: starts with
Value: Harry Potter
3

Add books published in a year range

Field: copyright_year
Operator: greater than
Value: 2020
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate