Expose dashboard template launch history navigation surface
This commit is contained in:
parent
e76ee5814d
commit
807e712b9b
5 changed files with 255 additions and 4 deletions
|
|
@ -9247,6 +9247,116 @@ UHyperTwistCoachDashboardWidget::GetSelectedTemplateLaunchHistoryInspectSurface(
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryNavigationInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedTemplateLaunchHistoryNavigationInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryNavigationInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Template launch history navigation");
|
||||
|
||||
const FHyperTwistCoachDashboardTemplateLaunchHistoryEntry* SelectedEntry =
|
||||
SelectedTemplateLaunchHistoryIndex >= 0
|
||||
&& SelectedTemplateLaunchHistoryIndex < TemplateLaunchHistoryEntries.Num()
|
||||
? &TemplateLaunchHistoryEntries[SelectedTemplateLaunchHistoryIndex]
|
||||
: nullptr;
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* SelectedStats =
|
||||
SelectedEntry != nullptr
|
||||
? FindCachedTemplateLaunchScopedStats(
|
||||
SelectedEntry->TemplateId,
|
||||
SelectedEntry->UserId)
|
||||
: nullptr;
|
||||
const bool bNavigationEnabled = TemplateLaunchHistoryEntries.Num() > 1;
|
||||
|
||||
Surface.PreviousLabel = !DisplayedPreviousTemplateLaunchNavigationLabel.IsEmpty()
|
||||
? DisplayedPreviousTemplateLaunchNavigationLabel
|
||||
: TEXT("Prev Template Launch");
|
||||
Surface.NextLabel = !DisplayedNextTemplateLaunchNavigationLabel.IsEmpty()
|
||||
? DisplayedNextTemplateLaunchNavigationLabel
|
||||
: TEXT("Next Template Launch");
|
||||
Surface.SelectedEntryIndex = SelectedTemplateLaunchHistoryIndex;
|
||||
Surface.HistoryEntryCount = TemplateLaunchHistoryEntries.Num();
|
||||
Surface.bHasSelectedEntry =
|
||||
SelectedEntry != nullptr && SelectedEntry->IsStructurallyValid();
|
||||
Surface.bSelectedEntryIsLatest =
|
||||
Surface.bHasSelectedEntry
|
||||
&& SelectedTemplateLaunchHistoryIndex == TemplateLaunchHistoryEntries.Num() - 1;
|
||||
Surface.bPreviousEnabled = bNavigationEnabled;
|
||||
Surface.bNextEnabled = bNavigationEnabled;
|
||||
if (!Surface.bHasSelectedEntry)
|
||||
{
|
||||
Surface.SelectedEntryOrdinal = TEXT("none");
|
||||
Surface.RecordedAtUtc = TEXT("n/a");
|
||||
Surface.CompletedAtUtc = TEXT("n/a");
|
||||
Surface.TemplateId = TEXT("n/a");
|
||||
Surface.SessionStateLabel = TEXT("n/a");
|
||||
Surface.AnalyticsOutcomeLine = TEXT("n/a");
|
||||
Surface.SelectionDetailLine = TEXT("");
|
||||
Surface.SuggestedModeLabel = TEXT("n/a");
|
||||
Surface.SuggestedSelectionLabel = TEXT("n/a");
|
||||
Surface.StatusLine =
|
||||
TEXT("Template launch navigation: no completed template-backed runs retained yet.");
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s: %s | %s: %s | selected latest: no"),
|
||||
*Surface.PreviousLabel,
|
||||
Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.NextLabel,
|
||||
Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
Surface.bHasScopedStats =
|
||||
SelectedStats != nullptr && SelectedStats->IsStructurallyValid();
|
||||
Surface.bHasSelectionProvenance =
|
||||
SelectedEntry->SelectionProvenance.IsStructurallyValid();
|
||||
Surface.SelectedEntryOrdinal = FString::Printf(
|
||||
TEXT("%d/%d"),
|
||||
SelectedTemplateLaunchHistoryIndex + 1,
|
||||
TemplateLaunchHistoryEntries.Num());
|
||||
Surface.RecordedAtUtc = SelectedEntry->RecordedAtUtc.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: SelectedEntry->RecordedAtUtc;
|
||||
Surface.CompletedAtUtc =
|
||||
SelectedEntry->CompletedAtUtc.IsEmpty() ? TEXT("n/a") : SelectedEntry->CompletedAtUtc;
|
||||
Surface.TemplateId =
|
||||
SelectedEntry->TemplateId.IsEmpty() ? TEXT("n/a") : SelectedEntry->TemplateId;
|
||||
Surface.SessionStateLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->SessionState);
|
||||
Surface.AnalyticsOutcomeLine =
|
||||
HyperTwistCoachDashboardWidgetInternal::BuildTemplateLaunchAnalyticsOutcomeFragment(
|
||||
SelectedStats);
|
||||
Surface.SelectionDetailLine =
|
||||
HyperTwistCoachDashboardWidgetInternal::BuildTemplateLaunchSelectionDetailFragment(
|
||||
Surface.bHasSelectionProvenance ? &SelectedEntry->SelectionProvenance : nullptr);
|
||||
Surface.SuggestedModeLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->SuggestedMode);
|
||||
Surface.SuggestedSelectionLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->SuggestedSelectionPolicy);
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Template launch navigation: selected %s | Template: %s | State: %s | Completed: %s"),
|
||||
*Surface.SelectedEntryOrdinal,
|
||||
*Surface.TemplateId,
|
||||
*Surface.SessionStateLabel,
|
||||
*Surface.CompletedAtUtc);
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s: %s | %s: %s | aggregate: %s | mode: %s | selection: %s | selected latest: %s"),
|
||||
*Surface.PreviousLabel,
|
||||
Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.NextLabel,
|
||||
Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.AnalyticsOutcomeLine,
|
||||
*Surface.SuggestedModeLabel,
|
||||
*Surface.SuggestedSelectionLabel,
|
||||
Surface.bSelectedEntryIsLatest ? TEXT("yes") : TEXT("no"));
|
||||
if (!Surface.SelectionDetailLine.IsEmpty())
|
||||
{
|
||||
Surface.DetailLine += TEXT(" | ");
|
||||
Surface.DetailLine += Surface.SelectionDetailLine;
|
||||
}
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardGuidanceComparisonInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedGuidanceComparisonInspectSurface() const
|
||||
{
|
||||
|
|
@ -24623,8 +24733,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
if (PreviousTemplateLaunchHistoryButtonLabel != nullptr)
|
||||
{
|
||||
DisplayedPreviousTemplateLaunchNavigationLabel = TEXT("Prev Template Launch");
|
||||
PreviousTemplateLaunchHistoryButtonLabel->SetText(FText::FromString(
|
||||
TEXT("Prev Template Launch")));
|
||||
DisplayedPreviousTemplateLaunchNavigationLabel));
|
||||
}
|
||||
if (PreviousTemplateLaunchHistoryButton != nullptr)
|
||||
{
|
||||
|
|
@ -24632,8 +24743,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
if (NextTemplateLaunchHistoryButtonLabel != nullptr)
|
||||
{
|
||||
DisplayedNextTemplateLaunchNavigationLabel = TEXT("Next Template Launch");
|
||||
NextTemplateLaunchHistoryButtonLabel->SetText(FText::FromString(
|
||||
TEXT("Next Template Launch")));
|
||||
DisplayedNextTemplateLaunchNavigationLabel));
|
||||
}
|
||||
if (NextTemplateLaunchHistoryButton != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -791,6 +791,10 @@ public:
|
|||
FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryInspectSurface
|
||||
GetSelectedTemplateLaunchHistoryInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryNavigationInspectSurface
|
||||
GetDisplayedTemplateLaunchHistoryNavigationInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardGuidanceComparisonInspectSurface
|
||||
GetDisplayedGuidanceComparisonInspectSurface() const;
|
||||
|
|
@ -2032,6 +2036,8 @@ private:
|
|||
FString DisplayedNextHandoffHistoryNavigationLabel;
|
||||
FString DisplayedPreviousGuidanceDecisionNavigationLabel;
|
||||
FString DisplayedNextGuidanceDecisionNavigationLabel;
|
||||
FString DisplayedPreviousTemplateLaunchNavigationLabel;
|
||||
FString DisplayedNextTemplateLaunchNavigationLabel;
|
||||
FString DisplayedPreviousAttemptNavigationLabel;
|
||||
FString DisplayedNextAttemptNavigationLabel;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
|
||||
|
|
|
|||
|
|
@ -10113,6 +10113,87 @@ struct FHyperTwistTrainingCoachDashboardGuidanceDecisionHistoryInspectSurface
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryNavigationInspectSurface
|
||||
{
|
||||
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 PreviousLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NextLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedEntryOrdinal;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RecordedAtUtc;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CompletedAtUtc;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString TemplateId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SessionStateLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString AnalyticsOutcomeLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectionDetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedModeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedSelectionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SelectedEntryIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 HistoryEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectedEntry = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSelectedEntryIsLatest = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreviousEnabled = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNextEnabled = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasScopedStats = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectionProvenance = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasSelectedEntry
|
||||
|| bPreviousEnabled
|
||||
|| bNextEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryInspectSurface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 on that same retained-history navigation/control lane and adds the guidance decision history navigation control inspect surface over already-retained authored decision outcomes, so gameplay/Blueprint callers can inspect the live prev/next decision labels, enablement posture, selected retained decision ordinal, and lane/scope/action/latest-selection context without scraping button text or reopening retained-history derivation
|
||||
- the next clean move is to continue that same retained-history navigation/control lane and expose the template launch history navigation control surface rather than drifting back into backend continuity or reopening the already-inspectable history detail seams
|
||||
- the latest landed bounded `Phase 4` packet stays on that same retained-history navigation/control lane and adds the template launch history navigation control inspect surface over already-retained template-backed runs, so gameplay/Blueprint callers can inspect the live prev/next template-launch labels, enablement posture, selected retained launch ordinal, and template/state/analytics/latest-selection context without scraping button text or reopening retained-history derivation
|
||||
- the retained-history navigation/control lane now appears complete enough to reassess whether to pivot deliberately into the next broader `Phase 4` roadmap lane rather than widening this seam by drift
|
||||
- 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,52 @@
|
|||
# HyperTwist Phase 4 dashboard template launch history navigation control inspect surface packet
|
||||
|
||||
- bounded Phase `4` dashboard-consumer slice
|
||||
- date: `2026-05-10`
|
||||
|
||||
## Intent
|
||||
|
||||
Stay on the retained-history navigation/control lane inside `UHyperTwistCoachDashboardWidget` and expose the template launch history navigation controls directly to gameplay and Blueprint callers.
|
||||
|
||||
## Why this packet exists
|
||||
|
||||
The dashboard already derived and displayed:
|
||||
|
||||
- the previous template-launch-history button label
|
||||
- the next template-launch-history button label
|
||||
- the enablement posture for both controls
|
||||
|
||||
But that control state still only surfaced through button text and button enabled state. Callers still had to inspect widget controls directly to understand whether retained template-launch navigation is available and which retained template-backed run is currently selected.
|
||||
|
||||
## What changed
|
||||
|
||||
- added `FHyperTwistTrainingCoachDashboardTemplateLaunchHistoryNavigationInspectSurface`
|
||||
- added `GetDisplayedTemplateLaunchHistoryNavigationInspectSurface()`
|
||||
- retained the exact displayed previous/next template-launch-history labels inside the widget so the new inspect surface reports the same live strings the dashboard is already presenting
|
||||
- kept the packet bounded to `UHyperTwistCoachDashboardWidget` plus shared surface types, with no dashboard redesign 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 live previous/next template-launch-history labels
|
||||
- whether template-launch-history navigation is currently enabled
|
||||
- the selected retained launch ordinal, recorded/completed time, template id, and session state
|
||||
- the retained analytics outcome line, selection-detail posture, suggested mode/selection posture, and latest-selection posture
|
||||
|
||||
without scraping button text or reopening retained-history derivation.
|
||||
|
||||
## Validation
|
||||
|
||||
- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln`
|
||||
- passed with `0 Warning(s), 0 Error(s)`
|
||||
|
||||
## Next clean slice
|
||||
|
||||
Reassess whether the retained-history navigation/control lane is now complete enough to pivot deliberately into the next broader `Phase 4` roadmap lane.
|
||||
Loading…
Add table
Reference in a new issue