Activity editing
This commit is contained in:
parent
0c58555b43
commit
e8ff5f1411
@ -8,7 +8,6 @@ from textual.events import DescendantBlur
|
|||||||
from textual.widgets import Header, Footer, DataTable, Input, Button, Label, Checkbox
|
from textual.widgets import Header, Footer, DataTable, Input, Button, Label, Checkbox
|
||||||
from textual.containers import Horizontal, Vertical
|
from textual.containers import Horizontal, Vertical
|
||||||
from textual.coordinate import Coordinate
|
from textual.coordinate import Coordinate
|
||||||
from textual.reactive import reactive
|
|
||||||
from textual.screen import Screen, ModalScreen
|
from textual.screen import Screen, ModalScreen
|
||||||
|
|
||||||
from textual_autocomplete import AutoComplete, Dropdown, DropdownItem
|
from textual_autocomplete import AutoComplete, Dropdown, DropdownItem
|
||||||
@ -75,21 +74,65 @@ class ListScreen(Screen):
|
|||||||
self._refresh()
|
self._refresh()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ActivityEditScreen(ModalScreen):
|
class ActivityEditScreen(ModalScreen):
|
||||||
BINDINGS = [("escape", "cancel", "Cancel")]
|
BINDINGS = [
|
||||||
|
("escape", "cancel", "Cancel"),
|
||||||
|
("ctrl+s", "save", "Save"),
|
||||||
|
]
|
||||||
|
|
||||||
|
category_id = None
|
||||||
|
category_name = ''
|
||||||
|
|
||||||
|
def _get_categories(self, input_state):
|
||||||
|
categories = [DropdownItem(c.name, str(c.id)) for c in HamsterCategory.select()]
|
||||||
|
return ActivityMappingScreen._filter_dropdowns(categories, input_state.value)
|
||||||
|
|
||||||
|
def __init__(self, category, activity):
|
||||||
|
if category is not None:
|
||||||
|
self.category_id = category.id
|
||||||
|
self.category_name = category.name
|
||||||
|
self.activity_name = activity.name
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Grid(
|
yield Vertical(
|
||||||
Label("Are you sure you want to quit?", id="question"),
|
Horizontal(Label("Category:"),
|
||||||
Button("Quit", variant="error", id="quit"),
|
AutoComplete(
|
||||||
Button("Cancel", variant="primary", id="cancel"),
|
Input(placeholder="Type to search...", id="category",
|
||||||
id="dialog",
|
value=self.category_name),
|
||||||
|
Dropdown(items=self._get_categories),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Horizontal(Label("Activity:"), Input(value=self.activity_name,
|
||||||
|
id='activity')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@on(Input.Submitted, "#category")
|
||||||
|
def category_submitted(self, event):
|
||||||
|
if event.control.parent.dropdown.selected_item is not None:
|
||||||
|
self.category_id = str(
|
||||||
|
event.control.parent.dropdown.selected_item.left_meta
|
||||||
|
)
|
||||||
|
self.query_one("#activity").focus()
|
||||||
|
|
||||||
|
@on(DescendantBlur, "#category")
|
||||||
|
def category_blur(self, event):
|
||||||
|
if event.control.parent.dropdown.selected_item is not None:
|
||||||
|
self.category_id = str(
|
||||||
|
event.control.parent.dropdown.selected_item.left_meta
|
||||||
|
)
|
||||||
|
|
||||||
def action_cancel(self):
|
def action_cancel(self):
|
||||||
self.dismiss(None)
|
self.dismiss(None)
|
||||||
|
|
||||||
|
def action_save(self):
|
||||||
|
self.dismiss(
|
||||||
|
{
|
||||||
|
"category": self.category_id,
|
||||||
|
"activity": self.query_one('#activity').value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ActivityMappingScreen(ModalScreen):
|
class ActivityMappingScreen(ModalScreen):
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
@ -376,10 +419,27 @@ class ActivityListScreen(ListScreen):
|
|||||||
del self.move_from_activity
|
del self.move_from_activity
|
||||||
|
|
||||||
def action_edit(self):
|
def action_edit(self):
|
||||||
def handle_edit(properties):
|
row_idx: int = self.table.cursor_row
|
||||||
print(properties)
|
row_cells = self.table.get_row_at(row_idx)
|
||||||
|
|
||||||
self.app.push_screen(ActivityEditScreen(), handle_edit)
|
try:
|
||||||
|
category = HamsterCategory.get(id=row_cells[0])
|
||||||
|
except HamsterCategory.DoesNotExist:
|
||||||
|
category = None
|
||||||
|
activity = HamsterActivity.get(id=row_cells[2])
|
||||||
|
|
||||||
|
def handle_edit(properties):
|
||||||
|
if properties is None:
|
||||||
|
return
|
||||||
|
activity.name = properties['activity']
|
||||||
|
activity.category_id = properties['category']
|
||||||
|
activity.save()
|
||||||
|
self._refresh()
|
||||||
|
|
||||||
|
self.app.push_screen(ActivityEditScreen(
|
||||||
|
category=category,
|
||||||
|
activity=activity
|
||||||
|
), handle_edit)
|
||||||
|
|
||||||
def action_mapping(self):
|
def action_mapping(self):
|
||||||
selected_activity = (
|
selected_activity = (
|
||||||
|
@ -1,50 +1,64 @@
|
|||||||
DataTable {
|
DataTable {
|
||||||
height: 90%;
|
height: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTable .datatable--cursor {
|
DataTable .datatable--cursor {
|
||||||
background: grey;
|
background: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTable:focus .datatable--cursor {
|
DataTable:focus .datatable--cursor {
|
||||||
background: orange;
|
background: orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
#filter {
|
#filter {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#filter Input {
|
#filter Input {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityEditScreen, ActivityMappingScreen {
|
ActivityEditScreen, ActivityMappingScreen {
|
||||||
align: center middle;
|
align: center middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActivityEditScreen > Vertical,
|
||||||
ActivityMappingScreen > Vertical {
|
ActivityMappingScreen > Vertical {
|
||||||
padding: 0 1;
|
padding: 0 1;
|
||||||
width: auto;
|
width: 80;
|
||||||
height: 30;
|
height: 30;
|
||||||
border: thick $background 80%;
|
border: thick $background 80%;
|
||||||
background: $surface;
|
background: $surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityMappingScreen Horizontal {
|
ActivityEditScreen > Vertical {
|
||||||
align: left middle;
|
height: 10;
|
||||||
width: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActivityMappingScreen Horizontal {
|
||||||
|
align: left middle;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityEditScreen Horizontal {
|
||||||
|
width: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityEditScreen Label,
|
||||||
ActivityMappingScreen Label {
|
ActivityMappingScreen Label {
|
||||||
padding: 0 1;
|
padding: 0 1;
|
||||||
width: auto;
|
width: auto;
|
||||||
border: blank;
|
border: blank;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityMappingScreen AutoComplete {
|
ActivityMappingScreen AutoComplete {
|
||||||
width: 80;
|
width: 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
#description, #tags {
|
#description, #tags {
|
||||||
width: 30;
|
width: 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityEditScreen Input {
|
||||||
|
width: 60;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class KimaiAPI(object):
|
|||||||
auth_headers = {"X-AUTH-USER": KIMAI_USERNAME, "X-AUTH-TOKEN": KIMAI_API_KEY}
|
auth_headers = {"X-AUTH-USER": KIMAI_USERNAME, "X-AUTH-TOKEN": KIMAI_API_KEY}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
requests_cache.install_cache("kimai", backend="sqlite", expire_after=1800)
|
# requests_cache.install_cache("kimai", backend="sqlite", expire_after=1800)
|
||||||
self.customers_json = requests.get(
|
self.customers_json = requests.get(
|
||||||
f"{self.KIMAI_API_URL}/customers?visible=3", headers=self.auth_headers
|
f"{self.KIMAI_API_URL}/customers?visible=3", headers=self.auth_headers
|
||||||
).json()
|
).json()
|
||||||
|
Loading…
Reference in New Issue
Block a user