viewProjectQueues :: ProjectInfo -> ProjectState -> Html
viewProjectQueues info state = do
  let
    pullRequests = Project.classifyPullRequests state
    filterPrs predicate = fmap fst $ filter (predicate . snd) pullRequests

  let building = filterPrs (== Project.PrStatusBuildPending)
  h2 "Building"
  if null building
    then p "There are no builds in progress at the moment."
    else viewList viewPullRequestWithApproval info state building

  let approved = filterPrs (== Project.PrStatusApproved)
  unless (null approved) $ do
    h2 "Approved"
    viewList viewPullRequestWithApproval info state approved

  let awaitingApproval = filterPrs (== Project.PrStatusAwaitingApproval)
  unless (null awaitingApproval) $ do
    h2 "Awaiting approval"
    viewList viewPullRequest info state awaitingApproval

  let failed = filterPrs $ \ st ->
        (st == Project.PrStatusFailedConflict) || (st == Project.PrStatusFailedBuild)
  unless (null failed) $ do
    h2 "Failed"
    -- TODO: Also render failure reason: conflicted or build failed.
    viewList viewPullRequestWithApproval info state failed

  -- TODO: Keep a list of the last n integrated pull requests, so they stay
  -- around for a bit after they have been closed.
  let integrated = filterPrs (== Project.PrStatusIntegrated)
  unless (null integrated) $ do
    h2 "Recently integrated"
    viewList viewPullRequestWithApproval info state integrated

-- Renders the contents of a list item with a link for a pull request.
viewProjectQueues :: ProjectInfo -> ProjectState -> Html
viewProjectQueues info state = do
  let
    pullRequests = Project.classifyPullRequests state
    filterPrs predicate = fmap fst $ filter (predicate . snd) pullRequests

  let building = filterPrs (== Project.PrStatusBuildPending)
  h2 "Building"
  if null building
    then p "There are no builds in progress at the moment."
    else viewList viewPullRequestWithApproval info state building

  let approved = filterPrs (== Project.PrStatusApproved)
  unless (null approved) $ do
    h2 "Approved"
    viewList viewPullRequestWithApproval info state approved

  let awaitingApproval = filterPrs (== Project.PrStatusAwaitingApproval)
  unless (null awaitingApproval) $ do
    h2 "Awaiting approval"
    viewList viewPullRequest info state awaitingApproval

  let failed = filterPrs $ \ st ->
        (st == Project.PrStatusFailedConflict) || (st == Project.PrStatusFailedBuild)
  unless (null failed) $ do
    h2 "Failed"
    -- TODO: Also render failure reason: conflicted or build failed.
    viewList viewPullRequestWithApproval info state failed

  -- TODO: Keep a list of the last n integrated pull requests, so they stay
  -- around for a bit after they have been closed.
  let integrated = filterPrs (== Project.PrStatusIntegrated)
  unless (null integrated) $ do
    h2 "Recently integrated"
    viewList viewPullRequestWithApproval info state integrated

-- Renders the contents of a list item with a link for a pull request.
viewProjectQueues info state = do
  let
    pullRequests = Project.classifyPullRequests state
    filterPrs predicate = fmap fst $ filter (predicate . snd) pullRequests

  let building = filterPrs (== Project.PrStatusBuildPending)
  h2 "Building"
  if null building
    then p "There are no builds in progress at the moment."
    else viewList viewPullRequestWithApproval info state building

  let approved = filterPrs (== Project.PrStatusApproved)
  unless (null approved) $ do
    h2 "Approved"
    viewList viewPullRequestWithApproval info state approved

  let awaitingApproval = filterPrs (== Project.PrStatusAwaitingApproval)
  unless (null awaitingApproval) $ do
    h2 "Awaiting approval"
    viewList viewPullRequest info state awaitingApproval

  let failed = filterPrs $ \ st ->
        (st == Project.PrStatusFailedConflict) || (st == Project.PrStatusFailedBuild)
  unless (null failed) $ do
    h2 "Failed"
    -- TODO: Also render failure reason: conflicted or build failed.
    viewList viewPullRequestWithApproval info state failed

  -- TODO: Keep a list of the last n integrated pull requests, so they stay
  -- around for a bit after they have been closed.
  let integrated = filterPrs (== Project.PrStatusIntegrated)
  unless (null integrated) $ do
    h2 "Recently integrated"
    viewList viewPullRequestWithApproval info state integrated

-- Renders the contents of a list item with a link for a pull request.