Expose dashboard template-launch and preview action control surfaces
This commit is contained in:
parent
a052777bed
commit
9fafb7d5c7
5 changed files with 515 additions and 5 deletions
|
|
@ -12683,6 +12683,259 @@ UHyperTwistCoachDashboardWidget::GetDisplayedRunRecapActionControlInspectSurface
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardPreferredTemplateLaunchActionInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedPreferredTemplateLaunchActionInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardPreferredTemplateLaunchActionInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Preferred template launch action");
|
||||
|
||||
const bool bHasActiveRun = CachedRunState.Session.IsStructurallyValid()
|
||||
&& CachedRunState.ActiveDeck.IsStructurallyValid();
|
||||
FHyperTwistTrainingTemplateLaunchSelectionProvenance SelectionProvenance;
|
||||
const FHyperTwistTrainingSessionTemplate* PreferredTemplateLaunch =
|
||||
FindPreferredDashboardTemplateLaunch(&SelectionProvenance);
|
||||
int32 EligibleTemplateCount = 0;
|
||||
for (const FHyperTwistTrainingSessionTemplate& SessionTemplate : CachedActiveTrainingSessionTemplates)
|
||||
{
|
||||
if (HyperTwistCoachDashboardWidgetInternal::ScoreTemplateForDashboardLaunch(SessionTemplate) > 0)
|
||||
{
|
||||
EligibleTemplateCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const bool bHasPreferredTemplate = PreferredTemplateLaunch != nullptr;
|
||||
const bool bUsesReviewLane =
|
||||
bHasPreferredTemplate
|
||||
&& (PreferredTemplateLaunch->bPreferReviewRun
|
||||
|| PreferredTemplateLaunch->TemplateKind == EHyperTwistTrainingSessionTemplateKind::ReviewPlan
|
||||
|| PreferredTemplateLaunch->TemplateKind == EHyperTwistTrainingSessionTemplateKind::Coach);
|
||||
const FString PreferredTemplateTitle = bHasPreferredTemplate
|
||||
? (PreferredTemplateLaunch->Title.IsEmpty()
|
||||
? PreferredTemplateLaunch->TemplateId
|
||||
: PreferredTemplateLaunch->Title)
|
||||
: TEXT("n/a");
|
||||
const FString PreferredTemplateUserId = bHasPreferredTemplate
|
||||
? (PreferredTemplateLaunch->UserId.IsEmpty() ? DefaultUserId : PreferredTemplateLaunch->UserId)
|
||||
: FString();
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* PreferredTemplateStats =
|
||||
bHasPreferredTemplate
|
||||
? FindCachedTemplateLaunchScopedStats(
|
||||
PreferredTemplateLaunch->TemplateId,
|
||||
PreferredTemplateUserId)
|
||||
: nullptr;
|
||||
const FString TemplateSelectionDetail =
|
||||
HyperTwistCoachDashboardWidgetInternal::BuildTemplateLaunchSelectionDetailFragment(
|
||||
SelectionProvenance.IsStructurallyValid() ? &SelectionProvenance : nullptr
|
||||
);
|
||||
const bool bCanLaunchPreferredTemplate =
|
||||
!bHasLiveAttemptTimer && !bHasActiveRun && bHasPreferredTemplate;
|
||||
|
||||
FString TemplateActionLabel = TEXT("No Template");
|
||||
if (bHasPreferredTemplate)
|
||||
{
|
||||
TemplateActionLabel =
|
||||
PreferredTemplateTitle.Len() <= 28
|
||||
? PreferredTemplateTitle
|
||||
: (bUsesReviewLane ? TEXT("Launch Review Template") : TEXT("Launch Recovery Template"));
|
||||
}
|
||||
if (bHasLiveAttemptTimer && bHasPreferredTemplate)
|
||||
{
|
||||
TemplateActionLabel = TEXT("Template Busy");
|
||||
}
|
||||
else if (bHasActiveRun && bHasPreferredTemplate)
|
||||
{
|
||||
TemplateActionLabel = TEXT("Clear Run For Template");
|
||||
}
|
||||
|
||||
Surface.ActionLabel = !DisplayedTemplateLaunchActionLabel.IsEmpty()
|
||||
? DisplayedTemplateLaunchActionLabel
|
||||
: TemplateActionLabel;
|
||||
Surface.DisplayedTemplateStatusLine = !DisplayedTemplateLaunchStatusLine.IsEmpty()
|
||||
? DisplayedTemplateLaunchStatusLine
|
||||
: TEXT("Template launch status: not yet displayed.");
|
||||
Surface.DisplayedTemplateDetailLine = !DisplayedTemplateLaunchDetailLine.IsEmpty()
|
||||
? DisplayedTemplateLaunchDetailLine
|
||||
: TEXT("Template launch detail: not yet displayed.");
|
||||
Surface.TemplateTitle = PreferredTemplateTitle;
|
||||
Surface.TemplateId = bHasPreferredTemplate && !PreferredTemplateLaunch->TemplateId.IsEmpty()
|
||||
? PreferredTemplateLaunch->TemplateId
|
||||
: TEXT("n/a");
|
||||
Surface.TemplateKindLabel = bHasPreferredTemplate
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(PreferredTemplateLaunch->TemplateKind)
|
||||
: TEXT("n/a");
|
||||
Surface.UserId = PreferredTemplateUserId.IsEmpty() ? TEXT("n/a") : PreferredTemplateUserId;
|
||||
Surface.FocusDeckId =
|
||||
bHasPreferredTemplate && !PreferredTemplateLaunch->FocusDeckId.IsEmpty()
|
||||
? PreferredTemplateLaunch->FocusDeckId
|
||||
: TEXT("n/a");
|
||||
Surface.GuidanceLabel =
|
||||
bHasPreferredTemplate && !PreferredTemplateLaunch->GuidanceLabel.IsEmpty()
|
||||
? PreferredTemplateLaunch->GuidanceLabel
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedModeLabel = bHasPreferredTemplate
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(PreferredTemplateLaunch->SuggestedMode)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedSelectionLabel = bHasPreferredTemplate
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
PreferredTemplateLaunch->SuggestedSelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.SelectionDetailLine =
|
||||
TemplateSelectionDetail.IsEmpty() ? TEXT("none") : TemplateSelectionDetail;
|
||||
Surface.EligibleTemplateCount = EligibleTemplateCount;
|
||||
Surface.ActiveTemplateCount = CachedActiveTrainingSessionTemplates.Num();
|
||||
Surface.RecommendedCaseCount =
|
||||
bHasPreferredTemplate ? PreferredTemplateLaunch->RecommendedCaseCount : 0;
|
||||
Surface.FocusCaseCount = bHasPreferredTemplate ? PreferredTemplateLaunch->FocusCaseIds.Num() : 0;
|
||||
Surface.bHasPreferredTemplate = bHasPreferredTemplate;
|
||||
Surface.bUsesReviewLane = bUsesReviewLane;
|
||||
Surface.bHasScopedStats =
|
||||
PreferredTemplateStats != nullptr && PreferredTemplateStats->IsStructurallyValid();
|
||||
Surface.bHasSelectionProvenance = SelectionProvenance.IsStructurallyValid();
|
||||
Surface.bHasLiveAttemptTimer = bHasLiveAttemptTimer;
|
||||
Surface.bHasActiveRun = bHasActiveRun;
|
||||
Surface.bActionEnabled = bCanLaunchPreferredTemplate;
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("%s | Action: %s (%s)"),
|
||||
*Surface.DisplayedTemplateStatusLine,
|
||||
*Surface.ActionLabel,
|
||||
Surface.bActionEnabled ? TEXT("enabled") : TEXT("disabled"));
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s | active run %s | live timer %s | review lane %s | selection provenance %s"),
|
||||
*Surface.DisplayedTemplateDetailLine,
|
||||
Surface.bHasActiveRun ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bHasLiveAttemptTimer ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bUsesReviewLane ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bHasSelectionProvenance ? TEXT("yes") : TEXT("no"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedRecommendedPreviewActionInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Recommended preview action");
|
||||
Surface.GuidanceLaneLabel = TEXT("recommended");
|
||||
|
||||
const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString
|
||||
{
|
||||
return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: TEXT("none"));
|
||||
};
|
||||
|
||||
const FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface PreviewSurface =
|
||||
GetDisplayedRecommendedGuidanceDeckPreviewInspectSurface();
|
||||
const bool bActionEnabled =
|
||||
!bHasLiveAttemptTimer && CachedCoachPanelState.bCanStartCoachRecommendedRun;
|
||||
|
||||
Surface.ActionLabel = !DisplayedPreviewRecommendedActionLabel.IsEmpty()
|
||||
? DisplayedPreviewRecommendedActionLabel
|
||||
: TEXT("Preview Recommended");
|
||||
Surface.PreviewStatusLine = PreviewSurface.StatusLine.IsEmpty()
|
||||
? TEXT("Recommended guidance: no guidance available.")
|
||||
: PreviewSurface.StatusLine;
|
||||
Surface.DeckLabel = PreviewSurface.DeckLabel.IsEmpty() ? TEXT("n/a") : PreviewSurface.DeckLabel;
|
||||
Surface.BriefHeadline =
|
||||
PreviewSurface.BriefHeadline.IsEmpty() ? TEXT("n/a") : PreviewSurface.BriefHeadline;
|
||||
Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane);
|
||||
Surface.FocusDeckId =
|
||||
PreviewSurface.FocusDeckId.IsEmpty() ? TEXT("n/a") : PreviewSurface.FocusDeckId;
|
||||
Surface.FocusMethodSegmentId = PreviewSurface.FocusMethodSegmentId.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: PreviewSurface.FocusMethodSegmentId;
|
||||
Surface.CaseCount = PreviewSurface.CaseCount;
|
||||
Surface.FocusCaseCount = PreviewSurface.FocusCaseCount;
|
||||
Surface.bGuidanceReadyToLaunch = PreviewSurface.bGuidanceReadyToLaunch;
|
||||
Surface.bHasGuidancePayload =
|
||||
PreviewSurface.bHasDeck || PreviewSurface.bHasBrief || PreviewSurface.bGuidanceReadyToLaunch;
|
||||
Surface.bHasDeck = PreviewSurface.bHasDeck;
|
||||
Surface.bHasBrief = PreviewSurface.bHasBrief;
|
||||
Surface.bUsesBriefFallback = PreviewSurface.bUsesBriefFallback;
|
||||
Surface.bHasLiveAttemptTimer = bHasLiveAttemptTimer;
|
||||
Surface.bActionEnabled = bActionEnabled;
|
||||
Surface.bActivePreviewLane = PreviewSurface.bActivePreviewLane;
|
||||
Surface.bClosedLoopIdleDashboard = PreviewSurface.bClosedLoopIdleDashboard;
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("%s | Action: %s (%s)"),
|
||||
*Surface.PreviewStatusLine,
|
||||
*Surface.ActionLabel,
|
||||
Surface.bActionEnabled ? TEXT("enabled") : TEXT("disabled"));
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s | live timer %s | active preview lane %s"),
|
||||
*PreviewSurface.DetailLine,
|
||||
Surface.bHasLiveAttemptTimer ? TEXT("yes") : TEXT("no"),
|
||||
*Surface.ActivePreviewLaneLabel);
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedFollowUpPreviewActionInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Follow-up preview action");
|
||||
Surface.GuidanceLaneLabel = TEXT("follow-up");
|
||||
|
||||
const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString
|
||||
{
|
||||
return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: TEXT("none"));
|
||||
};
|
||||
|
||||
const FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface PreviewSurface =
|
||||
GetDisplayedFollowUpGuidanceDeckPreviewInspectSurface();
|
||||
const bool bActionEnabled =
|
||||
!bHasLiveAttemptTimer
|
||||
&& CachedCoachPanelState.bCanStartCoachFollowUpRun
|
||||
&& CachedCoachPanelState.bHasFollowUpGuidance;
|
||||
|
||||
Surface.ActionLabel = !DisplayedPreviewFollowUpActionLabel.IsEmpty()
|
||||
? DisplayedPreviewFollowUpActionLabel
|
||||
: TEXT("Preview Follow-Up");
|
||||
Surface.PreviewStatusLine = PreviewSurface.StatusLine.IsEmpty()
|
||||
? TEXT("Follow-up guidance: no guidance available.")
|
||||
: PreviewSurface.StatusLine;
|
||||
Surface.DeckLabel = PreviewSurface.DeckLabel.IsEmpty() ? TEXT("n/a") : PreviewSurface.DeckLabel;
|
||||
Surface.BriefHeadline =
|
||||
PreviewSurface.BriefHeadline.IsEmpty() ? TEXT("n/a") : PreviewSurface.BriefHeadline;
|
||||
Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane);
|
||||
Surface.FocusDeckId =
|
||||
PreviewSurface.FocusDeckId.IsEmpty() ? TEXT("n/a") : PreviewSurface.FocusDeckId;
|
||||
Surface.FocusMethodSegmentId = PreviewSurface.FocusMethodSegmentId.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: PreviewSurface.FocusMethodSegmentId;
|
||||
Surface.CaseCount = PreviewSurface.CaseCount;
|
||||
Surface.FocusCaseCount = PreviewSurface.FocusCaseCount;
|
||||
Surface.bGuidanceReadyToLaunch = PreviewSurface.bGuidanceReadyToLaunch;
|
||||
Surface.bHasGuidancePayload =
|
||||
CachedCoachPanelState.bHasFollowUpGuidance
|
||||
|| PreviewSurface.bHasDeck
|
||||
|| PreviewSurface.bHasBrief
|
||||
|| PreviewSurface.bGuidanceReadyToLaunch;
|
||||
Surface.bHasDeck = PreviewSurface.bHasDeck;
|
||||
Surface.bHasBrief = PreviewSurface.bHasBrief;
|
||||
Surface.bUsesBriefFallback = PreviewSurface.bUsesBriefFallback;
|
||||
Surface.bHasLiveAttemptTimer = bHasLiveAttemptTimer;
|
||||
Surface.bActionEnabled = bActionEnabled;
|
||||
Surface.bActivePreviewLane = PreviewSurface.bActivePreviewLane;
|
||||
Surface.bClosedLoopIdleDashboard = PreviewSurface.bClosedLoopIdleDashboard;
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("%s | Action: %s (%s)"),
|
||||
*Surface.PreviewStatusLine,
|
||||
*Surface.ActionLabel,
|
||||
Surface.bActionEnabled ? TEXT("enabled") : TEXT("disabled"));
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s | live timer %s | active preview lane %s"),
|
||||
*PreviewSurface.DetailLine,
|
||||
Surface.bHasLiveAttemptTimer ? TEXT("yes") : TEXT("no"),
|
||||
*Surface.ActivePreviewLaneLabel);
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardActiveAttemptTimerStatusInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedActiveAttemptTimerStatusInspectSurface() const
|
||||
{
|
||||
|
|
@ -25851,6 +26104,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
CoachHandoffRecommendationDetailTextBlock->SetText(FText::FromString(CoachHandoffRecommendationDetailLine));
|
||||
}
|
||||
DisplayedTemplateLaunchStatusLine = TemplateLaunchStatusLine;
|
||||
DisplayedTemplateLaunchDetailLine = TemplateLaunchDetailLine;
|
||||
if (TemplateLaunchHeaderTextBlock != nullptr)
|
||||
{
|
||||
TemplateLaunchHeaderTextBlock->SetText(FText::FromString(TEXT("[Template Launch]")));
|
||||
|
|
@ -26062,17 +26317,20 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
TemplateLaunchButtonLabel = TEXT("Clear Run For Template");
|
||||
}
|
||||
DisplayedTemplateLaunchActionLabel = TemplateLaunchButtonLabel;
|
||||
if (StartTemplateLaunchButtonLabel != nullptr)
|
||||
{
|
||||
StartTemplateLaunchButtonLabel->SetText(FText::FromString(TemplateLaunchButtonLabel));
|
||||
StartTemplateLaunchButtonLabel->SetText(FText::FromString(DisplayedTemplateLaunchActionLabel));
|
||||
}
|
||||
if (StartTemplateLaunchButton != nullptr)
|
||||
{
|
||||
StartTemplateLaunchButton->SetIsEnabled(bCanLaunchPreferredTemplate);
|
||||
}
|
||||
DisplayedPreviewRecommendedActionLabel = TEXT("Preview Recommended");
|
||||
if (PreviewRecommendedButtonLabel != nullptr)
|
||||
{
|
||||
PreviewRecommendedButtonLabel->SetText(FText::FromString(TEXT("Preview Recommended")));
|
||||
PreviewRecommendedButtonLabel->SetText(FText::FromString(
|
||||
DisplayedPreviewRecommendedActionLabel));
|
||||
}
|
||||
if (PreviewRecommendedButton != nullptr)
|
||||
{
|
||||
|
|
@ -26080,9 +26338,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
!bHasLiveAttemptTimer && CachedCoachPanelState.bCanStartCoachRecommendedRun
|
||||
);
|
||||
}
|
||||
DisplayedPreviewFollowUpActionLabel = TEXT("Preview Follow-Up");
|
||||
if (PreviewFollowUpButtonLabel != nullptr)
|
||||
{
|
||||
PreviewFollowUpButtonLabel->SetText(FText::FromString(TEXT("Preview Follow-Up")));
|
||||
PreviewFollowUpButtonLabel->SetText(FText::FromString(
|
||||
DisplayedPreviewFollowUpActionLabel));
|
||||
}
|
||||
if (PreviewFollowUpButton != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -887,6 +887,18 @@ public:
|
|||
FHyperTwistTrainingCoachDashboardRunRecapActionControlInspectSurface
|
||||
GetDisplayedRunRecapActionControlInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardPreferredTemplateLaunchActionInspectSurface
|
||||
GetDisplayedPreferredTemplateLaunchActionInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface
|
||||
GetDisplayedRecommendedPreviewActionInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface
|
||||
GetDisplayedFollowUpPreviewActionInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardActiveAttemptTimerStatusInspectSurface
|
||||
GetDisplayedActiveAttemptTimerStatusInspectSurface() const;
|
||||
|
|
@ -2026,8 +2038,11 @@ private:
|
|||
FString DisplayedTransitionStatusLine;
|
||||
FString DisplayedActiveRunStatusLine;
|
||||
FString DisplayedActiveRunSummaryLine;
|
||||
FString DisplayedTemplateLaunchStatusLine;
|
||||
FString DisplayedTemplateLaunchDetailLine;
|
||||
FString DisplayedRunRecapStatusLine;
|
||||
FString DisplayedRunRecapDetailLine;
|
||||
FString DisplayedTemplateLaunchActionLabel;
|
||||
FString DisplayedRepeatRunActionLabel;
|
||||
FString DisplayedDismissRecapActionLabel;
|
||||
FString DisplayedCurrentCasePromptLine;
|
||||
|
|
@ -2049,6 +2064,8 @@ private:
|
|||
FString DisplayedAttemptInputStatusLine;
|
||||
FString DisplayedSplitCaptureStatusLine;
|
||||
FString DisplayedTimerStatusLine;
|
||||
FString DisplayedPreviewRecommendedActionLabel;
|
||||
FString DisplayedPreviewFollowUpActionLabel;
|
||||
FString DisplayedRecommendedDeckPreviewLine;
|
||||
FString DisplayedFollowUpDeckPreviewLine;
|
||||
FString DisplayedMethodDrillDiagnosticsStatusLine;
|
||||
|
|
|
|||
|
|
@ -13536,6 +13536,179 @@ struct FHyperTwistTrainingCoachDashboardRunRecapActionControlInspectSurface
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardPreferredTemplateLaunchActionInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DisplayedTemplateStatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DisplayedTemplateDetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString TemplateTitle;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString TemplateId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString TemplateKindLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString UserId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusDeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString GuidanceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedModeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedSelectionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectionDetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 EligibleTemplateCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ActiveTemplateCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 RecommendedCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FocusCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasPreferredTemplate = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsesReviewLane = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasScopedStats = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectionProvenance = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasLiveAttemptTimer = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasActiveRun = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bActionEnabled = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasPreferredTemplate
|
||||
|| bActionEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString GuidanceLaneLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreviewStatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeckLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString BriefHeadline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActivePreviewLaneLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusDeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusMethodSegmentId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 CaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FocusCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bGuidanceReadyToLaunch = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasGuidancePayload = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDeck = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasBrief = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsesBriefFallback = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasLiveAttemptTimer = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bActionEnabled = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bActivePreviewLane = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bClosedLoopIdleDashboard = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bGuidanceReadyToLaunch
|
||||
|| bHasGuidancePayload
|
||||
|| bActionEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardActiveAttemptTimerStatusInspectSurface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ Current correction call from the source-exposed audit and current execution refr
|
|||
- the latest landed bounded `Phase 4` packet closes the retained-idle comparison/outcome actionability gap at the end of the recognition-assisted coach-to-review continuity lane, and the final retained-surface confirmation pass now leaves that closure lane functionally complete
|
||||
- the retained idle widget surface now keeps retained comparison and decision history inspectable without continuing to advertise live launch or guidance-outcome actions once the coach-to-review loop has already collapsed to truthful closed-loop idle
|
||||
- the now-complete deliberate `UHyperTwistTrainingRuntimeLibrary` world-context consumer lane reaches through active generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup, normalized-order lookup, and evaluation-order lookup inspect surfaces, so gameplay/Blueprint callers can inspect one retained merged-roster row directly by phase id, normalized order, or evaluation order without scanning the merged roster array or re-running inspect derivation details directly
|
||||
- the latest landed bounded `Phase 4` packet stays adjacent in that same live dashboard consumer lane and adds the run-recap action control inspect surface over the already-retained recap action labels and enablement posture, so gameplay/Blueprint callers can inspect the exact surfaced repeat/dismiss labels and their gating state without scraping widget button text
|
||||
- the next best clean move is to stay adjacent in that same live dashboard consumer lane and expose the preferred template-launch plus recommended/follow-up preview action control surface trio over the already-derived launch/preview button labels and enablement posture
|
||||
- the latest landed bounded `Phase 4` packet stays adjacent in that same live dashboard consumer lane and adds the preferred template-launch plus recommended/follow-up preview action control surface trio over the already-derived launch/preview button labels and enablement posture, so gameplay/Blueprint callers can inspect the exact surfaced template/preview action labels and their gating state without scraping widget button text
|
||||
- the next best clean move is to stay adjacent in that same live dashboard consumer lane and expose the guidance preview case navigation control surface pair over the already-derived `Prev Guidance Case` / `Next Guidance Case` labels and enablement posture
|
||||
- the current execution-discipline rule that broad refactor / monolith-splitting work should not interrupt the active bounded roadmap packet unless structure is actually blocking it
|
||||
|
||||
## Donor portfolio phase taxonomy
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
# HyperTwist Phase 4 dashboard live template-launch and preview action control inspect surface packet
|
||||
|
||||
- bounded Phase `4` dashboard-consumer slice
|
||||
- date: `2026-05-10`
|
||||
|
||||
## Intent
|
||||
|
||||
Stay adjacent in the live dashboard consumer lane and expose the preferred template-launch plus recommended/follow-up preview action controls directly to gameplay and Blueprint callers.
|
||||
|
||||
## Why this packet exists
|
||||
|
||||
`UHyperTwistCoachDashboardWidget` already displayed:
|
||||
|
||||
- the preferred template-launch action label
|
||||
- the recommended preview action label
|
||||
- the follow-up preview action label
|
||||
- the enablement posture behind those three controls
|
||||
|
||||
But that control band still only surfaced through button labels and `SetIsEnabled` state. Callers still had to scrape widget controls to understand whether the dashboard was willing to launch the preferred template, whether recommended guidance preview was currently actionable, and whether follow-up guidance preview was currently blocked by timer or guidance availability.
|
||||
|
||||
## What changed
|
||||
|
||||
- added `FHyperTwistTrainingCoachDashboardPreferredTemplateLaunchActionInspectSurface`
|
||||
- added `FHyperTwistTrainingCoachDashboardGuidancePreviewActionInspectSurface`
|
||||
- added `GetDisplayedPreferredTemplateLaunchActionInspectSurface()`
|
||||
- added `GetDisplayedRecommendedPreviewActionInspectSurface()`
|
||||
- added `GetDisplayedFollowUpPreviewActionInspectSurface()`
|
||||
- retained the exact displayed template-launch, recommended-preview, and follow-up-preview action labels inside the widget so the new surfaces report the same live strings the dashboard is already presenting
|
||||
- retained the exact displayed template-launch status/detail lines inside the widget so the preferred-template action surface reports the same live template band the dashboard is already presenting
|
||||
- kept the packet bounded to `UHyperTwistCoachDashboardWidget` plus shared surface types, with no template-selection refactor and no backend continuity changes
|
||||
|
||||
## Files
|
||||
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistTrainingTypes.h`
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistCoachDashboardWidget.h`
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Private\HyperTwistTraining\HyperTwistCoachDashboardWidget.cpp`
|
||||
- `C:\HyperTwist\docs\HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md`
|
||||
|
||||
## Outcome
|
||||
|
||||
Gameplay and Blueprint callers can now inspect:
|
||||
|
||||
- the exact displayed preferred template-launch action label
|
||||
- the exact displayed recommended preview action label
|
||||
- the exact displayed follow-up preview action label
|
||||
- whether each of those three actions is currently enabled
|
||||
- the displayed template-launch status/detail band aligned with the preferred template action
|
||||
- whether recommended or follow-up preview is currently backed by a live deck, a brief fallback, or neither
|
||||
- which preview lane is currently active behind those controls
|
||||
|
||||
without scraping widget button text or reopening launch/preview gating logic.
|
||||
|
||||
## Validation
|
||||
|
||||
- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln`
|
||||
- passed with `0 Warning(s), 0 Error(s)`
|
||||
|
||||
## Next clean slice
|
||||
|
||||
Stay on the same live dashboard consumer lane and expose the guidance preview case navigation control surface pair over the already-derived `Prev Guidance Case` / `Next Guidance Case` labels and enablement posture.
|
||||
Loading…
Add table
Reference in a new issue