From cee7a584abb5190602764fef81ba7cdf5ccc40f5 Mon Sep 17 00:00:00 2001
From: "James E. Blair" <jeblair@redhat.com>
Date: Thu, 23 Feb 2017 20:58:45 -0500
Subject: [PATCH] Some improvements to board view

* Delete all items before refreshing.  This isn't great because we
  lose the cursor position, but it's better than what's there now
  because it just appends duplicate data.
* Make the title show up whether the worklist item is a story or
  task.
* Make worklist items clickable links which take you to the story.

Change-Id: Iba0071fd70b629ce68ceebb27b5eae8cf06932f1
---
 boartty/app.py             |  7 +++++++
 boartty/db.py              | 16 ++++++++++++++++
 boartty/view/board.py      | 24 ++++++++++++++++--------
 boartty/view/story_list.py |  7 +------
 4 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/boartty/app.py b/boartty/app.py
index a288fc3..75a0d1b 100644
--- a/boartty/app.py
+++ b/boartty/app.py
@@ -706,6 +706,13 @@ class App(object):
         webbrowser.open_new_tab(url)
         self.loop.screen.clear()
 
+    def openStory(self, story_key):
+        try:
+            view = view_story.StoryView(self, story_key)
+            self.changeScreen(view)
+        except boartty.view.DisplayError as e:
+            self.error(str(e))
+
     def time(self, dt):
         if dt is None:
             return None
diff --git a/boartty/db.py b/boartty/db.py
index 95b72e8..ce4781e 100644
--- a/boartty/db.py
+++ b/boartty/db.py
@@ -450,6 +450,22 @@ class WorklistItem(object):
         return '<WorklistItem key=%s id=%s story=%s task=%s>' % (
             self.key, self.id, self.story, self.task)
 
+    @property
+    def title(self):
+        if self.story:
+            return self.story.title
+        elif self.task:
+            return self.task.title
+        return 'Unknown'
+
+    @property
+    def dereferenced_story_key(self):
+        if self.story:
+            return self.story.key
+        elif self.task:
+            return self.task.story.key
+        return None
+
 class SyncQuery(object):
     def __init__(self, name):
         self.name = name
diff --git a/boartty/view/board.py b/boartty/view/board.py
index 1c9829a..7dacd08 100644
--- a/boartty/view/board.py
+++ b/boartty/view/board.py
@@ -48,12 +48,10 @@ class BoardView(urwid.WidgetWrap, mywid.Searchable):
         return [(c[0], key(c[0]), c[1]) for c in commands]
 
     def interested(self, event):
-        if not (isinstance(event, sync.BoardAddedEvent)
-                or
-                isinstance(event, sync.StoryAddedEvent)
-                or
-                (isinstance(event, sync.StoryUpdatedEvent) and
-                 event.status_changed)):
+        if not ((isinstance(event, sync.BoardUpdatedEvent) and
+                 event.board_key == self.board_key) or
+                (isinstance(event, sync.WorklistUpdatedEvent) and
+                 event.worklist_key in self.worklist_keys)):
             self.log.debug("Ignoring refresh board due to event %s" % (event,))
             return False
         self.log.debug("Refreshing board due to event %s" % (event,))
@@ -65,9 +63,10 @@ class BoardView(urwid.WidgetWrap, mywid.Searchable):
         self.searchInit()
         self.app = app
         self.board_key = board_key
+        self.worklist_keys = set()
 
         self.title_label = urwid.Text(u'', wrap='clip')
-        self.description_label = urwid.Text(u'', wrap='clip')
+        self.description_label = urwid.Text(u'')
         board_info = []
         board_info_map={'story-data': 'focused-story-data'}
         for l, v in [("Title", self.title_label),
@@ -101,14 +100,23 @@ class BoardView(urwid.WidgetWrap, mywid.Searchable):
                 items = []
                 self.log.debug("Display lane %s", lane)
                 items.append(urwid.Text(lane.worklist.title))
+                self.worklist_keys.add(lane.worklist.key)
                 for item in lane.worklist.items:
                     self.log.debug("Display item %s", item)
-                    items.append(urwid.Text(item.story.title))
+                    items.append(mywid.TextButton(item.title,
+                                                  on_press=self.openItem,
+                                                  user_data=item.dereferenced_story_key))
                 pile = urwid.Pile(items)
                 columns.append(pile)
             columns = urwid.Columns(columns)
+            for x in self.listbox.body[self.listbox_board_start:]:
+                self.listbox.body.remove(x)
             self.listbox.body.append(columns)
 
+    def openItem(self, widget, story_key):
+        self.log.debug("Open story %s", story_key)
+        self.app.openStory(story_key)
+
     def handleCommands(self, commands):
         if keymap.REFRESH in commands:
             self.app.sync.submitTask(
diff --git a/boartty/view/story_list.py b/boartty/view/story_list.py
index 6d6126c..09024b3 100644
--- a/boartty/view/story_list.py
+++ b/boartty/view/story_list.py
@@ -505,9 +505,4 @@ class StoryListView(urwid.WidgetWrap, mywid.Searchable):
         return False
 
     def onSelect(self, button, story_key):
-        try:
-            view = view_story.StoryView(self.app, story_key)
-            self.app.changeScreen(view)
-        except boartty.view.DisplayError as e:
-            self.app.error(str(e))
-
+        self.app.openStory(story_key)