mirror of
https://github.com/gmbrax/Pilgrim.git
synced 2026-11-10 13:00:17 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
821845530a | ||
|
|
58c7bfd8e9 | ||
|
|
03fb3b23c2 |
Generated
+20
-21
@@ -6,10 +6,8 @@
|
|||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="0a7f92e2-b44a-4dfe-8e01-136d1c0c18be" name="Changes" comment="Added the travel_diary id as foreign key to the photos and add a check on the creation to avoid leaving it empty or bad referenced">
|
<list default="true" id="0a7f92e2-b44a-4dfe-8e01-136d1c0c18be" name="Changes" comment="Added the travel_diary id as foreign key to the photos and add a check on the creation to avoid leaving it empty or bad referenced">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pilgrim/models/entry.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/models/entry.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/pilgrim/service/photo_service.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/service/photo_service.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pilgrim/models/photo.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/models/photo.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/pilgrim/ui/screens/diary_list_screen.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/ui/screens/diary_list_screen.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pilgrim/models/photo_in_entry.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/models/photo_in_entry.py" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pilgrim/service/entry_service.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/pilgrim/service/entry_service.py" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -52,24 +50,24 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"Python.Database.executor": "Run",
|
"Python.Database.executor": "Run",
|
||||||
"Python.command.executor": "Run",
|
"Python.command.executor": "Run",
|
||||||
"Python.main.executor": "Run",
|
"Python.main.executor": "Run",
|
||||||
"Python.pilgrim.executor": "Run",
|
"Python.pilgrim.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"git-widget-placeholder": "master",
|
"git-widget-placeholder": "feat-TUI",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RunManager">
|
<component name="RunManager">
|
||||||
<configuration name="pilgrim" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
<configuration name="pilgrim" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
<module name="Pilgrim" />
|
<module name="Pilgrim" />
|
||||||
@@ -117,6 +115,7 @@
|
|||||||
<updated>1748985568579</updated>
|
<updated>1748985568579</updated>
|
||||||
<workItem from="1748985569621" duration="2124000" />
|
<workItem from="1748985569621" duration="2124000" />
|
||||||
<workItem from="1748992451560" duration="312000" />
|
<workItem from="1748992451560" duration="312000" />
|
||||||
|
<workItem from="1749508687224" duration="371000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="Added a Back Relationship in Entry to list all the photos">
|
<task id="LOCAL-00001" summary="Added a Back Relationship in Entry to list all the photos">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
|
|||||||
+3
-1
@@ -18,7 +18,9 @@ classifiers = [
|
|||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sqlalchemy"
|
"sqlalchemy",
|
||||||
|
"textual",
|
||||||
|
"textual-dev"
|
||||||
]
|
]
|
||||||
[template.plugins.default]
|
[template.plugins.default]
|
||||||
src-layout = true
|
src-layout = true
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ greenlet==3.2.2
|
|||||||
SQLAlchemy==2.0.41
|
SQLAlchemy==2.0.41
|
||||||
typing_extensions==4.14.0
|
typing_extensions==4.14.0
|
||||||
|
|
||||||
|
|
||||||
|
textual~=3.3.0
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
from pilgrim.database import Database
|
from pilgrim.database import Database
|
||||||
|
from pilgrim.service.mocks.service_manager_mock import ServiceManagerMock
|
||||||
from pilgrim.service.servicemanager import ServiceManager
|
from pilgrim.service.servicemanager import ServiceManager
|
||||||
|
from pilgrim.ui.ui import UIApp
|
||||||
|
|
||||||
|
|
||||||
class Application:
|
class Application:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.database = Database()
|
self.database = Database()
|
||||||
|
self.ui = UIApp(ServiceManagerMock())
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.database.create()
|
self.database.create()
|
||||||
|
self.ui.run()
|
||||||
|
|
||||||
def get_service_manager(self):
|
def get_service_manager(self):
|
||||||
session = self.database.session()
|
session = self.database.session()
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
from typing import List
|
||||||
|
from pilgrim.service.entry_service import EntryService
|
||||||
|
from pilgrim.models.entry import Entry
|
||||||
|
|
||||||
|
|
||||||
|
class EntryServiceMock(EntryService):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(None)
|
||||||
|
|
||||||
|
self.mock_data = {
|
||||||
|
1: Entry(title="The Adventure Begins", text="I'm hopping in the Plane to finally visit canadian lands",
|
||||||
|
date="26/07/2025", travel_diary_id=1, id=1,
|
||||||
|
photos=[]),
|
||||||
|
2: Entry(title="The Landing", text="Finally on Canadian Soil", date="27/07/2025",
|
||||||
|
travel_diary_id=1, id=2,photos=[]),
|
||||||
|
3: Entry(title="The Mount Royal", text="The Mount Royal is fucking awesome", date="28/07/2025",
|
||||||
|
travel_diary_id=1, id=3, photos=[]),
|
||||||
|
}
|
||||||
|
self._next_id = 4
|
||||||
|
|
||||||
|
def create(self, travel_diary_id: int, title: str, text: str, date: str) -> Entry:
|
||||||
|
new_entry = Entry(title, text, date, travel_diary_id, id=self._next_id)
|
||||||
|
self.mock_data[self._next_id] = new_entry
|
||||||
|
self._next_id += 1
|
||||||
|
return new_entry
|
||||||
|
|
||||||
|
def read_by_id(self, entry_id: int) -> Entry | None:
|
||||||
|
return self.mock_data.get(entry_id)
|
||||||
|
|
||||||
|
def read_all(self) -> List[Entry]:
|
||||||
|
return list(self.mock_data.values())
|
||||||
|
|
||||||
|
def update(self, entry_id: int, entry_dst: Entry) -> Entry | None:
|
||||||
|
item_to_update = self.mock_data.get(entry_id)
|
||||||
|
if item_to_update:
|
||||||
|
item_to_update.title = entry_dst.title if entry_dst.title is not None else item_to_update.title
|
||||||
|
item_to_update.text = entry_dst.text if entry_dst.text is not None else item_to_update.text
|
||||||
|
item_to_update.date = entry_dst.date if entry_dst.date is not None else item_to_update.date
|
||||||
|
item_to_update.fk_travel_diary_id = entry_dst.fk_travel_diary_id if (entry_dst.fk_travel_diary_id
|
||||||
|
is not None) else entry_dst.id
|
||||||
|
item_to_update.photos.extend(entry_dst.photos)
|
||||||
|
|
||||||
|
return item_to_update
|
||||||
|
return None
|
||||||
|
|
||||||
|
def delete(self, entry_id: int) -> Entry | None:
|
||||||
|
return self.mock_data.pop(entry_id, None)
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from pilgrim.models.photo import Photo
|
||||||
|
from pilgrim.service.photo_service import PhotoService
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoServiceMock(PhotoService):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(None)
|
||||||
|
self.mock_data = {}
|
||||||
|
self._next_id = 1
|
||||||
|
|
||||||
|
def create(self, filepath: Path, name: str, travel_diary_id, addition_date=None, caption=None) -> Photo | None:
|
||||||
|
new_photo = Photo(filepath, name, addition_date=addition_date, caption=caption)
|
||||||
|
self.mock_data[self._next_id] = new_photo
|
||||||
|
self._next_id += 1
|
||||||
|
return new_photo
|
||||||
|
|
||||||
|
|
||||||
|
def read_by_id(self, photo_id: int) -> Photo:
|
||||||
|
return self.mock_data.get(photo_id)
|
||||||
|
|
||||||
|
def read_all(self) -> List[Photo]:
|
||||||
|
return list(self.mock_data.values())
|
||||||
|
|
||||||
|
def update(self, photo_id: Photo, photo_dst: Photo) -> Photo | None:
|
||||||
|
item_to_update:Photo = self.mock_data.get(photo_id)
|
||||||
|
if item_to_update:
|
||||||
|
item_to_update.filepath = photo_dst.filepath if photo_dst.filepath else item_to_update.filepath
|
||||||
|
item_to_update.name = photo_dst.name if photo_dst.name else item_to_update.name
|
||||||
|
item_to_update.caption = photo_dst.caption if photo_dst.caption else item_to_update.caption
|
||||||
|
item_to_update.addition_date = photo_dst.addition_date if photo_dst.addition_date\
|
||||||
|
else item_to_update.addition_date
|
||||||
|
item_to_update.fk_travel_diary_id = photo_dst.fk_travel_diary_id if photo_dst.fk_travel_diary_id \
|
||||||
|
else item_to_update.fk_travel_diary_id
|
||||||
|
item_to_update.entries.extend(photo_dst.entries)
|
||||||
|
return item_to_update
|
||||||
|
return None
|
||||||
|
|
||||||
|
def delete(self, photo_id: int) -> Photo | None:
|
||||||
|
return self.mock_data.pop(photo_id, None)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
from pilgrim.service.mocks.entry_service_mock import EntryServiceMock
|
||||||
|
from pilgrim.service.mocks.photo_service_mock import PhotoServiceMock
|
||||||
|
from pilgrim.service.mocks.travel_diary_service_mock import TravelDiaryServiceMock
|
||||||
|
from pilgrim.service.photo_service import PhotoService
|
||||||
|
from pilgrim.service.servicemanager import ServiceManager
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceManagerMock(ServiceManager):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def get_entry_service(self):
|
||||||
|
return EntryServiceMock()
|
||||||
|
|
||||||
|
def get_travel_diary_service(self):
|
||||||
|
return TravelDiaryServiceMock()
|
||||||
|
|
||||||
|
def get_photo_service(self):
|
||||||
|
return PhotoServiceMock()
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
from pilgrim.service.travel_diary_service import TravelDiaryService
|
||||||
|
from pilgrim.models.travel_diary import TravelDiary
|
||||||
|
|
||||||
|
|
||||||
|
class TravelDiaryServiceMock(TravelDiaryService):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(None)
|
||||||
|
self.mock_data = {
|
||||||
|
1:TravelDiary(id=1,name="Montreal"),
|
||||||
|
2:TravelDiary(id=2,name="Rio de Janeiro"),
|
||||||
|
}
|
||||||
|
self._next_id = 3
|
||||||
|
|
||||||
|
def create(self, name: str):
|
||||||
|
new_travel_diary = TravelDiary(id=self._next_id,name=name)
|
||||||
|
self.mock_data[self._next_id] = new_travel_diary
|
||||||
|
self._next_id += 1
|
||||||
|
return new_travel_diary
|
||||||
|
|
||||||
|
def read_by_id(self, travel_id: int):
|
||||||
|
return self.mock_data[travel_id]
|
||||||
|
|
||||||
|
def read_all(self):
|
||||||
|
return list(self.mock_data.values())
|
||||||
|
|
||||||
|
def update(self, travel_diary_id: int, travel_diary_dst: TravelDiary):
|
||||||
|
item_to_update = self.mock_data.get(travel_diary_id)
|
||||||
|
if item_to_update:
|
||||||
|
item_to_update.name = travel_diary_dst.name if travel_diary_dst.name is not None else item_to_update.name
|
||||||
|
return item_to_update
|
||||||
|
return None
|
||||||
|
|
||||||
|
def delete(self, travel_diary_id: int):
|
||||||
|
return self.mock_data.pop(travel_diary_id, None)
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from pilgrim import Photo, TravelDiary
|
|
||||||
|
|
||||||
|
from pilgrim.models.photo import Photo
|
||||||
|
from pilgrim.models.travel_diary import TravelDiary
|
||||||
|
|
||||||
class PhotoService:
|
class PhotoService:
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
|
|||||||
@@ -18,18 +18,18 @@ class TravelDiaryService:
|
|||||||
def read_all(self):
|
def read_all(self):
|
||||||
return self.session.query(TravelDiary).all()
|
return self.session.query(TravelDiary).all()
|
||||||
|
|
||||||
def update(self, travel_diary_src:TravelDiary,travel_diary_dst:TravelDiary):
|
def update(self, travel_diary_id: TravelDiary, travel_diary_dst: TravelDiary):
|
||||||
original = self.read_by_id(travel_diary_src.id)
|
original = self.read_by_id(travel_diary_id.id)
|
||||||
if original is not None:
|
if original is not None:
|
||||||
original.name = travel_diary_dst.name
|
original.name = travel_diary_dst.name
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
self.session.refresh(original)
|
self.session.refresh(original)
|
||||||
return original
|
return original
|
||||||
|
|
||||||
def delete(self, travel_diary_src:TravelDiary):
|
def delete(self, travel_diary_id: TravelDiary):
|
||||||
excluded = self.read_by_id(travel_diary_src.id)
|
excluded = self.read_by_id(travel_diary_id.id)
|
||||||
if excluded is not None:
|
if excluded is not None:
|
||||||
self.session.delete(travel_diary_src)
|
self.session.delete(travel_diary_id)
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
return excluded
|
return excluded
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
from textual.app import ComposeResult
|
||||||
|
from textual.screen import Screen
|
||||||
|
from textual.widgets import Header, Footer, Label, Static, OptionList, Button
|
||||||
|
from textual.binding import Binding
|
||||||
|
from textual.containers import Vertical, Container, Horizontal
|
||||||
|
|
||||||
|
|
||||||
|
class DiaryListScreen(Screen):
|
||||||
|
TITLE = "Pilgrim - Main"
|
||||||
|
|
||||||
|
BINDINGS = [
|
||||||
|
Binding("n", "new_diary", "Novo Diário"),
|
||||||
|
Binding("^q", "quit", "Sair"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.selected_diary_index = None # Armazena o índice do diário selecionado
|
||||||
|
|
||||||
|
def compose(self) -> ComposeResult:
|
||||||
|
yield Header()
|
||||||
|
yield Container(
|
||||||
|
Static("Pilgrim", classes="app-title"),
|
||||||
|
Label("Select a diary"),
|
||||||
|
OptionList(id="option-list", classes="diary-options"),
|
||||||
|
Horizontal(
|
||||||
|
Button("New diary", id="new-diary"),
|
||||||
|
|
||||||
|
Button("Edit diary", id="edit-diary"),
|
||||||
|
Button("🔄 Refresh", id="refresh-btn"),
|
||||||
|
classes="actions-buttons",
|
||||||
|
),
|
||||||
|
classes="dialog-container"
|
||||||
|
)
|
||||||
|
yield Static(
|
||||||
|
"Tip: use ↑↓ to navigate • ENTER to Select • "
|
||||||
|
"TAB to alternate the fields • SHIFT + TAB to alternate back ",
|
||||||
|
classes="tips"
|
||||||
|
)
|
||||||
|
yield Footer()
|
||||||
|
|
||||||
|
def on_mount(self) -> None:
|
||||||
|
self.refresh_diaries()
|
||||||
|
self.update_buttons_state() # Atualiza estado inicial dos botões
|
||||||
|
|
||||||
|
def refresh_diaries(self):
|
||||||
|
try:
|
||||||
|
service_manager = self.app.service_manager
|
||||||
|
option_list = self.query_one(".diary-options")
|
||||||
|
option_list.clear_options()
|
||||||
|
travel_diary_service = service_manager.get_travel_diary_service()
|
||||||
|
diaries = travel_diary_service.read_all()
|
||||||
|
|
||||||
|
if not diaries:
|
||||||
|
# Para OptionList vazio, você pode adicionar uma string simples
|
||||||
|
option_list.add_option("[dim]Nenhum diário encontrado. Pressione 'N' para criar um novo![/dim]")
|
||||||
|
else:
|
||||||
|
for diary in diaries:
|
||||||
|
# Adiciona cada opção como string com markup rich
|
||||||
|
option_list.add_option(f"[b]{diary.name}[/b]\n[dim]ID: {diary.id}[/dim]")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.notify("Error: " + str(e))
|
||||||
|
|
||||||
|
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
|
||||||
|
"""Handle quando uma opção é selecionada"""
|
||||||
|
diaries = self.app.service_manager.get_travel_diary_service().read_all()
|
||||||
|
|
||||||
|
if diaries and event.option_index < len(diaries):
|
||||||
|
self.selected_diary_index = event.option_index
|
||||||
|
selected_diary = diaries[event.option_index]
|
||||||
|
self.notify(f"Diário selecionado: {selected_diary.name}")
|
||||||
|
else:
|
||||||
|
# Caso seja a opção "nenhum diário encontrado"
|
||||||
|
self.selected_diary_index = None
|
||||||
|
|
||||||
|
self.update_buttons_state()
|
||||||
|
|
||||||
|
def update_buttons_state(self):
|
||||||
|
"""Atualiza o estado dos botões baseado na seleção"""
|
||||||
|
edit_button = self.query_one("#edit-diary")
|
||||||
|
|
||||||
|
|
||||||
|
# Só habilita os botões se há um diário selecionado
|
||||||
|
has_selection = self.selected_diary_index is not None
|
||||||
|
edit_button.disabled = not has_selection
|
||||||
|
|
||||||
|
|
||||||
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||||
|
"""Handle cliques nos botões"""
|
||||||
|
button_id = event.button.id
|
||||||
|
|
||||||
|
if button_id == "new-diary":
|
||||||
|
self.action_new_diary()
|
||||||
|
elif button_id == "edit-diary":
|
||||||
|
self.action_edit_diary()
|
||||||
|
elif button_id == "refresh-btn":
|
||||||
|
self.refresh_diaries()
|
||||||
|
self.notify("Lista atualizada manualmente!")
|
||||||
|
|
||||||
|
def action_new_diary(self):
|
||||||
|
"""Ação para criar novo diário"""
|
||||||
|
self.notify("Criando novo diário...")
|
||||||
|
# Aqui você pode navegar para uma tela de criação de diário
|
||||||
|
|
||||||
|
def action_edit_diary(self):
|
||||||
|
"""Ação para editar diário selecionado"""
|
||||||
|
if self.selected_diary_index is not None:
|
||||||
|
diaries = self.app.service_manager.get_travel_diary_service().read_all()
|
||||||
|
if self.selected_diary_index < len(diaries):
|
||||||
|
selected_diary = diaries[self.selected_diary_index]
|
||||||
|
self.notify(f"Editando diário: {selected_diary.name}")
|
||||||
|
# Aqui você pode navegar para uma tela de edição
|
||||||
|
# self.app.push_screen(EditDiaryScreen(diary=selected_diary))
|
||||||
|
|
||||||
|
def refresh_diaries(self):
|
||||||
|
"""Atualiza a lista de diários no OptionList"""
|
||||||
|
try:
|
||||||
|
service_manager = self.app.service_manager
|
||||||
|
option_list = self.query_one("#option-list") # Usando ID em vez de classe
|
||||||
|
|
||||||
|
# Debug
|
||||||
|
current_count = len(option_list.options) if hasattr(option_list, 'options') else 0
|
||||||
|
self.notify(f"OptionList atual tem {current_count} opções")
|
||||||
|
|
||||||
|
option_list.clear_options()
|
||||||
|
|
||||||
|
travel_diary_service = service_manager.get_travel_diary_service()
|
||||||
|
diaries = travel_diary_service.read_all()
|
||||||
|
|
||||||
|
self.notify(f"Carregando {len(diaries)} diários do serviço")
|
||||||
|
|
||||||
|
if not diaries:
|
||||||
|
option_list.add_option("[dim]Nenhum diário encontrado. Pressione 'N' para criar um novo![/dim]")
|
||||||
|
self.selected_diary_index = None
|
||||||
|
else:
|
||||||
|
for diary in diaries:
|
||||||
|
option_list.add_option(f"[b]{diary.name}[/b]\n[dim]ID: {diary.id}[/dim]")
|
||||||
|
|
||||||
|
# Valida se a seleção ainda é válida
|
||||||
|
if (self.selected_diary_index is not None and
|
||||||
|
self.selected_diary_index >= len(diaries)):
|
||||||
|
self.selected_diary_index = None
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.notify("Error no refresh_diaries: " + str(e))
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
.dialog-container{
|
||||||
|
content-align: center top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-title{
|
||||||
|
dock: top;
|
||||||
|
height: 3;
|
||||||
|
content-align: center middle;
|
||||||
|
text-style: bold;
|
||||||
|
color: $accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-buttons{
|
||||||
|
height: auto;
|
||||||
|
margin: 1 0;
|
||||||
|
align: center middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips{
|
||||||
|
dock: bottom;
|
||||||
|
height: 4;
|
||||||
|
content-align: center middle;
|
||||||
|
color: $text-muted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from textual.app import App
|
||||||
|
|
||||||
|
from pilgrim.service.servicemanager import ServiceManager
|
||||||
|
from pilgrim.ui.screens.diary_list_screen import DiaryListScreen
|
||||||
|
|
||||||
|
CSS_FILE_PATH = Path(__file__).parent / "styles" / "pilgrim.css"
|
||||||
|
|
||||||
|
|
||||||
|
class UIApp(App):
|
||||||
|
CSS_PATH = CSS_FILE_PATH
|
||||||
|
|
||||||
|
def __init__(self,service_manager: ServiceManager):
|
||||||
|
super().__init__()
|
||||||
|
self.service_manager = service_manager
|
||||||
|
|
||||||
|
|
||||||
|
def on_mount(self) -> None:
|
||||||
|
"""Chamado quando a app inicia. Carrega a tela principal."""
|
||||||
|
self.push_screen(DiaryListScreen())
|
||||||
Reference in New Issue
Block a user