module Web.View.AgentProposals.Show where
import Web.Types
import Generated.Types
import IHP.Prelude
import IHP.ViewPrelude
data ShowView = ShowView
{ proposal :: !AgentProposal
, mWidget :: !(Maybe Widget)
, mCandidate :: !(Maybe RequirementCandidate)
, mDecision :: !(Maybe DecisionRecord)
, mReview :: !(Maybe AgentReviewRecord)
, confidences :: ![ConfidenceAnnotation]
, users :: ![User]
}
instance View ShowView where
html ShowView { .. } = [hsx|
" text-sm px-2 py-1 rounded font-medium"}>
{proposal.proposalType}
" text-sm px-2 py-1 rounded font-medium"}>
{proposal.status}
AI Output
{proposal.content}
{if null confidences then mempty else renderConfidences confidences}
Source Context
- Widget
- {maybe "—" (.name) mWidget}
- Candidate
- {maybe "—" (.title) mCandidate}
- Decision
- {maybe "—" (.title) mDecision}
{case mReview of
Just review -> renderExistingReview review users
Nothing -> renderReviewForm proposal.id proposal.status}
Model: {proposal.modelRef}
· Created: {show proposal.createdAt}
|]
renderConfidences :: [ConfidenceAnnotation] -> Html
renderConfidences cs = [hsx|
Confidence Breakdown
{forEach cs renderConfidenceRow}
|]
renderConfidenceRow :: ConfidenceAnnotation -> Html
renderConfidenceRow c =
let pct = show (round (c.score * 100) :: Int) <> "%"
barWidth = "width: " <> pct
in [hsx|
{c.dimension}
{pct}
{maybe mempty (\e -> [hsx|
{e}
|]) c.explanation}
|]
renderExistingReview :: AgentReviewRecord -> [User] -> Html
renderExistingReview review users = [hsx|
Review Decision
" text-sm px-2 py-1 rounded font-medium"}>
{review.decision}
by {reviewerName users review.reviewerId} at {show review.reviewedAt}
{maybe mempty (\n -> [hsx|
{n}
|]) review.notes}
|]
renderReviewForm :: Id AgentProposal -> Text -> Html
renderReviewForm pid status
| status /= "pending" = mempty
| otherwise = [hsx|
Review This Proposal
|]
reviewerName :: [User] -> Maybe (Id User) -> Text
reviewerName _ Nothing = "unknown"
reviewerName users (Just uid) = maybe "(unknown)" (.name) (find (\u -> u.id == uid) users)
proposalTypeBadge :: Text -> Text
proposalTypeBadge "summary" = "bg-blue-100 text-blue-800"
proposalTypeBadge "requirement_draft" = "bg-indigo-100 text-indigo-800"
proposalTypeBadge "duplicate_flag" = "bg-orange-100 text-orange-800"
proposalTypeBadge "policy_flag" = "bg-red-100 text-red-800"
proposalTypeBadge "impl_proposal" = "bg-green-100 text-green-800"
proposalTypeBadge _ = "bg-gray-100 text-gray-600"
statusBadge :: Text -> Text
statusBadge "pending" = "bg-yellow-100 text-yellow-800"
statusBadge "accepted" = "bg-green-100 text-green-800"
statusBadge "rejected" = "bg-red-100 text-red-800"
statusBadge "superseded" = "bg-gray-100 text-gray-500"
statusBadge _ = "bg-gray-100 text-gray-600"
decisionBadge :: Text -> Text
decisionBadge "accepted" = "bg-green-100 text-green-800"
decisionBadge "rejected" = "bg-red-100 text-red-800"
decisionBadge "modified" = "bg-blue-100 text-blue-800"
decisionBadge _ = "bg-gray-100 text-gray-600"