|
|
@ -3,7 +3,7 @@ from textual.widgets import Static, Label, ListItem, ListView, TextArea, Input
|
|
|
|
from textual.containers import Horizontal, Vertical
|
|
|
|
from textual.containers import Horizontal, Vertical
|
|
|
|
from textual.screen import Screen
|
|
|
|
from textual.screen import Screen
|
|
|
|
from textual.binding import Binding
|
|
|
|
from textual.binding import Binding
|
|
|
|
from board import Board
|
|
|
|
from board import Board, Task
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TaskList(ListView):
|
|
|
|
class TaskList(ListView):
|
|
|
@ -16,20 +16,38 @@ class TaskList(ListView):
|
|
|
|
Binding("j", "cursor_down", "Cursor Down", show=False, priority=True),
|
|
|
|
Binding("j", "cursor_down", "Cursor Down", show=False, priority=True),
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
class EditScreen(Screen):
|
|
|
|
class EditTaskScreen(Screen):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
This is a screen used to edit the name of a task
|
|
|
|
This is a screen used to edit the name of a task
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
CSS="""
|
|
|
|
CSS="""
|
|
|
|
Label{
|
|
|
|
Label{
|
|
|
|
width:50%;
|
|
|
|
width:50%;
|
|
|
|
|
|
|
|
background: #282828;
|
|
|
|
|
|
|
|
padding: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Input{
|
|
|
|
Input{
|
|
|
|
width:50%;
|
|
|
|
width:50%;
|
|
|
|
|
|
|
|
background: #282828;
|
|
|
|
|
|
|
|
padding: 0 0;
|
|
|
|
|
|
|
|
border: #ebdbb9;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Input:focus{
|
|
|
|
|
|
|
|
border: #458588;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TextArea{
|
|
|
|
|
|
|
|
width: 50%;
|
|
|
|
|
|
|
|
height: 25%;
|
|
|
|
|
|
|
|
background: #282828;
|
|
|
|
|
|
|
|
border: #ebdbb9;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TextArea:focus{
|
|
|
|
|
|
|
|
border: #458588;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
BINDINGS = [
|
|
|
|
BINDINGS = [
|
|
|
|
Binding('enter', 'save', 'Save Changes', priority=True)
|
|
|
|
Binding('ctrl+s', 'save', 'Save Changes', priority=True),
|
|
|
|
]
|
|
|
|
]
|
|
|
|
def __init__(self,text):
|
|
|
|
def __init__(self,text):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -43,6 +61,60 @@ class EditScreen(Screen):
|
|
|
|
Compose the widgets on the screen, this screen doesn't need dynamic layout changes
|
|
|
|
Compose the widgets on the screen, this screen doesn't need dynamic layout changes
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
yield Label('Task Name:')
|
|
|
|
yield Label('Task Name:')
|
|
|
|
|
|
|
|
yield Input(value=self.text.summary)
|
|
|
|
|
|
|
|
yield Label('Score:')
|
|
|
|
|
|
|
|
if self.text.score:
|
|
|
|
|
|
|
|
yield Input(value=self.text.score)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
yield Input(value="")
|
|
|
|
|
|
|
|
yield Label('Description:')
|
|
|
|
|
|
|
|
if self.text.description:
|
|
|
|
|
|
|
|
yield TextArea(self.text.description, language='markdown')
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
yield TextArea(language='markdown')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def action_save(self):
|
|
|
|
|
|
|
|
query = self.query(selector=Input)
|
|
|
|
|
|
|
|
self.text.summary = query.nodes[0].value
|
|
|
|
|
|
|
|
self.text.score = query.nodes[1].value
|
|
|
|
|
|
|
|
query = self.query(selector=TextArea)
|
|
|
|
|
|
|
|
self.text.description = query.nodes[0].text
|
|
|
|
|
|
|
|
self.dismiss(self.text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EditColScreen(Screen):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
This is a screen used to edit the name of a task
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
CSS="""
|
|
|
|
|
|
|
|
Label{
|
|
|
|
|
|
|
|
width:50%;
|
|
|
|
|
|
|
|
background: #282828;
|
|
|
|
|
|
|
|
padding: 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Input{
|
|
|
|
|
|
|
|
width:50%;
|
|
|
|
|
|
|
|
background: #282828;
|
|
|
|
|
|
|
|
padding: 0 0;
|
|
|
|
|
|
|
|
border: #ebdbb9;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
BINDINGS = [
|
|
|
|
|
|
|
|
Binding('ctrl+s', 'save', 'Save Changes', priority=True),
|
|
|
|
|
|
|
|
Binding('enter', 'save', 'Save Changes', priority=True),
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
def __init__(self,text):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Initialize the screen
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
self.text = text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compose(self):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Compose the widgets on the screen, this screen doesn't need dynamic layout changes
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
yield Label('Column Name:')
|
|
|
|
yield Input(value=self.text)
|
|
|
|
yield Input(value=self.text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -60,6 +132,7 @@ class KanbanForm(App):
|
|
|
|
Binding("L", "move_up", "Focus Next", show=False),
|
|
|
|
Binding("L", "move_up", "Focus Next", show=False),
|
|
|
|
Binding("H", "move_down", "Focus Prev", show=False),
|
|
|
|
Binding("H", "move_down", "Focus Prev", show=False),
|
|
|
|
Binding("e", "edit_task", "Edit Task", show=False,),
|
|
|
|
Binding("e", "edit_task", "Edit Task", show=False,),
|
|
|
|
|
|
|
|
Binding("r", "edit_column", "Edit Column Name", show=False,),
|
|
|
|
Binding('q', 'exit', "Exit")
|
|
|
|
Binding('q', 'exit', "Exit")
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
@ -68,7 +141,7 @@ class KanbanForm(App):
|
|
|
|
Initialization function for form
|
|
|
|
Initialization function for form
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
# Initialize our board class
|
|
|
|
# Initialize our board class
|
|
|
|
self.board = Board(file = '.board.md')
|
|
|
|
self.board = Board(file = '.board.yaml')
|
|
|
|
self.cols = list()
|
|
|
|
self.cols = list()
|
|
|
|
|
|
|
|
|
|
|
|
self.col_widgets = list()
|
|
|
|
self.col_widgets = list()
|
|
|
@ -83,7 +156,7 @@ class KanbanForm(App):
|
|
|
|
with Vertical(classes=col_class):
|
|
|
|
with Vertical(classes=col_class):
|
|
|
|
yield Static(col, classes='header')
|
|
|
|
yield Static(col, classes='header')
|
|
|
|
yield TaskList(
|
|
|
|
yield TaskList(
|
|
|
|
*[ListItem(Label(task)) for task in self.board.get_tasks()[i]])
|
|
|
|
*[ListItem(Label(task.summary)) for task in self.board.get_tasks()[i]])
|
|
|
|
|
|
|
|
|
|
|
|
# Now make all TaskLists except the first have no highlights
|
|
|
|
# Now make all TaskLists except the first have no highlights
|
|
|
|
def action_fnext(self):
|
|
|
|
def action_fnext(self):
|
|
|
@ -92,7 +165,7 @@ class KanbanForm(App):
|
|
|
|
|
|
|
|
|
|
|
|
def action_move_up(self):
|
|
|
|
def action_move_up(self):
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
text = self.board.get_task(icol, itask)
|
|
|
|
text = self.board.get_task(icol, itask).summary
|
|
|
|
moved = self.board.move_task(icol, itask, 1)
|
|
|
|
moved = self.board.move_task(icol, itask, 1)
|
|
|
|
if moved:
|
|
|
|
if moved:
|
|
|
|
query = self.query(selector=TaskList)
|
|
|
|
query = self.query(selector=TaskList)
|
|
|
@ -109,7 +182,7 @@ class KanbanForm(App):
|
|
|
|
|
|
|
|
|
|
|
|
def action_move_down(self):
|
|
|
|
def action_move_down(self):
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
text = self.board.get_task(icol, itask)
|
|
|
|
text = self.board.get_task(icol, itask).summary
|
|
|
|
moved = self.board.move_task(icol, itask, -1)
|
|
|
|
moved = self.board.move_task(icol, itask, -1)
|
|
|
|
if moved:
|
|
|
|
if moved:
|
|
|
|
query = self.query(selector=TaskList)
|
|
|
|
query = self.query(selector=TaskList)
|
|
|
@ -122,10 +195,25 @@ class KanbanForm(App):
|
|
|
|
def action_edit_task(self):
|
|
|
|
def action_edit_task(self):
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
task = self.board.get_task(icol, itask)
|
|
|
|
task = self.board.get_task(icol, itask)
|
|
|
|
self.push_screen(EditScreen(task), self.update_task)
|
|
|
|
self.push_screen(EditTaskScreen(task), self.update_task)
|
|
|
|
|
|
|
|
|
|
|
|
def action_new_task(self):
|
|
|
|
def action_new_task(self):
|
|
|
|
self.push_screen(EditScreen(""), self.new_task)
|
|
|
|
self.push_screen(EditTaskScreen(Task(None,None,None)), self.new_task)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def action_edit_column(self):
|
|
|
|
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
|
|
|
|
text = self.board.get_columns()[icol]
|
|
|
|
|
|
|
|
self.push_screen(EditColScreen(text), self.update_col)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_col(self, text):
|
|
|
|
|
|
|
|
""" Update the column
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
|
|
|
|
query = self.query(selector=Static)
|
|
|
|
|
|
|
|
query = [node for node in query.nodes if str(node) == 'Static()']
|
|
|
|
|
|
|
|
query[icol].update(text)
|
|
|
|
|
|
|
|
self.board.get_columns()[icol] = text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def action_exit(self):
|
|
|
|
def action_exit(self):
|
|
|
|
""" Exit the application """
|
|
|
|
""" Exit the application """
|
|
|
@ -153,21 +241,21 @@ class KanbanForm(App):
|
|
|
|
|
|
|
|
|
|
|
|
return col_index, task_index
|
|
|
|
return col_index, task_index
|
|
|
|
|
|
|
|
|
|
|
|
def update_task(self, text):
|
|
|
|
def update_task(self, task):
|
|
|
|
""" This function gets the text inputted in the edit screen and updates the underlying
|
|
|
|
""" This function gets the text inputted in the edit screen and updates the underlying
|
|
|
|
task and the board class
|
|
|
|
task and the board class
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
icol, itask = self.get_col_task()
|
|
|
|
self.focused.highlighted_child.children[0].update(text)
|
|
|
|
self.focused.highlighted_child.children[0].update(task.summary)
|
|
|
|
self.board.update_task(icol, itask, text)
|
|
|
|
self.board.update_task(icol, itask, task)
|
|
|
|
|
|
|
|
|
|
|
|
def new_task(self, text):
|
|
|
|
def new_task(self, task):
|
|
|
|
""" This function adds a new task to our board
|
|
|
|
""" This function adds a new task to our board
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
icol,_ = self.get_col_task()
|
|
|
|
icol,_ = self.get_col_task()
|
|
|
|
self.focused.mount(ListItem(Label(text)))
|
|
|
|
self.focused.mount(ListItem(Label(task.summary)))
|
|
|
|
self.board.add_task(icol, text)
|
|
|
|
self.board.add_task(icol, task)
|
|
|
|
self.focused.highlighted_child
|
|
|
|
self.focused.highlighted_child
|
|
|
|
|
|
|
|
|
|
|
|
# def on_key(self):
|
|
|
|
# def on_key(self):
|
|
|
|