Sort /blocked page by blocking impact (transitive dependents)

t-189·WorkTask·
·
·
·Omni/Jr.hs
Created3 months ago·Updated3 months ago

Description

Edit

On the /blocked page, sort tasks by how many other tasks they transitively block. Tasks that unblock the most downstream work should appear first.

Example

If: A blocks B, B blocks C, C blocks D

  • A has blocking impact 3 (blocks B, C, D)
  • B has blocking impact 2 (blocks C, D)
  • C has blocking impact 1 (blocks D)
  • D has blocking impact 0

Sort order: A, B, C, D (highest impact first)

Implementation

1. Add helper in TaskCore.hs:

-- Count how many tasks are transitively blocked by this task
getBlockingImpact :: [Task] -> Task -> Int
getBlockingImpact allTasks task =
  length (getTransitiveDependents allTasks (taskId task))

-- Get all tasks that depend on this task (directly or transitively)
getTransitiveDependents :: [Task] -> Text -> [Task]
getTransitiveDependents allTasks tid =
  let directDeps = filter (dependsOn tid) allTasks
      transitive = concatMap (getTransitiveDependents allTasks . taskId) directDeps
  in List.nubBy ((==) `on` taskId) (directDeps ++ transitive)

-- Check if task depends on given ID with Blocks dependency type
dependsOn :: Text -> Task -> Bool  
dependsOn tid task = 
  any (\d -> depId d == tid && depType d == Blocks) (taskDependencies task)

2. Update blockedHandler in Web.hs:

blockedHandler :: Handler BlockedPage
blockedHandler = do
  now <- liftIO getCurrentTime
  blocked <- liftIO TaskCore.getBlockedTasks
  allTasks <- liftIO TaskCore.loadTasks
  let sorted = List.sortBy (comparing (Down . TaskCore.getBlockingImpact allTasks)) blocked
  pure (BlockedPage sorted now)

3. Optionally show the count in the UI:

-- In renderTaskCard or a blocked-specific variant
Lucid.span_ [Lucid.class_ "blocking-impact"] 
  (Lucid.toHtml ("Blocks " <> tshow impact <> " tasks"))

4. Add CSS for .blocking-impact badge (subtle, informational)

Edge Cases

  • Circular dependencies: use Set to track visited nodes and avoid infinite loops
  • Tasks with no dependents: impact = 0, sort to bottom

Files: Omni/Task/Core.hs (helpers), Omni/Jr/Web.hs (handler, optional UI)

Timeline (0)

No activity yet.