diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-27 13:53:59 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-27 13:53:59 -0500 |
| commit | 6eb6e6693a27c9450be4963c0d2043c88e2c5edb (patch) | |
| tree | 7762d12374cb5d0284b6ceb97a65207f867ff08e /Omni/Jr | |
| parent | 2cec3abd126f1e24b4519d6b694623a049e47032 (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.hs | 50 |
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 |
