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}

{candidate.title}

Edit
" 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|

Source thread:

{t.title}
|] 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||] 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"