Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from typing import Any, Dict, List, Optional, Sequence
from .collections_search_text import search_text ← from collections.search-text ^1.0.0 · built alongside by fune
from .todo_filter_types import TodoFilter
from .todo_item import Todo ← from todo.item ^1.0.0 · built alongside by fune
from .todo_item_validate_draft import trim_space
from .todo_normalise_tags import normalise_tags ← from todo.normalise-tags ^1.0.0 · built alongside by fune
_VIEWS = ("all", "active", "completed")
def filter_todos(todos: Sequence[Todo], filter: TodoFilter) -> List[Todo]:
"""The todos a list shows for its view, tag and search box, in input order.
The tag is normalised like stored tags, so "#Home" finds "home"; one that
normalises to nothing matches no todo. The search covers the title, the
notes and the tags joined with spaces (collections.search-text).
"""
if filter.view not in _VIEWS:
raise ValueError(f'unknown view "{filter.view}": expected all, active or completed')
wanted: Optional[str] = None
if filter.tag is not None:
tags = normalise_tags([filter.tag])
if len(tags) == 0:
return []
wanted = tags[0]
kept: List[Todo] = []
for todo in todos:
if filter.view == "active" and todo.done:
continue
if filter.view == "completed" and not todo.done:
continue
if wanted is not None and wanted not in todo.tags:
continue
kept.append(todo)
query = trim_space(filter.query)
if query == "":
return kept
records: List[Dict[str, Any]] = [
{"i": i, "title": todo.title, "notes": todo.notes, "tags": " ".join(todo.tags)} for i, todo in enumerate(kept)
]
return [kept[r["i"]] for r in search_text(records, ["title", "notes", "tags"], query)]