module Web.View.Widgets.Show where import Web.Types import Generated.Types import IHP.Prelude import IHP.ViewPrelude import Web.Routes () import Application.Helper.View (widgetEnvelope) data ShowView = ShowView { widget :: !Widget , hub :: !Hub , versions :: ![WidgetVersion] , events :: ![InteractionEvent] , annotations :: ![Annotation] , recentSignals :: ![OutcomeSignal] , isRegressed :: !Bool , cycleCount :: !Int , mAdapterSpec :: !(Maybe WidgetAdapterSpec) } instance View ShowView where html ShowView { .. } = [hsx|
Hubs / {hub.name} / {widget.name}
{renderCycleBanner cycleCount} {if isRegressed then renderRegressionBanner else mempty} {widgetEnvelope widget widgetHeader}

Total Events

{length events}

Annotations

{length annotations}

Versions

{length versions}

Annotations

{if length annotations >= 3 then renderDraftRequirementForm widget.id else mempty}
+ Add
{forEach rootAnnotations (renderAnnotation childrenOf)}

Annotation Breakdown

{forEach categoryBreakdown renderCategoryRow}

Interaction Events

{forEach events renderEventRow}
Event Actor Occurred
{renderSignalsSection recentSignals}

Version History

{forEach versions renderVersionRow}
Version Recorded
|] where widgetHeader = [hsx|

{widget.name}

{widget.widgetType} {widget.policyScope} {widget.status} v{show widget.version} {renderAdapterBadge mAdapterSpec}

Edit
|] rootAnnotations = filter (\a -> isNothing a.parentId) annotations childrenOf parent = filter (\a -> a.parentId == Just parent.id) annotations categoryBreakdown = [ (cat, length (filter (\a -> a.category == cat) annotations)) | cat <- ["friction","defect","wish","policy_concern","doc_gap","trust","other"] , any (\a -> a.category == cat) annotations ] renderAnnotation :: (Annotation -> [Annotation]) -> Annotation -> Html renderAnnotation childrenOf a = [hsx|
{a.category} {a.actorType} {show a.createdAt}

{a.body}

{forEach (childrenOf a) (renderAnnotation childrenOf)}
|] renderEventRow :: InteractionEvent -> Html renderEventRow e = [hsx| {e.eventType} {e.actorType} {show e.occurredAt} |] renderVersionRow :: WidgetVersion -> Html renderVersionRow v = [hsx| v{show v.version} {show v.createdAt} |] renderCategoryRow :: (Text, Int) -> Html renderCategoryRow (cat, count) = [hsx|
{cat} {show count}
|] renderSignalRow :: OutcomeSignal -> Html renderSignalRow sig = [hsx|
" text-xs px-2 py-0.5 rounded font-medium"}> {sig.signalType} {maybe mempty renderSignalValue sig.value} {show sig.observedAt}
|] signalTypeClass :: Text -> Text signalTypeClass "improved" = "bg-green-100 text-green-800" signalTypeClass "regressed" = "bg-red-100 text-red-800" signalTypeClass "neutral" = "bg-gray-100 text-gray-600" signalTypeClass "inconclusive" = "bg-yellow-100 text-yellow-800" signalTypeClass _ = "bg-gray-100 text-gray-600" renderCycleBanner :: Int -> Html renderCycleBanner n | n >= 2 = [hsx|
⟳ {show n} cycles Recurring friction — this widget has been through {show n} improvement cycles.
|] renderCycleBanner _ = mempty renderRegressionBanner :: Html renderRegressionBanner = [hsx|
⚠ Regression detected This widget had an improved signal but has since received high/critical annotations.
|] renderDraftRequirementForm :: Id Widget -> Html renderDraftRequirementForm wid = [hsx|
|] renderSignalsSection :: [OutcomeSignal] -> Html renderSignalsSection [] = mempty renderSignalsSection sigs = [hsx|

Recent Outcome Signals

{forEach sigs renderSignalRow}
|] renderSignalValue :: Double -> Html renderSignalValue v = [hsx|{show v}|] renderAdapterBadge :: Maybe WidgetAdapterSpec -> Html renderAdapterBadge Nothing = mempty renderAdapterBadge (Just s) = [hsx| adapter: {s.name} |]