389 lines
22 KiB
XML
389 lines
22 KiB
XML
<?xml version="1.0" encoding="utf-8" ?>
|
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
|
xmlns:controls="clr-namespace:IronServices.Maui.Controls"
|
|
x:Class="IronServices.Maui.Controls.UserJourneyView"
|
|
x:DataType="controls:UserJourneyView"
|
|
Title="User Journeys">
|
|
|
|
<ContentPage.Resources>
|
|
<ResourceDictionary>
|
|
<controls:IsGreaterThanZeroConverter x:Key="IsGreaterThanZero" />
|
|
<controls:StringToBoolConverter x:Key="StringToBool" />
|
|
<controls:NestingLevelToMarginConverter x:Key="NestingToMargin" />
|
|
<controls:DictionaryToStringConverter x:Key="DictToString" />
|
|
<controls:CountToVisibilityConverter x:Key="CountToVisibility" />
|
|
</ResourceDictionary>
|
|
</ContentPage.Resources>
|
|
|
|
<ContentPage.ToolbarItems>
|
|
<ToolbarItem x:Name="RefreshToolbarItem"
|
|
Text="Refresh"
|
|
Order="Primary"
|
|
Clicked="OnRefreshClicked" />
|
|
<ToolbarItem x:Name="ShareToolbarItem"
|
|
Text="Share"
|
|
Order="Primary"
|
|
Clicked="OnShareClicked" />
|
|
<ToolbarItem x:Name="ClearToolbarItem"
|
|
Text="Clear"
|
|
Order="Secondary"
|
|
Clicked="OnClearClicked" />
|
|
</ContentPage.ToolbarItems>
|
|
|
|
<Grid RowDefinitions="Auto,*,Auto">
|
|
|
|
<!-- Header Bar with Summary and View Mode Toggle -->
|
|
<Border Grid.Row="0"
|
|
Padding="16,12"
|
|
BackgroundColor="{AppThemeBinding Light={StaticResource Gray100}, Dark={StaticResource Gray800}}"
|
|
StrokeThickness="0">
|
|
<Grid ColumnDefinitions="*,Auto,Auto">
|
|
<!-- Count Label -->
|
|
<Label x:Name="CountLabel"
|
|
Text="0 journeys"
|
|
FontSize="14"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray600}, Dark={StaticResource Gray400}}"
|
|
VerticalOptions="Center" />
|
|
|
|
<!-- View Mode Selector -->
|
|
<HorizontalStackLayout Grid.Column="1" Spacing="4" Margin="0,0,12,0">
|
|
<Button x:Name="TimelineBtn"
|
|
Text="Timeline"
|
|
Clicked="OnTimelineSelected"
|
|
BackgroundColor="{StaticResource Primary}"
|
|
TextColor="White"
|
|
FontSize="11"
|
|
Padding="8,4"
|
|
CornerRadius="4"
|
|
HeightRequest="28" />
|
|
<Button x:Name="TreeBtn"
|
|
Text="Tree"
|
|
Clicked="OnTreeSelected"
|
|
BackgroundColor="Transparent"
|
|
TextColor="{StaticResource Primary}"
|
|
FontSize="11"
|
|
Padding="8,4"
|
|
CornerRadius="4"
|
|
HeightRequest="28" />
|
|
<Button x:Name="FlowBtn"
|
|
Text="Flow"
|
|
Clicked="OnFlowSelected"
|
|
BackgroundColor="Transparent"
|
|
TextColor="{StaticResource Primary}"
|
|
FontSize="11"
|
|
Padding="8,4"
|
|
CornerRadius="4"
|
|
HeightRequest="28" />
|
|
</HorizontalStackLayout>
|
|
|
|
<!-- Live Updates Indicator -->
|
|
<HorizontalStackLayout Grid.Column="2" Spacing="4" IsVisible="{Binding EnableLiveUpdates}">
|
|
<Ellipse WidthRequest="8" HeightRequest="8" Fill="Green" VerticalOptions="Center" />
|
|
<Label Text="Live" FontSize="11" TextColor="Green" VerticalOptions="Center" />
|
|
</HorizontalStackLayout>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Main Content Area -->
|
|
<Grid x:Name="ContentArea" Grid.Row="1">
|
|
|
|
<!-- Timeline View (default) -->
|
|
<CollectionView x:Name="JourneyList"
|
|
SelectionMode="Single"
|
|
SelectionChanged="OnJourneySelected">
|
|
<CollectionView.EmptyView>
|
|
<VerticalStackLayout VerticalOptions="Center" HorizontalOptions="Center" Padding="32">
|
|
<Label Text="No journeys captured"
|
|
FontSize="18"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}"
|
|
HorizontalOptions="Center" />
|
|
<Label Text="User journeys will appear here when tracked"
|
|
FontSize="14"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}"
|
|
HorizontalOptions="Center"
|
|
Margin="0,8,0,0" />
|
|
</VerticalStackLayout>
|
|
</CollectionView.EmptyView>
|
|
|
|
<CollectionView.ItemTemplate>
|
|
<DataTemplate x:DataType="controls:JourneyItem">
|
|
<Border Padding="12"
|
|
Margin="8,4"
|
|
BackgroundColor="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray900}}"
|
|
Stroke="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray700}}"
|
|
StrokeShape="RoundRectangle 8">
|
|
<Grid RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,*,Auto">
|
|
|
|
<!-- Status Badge -->
|
|
<Border Grid.Row="0" Grid.Column="0"
|
|
Padding="6,2"
|
|
StrokeThickness="0"
|
|
BackgroundColor="{Binding StatusColor}"
|
|
StrokeShape="RoundRectangle 4"
|
|
VerticalOptions="Start"
|
|
Margin="0,0,8,0">
|
|
<Label Text="{Binding StatusIcon}"
|
|
FontSize="10"
|
|
TextColor="White"
|
|
FontAttributes="Bold" />
|
|
</Border>
|
|
|
|
<!-- Journey Name -->
|
|
<Label Grid.Row="0" Grid.Column="1"
|
|
Text="{Binding Name}"
|
|
FontSize="14"
|
|
FontAttributes="Bold"
|
|
LineBreakMode="TailTruncation"
|
|
MaxLines="1"
|
|
VerticalOptions="Center" />
|
|
|
|
<!-- Duration and Time -->
|
|
<VerticalStackLayout Grid.Row="0" Grid.Column="2" Spacing="2">
|
|
<Label Text="{Binding DurationDisplay}"
|
|
FontSize="12"
|
|
FontAttributes="Bold"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray700}, Dark={StaticResource Gray300}}"
|
|
HorizontalOptions="End" />
|
|
<Label Text="{Binding TimeAgo}"
|
|
FontSize="10"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}"
|
|
HorizontalOptions="End" />
|
|
</VerticalStackLayout>
|
|
|
|
<!-- Journey Details Row -->
|
|
<HorizontalStackLayout Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
|
|
Spacing="12" Margin="0,8,0,0">
|
|
<Label Text="{Binding StepCount, StringFormat='{0} steps'}"
|
|
FontSize="12"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray600}, Dark={StaticResource Gray400}}" />
|
|
<Label Text="{Binding FailedStepCount, StringFormat='{0} failed'}"
|
|
FontSize="12"
|
|
TextColor="Red"
|
|
IsVisible="{Binding HasFailedSteps}" />
|
|
<Label Text="{Binding Exceptions.Count, StringFormat='{0} errors'}"
|
|
FontSize="12"
|
|
TextColor="Red"
|
|
IsVisible="{Binding HasExceptions}" />
|
|
</HorizontalStackLayout>
|
|
|
|
<!-- User Info Row -->
|
|
<HorizontalStackLayout Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"
|
|
Spacing="8" Margin="0,4,0,0"
|
|
IsVisible="{Binding HasUser}">
|
|
<Label Text="User:"
|
|
FontSize="11"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}" />
|
|
<Label Text="{Binding UserId}"
|
|
FontSize="11"
|
|
TextColor="{StaticResource Primary}"
|
|
LineBreakMode="TailTruncation"
|
|
MaxLines="1" />
|
|
</HorizontalStackLayout>
|
|
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</CollectionView.ItemTemplate>
|
|
</CollectionView>
|
|
|
|
<!-- Tree View (shown when ViewMode = Tree) -->
|
|
<ScrollView x:Name="TreeViewContainer" IsVisible="False">
|
|
<VerticalStackLayout x:Name="TreeViewContent" Padding="8" Spacing="4">
|
|
<!-- Tree nodes will be built programmatically -->
|
|
</VerticalStackLayout>
|
|
</ScrollView>
|
|
|
|
<!-- Flow View (shown when ViewMode = Flow) -->
|
|
<ScrollView x:Name="FlowViewContainer" IsVisible="False" Orientation="Both">
|
|
<GraphicsView x:Name="FlowGraphicsView"
|
|
WidthRequest="800"
|
|
HeightRequest="400" />
|
|
</ScrollView>
|
|
|
|
</Grid>
|
|
|
|
<!-- Detail Panel (shows when journey selected) -->
|
|
<Border x:Name="DetailPanel"
|
|
Grid.Row="2"
|
|
IsVisible="False"
|
|
Padding="16"
|
|
BackgroundColor="{AppThemeBinding Light={StaticResource Gray100}, Dark={StaticResource Gray800}}"
|
|
Stroke="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"
|
|
StrokeShape="Rectangle"
|
|
MaximumHeightRequest="400">
|
|
<ScrollView>
|
|
<VerticalStackLayout Spacing="12">
|
|
|
|
<!-- Header with Close Button -->
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<Label x:Name="DetailTitle"
|
|
FontSize="16"
|
|
FontAttributes="Bold"
|
|
LineBreakMode="TailTruncation" />
|
|
<Button Grid.Column="1"
|
|
Text="Close"
|
|
Clicked="OnCloseDetailClicked"
|
|
BackgroundColor="Transparent"
|
|
TextColor="{StaticResource Primary}"
|
|
FontSize="12"
|
|
Padding="8,4" />
|
|
</Grid>
|
|
|
|
<!-- Status, Duration, User -->
|
|
<HorizontalStackLayout Spacing="16">
|
|
<HorizontalStackLayout Spacing="4">
|
|
<Label Text="Status:" FontSize="12" TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}" />
|
|
<Label x:Name="DetailStatus" FontSize="12" FontAttributes="Bold" />
|
|
</HorizontalStackLayout>
|
|
<HorizontalStackLayout Spacing="4">
|
|
<Label Text="Duration:" FontSize="12" TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}" />
|
|
<Label x:Name="DetailDuration" FontSize="12" FontAttributes="Bold" />
|
|
</HorizontalStackLayout>
|
|
<HorizontalStackLayout x:Name="DetailUserContainer" Spacing="4" IsVisible="False">
|
|
<Label Text="User:" FontSize="12" TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}" />
|
|
<Label x:Name="DetailUser" FontSize="12" TextColor="{StaticResource Primary}" />
|
|
</HorizontalStackLayout>
|
|
</HorizontalStackLayout>
|
|
|
|
<!-- Steps Section -->
|
|
<VerticalStackLayout x:Name="StepsSection" Spacing="4">
|
|
<Label Text="Steps" FontSize="14" FontAttributes="Bold" />
|
|
<CollectionView x:Name="StepsList"
|
|
MaximumHeightRequest="150"
|
|
SelectionMode="Single"
|
|
SelectionChanged="OnStepSelected">
|
|
<CollectionView.ItemTemplate>
|
|
<DataTemplate x:DataType="controls:StepItem">
|
|
<Grid Margin="{Binding IndentMargin}" Padding="8,4" ColumnDefinitions="Auto,*,Auto">
|
|
<!-- Status Indicator -->
|
|
<Border Padding="4,2"
|
|
StrokeThickness="0"
|
|
BackgroundColor="{Binding StatusColor}"
|
|
StrokeShape="RoundRectangle 2"
|
|
VerticalOptions="Center"
|
|
Margin="0,0,8,0">
|
|
<Label Text="{Binding StatusIcon}"
|
|
FontSize="9"
|
|
TextColor="White"
|
|
FontAttributes="Bold" />
|
|
</Border>
|
|
<!-- Step Name -->
|
|
<VerticalStackLayout Grid.Column="1" VerticalOptions="Center">
|
|
<Label Text="{Binding Name}"
|
|
FontSize="12"
|
|
LineBreakMode="TailTruncation" />
|
|
<Label Text="{Binding FailureReason}"
|
|
FontSize="10"
|
|
TextColor="Red"
|
|
IsVisible="{Binding HasFailureReason}"
|
|
LineBreakMode="TailTruncation" />
|
|
</VerticalStackLayout>
|
|
<!-- Duration -->
|
|
<Label Grid.Column="2"
|
|
Text="{Binding DurationDisplay}"
|
|
FontSize="11"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}"
|
|
VerticalOptions="Center" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
</CollectionView.ItemTemplate>
|
|
</CollectionView>
|
|
</VerticalStackLayout>
|
|
|
|
<!-- Breadcrumbs Section -->
|
|
<VerticalStackLayout x:Name="BreadcrumbsSection" Spacing="4" IsVisible="False">
|
|
<Label Text="Breadcrumbs" FontSize="14" FontAttributes="Bold" />
|
|
<CollectionView x:Name="BreadcrumbsList" MaximumHeightRequest="100">
|
|
<CollectionView.ItemTemplate>
|
|
<DataTemplate x:DataType="controls:BreadcrumbItem">
|
|
<Grid Padding="4" ColumnDefinitions="Auto,Auto,*">
|
|
<Label Text="{Binding TimestampDisplay}"
|
|
FontSize="10"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray400}}"
|
|
VerticalOptions="Center"
|
|
Margin="0,0,8,0" />
|
|
<Border Grid.Column="1"
|
|
Padding="4,1"
|
|
StrokeThickness="0"
|
|
BackgroundColor="{Binding LevelColor}"
|
|
StrokeShape="RoundRectangle 2"
|
|
VerticalOptions="Center"
|
|
Margin="0,0,8,0">
|
|
<Label Text="{Binding Category}"
|
|
FontSize="9"
|
|
TextColor="White" />
|
|
</Border>
|
|
<Label Grid.Column="2"
|
|
Text="{Binding Message}"
|
|
FontSize="11"
|
|
LineBreakMode="TailTruncation"
|
|
VerticalOptions="Center" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
</CollectionView.ItemTemplate>
|
|
</CollectionView>
|
|
</VerticalStackLayout>
|
|
|
|
<!-- Exceptions Section -->
|
|
<VerticalStackLayout x:Name="ExceptionsSection" Spacing="4" IsVisible="False">
|
|
<Label Text="Exceptions" FontSize="14" FontAttributes="Bold" TextColor="Red" />
|
|
<CollectionView x:Name="ExceptionsList"
|
|
MaximumHeightRequest="120"
|
|
SelectionMode="Single"
|
|
SelectionChanged="OnExceptionSelected">
|
|
<CollectionView.ItemTemplate>
|
|
<DataTemplate x:DataType="controls:ExceptionItem">
|
|
<Border Padding="8" Margin="0,2"
|
|
BackgroundColor="{AppThemeBinding Light=#FEE2E2, Dark=#7F1D1D}"
|
|
Stroke="Transparent"
|
|
StrokeShape="RoundRectangle 4">
|
|
<VerticalStackLayout Spacing="2">
|
|
<HorizontalStackLayout Spacing="8">
|
|
<Label Text="{Binding TimestampDisplay}"
|
|
FontSize="10"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray500}, Dark={StaticResource Gray300}}" />
|
|
<Label Text="{Binding ExceptionType}"
|
|
FontSize="11"
|
|
FontAttributes="Bold"
|
|
TextColor="Red" />
|
|
</HorizontalStackLayout>
|
|
<Label Text="{Binding Message}"
|
|
FontSize="11"
|
|
LineBreakMode="TailTruncation"
|
|
MaxLines="2" />
|
|
</VerticalStackLayout>
|
|
</Border>
|
|
</DataTemplate>
|
|
</CollectionView.ItemTemplate>
|
|
</CollectionView>
|
|
</VerticalStackLayout>
|
|
|
|
<!-- Metadata Section -->
|
|
<VerticalStackLayout x:Name="MetadataSection" Spacing="4" IsVisible="False">
|
|
<Label Text="Metadata" FontSize="14" FontAttributes="Bold" />
|
|
<Label x:Name="MetadataLabel"
|
|
FontFamily="Consolas"
|
|
FontSize="11"
|
|
TextColor="{AppThemeBinding Light={StaticResource Gray600}, Dark={StaticResource Gray400}}" />
|
|
</VerticalStackLayout>
|
|
|
|
<!-- Copy Button -->
|
|
<Button x:Name="CopyButton"
|
|
Text="Copy to Clipboard"
|
|
Clicked="OnCopyClicked"
|
|
BackgroundColor="{StaticResource Primary}"
|
|
TextColor="White"
|
|
FontSize="12"
|
|
Padding="12,8"
|
|
CornerRadius="4"
|
|
HorizontalOptions="Start" />
|
|
|
|
</VerticalStackLayout>
|
|
</ScrollView>
|
|
</Border>
|
|
|
|
</Grid>
|
|
|
|
</ContentPage>
|