Expose dashboard queue overview and selected entry inspect surfaces
This commit is contained in:
parent
5a41e79107
commit
18e1e065fc
5 changed files with 469 additions and 13 deletions
|
|
@ -11548,6 +11548,187 @@ UHyperTwistCoachDashboardWidget::GetDisplayedStartSelectedQueueActionInspectSurf
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardQueueCountsStatusInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedQueueCountsStatusInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardQueueCountsStatusInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Queue counts / status");
|
||||
|
||||
Surface.QueueId = CachedCoachSessionQueueState.QueueId.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachSessionQueueState.QueueId;
|
||||
Surface.ActiveQueueEntryId = CachedCoachPanelState.ActiveQueueEntryId.IsEmpty()
|
||||
? TEXT("none")
|
||||
: CachedCoachPanelState.ActiveQueueEntryId;
|
||||
Surface.NextQueueSourceLabel = CachedCoachPanelState.NextQueueSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachPanelState.NextQueueSourceLabel;
|
||||
Surface.SignalCount = CachedCoachPanelState.SignalCount;
|
||||
Surface.TotalEntryCount = CachedCoachSessionQueueState.TotalEntryCount;
|
||||
Surface.PendingEntryCount = CachedCoachSessionQueueState.PendingEntryCount;
|
||||
Surface.ReadyEntryCount = CachedCoachSessionQueueState.ReadyEntryCount;
|
||||
Surface.DeferredEntryCount = CachedCoachSessionQueueState.DeferredEntryCount;
|
||||
Surface.InProgressEntryCount = CachedCoachSessionQueueState.InProgressEntryCount;
|
||||
Surface.CompletedEntryCount = CachedCoachSessionQueueState.CompletedEntryCount;
|
||||
Surface.QueuedEventCount = CachedCoachQueueExecutionSummary.QueuedEventCount;
|
||||
Surface.StartedEventCount = CachedCoachQueueExecutionSummary.StartedEventCount;
|
||||
Surface.CompletedEventCount = CachedCoachQueueExecutionSummary.CompletedEventCount;
|
||||
Surface.DeferredEventCount = CachedCoachQueueExecutionSummary.DeferredEventCount;
|
||||
Surface.PromotedEventCount = CachedCoachQueueExecutionSummary.PromotedEventCount;
|
||||
Surface.ManualRescheduleEventCount = CachedCoachQueueExecutionSummary.ManualRescheduleEventCount;
|
||||
Surface.bHasOutstandingDeferredWork = CachedCoachQueueExecutionSummary.bHasOutstandingDeferredWork;
|
||||
Surface.bHasCompletionGap = CachedCoachQueueExecutionSummary.bHasCompletionGap;
|
||||
Surface.bHasArchiveAwareFriction = CachedCoachQueueExecutionSummary.bHasArchiveAwareFriction;
|
||||
Surface.bHasBlockedFollowUpFriction = CachedCoachQueueExecutionSummary.bHasBlockedFollowUpFriction;
|
||||
Surface.StatusLine = !DisplayedQueueStatusLine.IsEmpty()
|
||||
? DisplayedQueueStatusLine
|
||||
: CachedCoachPanelState.QueueStatusLine;
|
||||
Surface.CountsLine = !DisplayedQueueCountsLine.IsEmpty()
|
||||
? DisplayedQueueCountsLine
|
||||
: FString::Printf(
|
||||
TEXT("Signals: %d | Ready: %d | Deferred: %d | In-progress: %d | Completed: %d"),
|
||||
Surface.SignalCount,
|
||||
Surface.ReadyEntryCount,
|
||||
Surface.DeferredEntryCount,
|
||||
Surface.InProgressEntryCount,
|
||||
Surface.CompletedEntryCount);
|
||||
Surface.ExecutionLine = !DisplayedQueueExecutionLine.IsEmpty()
|
||||
? DisplayedQueueExecutionLine
|
||||
: FString::Printf(
|
||||
TEXT("Execution: queued %d | started %d | completed %d | deferred %d | promoted %d | manual reschedules %d | outstanding deferred: %s | completion gap: %s | archive-aware friction: %s | blocked follow-up friction: %s"),
|
||||
Surface.QueuedEventCount,
|
||||
Surface.StartedEventCount,
|
||||
Surface.CompletedEventCount,
|
||||
Surface.DeferredEventCount,
|
||||
Surface.PromotedEventCount,
|
||||
Surface.ManualRescheduleEventCount,
|
||||
Surface.bHasOutstandingDeferredWork ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bHasCompletionGap ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bHasArchiveAwareFriction ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bHasBlockedFollowUpFriction ? TEXT("yes") : TEXT("no"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueSummaryInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedSelectedQueueSummaryInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueSummaryInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Selected queue summary");
|
||||
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry* SelectedEntry = FindSelectedQueueEntry();
|
||||
Surface.SelectedQueueEntryId =
|
||||
SelectedEntry != nullptr && !SelectedEntry->EntryId.IsEmpty()
|
||||
? SelectedEntry->EntryId
|
||||
: TEXT("none");
|
||||
Surface.SelectedQueueSourceLabel =
|
||||
SelectedEntry != nullptr && !SelectedEntry->SourceLabel.IsEmpty()
|
||||
? SelectedEntry->SourceLabel
|
||||
: TEXT("n/a");
|
||||
Surface.SelectedQueueStateLabel =
|
||||
SelectedEntry != nullptr
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(SelectedEntry->EntryState)
|
||||
: TEXT("n/a");
|
||||
Surface.SelectedQueuePriorityLabel =
|
||||
SelectedEntry != nullptr && !SelectedEntry->PriorityLabel.IsEmpty()
|
||||
? SelectedEntry->PriorityLabel
|
||||
: TEXT("n/a");
|
||||
Surface.SelectedQueueOrdinal =
|
||||
SelectedEntry != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("%d/%d"),
|
||||
SelectedQueueEntryIndex + 1,
|
||||
CachedCoachSessionQueueState.Entries.Num())
|
||||
: TEXT("none");
|
||||
Surface.SelectedQueuePriorityScore =
|
||||
SelectedEntry != nullptr ? SelectedEntry->PriorityScore : 0.0f;
|
||||
Surface.SelectedQueueEntryIndex = SelectedQueueEntryIndex;
|
||||
Surface.TotalQueueEntries = CachedCoachSessionQueueState.Entries.Num();
|
||||
Surface.bHasSelectedQueueEntry = SelectedEntry != nullptr;
|
||||
Surface.bSelectedEntryMatchesActiveQueue =
|
||||
SelectedEntry != nullptr
|
||||
&& SelectedEntry->EntryId == CachedCoachPanelState.ActiveQueueEntryId;
|
||||
Surface.StatusLine = !DisplayedSelectedQueueSummaryLine.IsEmpty()
|
||||
? DisplayedSelectedQueueSummaryLine
|
||||
: (SelectedEntry != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Selected queue item %d/%d | Source: %s | State: %s | Priority: %s (%.1f)"),
|
||||
SelectedQueueEntryIndex + 1,
|
||||
CachedCoachSessionQueueState.Entries.Num(),
|
||||
*Surface.SelectedQueueSourceLabel,
|
||||
*Surface.SelectedQueueStateLabel,
|
||||
*Surface.SelectedQueuePriorityLabel,
|
||||
Surface.SelectedQueuePriorityScore)
|
||||
: TEXT("Selected queue item: none"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedSelectedQueueEntryDetailInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Selected queue-entry detail");
|
||||
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry* SelectedEntry = FindSelectedQueueEntry();
|
||||
Surface.SelectedQueueEntryId =
|
||||
SelectedEntry != nullptr && !SelectedEntry->EntryId.IsEmpty()
|
||||
? SelectedEntry->EntryId
|
||||
: TEXT("none");
|
||||
Surface.EntryHeadline =
|
||||
SelectedEntry != nullptr && !SelectedEntry->Headline.IsEmpty()
|
||||
? SelectedEntry->Headline
|
||||
: TEXT("n/a");
|
||||
Surface.FocusDeckId =
|
||||
SelectedEntry != nullptr && !SelectedEntry->FocusDeckId.IsEmpty()
|
||||
? SelectedEntry->FocusDeckId
|
||||
: TEXT("n/a");
|
||||
Surface.FocusMethodSegmentId =
|
||||
SelectedEntry != nullptr && !SelectedEntry->FocusMethodSegmentId.IsEmpty()
|
||||
? SelectedEntry->FocusMethodSegmentId
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedModeLabel =
|
||||
SelectedEntry != nullptr
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(SelectedEntry->SuggestedMode)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedSelectionPolicyLabel =
|
||||
SelectedEntry != nullptr
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->SuggestedSelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.DeferredUntilUtc =
|
||||
SelectedEntry != nullptr && !SelectedEntry->DeferredUntilUtc.IsEmpty()
|
||||
? SelectedEntry->DeferredUntilUtc
|
||||
: TEXT("n/a");
|
||||
Surface.DeferralReasonLabel =
|
||||
SelectedEntry != nullptr && !SelectedEntry->DeferralReasonLabel.IsEmpty()
|
||||
? SelectedEntry->DeferralReasonLabel
|
||||
: TEXT("n/a");
|
||||
Surface.FocusCaseCount = SelectedEntry != nullptr ? SelectedEntry->FocusCaseIds.Num() : 0;
|
||||
Surface.bHasSelectedQueueEntry = SelectedEntry != nullptr;
|
||||
Surface.bRequiresFollowUp = SelectedEntry != nullptr && SelectedEntry->bRequiresFollowUp;
|
||||
Surface.bRequiresArchiveRetentionTuning =
|
||||
SelectedEntry != nullptr && SelectedEntry->bRequiresArchiveRetentionTuning;
|
||||
Surface.bPinned = SelectedEntry != nullptr && SelectedEntry->bPinned;
|
||||
Surface.bCanStartImmediately = SelectedEntry != nullptr && SelectedEntry->bCanStartImmediately;
|
||||
Surface.DetailLine = !DisplayedSelectedQueueEntryDetailLine.IsEmpty()
|
||||
? DisplayedSelectedQueueEntryDetailLine
|
||||
: (SelectedEntry != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Headline: %s | Deck: %s | Method: %s | Cases: %d | Mode: %s | Policy: %s | Deferred until: %s | Reason: %s | Follow-up: %s | Archive tune: %s | Pinned: %s"),
|
||||
*Surface.EntryHeadline,
|
||||
*Surface.FocusDeckId,
|
||||
*Surface.FocusMethodSegmentId,
|
||||
Surface.FocusCaseCount,
|
||||
*Surface.SuggestedModeLabel,
|
||||
*Surface.SuggestedSelectionPolicyLabel,
|
||||
*Surface.DeferredUntilUtc,
|
||||
*Surface.DeferralReasonLabel,
|
||||
Surface.bRequiresFollowUp ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bRequiresArchiveRetentionTuning ? TEXT("yes") : TEXT("no"),
|
||||
Surface.bPinned ? TEXT("yes") : TEXT("no"))
|
||||
: TEXT("Queue entry detail: no queue entry selected"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedLastAttemptReviewSummaryInspectSurface() const
|
||||
{
|
||||
|
|
@ -23860,13 +24041,14 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
if (QueueStatusTextBlock != nullptr)
|
||||
{
|
||||
QueueStatusTextBlock->SetText(FText::FromString(CachedCoachPanelState.QueueStatusLine));
|
||||
DisplayedQueueStatusLine = CachedCoachPanelState.QueueStatusLine;
|
||||
QueueStatusTextBlock->SetText(FText::FromString(DisplayedQueueStatusLine));
|
||||
}
|
||||
if (QueueSelectionTextBlock != nullptr)
|
||||
{
|
||||
if (const FHyperTwistTrainingCoachSessionQueueStateEntry* SelectedEntry = FindSelectedQueueEntry())
|
||||
{
|
||||
QueueSelectionTextBlock->SetText(FText::FromString(FString::Printf(
|
||||
DisplayedSelectedQueueSummaryLine = FString::Printf(
|
||||
TEXT("Selected queue item %d/%d | Source: %s | State: %s | Priority: %s (%.1f)"),
|
||||
SelectedQueueEntryIndex + 1,
|
||||
CachedCoachSessionQueueState.Entries.Num(),
|
||||
|
|
@ -23874,11 +24056,13 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(SelectedEntry->EntryState),
|
||||
SelectedEntry->PriorityLabel.IsEmpty() ? TEXT("n/a") : *SelectedEntry->PriorityLabel,
|
||||
SelectedEntry->PriorityScore
|
||||
)));
|
||||
);
|
||||
QueueSelectionTextBlock->SetText(FText::FromString(DisplayedSelectedQueueSummaryLine));
|
||||
}
|
||||
else
|
||||
{
|
||||
QueueSelectionTextBlock->SetText(FText::FromString(TEXT("Selected queue item: none")));
|
||||
DisplayedSelectedQueueSummaryLine = TEXT("Selected queue item: none");
|
||||
QueueSelectionTextBlock->SetText(FText::FromString(DisplayedSelectedQueueSummaryLine));
|
||||
}
|
||||
}
|
||||
if (QueueEntryDetailTextBlock != nullptr)
|
||||
|
|
@ -23891,7 +24075,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FString DeferralReason = SelectedEntry->DeferralReasonLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: SelectedEntry->DeferralReasonLabel;
|
||||
QueueEntryDetailTextBlock->SetText(FText::FromString(FString::Printf(
|
||||
DisplayedSelectedQueueEntryDetailLine = FString::Printf(
|
||||
TEXT("Headline: %s | Deck: %s | Method: %s | Cases: %d | Mode: %s | Policy: %s | Deferred until: %s | Reason: %s | Follow-up: %s | Archive tune: %s | Pinned: %s"),
|
||||
*SelectedEntry->Headline,
|
||||
SelectedEntry->FocusDeckId.IsEmpty() ? TEXT("n/a") : *SelectedEntry->FocusDeckId,
|
||||
|
|
@ -23904,27 +24088,30 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
SelectedEntry->bRequiresFollowUp ? TEXT("yes") : TEXT("no"),
|
||||
SelectedEntry->bRequiresArchiveRetentionTuning ? TEXT("yes") : TEXT("no"),
|
||||
SelectedEntry->bPinned ? TEXT("yes") : TEXT("no")
|
||||
)));
|
||||
);
|
||||
QueueEntryDetailTextBlock->SetText(FText::FromString(DisplayedSelectedQueueEntryDetailLine));
|
||||
}
|
||||
else
|
||||
{
|
||||
QueueEntryDetailTextBlock->SetText(FText::FromString(TEXT("Queue entry detail: no queue entry selected")));
|
||||
DisplayedSelectedQueueEntryDetailLine = TEXT("Queue entry detail: no queue entry selected");
|
||||
QueueEntryDetailTextBlock->SetText(FText::FromString(DisplayedSelectedQueueEntryDetailLine));
|
||||
}
|
||||
}
|
||||
if (QueueCountsTextBlock != nullptr)
|
||||
{
|
||||
QueueCountsTextBlock->SetText(FText::FromString(FString::Printf(
|
||||
DisplayedQueueCountsLine = FString::Printf(
|
||||
TEXT("Signals: %d | Ready: %d | Deferred: %d | In-progress: %d | Completed: %d"),
|
||||
CachedCoachPanelState.SignalCount,
|
||||
CachedCoachSessionQueueState.ReadyEntryCount,
|
||||
CachedCoachSessionQueueState.DeferredEntryCount,
|
||||
CachedCoachSessionQueueState.InProgressEntryCount,
|
||||
CachedCoachSessionQueueState.CompletedEntryCount
|
||||
)));
|
||||
);
|
||||
QueueCountsTextBlock->SetText(FText::FromString(DisplayedQueueCountsLine));
|
||||
}
|
||||
if (QueueExecutionTextBlock != nullptr)
|
||||
{
|
||||
QueueExecutionTextBlock->SetText(FText::FromString(FString::Printf(
|
||||
DisplayedQueueExecutionLine = FString::Printf(
|
||||
TEXT("Execution: queued %d | started %d | completed %d | deferred %d | promoted %d | manual reschedules %d | outstanding deferred: %s | completion gap: %s | archive-aware friction: %s | blocked follow-up friction: %s"),
|
||||
CachedCoachQueueExecutionSummary.QueuedEventCount,
|
||||
CachedCoachQueueExecutionSummary.StartedEventCount,
|
||||
|
|
@ -23936,7 +24123,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
CachedCoachQueueExecutionSummary.bHasCompletionGap ? TEXT("yes") : TEXT("no"),
|
||||
CachedCoachQueueExecutionSummary.bHasArchiveAwareFriction ? TEXT("yes") : TEXT("no"),
|
||||
CachedCoachQueueExecutionSummary.bHasBlockedFollowUpFriction ? TEXT("yes") : TEXT("no")
|
||||
)));
|
||||
);
|
||||
QueueExecutionTextBlock->SetText(FText::FromString(DisplayedQueueExecutionLine));
|
||||
}
|
||||
if (ScheduleHeaderTextBlock != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -863,6 +863,18 @@ public:
|
|||
FHyperTwistTrainingCoachDashboardStartSelectedQueueActionInspectSurface
|
||||
GetDisplayedStartSelectedQueueActionInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardQueueCountsStatusInspectSurface
|
||||
GetDisplayedQueueCountsStatusInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueSummaryInspectSurface
|
||||
GetDisplayedSelectedQueueSummaryInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface
|
||||
GetDisplayedSelectedQueueEntryDetailInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
|
||||
GetDisplayedLastAttemptReviewSummaryInspectSurface() const;
|
||||
|
|
@ -1950,6 +1962,11 @@ private:
|
|||
FString DisplayedQueuedRunLabel;
|
||||
FString DisplayedFollowUpRunLabel;
|
||||
FString DisplayedRecommendedRunLabel;
|
||||
FString DisplayedQueueStatusLine;
|
||||
FString DisplayedQueueCountsLine;
|
||||
FString DisplayedQueueExecutionLine;
|
||||
FString DisplayedSelectedQueueSummaryLine;
|
||||
FString DisplayedSelectedQueueEntryDetailLine;
|
||||
FString DisplayedPreviousQueueNavigationLabel;
|
||||
FString DisplayedStartSelectedQueueActionLabel;
|
||||
FString DisplayedNextQueueNavigationLabel;
|
||||
|
|
|
|||
|
|
@ -11358,6 +11358,201 @@ struct FHyperTwistTrainingCoachDashboardStartSelectedQueueActionInspectSurface
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardQueueCountsStatusInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CountsLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ExecutionLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString QueueId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActiveQueueEntryId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NextQueueSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SignalCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 TotalEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PendingEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ReadyEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DeferredEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 InProgressEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 CompletedEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 QueuedEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 StartedEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 CompletedEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DeferredEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PromotedEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ManualRescheduleEventCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasOutstandingDeferredWork = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasCompletionGap = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasArchiveAwareFriction = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasBlockedFollowUpFriction = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !CountsLine.IsEmpty()
|
||||
|| !ExecutionLine.IsEmpty()
|
||||
|| TotalEntryCount > 0
|
||||
|| QueuedEventCount > 0;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardSelectedQueueSummaryInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueueEntryId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueueSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueueStateLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueuePriorityLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueueOrdinal;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
float SelectedQueuePriorityScore = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SelectedQueueEntryIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 TotalQueueEntries = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectedQueueEntry = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSelectedEntryMatchesActiveQueue = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| bHasSelectedQueueEntry;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedQueueEntryId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString EntryHeadline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusDeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusMethodSegmentId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedModeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedSelectionPolicyLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeferredUntilUtc;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeferralReasonLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FocusCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectedQueueEntry = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRequiresFollowUp = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRequiresArchiveRetentionTuning = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPinned = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCanStartImmediately = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !DetailLine.IsEmpty()
|
||||
|| bHasSelectedQueueEntry;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds verification action, selected-queue navigation, and start-selected action enablement inspect surfaces over already-derived live dashboard verification and queue-control presentation state, so gameplay/Blueprint callers can inspect the verify action plus the current queue-navigation and selected-entry launch labels and enablement without scraping widget buttons or reopening queue-control derivation
|
||||
- the next clean move is to stay on that same live dashboard guidance-consumer lane and land the queue counts/status, selected-queue summary, and selected queue-entry detail inspect surface group rather than drifting back into backend continuity or reopening the already-complete retained-history seam
|
||||
- the latest landed bounded `Phase 4` packet stays on that same live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds queue counts/status, selected-queue summary, and selected queue-entry detail inspect surfaces over already-derived live dashboard queue overview and selected-entry presentation state, so gameplay/Blueprint callers can inspect the live queue status line, counts/execution posture, current selected-entry summary, and selected-entry detail without scraping widget text or reopening queue-state derivation
|
||||
- the next clean move is to stay on that same live dashboard guidance-consumer lane and land the schedule horizon status and schedule policy / friction inspect surface pair rather than drifting back into backend continuity or reopening the already-complete retained-history seam
|
||||
- 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
|
||||
|
||||
## Current execution-reality references
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
# HyperTwist Phase 4 dashboard live queue counts/status, selected queue summary, and selected queue-entry detail inspect surface packet
|
||||
|
||||
- bounded Phase `4` dashboard-consumer slice
|
||||
- date: `2026-05-09`
|
||||
|
||||
## Intent
|
||||
|
||||
Stay on the deliberate live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and expose the remaining live queue overview and selected-entry presentation state directly to gameplay and Blueprint callers.
|
||||
|
||||
## Why this packet exists
|
||||
|
||||
The dashboard already derived:
|
||||
|
||||
- the live queue status line for the active coach queue posture
|
||||
- the live queue counts and queue execution summary lines
|
||||
- the selected queue-item summary line
|
||||
- the selected queue-entry detail line
|
||||
|
||||
But that live state still only surfaced through widget text blocks. Callers still had to scrape dashboard text to inspect what the queue overview and current selected entry were actually presenting.
|
||||
|
||||
## What changed
|
||||
|
||||
- added `FHyperTwistTrainingCoachDashboardQueueCountsStatusInspectSurface`
|
||||
- added `FHyperTwistTrainingCoachDashboardSelectedQueueSummaryInspectSurface`
|
||||
- added `FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface`
|
||||
- added `GetDisplayedQueueCountsStatusInspectSurface()`
|
||||
- added `GetDisplayedSelectedQueueSummaryInspectSurface()`
|
||||
- added `GetDisplayedSelectedQueueEntryDetailInspectSurface()`
|
||||
- retained the exact displayed queue status, counts, execution, selected-summary, and selected-entry detail lines inside the widget so the new inspect surfaces report 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 queue status line, signal/entry counts, and queue execution posture
|
||||
- the current selected queue-entry summary, source/state/priority posture, and selection ordinal
|
||||
- the current selected queue-entry detail, suggested mode/policy posture, deferral context, and follow-up/archive/pinning posture
|
||||
|
||||
without scraping dashboard text blocks or reopening queue-state derivation.
|
||||
|
||||
## 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 guidance-consumer lane and land the schedule horizon status and schedule policy / friction inspect surface pair.
|
||||
Loading…
Add table
Reference in a new issue