From 4cb283b890463428d52a4e8eb6d0700bb21f2d51 Mon Sep 17 00:00:00 2001 From: Aaron Gutierrez Date: Mon, 11 Dec 2017 22:28:04 -0800 Subject: [PATCH] Add support for subtasks --- asana_service.py | 2 ++ main.py | 1 - models/models.py | 23 +++++++++++++-------- ui/constants.py | 12 +++++------ ui/task_details.py | 51 ++++++++++++++++++++++++++++++---------------- ui/task_list.py | 2 +- 6 files changed, 58 insertions(+), 33 deletions(-) diff --git a/asana_service.py b/asana_service.py index 2f93dbb..74caf14 100644 --- a/asana_service.py +++ b/asana_service.py @@ -19,6 +19,8 @@ class AsanaService(object): 'custom_fields.text_value', 'custom_fields.number_value', 'custom_fields.enum_value.name', + 'subtasks.completed', + 'subtasks.name', ] def __init__(self, client): diff --git a/main.py b/main.py index df0c66b..7aebe2d 100755 --- a/main.py +++ b/main.py @@ -84,7 +84,6 @@ class CmdAsana(object): def exit_handler(self, key): if key in ('q', 'Q', 'esc'): raise urwid.ExitMainLoop() - print(key) if key in ('backspace'): self.ui.go_back() diff --git a/models/models.py b/models/models.py index 20ae9f6..e039178 100644 --- a/models/models.py +++ b/models/models.py @@ -21,7 +21,7 @@ class User(AsanaObject): class Task(AsanaObject): def name(self): if self.object_dict['completed']: - return '✓ %s' % super(self).name() + return '✓ %s' % super(Task, self).name() return super(Task, self).name() def assignee(self): @@ -59,6 +59,12 @@ class Task(AsanaObject): else: return [] + def subtasks(self): + if 'subtasks' in self.object_dict: + return [Task(t) for t in self.object_dict['subtasks']] + else: + return [] + def custom_fields(self): if 'custom_fields' in self.object_dict: return [CustomField(c) for c in self.object_dict['custom_fields']] @@ -74,20 +80,21 @@ class Project(AsanaObject): class CustomField(AsanaObject): def string_value(self): if 'text_value' in self.object_dict: - return self.object_dict['text_value'] + return str(self.object_dict['text_value']) elif 'number_value' in self.object_dict: - return self.object_dict['number_value'] + return str(self.object_dict['number_value']) elif 'enum_value' in self.object_dict and self.object_dict['enum_value']: enum_value = AsanaObject(self.object_dict['enum_value']) - return enum_value.name() + return str(enum_value.name()) return '' class Story(AsanaObject): - def string_value(self): + def creator(self): if 'created_by' in self.object_dict: - creator = self.object_dict['created_by']['name'] + ' ' + return self.object_dict['created_by']['name'] + ' ' else: - creator = '' + return '' - return '%s%s' % (creator, self.object_dict['text']) + def text(self): + return self.object_dict['text'] diff --git a/ui/constants.py b/ui/constants.py index 75b24f5..38fd8ad 100644 --- a/ui/constants.py +++ b/ui/constants.py @@ -1,14 +1,14 @@ palette = [ - ('selected', 'standout', ''), - ('selected workspace', 'standout,bold', ''), + ('atm_section', 'white,bold', 'dark blue'), + ('author', 'bold,dark blue', ''), + ('custom_fields', 'dark red', ''), ('header', 'bold,light green', ''), - ('secondary', 'light green', ''), - ('task', 'light green', ''), ('project', 'yellow', ''), ('section', 'dark green,bold', ''), - ('atm_section', 'white,bold', 'dark blue'), + ('selected', 'standout', ''), + ('task', 'light green', ''), + ('text', '', ''), ('workspace', 'white', 'dark blue'), - ('pager', 'standout', ''), ] keys = { diff --git a/ui/task_details.py b/ui/task_details.py index 38d0530..745405d 100644 --- a/ui/task_details.py +++ b/ui/task_details.py @@ -1,5 +1,7 @@ import urwid +from ui.task_list import TaskRow + class TaskDetails(object): def __init__(self, task, stories, on_subtask_click, on_project_click, on_comment): @@ -8,17 +10,28 @@ class TaskDetails(object): self.on_project_click = on_project_click, self.on_comment = on_comment - self.details = urwid.Pile([ - ('pack', urwid.Text(('task', task.name()))), - ('pack', urwid.Divider('-')), - ('weight', 1, Memberships(task, on_subtask_click, on_project_click) \ - .component()), - ('pack', urwid.Divider('-')), - ('pack', CustomFields(task).component()), - ('pack', urwid.Divider('-')), - ('weight', 20, urwid.Filler(urwid.Text(task.description()))), - ('weight', 5, urwid.Filler(Stories(stories).component())) - ]) + body = [ + urwid.Text(('task', task.name())), + urwid.Divider('-'), + Memberships(task, on_subtask_click, on_project_click).component(), + urwid.Divider('-'), + CustomFields(task).component(), + urwid.Divider('='), + urwid.Text(task.description()), + urwid.Divider('-'), + ] + + if task.subtasks(): + body.append(urwid.Pile([ + TaskRow(t, on_subtask_click) for t in task.subtasks() + ])) + + body = body + [ + urwid.Divider('-'), + Stories(stories).component() + ] + + self.details = urwid.ListBox(urwid.SimpleFocusListWalker(body)) def component(self): return self.details @@ -35,17 +48,17 @@ class Memberships(object): on_press = lambda x: on_subtask_click(task.parent().id()) )) - self.memberships = urwid.ListBox( - urwid.SimpleFocusListWalker(components) - ) + self.memberships = urwid.Pile(components) def component(self): return self.memberships class CustomFields(object): def __init__(self, task): - components = [urwid.Text('%s: %s' % (f.name(), f.string_value())) - for f in task.custom_fields()] + components = [urwid.Text([ + ('custom_fields', f.name() + ': '), + f.string_value() + ]) for f in task.custom_fields()] self.custom_fields = urwid.Pile(components) @@ -54,7 +67,11 @@ class CustomFields(object): class Stories(object): def __init__(self, stories): - components = [urwid.Text(s.string_value()) for s in stories] + components = [urwid.Text([ + ('author', s.creator()), + s.text(), + '\n' + ]) for s in stories] self.stories = urwid.Pile(components) diff --git a/ui/task_list.py b/ui/task_list.py index c138239..9b50aa1 100644 --- a/ui/task_list.py +++ b/ui/task_list.py @@ -53,7 +53,7 @@ class TaskRow(urwid.SelectableIcon): def __init__(self, task, on_click): self.on_click = on_click self.task = task - style = 'section' if task.name()[-1] == ':' else 'task' + style = 'section' if task.name() and task.name()[-1] == ':' else 'task' super(TaskRow, self).__init__((style, task.name())) def keypress(self, size, key):