voidcli 1.0.0__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {voidcli-1.0.0 → voidcli-1.1.0}/PKG-INFO +1 -1
  2. {voidcli-1.0.0 → voidcli-1.1.0}/pyproject.toml +1 -1
  3. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/collection.py +21 -3
  4. voidcli-1.1.0/void/views/note_modal.py +73 -0
  5. {voidcli-1.0.0 → voidcli-1.1.0}/.gitignore +0 -0
  6. {voidcli-1.0.0 → voidcli-1.1.0}/LICENSE +0 -0
  7. {voidcli-1.0.0 → voidcli-1.1.0}/README.md +0 -0
  8. {voidcli-1.0.0 → voidcli-1.1.0}/void/__init__.py +0 -0
  9. {voidcli-1.0.0 → voidcli-1.1.0}/void/controllers/__init__.py +0 -0
  10. {voidcli-1.0.0 → voidcli-1.1.0}/void/controllers/activity.py +0 -0
  11. {voidcli-1.0.0 → voidcli-1.1.0}/void/controllers/category.py +0 -0
  12. {voidcli-1.0.0 → voidcli-1.1.0}/void/controllers/note.py +0 -0
  13. {voidcli-1.0.0 → voidcli-1.1.0}/void/database/__init__.py +0 -0
  14. {voidcli-1.0.0 → voidcli-1.1.0}/void/database/connection.py +0 -0
  15. {voidcli-1.0.0 → voidcli-1.1.0}/void/database/init_tables.sql +0 -0
  16. {voidcli-1.0.0 → voidcli-1.1.0}/void/main.py +0 -0
  17. {voidcli-1.0.0 → voidcli-1.1.0}/void/models/__init__.py +0 -0
  18. {voidcli-1.0.0 → voidcli-1.1.0}/void/models/activity.py +0 -0
  19. {voidcli-1.0.0 → voidcli-1.1.0}/void/models/category.py +0 -0
  20. {voidcli-1.0.0 → voidcli-1.1.0}/void/models/note.py +0 -0
  21. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/__init__.py +0 -0
  22. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/activity.py +0 -0
  23. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/day_note.py +0 -0
  24. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/note.py +0 -0
  25. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/note_form.py +0 -0
  26. {voidcli-1.0.0 → voidcli-1.1.0}/void/views/welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: voidcli
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Project-URL: Repository, https://github.com/NelsonUrrutia/void
5
5
  Author-email: Nelson Urrutia <nelurrutia15@gmail.com>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "voidcli"
7
- version = "1.0.0"
7
+ version = "1.1.0"
8
8
  description = ""
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -2,11 +2,13 @@ from datetime import date
2
2
  from itertools import groupby
3
3
  from typing import override
4
4
 
5
+ from textual import on
5
6
  from textual.app import ComposeResult
6
- from textual.containers import Grid, Vertical, VerticalScroll
7
- from textual.widgets import Label, Static
7
+ from textual.containers import Grid, Right, Vertical, VerticalScroll
8
+ from textual.widgets import Button, Label, Static
8
9
 
9
10
  from void.controllers.note import NoteController
11
+ from void.views.note_modal import NoteModal
10
12
 
11
13
 
12
14
  class CollectionView(Static):
@@ -16,16 +18,24 @@ class CollectionView(Static):
16
18
  grid-size: 3;
17
19
  grid-gutter: 1;
18
20
  }
21
+ .note_card_actions{
22
+ height: auto;
23
+ margin: 0 0 1 0;
24
+ }
19
25
  """
20
26
 
21
27
  @override
22
28
  def __init__(self) -> None:
23
29
  super().__init__()
24
30
  self.ctrl = NoteController()
31
+ self.notes_by_date: dict[str, list] = {}
25
32
 
26
33
  @override
27
34
  def compose(self) -> ComposeResult:
28
35
  notes = self.ctrl.get_notes()
36
+ self.notes_by_date = {
37
+ note_date: list(rows) for note_date, rows in groupby(notes, key=lambda row: row["note_date"])
38
+ }
29
39
  with Vertical(classes="header"):
30
40
  yield Label("VOID COLLECTION", classes="module_title")
31
41
  with VerticalScroll(classes="main_container"):
@@ -33,7 +43,7 @@ class CollectionView(Static):
33
43
  yield Label("No VOID NOTE saved yet.")
34
44
  return
35
45
  with Grid(classes="card_grid note_grid"):
36
- for note_date, rows in groupby(notes, key=lambda row: row["note_date"]):
46
+ for note_date, rows in self.notes_by_date.items():
37
47
  with Vertical(classes="note_card") as card:
38
48
  card.border_title = self.format_date(note_date)
39
49
  for row in rows:
@@ -43,6 +53,14 @@ class CollectionView(Static):
43
53
  yield Label(row["notes"], classes="entry_note")
44
54
  else:
45
55
  yield Label("No notes written.", classes="entry_empty")
56
+ with Right(classes="note_card_actions"):
57
+ yield Button("EXPAND", name=note_date, classes="open_note", flat=True)
46
58
 
47
59
  def format_date(self, date_str):
48
60
  return date.fromisoformat(date_str).strftime("%B %d, %Y").upper()
61
+
62
+ @on(Button.Pressed, ".open_note")
63
+ def on_open_note(self, event: Button.Pressed) -> None:
64
+ note_date = event.button.name
65
+ if note_date in self.notes_by_date:
66
+ self.app.push_screen(NoteModal(self.format_date(note_date), self.notes_by_date[note_date]))
@@ -0,0 +1,73 @@
1
+ from itertools import groupby
2
+ from typing import override
3
+
4
+ from textual import on
5
+ from textual.app import ComposeResult
6
+ from textual.binding import Binding
7
+ from textual.containers import Center, Vertical, VerticalScroll
8
+ from textual.screen import ModalScreen
9
+ from textual.widgets import Button, Label
10
+
11
+
12
+ class NoteModal(ModalScreen[None]):
13
+
14
+ BINDINGS = [Binding("escape", "close", "Close")]
15
+
16
+ DEFAULT_CSS = """
17
+ NoteModal{
18
+ align: center middle;
19
+ }
20
+ .modal_card{
21
+ width: 90%;
22
+ height: 90%;
23
+ padding: 1 4;
24
+ border: round $primary;
25
+ border-title-color: $accent;
26
+ border-title-style: bold;
27
+ background: $background;
28
+ }
29
+ .modal_card .section_title{
30
+ padding: 1 0 1 0;
31
+ }
32
+ .modal_card .entry_card{
33
+ padding: 1 0 1 2;
34
+ }
35
+ .modal_body{
36
+ height: 1fr;
37
+ }
38
+ .modal_footer{
39
+ height: auto;
40
+ padding: 1 0 0 0;
41
+ }
42
+ """
43
+
44
+ @override
45
+ def __init__(self, title: str, rows: list) -> None:
46
+ super().__init__()
47
+ self.note_title = title
48
+ self.rows = sorted(rows, key=lambda row: (row["category"], row["activity"]))
49
+
50
+ @override
51
+ def compose(self) -> ComposeResult:
52
+ with Vertical(classes="modal_card") as card:
53
+ card.border_title = self.note_title
54
+ with VerticalScroll(classes="modal_body"):
55
+ for category, group in groupby(self.rows, key=lambda row: row["category"]):
56
+ entries = list(group)
57
+ yield Label(f"── {category.upper()} · {len(entries)} ", classes="section_title")
58
+ for row in entries:
59
+ with Vertical(classes="entry_card"):
60
+ yield Label(row["activity"], classes="entry_title")
61
+ if row["notes"]:
62
+ yield Label(row["notes"], classes="entry_note")
63
+ else:
64
+ yield Label("No notes written.", classes="entry_empty")
65
+ with Center(classes="modal_footer"):
66
+ yield Button("CLOSE", id="close_note_modal", variant="primary", flat=True)
67
+
68
+ @on(Button.Pressed, "#close_note_modal")
69
+ def on_close_pressed(self) -> None:
70
+ self.action_close()
71
+
72
+ def action_close(self) -> None:
73
+ self.dismiss()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes