feat: node search picker, ByNode grouping fix, PDF export
- node picker: Search/Path on Repository, SearchNodes binding, debounced search dropdown showing title + full path - ByNode summary groups by nodeID with NodePath as label (not NodeTitle) - PDF export for worklog reports with embedded DejaVuSans fonts - ExportWorklogPDF binding + button on Journal screen - Removed unused Section field from ReportFilter - ListReport now calls BuildReportPaths so nodePath is available - go.sum: +github.com/signintech/gopdf dependency
This commit is contained in:
@@ -185,6 +185,46 @@ func (r *Repository) CountChildren(parentID string, types ...string) (int, error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// Search finds active nodes whose title contains the query (case-insensitive).
|
||||
func (r *Repository) Search(query string, limit int) ([]Node, error) {
|
||||
q := `SELECT ` + nodeColumns + ` FROM nodes
|
||||
WHERE deleted_at IS NULL AND title LIKE ? ORDER BY sort_order, title LIMIT ?`
|
||||
rows, err := r.db.Query(q, "%"+query+"%", limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return scanNodes(rows)
|
||||
}
|
||||
|
||||
// Path builds the full path from root to the given node by walking parent_id chain.
|
||||
// Returns "title1 > title2 > ... > nodetitle". Returns empty string on error.
|
||||
func (r *Repository) Path(nodeID string) string {
|
||||
var segments []string
|
||||
currentID := nodeID
|
||||
seen := make(map[string]bool)
|
||||
for i := 0; i < 10; i++ {
|
||||
if currentID == "" || seen[currentID] {
|
||||
break
|
||||
}
|
||||
seen[currentID] = true
|
||||
var title string
|
||||
var parent sql.NullString
|
||||
err := r.db.QueryRow(
|
||||
`SELECT title, parent_id FROM nodes WHERE id = ?`, currentID,
|
||||
).Scan(&title, &parent)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
segments = append([]string{title}, segments...)
|
||||
if !parent.Valid {
|
||||
break
|
||||
}
|
||||
currentID = parent.String
|
||||
}
|
||||
return strings.Join(segments, " > ")
|
||||
}
|
||||
|
||||
// ListByParent returns children as *Node pointers. parentID must not be empty.
|
||||
func (r *Repository) ListByParent(parentID string) ([]*Node, error) {
|
||||
rows, err := r.db.Query(
|
||||
|
||||
Reference in New Issue
Block a user