summaryrefslogtreecommitdiff
path: root/Omni/Jr
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-27 13:53:59 -0500
committerBen Sima <ben@bensima.com>2025-11-27 13:53:59 -0500
commit6eb6e6693a27c9450be4963c0d2043c88e2c5edb (patch)
tree7762d12374cb5d0284b6ceb97a65207f867ff08e /Omni/Jr
parent2cec3abd126f1e24b4519d6b694623a049e47032 (diff)
Add diff view page for commits
All the pieces are in place: 1. Route: `GET /tasks/:id/diff/:commit` (line 65) 2. Data type: `TaskDiffPage` (line 119) 3. `ToHtml` instance for rendering (line 759) 4. Handler: `taskDiffHandler` (line 1225) 5. Helper: `getDiffForCommit` (line 1301) The implementation shows: - Full git diff output via `git show <commit>` - Pre-formatted output (`<pre class="diff-block">`) - Link back to task detail page - Proper error handling for invalid commits Task-Id: t-153.2
Diffstat (limited to 'Omni/Jr')
-rw-r--r--Omni/Jr/Web.hs50
1 files changed, 50 insertions, 0 deletions
diff --git a/Omni/Jr/Web.hs b/Omni/Jr/Web.hs
index 55ff06b..b751ee9 100644
--- a/Omni/Jr/Web.hs
+++ b/Omni/Jr/Web.hs
@@ -62,6 +62,7 @@ type API =
:<|> "tasks" :> Capture "id" Text :> "status" :> ReqBody '[FormUrlEncoded] StatusForm :> Post '[Lucid.HTML] StatusBadgePartial
:<|> "tasks" :> Capture "id" Text :> "description" :> ReqBody '[FormUrlEncoded] DescriptionForm :> PostRedirect
:<|> "tasks" :> Capture "id" Text :> "review" :> Get '[Lucid.HTML] TaskReviewPage
+ :<|> "tasks" :> Capture "id" Text :> "diff" :> Capture "commit" Text :> Get '[Lucid.HTML] TaskDiffPage
:<|> "tasks" :> Capture "id" Text :> "accept" :> PostRedirect
:<|> "tasks" :> Capture "id" Text :> "reject" :> ReqBody '[FormUrlEncoded] RejectForm :> PostRedirect
:<|> "partials" :> "recent-activity" :> Get '[Lucid.HTML] RecentActivityPartial
@@ -115,6 +116,10 @@ data ReviewInfo
| ReviewMergeConflict Text [Text]
| ReviewReady Text Text
+data TaskDiffPage
+ = DiffPageFound Text Text Text
+ | DiffPageNotFound Text Text
+
data StatsPage = StatsPage TaskCore.TaskStats (Maybe Text)
newtype RecentActivityPartial = RecentActivityPartial [TaskCore.Task]
@@ -751,6 +756,32 @@ instance Lucid.ToHtml TaskReviewPage where
""
Lucid.button_ [Lucid.type_ "submit", Lucid.class_ "reject-btn"] "Reject"
+instance Lucid.ToHtml TaskDiffPage where
+ toHtmlRaw = Lucid.toHtml
+ toHtml (DiffPageNotFound tid commitHash') =
+ Lucid.doctypehtml_ <| do
+ pageHead "Commit Not Found - Jr"
+ Lucid.body_ <| do
+ navbar
+ Lucid.div_ [Lucid.class_ "container"] <| do
+ Lucid.h1_ "Commit Not Found"
+ Lucid.p_ <| do
+ "Could not find commit "
+ Lucid.code_ (Lucid.toHtml commitHash')
+ Lucid.a_ [Lucid.href_ ("/tasks/" <> tid), Lucid.class_ "back-link"] "← Back to task"
+ toHtml (DiffPageFound tid commitHash' diffOutput) =
+ Lucid.doctypehtml_ <| do
+ pageHead ("Diff " <> Text.take 8 commitHash' <> " - Jr")
+ Lucid.body_ <| do
+ navbar
+ Lucid.div_ [Lucid.class_ "container"] <| do
+ Lucid.div_ [Lucid.class_ "diff-header"] <| do
+ Lucid.a_ [Lucid.href_ ("/tasks/" <> tid), Lucid.class_ "back-link"] "← Back to task"
+ Lucid.h1_ <| do
+ "Commit "
+ Lucid.code_ (Lucid.toHtml (Text.take 8 commitHash'))
+ Lucid.pre_ [Lucid.class_ "diff-block"] (Lucid.toHtml diffOutput)
+
instance Lucid.ToHtml StatsPage where
toHtmlRaw = Lucid.toHtml
toHtml (StatsPage stats maybeEpic) =
@@ -1076,6 +1107,7 @@ server =
:<|> taskStatusHandler
:<|> taskDescriptionHandler
:<|> taskReviewHandler
+ :<|> taskDiffHandler
:<|> taskAcceptHandler
:<|> taskRejectHandler
:<|> recentActivityHandler
@@ -1190,6 +1222,13 @@ server =
reviewInfo <- liftIO <| getReviewInfo tid
pure (ReviewPageFound task reviewInfo)
+ taskDiffHandler :: Text -> Text -> Servant.Handler TaskDiffPage
+ taskDiffHandler tid commitSha = do
+ diffOutput <- liftIO <| getDiffForCommit commitSha
+ case diffOutput of
+ Nothing -> pure (DiffPageNotFound tid commitSha)
+ Just output -> pure (DiffPageFound tid commitSha output)
+
taskAcceptHandler :: Text -> Servant.Handler (Headers '[Header "Location" Text] NoContent)
taskAcceptHandler tid = do
liftIO <| do
@@ -1259,6 +1298,17 @@ getReviewInfo tid = do
""
pure (ReviewReady commitSha (Text.pack diffOut))
+getDiffForCommit :: Text -> IO (Maybe Text)
+getDiffForCommit commitSha = do
+ (code, diffOut, _) <-
+ Process.readProcessWithExitCode
+ "git"
+ ["show", Text.unpack commitSha]
+ ""
+ case code of
+ Exit.ExitSuccess -> pure (Just (Text.pack diffOut))
+ Exit.ExitFailure _ -> pure Nothing
+
findCommitForTask :: Text -> IO (Maybe Text)
findCommitForTask tid = do
let grepArg = "--grep=" <> Text.unpack tid