module Web.View.RequirementCandidates.Show where
import Web.View.Prelude
import Web.Routes ()
data ShowView = ShowView
{ candidate :: !RequirementCandidate
, widget :: !Widget
, triageStates :: ![TriageState]
, mAssignment :: !(Maybe ReviewerAssignment)
, users :: ![User]
, mSourceAnnotation :: !(Maybe Annotation)
, mSourceThread :: !(Maybe AnnotationThread)
}
instance View ShowView where
html ShowView { .. } = [hsx|
Candidates
/
{candidate.title}
" text-xs px-2 py-0.5 rounded font-medium"}>
{candidate.status}
{candidate.category}
Widget: {widget.name}
{candidate.description}
Source
{renderSource mSourceAnnotation mSourceThread}
Triage
{renderTriageActions candidate}
Reviewer
{renderReviewerSection candidate mAssignment users}
{renderGovernanceActions candidate}
Triage History
{renderTriageHistory triageStates}
|]
renderSource :: Maybe Annotation -> Maybe AnnotationThread -> Html
renderSource Nothing Nothing = [hsx|No source linked.
|]
renderSource (Just a) _ = [hsx|
Source annotation:
"{a.body}"
|]
renderSource Nothing (Just t) = [hsx|
|]
renderTriageActions :: RequirementCandidate -> Html
renderTriageActions c = [hsx|
{forEach (allowedNextStatuses c.status) (renderTriageButton c.id)}
|]
allowedNextStatuses :: Text -> [Text]
allowedNextStatuses "open" = ["in_review"]
allowedNextStatuses "in_review" = ["accepted", "rejected", "deferred"]
allowedNextStatuses "deferred" = ["in_review"]
allowedNextStatuses _ = []
renderTriageButton :: Id RequirementCandidate -> Text -> Html
renderTriageButton candidateId newStatus = [hsx|
|]
triageButtonClass :: Text -> Text
triageButtonClass "accepted" = "text-sm px-3 py-1.5 rounded border bg-green-50 border-green-300 text-green-800 hover:bg-green-100"
triageButtonClass "rejected" = "text-sm px-3 py-1.5 rounded border bg-red-50 border-red-300 text-red-800 hover:bg-red-100"
triageButtonClass "deferred" = "text-sm px-3 py-1.5 rounded border bg-gray-50 border-gray-300 text-gray-700 hover:bg-gray-100"
triageButtonClass _ = "text-sm px-3 py-1.5 rounded border bg-yellow-50 border-yellow-300 text-yellow-800 hover:bg-yellow-100"
renderReviewerSection :: RequirementCandidate -> Maybe ReviewerAssignment -> [User] -> Html
renderReviewerSection candidate mAssignment users = [hsx|
{renderAssignmentStatus mAssignment users}
|]
reviewerName :: ReviewerAssignment -> [User] -> Text
reviewerName ra users =
maybe "Unknown" (.name) (find (\u -> u.id == ra.userId) users)
renderTriageHistory :: [TriageState] -> Html
renderTriageHistory [] = [hsx|No triage actions recorded yet.
|]
renderTriageHistory states = [hsx|
{forEach states renderTriageRow}
|]
renderAssignmentStatus :: Maybe ReviewerAssignment -> [User] -> Html
renderAssignmentStatus Nothing _ = [hsx|Unassigned |]
renderAssignmentStatus (Just ra) users = [hsx|{reviewerName ra users} |]
renderUserOption :: User -> Html
renderUserOption u = [hsx|{u.name} |]
renderTriageNote :: Text -> Html
renderTriageNote n = [hsx|{n}
|]
renderTriageRow :: TriageState -> Html
renderTriageRow ts = [hsx|
" text-xs px-2 py-0.5 rounded mt-0.5 shrink-0"}>
{ts.status}
{maybe mempty renderTriageNote ts.notes}
{show ts.changedAt}
|]
renderGovernanceActions :: RequirementCandidate -> Html
renderGovernanceActions candidate
| candidate.status == "accepted" = [hsx|
Governance
{renderPromoteButton candidate}
{renderLinkDecisionButton candidate}
|]
| otherwise = mempty
renderPromoteButton :: RequirementCandidate -> Html
renderPromoteButton candidate =
case candidate.requirementId of
Just rid -> [hsx|
Requirement →
|]
Nothing -> [hsx|
|]
renderLinkDecisionButton :: RequirementCandidate -> Html
renderLinkDecisionButton candidate = [hsx|
|]
statusClass :: Text -> Text
statusClass "open" = "bg-blue-100 text-blue-700"
statusClass "in_review" = "bg-yellow-100 text-yellow-800"
statusClass "accepted" = "bg-green-100 text-green-800"
statusClass "rejected" = "bg-red-100 text-red-800"
statusClass "deferred" = "bg-gray-100 text-gray-600"
statusClass _ = "bg-gray-100 text-gray-600"