diff options
Diffstat (limited to 'Omni/Jr/Web.hs')
| -rw-r--r-- | Omni/Jr/Web.hs | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/Omni/Jr/Web.hs b/Omni/Jr/Web.hs index 5f0da6d..befda94 100644 --- a/Omni/Jr/Web.hs +++ b/Omni/Jr/Web.hs @@ -256,7 +256,7 @@ data ReadyQueuePage = ReadyQueuePage [TaskCore.Task] SortOrder UTCTime data BlockedPage = BlockedPage [(TaskCore.Task, Int)] SortOrder UTCTime -data InterventionPage = InterventionPage [TaskCore.Task] SortOrder UTCTime +data InterventionPage = InterventionPage TaskCore.HumanActionItems SortOrder UTCTime data TaskListPage = TaskListPage [TaskCore.Task] TaskFilters SortOrder UTCTime @@ -645,7 +645,7 @@ navbar = Lucid.div_ [Lucid.class_ "navbar-dropdown-content"] <| do Lucid.a_ [Lucid.href_ "/ready", Lucid.class_ "navbar-dropdown-item"] "Ready" Lucid.a_ [Lucid.href_ "/blocked", Lucid.class_ "navbar-dropdown-item"] "Blocked" - Lucid.a_ [Lucid.href_ "/intervention", Lucid.class_ "navbar-dropdown-item"] "Intervention" + Lucid.a_ [Lucid.href_ "/intervention", Lucid.class_ "navbar-dropdown-item"] "Human Action" Lucid.a_ [Lucid.href_ "/tasks", Lucid.class_ "navbar-dropdown-item"] "All" Lucid.div_ [Lucid.class_ "navbar-dropdown"] <| do Lucid.button_ [Lucid.class_ "navbar-dropdown-btn"] "Plans ▾" @@ -1053,19 +1053,61 @@ instance Lucid.ToHtml BlockedPage where instance Lucid.ToHtml InterventionPage where toHtmlRaw = Lucid.toHtml - toHtml (InterventionPage tasks currentSort _now) = - let crumbs = [Breadcrumb "Jr" (Just "/"), Breadcrumb "Needs Intervention" Nothing] + toHtml (InterventionPage actionItems currentSort _now) = + let crumbs = [Breadcrumb "Jr" (Just "/"), Breadcrumb "Needs Human Action" Nothing] + failed = TaskCore.failedTasks actionItems + epicsReady = TaskCore.epicsInReview actionItems + human = TaskCore.humanTasks actionItems + totalCount = length failed + length epicsReady + length human in Lucid.doctypehtml_ <| do - pageHead "Needs Intervention - Jr" + pageHead "Needs Human Action - Jr" pageBodyWithCrumbs crumbs <| do Lucid.div_ [Lucid.class_ "container"] <| do Lucid.div_ [Lucid.class_ "page-header-row"] <| do - Lucid.h1_ <| Lucid.toHtml ("Needs Intervention (" <> tshow (length tasks) <> " tasks)") + Lucid.h1_ <| Lucid.toHtml ("Needs Human Action (" <> tshow totalCount <> " items)") sortDropdown "/intervention" currentSort - Lucid.p_ [Lucid.class_ "info-msg"] "Tasks that have failed 3+ times and need human help." - if null tasks - then Lucid.p_ [Lucid.class_ "empty-msg"] "No tasks need intervention." - else Lucid.div_ [Lucid.class_ "task-list"] <| traverse_ renderTaskCard tasks + if totalCount == 0 + then Lucid.p_ [Lucid.class_ "empty-msg"] "No items need human action." + else do + unless (null failed) <| do + Lucid.h2_ [Lucid.class_ "section-header"] <| Lucid.toHtml ("Failed Tasks (" <> tshow (length failed) <> ")") + Lucid.p_ [Lucid.class_ "info-msg"] "Tasks that have failed 3+ times and need human help." + Lucid.div_ [Lucid.class_ "task-list"] <| traverse_ renderTaskCard (sortTasks currentSort failed) + unless (null epicsReady) <| do + Lucid.h2_ [Lucid.class_ "section-header"] <| Lucid.toHtml ("Epics Ready for Review (" <> tshow (length epicsReady) <> ")") + Lucid.p_ [Lucid.class_ "info-msg"] "Epics with all children completed. Verify before closing." + Lucid.div_ [Lucid.class_ "task-list"] <| traverse_ renderEpicReviewCard epicsReady + unless (null human) <| do + Lucid.h2_ [Lucid.class_ "section-header"] <| Lucid.toHtml ("Human Tasks (" <> tshow (length human) <> ")") + Lucid.p_ [Lucid.class_ "info-msg"] "Tasks explicitly marked as needing human work." + Lucid.div_ [Lucid.class_ "task-list"] <| traverse_ renderTaskCard (sortTasks currentSort human) + +renderEpicReviewCard :: (Monad m) => TaskCore.EpicForReview -> Lucid.HtmlT m () +renderEpicReviewCard epicReview = do + let task = TaskCore.epicTask epicReview + total = TaskCore.epicTotal epicReview + completed = TaskCore.epicCompleted epicReview + progressText = tshow completed <> "/" <> tshow total <> " subtasks done" + Lucid.div_ [Lucid.class_ "task-card"] <| do + Lucid.div_ [Lucid.class_ "task-card-header"] <| do + Lucid.div_ [Lucid.class_ "task-title-row"] <| do + Lucid.a_ + [Lucid.href_ ("/tasks/" <> TaskCore.taskId task), Lucid.class_ "task-link"] + <| Lucid.toHtml (TaskCore.taskTitle task) + Lucid.span_ [Lucid.class_ "badge badge-epic"] "Epic" + Lucid.span_ [Lucid.class_ "task-id"] <| Lucid.toHtml (TaskCore.taskId task) + Lucid.div_ [Lucid.class_ "task-card-body"] <| do + Lucid.div_ [Lucid.class_ "progress-info"] <| do + Lucid.span_ [Lucid.class_ "badge badge-success"] <| Lucid.toHtml progressText + Lucid.div_ [Lucid.class_ "epic-actions"] <| do + Lucid.form_ + [ Lucid.method_ "POST", + Lucid.action_ ("/tasks/" <> TaskCore.taskId task <> "/status"), + Lucid.class_ "inline-form" + ] + <| do + Lucid.input_ [Lucid.type_ "hidden", Lucid.name_ "status", Lucid.value_ "done"] + Lucid.button_ [Lucid.type_ "submit", Lucid.class_ "btn btn-success btn-sm"] "Approve & Close" instance Lucid.ToHtml KBPage where toHtmlRaw = Lucid.toHtml @@ -2446,10 +2488,9 @@ server = interventionHandler :: Maybe Text -> Servant.Handler InterventionPage interventionHandler maybeSortText = do now <- liftIO getCurrentTime - interventionTasks <- liftIO TaskCore.getInterventionTasks + actionItems <- liftIO TaskCore.getHumanActionItems let sortOrder = parseSortOrder maybeSortText - sortedTasks = sortTasks sortOrder interventionTasks - pure (InterventionPage sortedTasks sortOrder now) + pure (InterventionPage actionItems sortOrder now) statsHandler :: Maybe Text -> Servant.Handler StatsPage statsHandler maybeEpic = do |
