diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-10 15:06:42 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-10 15:06:42 +0300 |
| commit | b4682a3abfe299c19b24752b2fb1ce2477611ec3 (patch) | |
| tree | 1d7c87eb5c3eba0d4bf7103fa8717ba62faaccc2 /Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole | |
| parent | d03741164872fc4d849407ed877b6ea00220cc67 (diff) | |
| download | Tango-b4682a3abfe299c19b24752b2fb1ce2477611ec3.tar.gz Tango-b4682a3abfe299c19b24752b2fb1ce2477611ec3.zip | |
Implemented FSE/PPC Logs.
Diffstat (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole')
8 files changed, 563 insertions, 3 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj index 783dfa9fe..287273015 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj @@ -113,10 +113,14 @@ <Compile Include="PPCConsoleModule.cs" /> <Compile Include="ViewModels\ConsoleViewVM.cs" /> <Compile Include="ViewModels\FileSystemViewVM.cs" /> + <Compile Include="ViewModels\LogsViewVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModels\MonitoringViewVM.cs" /> <Compile Include="ViewModels\RemoteDesktopViewVM.cs" /> <Compile Include="ViewModels\UpdatesViewVM.cs" /> + <Compile Include="Views\LogsView.xaml.cs"> + <DependentUpon>LogsView.xaml</DependentUpon> + </Compile> <Compile Include="Views\UpdatesView.xaml.cs"> <DependentUpon>UpdatesView.xaml</DependentUpon> </Compile> @@ -252,6 +256,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\LogsView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\UpdatesView.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs index 4faa72e8e..a3b800b22 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs @@ -18,6 +18,7 @@ namespace Tango.FSE.PPCConsole TangoIOC.Default.Register<MonitoringViewVM>(); TangoIOC.Default.Register<FileSystemViewVM>(); TangoIOC.Default.Register<UpdatesViewVM>(); + TangoIOC.Default.Register<LogsViewVM>(); } public static MainViewVM MainViewVM @@ -67,5 +68,13 @@ namespace Tango.FSE.PPCConsole return TangoIOC.Default.GetInstance<UpdatesViewVM>(); } } + + public static LogsViewVM LogsViewVM + { + get + { + return TangoIOC.Default.GetInstance<LogsViewVM>(); + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs new file mode 100644 index 000000000..52955e18a --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.Core; +using Tango.Core.Commands; +using Tango.Core.Helpers; +using Tango.FSE.Common; +using Tango.FSE.Common.Connection; +using Tango.FSE.Common.Dialogs; +using Tango.FSE.Common.FileSystem; +using Tango.FSE.Common.Logging; +using Tango.Logging; +using Tango.PPC.Shared.Logs; +using Tango.SharedUI.Components; +using static Tango.SharedUI.Controls.NavigationControl; + +namespace Tango.FSE.PPCConsole.ViewModels +{ + public class LogsViewVM : FSEViewModel, INavigationViewModel + { + private bool _loaded; + + private List<RemoteLogFileModel<LogItemBase>> _logFiles; + /// <summary> + /// Gets or sets the remote log files. + /// </summary> + public List<RemoteLogFileModel<LogItemBase>> LogFiles + { + get { return _logFiles; } + set { _logFiles = value; RaisePropertyChangedAuto(); } + } + + private RemoteLogFileModel<LogItemBase> _selectedLogFile; + /// <summary> + /// Gets or sets the selected remote log file. + /// </summary> + public RemoteLogFileModel<LogItemBase> SelectedLogFile + { + get { return _selectedLogFile; } + set { _selectedLogFile = value; RaisePropertyChangedAuto(); OnSelectedLogFileChanged(); } + } + + /// <summary> + /// Gets or sets the application logs. + /// </summary> + public ObservableCollection<LogItemBase> ApplicationLogs { get; set; } + + /// <summary> + /// Gets or sets the application logs view. + /// </summary> + public ICollectionView ApplicationLogsView { get; set; } + + /// <summary> + /// Gets or sets the selected application logs categories. + /// </summary> + public SelectedObjectCollection<LogCategory> SelectedApplicationLogsCategories { get; set; } + + private String _applicationLogsFilter; + /// <summary> + /// Gets or sets the application logs filter. + /// </summary> + public String ApplicationLogsFilter + { + get { return _applicationLogsFilter; } + set { _applicationLogsFilter = value; RaisePropertyChangedAuto(); ApplicationLogsView.Refresh(); } + } + + /// <summary> + /// Opens the detailed application log dialog. + /// </summary> + public RelayCommand<LogItemBase> OpenApplicationLogItemCommand { get; set; } + + /// <summary> + /// Exports the selected log file to local disk. + /// </summary> + public RelayCommand ExportLogFileCommand { get; set; } + + /// <summary> + /// Exports all the downloaded log files to disk. + /// </summary> + public RelayCommand ExportAllDownloadedLogFilesCommand { get; set; } + + /// <summary> + /// Downloads all the available log files. + /// </summary> + public RelayCommand DownloadAllLogFilesCommand { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="LogsViewVM"/> class. + /// </summary> + public LogsViewVM() + { + ApplicationLogs = new ObservableCollection<LogItemBase>(); + ApplicationLogsView = CollectionViewSource.GetDefaultView(ApplicationLogs); + ApplicationLogsView.Filter = FilterApplicationLogs; + SelectedApplicationLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>() + { + LogCategory.Info, + LogCategory.Warning, + LogCategory.Error, + LogCategory.Critical, + }, new ObservableCollection<LogCategory>() + { + LogCategory.Info, + LogCategory.Warning, + LogCategory.Error, + LogCategory.Critical, + }); + + SelectedApplicationLogsCategories.SynchedSource.CollectionChanged += (_, __) => ApplicationLogsView.Refresh(); + + OpenApplicationLogItemCommand = new RelayCommand<LogItemBase>(OpenApplicationLogItem); + + ExportLogFileCommand = new RelayCommand(ExportSelectedLogFile); + ExportAllDownloadedLogFilesCommand = new RelayCommand(ExportAllDownloadedLogFiles); + DownloadAllLogFilesCommand = new RelayCommand(DownloadAllLogFiles); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + MachineProvider.MachineConnected += MachineProvider_MachineConnected; + } + + private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + if (e.DifferentFromPrevious) + { + _loaded = false; + + if (MachineProvider.ConnectionType.IsRemote() && IsVisible) + { + LoadLogFiles(); + } + } + } + + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (!_loaded) + { + LoadLogFiles(); + } + } + + private async void LoadLogFiles() + { + if (!MachineProvider.ConnectionType.IsRemote() || !IsFree) return; + + try + { + IsFree = false; + var logFiles = await LoggingProvider.GetApplicationLogFiles(); + LogFiles = logFiles.Select(x => + { + + var model = new RemoteLogFileModel<LogItemBase>(new ApplicationLogFileParser()); + model.RemoteLogFile = x; + model.DownloadCompleted += OnRemoteLogFileDownloadCompleted; + return model; + + }).ToList(); + SelectedLogFile = LogFiles.FirstOrDefault(); + _loaded = true; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading log files."); + } + finally + { + IsFree = true; + } + } + + private void OnRemoteLogFileDownloadCompleted(object sender, EventArgs e) + { + if (SelectedLogFile == sender) + { + OnSelectedLogFileChanged(); + } + } + + private void OnSelectedLogFileChanged() + { + if (SelectedLogFile == null) return; + + InvokeUI(() => + { + ApplicationLogs.Clear(); + foreach (var logItem in SelectedLogFile.LogItems) + { + ApplicationLogs.Add(logItem); + } + + ApplicationLogsView.Refresh(); + }); + } + + private async void OpenApplicationLogItem(LogItemBase logItem) + { + await NotificationProvider.ShowDialog(new ApplicationLogItemViewVM() { LogItem = logItem }); + } + + private bool FilterApplicationLogs(object obj) + { + var log = obj as LogItemBase; + return SelectedApplicationLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(ApplicationLogsFilter) || log.Message.ToLower().Contains(ApplicationLogsFilter.ToLower())); + } + + private async void ExportSelectedLogFile() + { + if (SelectedLogFile != null && SelectedLogFile.Status == RemoteLogFileStatus.Downloaded) + { + var result = await StorageProvider.SaveFile("Export Log File", "Application Log Files|*.log", SelectedLogFile.RemoteLogFile.Name, ".log"); + if (result) + { + using (NotificationProvider.PushTaskItem("Exporting log file...")) + { + try + { + File.Copy(SelectedLogFile.TemporaryFile, result.SelectedItem, true); + await NotificationProvider.ShowSuccess("Log file exported successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting application log file."); + await NotificationProvider.ShowError($"Could not export the log file.\n{ex.FlattenMessage()}"); + } + } + } + } + } + + private async void ExportAllDownloadedLogFiles() + { + var result = await StorageProvider.SelectFolder("Export Log Files"); + if (result) + { + var toExport = LogFiles.Where(x => x.Status == RemoteLogFileStatus.Downloaded).ToList(); + var count = toExport.Count; + + using (var task = NotificationProvider.PushTaskItem("Exporting log files...")) + { + foreach (var logFile in toExport.ToList()) + { + try + { + await Task.Delay(500); + File.Copy(logFile.TemporaryFile, Path.Combine(result.SelectedItem, logFile.RemoteLogFile.Name), true); + toExport.Remove(logFile); + task.UpdateProgress("Exporting log files...", count - toExport.Count, count, false); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error exporting application log file '{logFile.RemoteLogFile.Name}'."); + await NotificationProvider.ShowError($"Could not export '{logFile.RemoteLogFile.Name}'.\n{ex.FlattenMessage()}"); + } + } + } + + await NotificationProvider.ShowSuccess($"Successfully exported {count - toExport.Count} out of {count} log files."); + } + } + + private async void DownloadAllLogFiles() + { + var toDownload = LogFiles.Where(x => x.Status == RemoteLogFileStatus.None); + var totalSize = FileHelper.GetFriendlyFileSize(toDownload.Select(x => x.RemoteLogFile.Length).Sum()); + + if (await NotificationProvider.ShowWarningQuestion($"Are you sure you wish to download the entire history of log files?\nTotal size: {totalSize}", "DOWNLOAD", "CANCEL")) + { + foreach (var logFile in toDownload) + { + logFile.DownloadLogFile(); + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs index e18a75ef6..f4614ccf1 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs @@ -20,6 +20,7 @@ namespace Tango.FSE.PPCConsole.ViewModels MonitoringView, FileSystemView, UpdatesView, + LogsView, } private NavigationView _selectedView; diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml new file mode 100644 index 000000000..81258e971 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml @@ -0,0 +1,225 @@ +<UserControl x:Class="Tango.FSE.PPCConsole.Views.LogsView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:global="clr-namespace:Tango.FSE.PPCConsole" + xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI" + xmlns:vm="clr-namespace:Tango.FSE.PPCConsole.ViewModels" + xmlns:components="clr-namespace:Tango.SharedUI.Components;assembly=Tango.SharedUI" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Views" + mc:Ignorable="d" + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LogsViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LogsViewVM}" x:Name="control"> + + <UserControl.Resources> + + <Style x:Key="LogsGridCellStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + </Style> + + <Style x:Key="LogsGridStyle" TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter> + <Setter Property="AutoGenerateColumns" Value="False"></Setter> + <Setter Property="CanUserAddRows" Value="False"></Setter> + <Setter Property="CanUserDeleteRows" Value="False"></Setter> + <Setter Property="CanUserReorderColumns" Value="False"></Setter> + <Setter Property="CanUserResizeColumns" Value="False"></Setter> + <Setter Property="CanUserResizeRows" Value="False"></Setter> + <Setter Property="CanUserSortColumns" Value="False"></Setter> + <Setter Property="IsReadOnly" Value="True"></Setter> + <Setter Property="SelectionMode" Value="Single"></Setter> + <Setter Property="SelectionUnit" Value="FullRow"></Setter> + <Setter Property="RowHeight" Value="35"></Setter> + <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource FSE_PrimaryBackgroundBrush}"></Setter> + <Setter Property="HorizontalScrollBarVisibility" Value="Disabled"></Setter> + <Setter Property="CellStyle" Value="{StaticResource LogsGridCellStyle}" /> + </Style> + </UserControl.Resources> + + <Grid IsEnabled="{Binding IsFree}"> + <Grid Margin="0 20 0 0"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="270"/> + <ColumnDefinition Width="303*"/> + </Grid.ColumnDefinitions> + + <Grid> + <Border Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="5 5"> + <ListBox Background="Transparent" BorderThickness="0" ItemsSource="{Binding LogFiles}" SelectedItem="{Binding SelectedLogFile}"> + <ListBox.InputBindings> + <KeyBinding Key="Return" Command="{Binding SelectedLogFile.DownloadCommand}" /> + </ListBox.InputBindings> + <ListBox.ItemTemplate> + <DataTemplate> + <DockPanel> + <DockPanel.Style> + <Style TargetType="DockPanel"> + <Setter Property="Opacity" Value="0.6"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Status}" Value="Downloaded"> + <Setter Property="Opacity" Value="1"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </DockPanel.Style> + <material:PackIcon Kind="FileDocument" Width="Auto" Height="35" /> + <StackPanel Margin="5 0 0 0"> + <TextBlock Text="{Binding RemoteLogFile.DateCreated,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='MM/dd/yyyy HH:mm'}"></TextBlock> + <TextBlock Margin="0 5 0 0" Foreground="{StaticResource FSE_GrayBrush}" FontSize="{StaticResource FSE_SmallFontSize}"> + <Run Text="{Binding RemoteLogFile.Length,Converter={StaticResource ByteArrayToFileSizeConverter}}"></Run> + <Run>|</Run> + <Run Text="{Binding Duration,Mode=OneWay,StringFormat='hh\\:mm'}"></Run> + </TextBlock> + </StackPanel> + </DockPanel> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> + </Border> + </Grid> + + <Border Grid.Column="1" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="2" Margin="10 0 0 0"> + <Grid> + <Grid> + <DockPanel Margin="10 0 10 10"> + <Grid DockPanel.Dock="Top" Margin="12 10 0 0" Panel.ZIndex="100"> + <TextBlock Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontWeight="SemiBold"> + <Run Text="{Binding SelectedLogFile.RemoteLogFile.DateCreated,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='MM/dd/yyyy HH:mm'}"></Run> + <Run>-</Run> + <Run Text="{Binding SelectedLogFile.RemoteLogFile.DateModified,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='HH:mm'}"></Run> + </TextBlock> + <StackPanel Margin="0 0 0 -70" HorizontalAlignment="Right" > + <StackPanel Margin="0 30 0 0" Orientation="Horizontal"> + <ItemsControl VerticalAlignment="Center" ItemsSource="{Binding SelectedApplicationLogsCategories}" Visibility="{Binding ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <StackPanel Orientation="Horizontal" Margin="10 0 0 0"> + <CheckBox FocusVisualStyle="{x:Null}" IsChecked="{Binding IsSelected,Delay=200}" VerticalAlignment="Center"> + <CheckBox.Content> + <TextBlock Text="{Binding Data}" VerticalAlignment="Center"></TextBlock> + </CheckBox.Content> + </CheckBox> + </StackPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <DockPanel Margin="20 0 0 0" VerticalAlignment="Center"> + <material:PackIcon Kind="Search" VerticalAlignment="Center" Width="18" Height="18" /> + <TextBox Margin="5 0 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" FontSize="{StaticResource FSE_SmallFontSize}" material:HintAssist.Hint="filter" material:TextFieldAssist.RippleOnFocusEnabled="True" Text="{Binding ApplicationLogsFilter,UpdateSourceTrigger=PropertyChanged,Delay=1000}" Width="200"/> + </DockPanel> + </StackPanel> + </StackPanel> + </Grid> + + <DataGrid Margin="0 5 0 0" Style="{StaticResource LogsGridStyle}" ItemsSource="{Binding ApplicationLogs}" CellStyle="{StaticResource LogsGridCellStyle}" helpers:DataGridHelper.DoubleClickCommand="{Binding OpenApplicationLogItemCommand}"> + <DataGrid.Resources> + <components:BindingProxy x:Key="proxy" Data="{Binding}" /> + </DataGrid.Resources> + <DataGrid.Columns> + <DataGridTemplateColumn Header="#" Width="40" CellTemplate="{StaticResource FSE_LogIcon_Cell}"/> + <DataGridTextColumn Header="DATE TIME" Binding="{Binding TimeStamp,StringFormat='HH:mm:ss.ff'}" Width="100" /> + <DataGridTextColumn Visibility="{Binding Source={StaticResource proxy},Path=Data.ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}" Header="SERVICE" Binding="{Binding ClassName}" Width="200" /> + <DataGridTemplateColumn Header="MESSAGE" Width="1*" > + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <TextBlock TextWrapping="NoWrap" Text="{Binding Message,Converter={StaticResource StringToOneLineConverter},ConverterParameter='120'}"></TextBlock> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + </DataGrid.Columns> + </DataGrid> + </DockPanel> + </Grid> + + <Grid Background="{StaticResource FSE_SemiTransparentBrush}"> + <Grid.Style> + <Style TargetType="Grid"> + <Setter Property="Visibility" Value="Visible"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Downloaded"> + <Setter Property="Visibility" Value="Hidden"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Grid.Style> + + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <StackPanel.Style> + <Style TargetType="StackPanel"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="None"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </StackPanel.Style> + <material:PackIcon Kind="FileDocument" Width="100" Height="100" HorizontalAlignment="Center" /> + <TextBlock Margin="0 20 0 0">Download this log file from the remote machine in order to display its content</TextBlock> + <controls:TextIconButton Style="{StaticResource FSE_TextIconButton_Dark}" Margin="0 100 0 0" Height="45" Icon="Download" HorizontalAlignment="Center" Width="180" Command="{Binding SelectedLogFile.DownloadCommand}">DOWNLOAD</controls:TextIconButton> + </StackPanel> + + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <StackPanel.Style> + <Style TargetType="StackPanel"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Failed"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </StackPanel.Style> + <material:PackIcon Kind="AlertOutline" Width="100" Height="100" HorizontalAlignment="Center" Foreground="{StaticResource FSE_ErrorBrush}" /> + <TextBlock Margin="0 20 0 0">Error occurred while trying to download this log file</TextBlock> + <controls:TextIconButton Style="{StaticResource FSE_TextIconButton_Dark}" Margin="0 100 0 0" Height="45" Icon="Download" HorizontalAlignment="Center" Width="180" Command="{Binding SelectedLogFile.DownloadCommand}">TRY AGAIN</controls:TextIconButton> + </StackPanel> + + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <StackPanel.Style> + <Style TargetType="StackPanel"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Downloading"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </StackPanel.Style> + <material:PackIcon Kind="FileDownload" Width="100" Height="100" HorizontalAlignment="Center" /> + <TextBlock Margin="0 20 0 0" HorizontalAlignment="Center">Downloading log file, please wait...</TextBlock> + <ProgressBar Margin="0 140 0 0" Width="600" Height="5" Minimum="0" Maximum="{Binding SelectedLogFile.Handler.Length}" Value="{Binding SelectedLogFile.Handler.Position}"></ProgressBar> + </StackPanel> + </Grid> + + <StackPanel Margin="0 0 40 20" HorizontalAlignment="Right" VerticalAlignment="Bottom"> + <material:PopupBox PopupMode="Click" Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}" PlacementMode="TopAndAlignCentres" FocusVisualStyle="{x:Null}"> + <StackPanel> + <Button ToolTip="Download all log files" Command="{Binding DownloadAllLogFilesCommand}"> + <material:PackIcon Kind="DownloadMultiple" /> + </Button> + <Button ToolTip="Export all downloaded log files" Command="{Binding ExportAllDownloadedLogFilesCommand}"> + <material:PackIcon Kind="DatabaseExport" /> + </Button> + <Button ToolTip="Export selected log file" Command="{Binding ExportLogFileCommand}"> + <material:PackIcon Kind="FileExportOutline" /> + </Button> + </StackPanel> + </material:PopupBox> + </StackPanel> + </Grid> + </Border> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs new file mode 100644 index 000000000..d08f18326 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.PPCConsole.Views +{ + /// <summary> + /// Interaction logic for LogsView.xaml + /// </summary> + public partial class LogsView : UserControl + { + public LogsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml index 1efc0516f..b8932be95 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml @@ -29,19 +29,20 @@ </Style.Triggers> </Style> </Grid.Style> - <commonControls:FSETabControl TabsWidth="900" x:Name="tabs" SelectedObject="{Binding SelectedView,Mode=TwoWay}"> + <commonControls:FSETabControl TabsWidth="1000" x:Name="tabs" SelectedObject="{Binding SelectedView,Mode=TwoWay}"> <local:MonitoringView Tag="MONITORING" /> <local:RemoteDesktopView Tag="REMOTE DESKTOP" /> <local:ConsoleView Tag="COMMAND PROMPT" /> <local:FileSystemView Tag="FILE SYSTEM" /> <local:UpdatesView Tag="UPDATES" /> + <local:LogsView Tag="LOGS" /> </commonControls:FSETabControl> <TextBlock resolution:ResolutionHelper.MinWidth="1500" Margin="10 0 0 0" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_ModuleHeaderFontSize}" Foreground="{StaticResource FSE_PrimaryAccentDarkBrush}" VerticalAlignment="Top" HorizontalAlignment="Left" Text="{Binding ElementName=tabs,Path=SelectedElement.Tag,Converter={StaticResource StringToTitleCaseConverter}}"></TextBlock> </Grid> </Grid> - <Grid Background="#DE202020" Visibility="{Binding MachineProvider.IsPPCAvailable,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <Grid Background="#DE202020" Visibility="{Binding MachineProvider.IsPPCAvailable,Converter={StaticResource BooleanToVisibilityInverseConverter},FallbackValue='Visible',TargetNullValue='Visible'}"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <material:PackIcon HorizontalAlignment="Center" Kind="AlertOutline" Width="100" Height="100" /> <TextBlock Margin="0 20 0 0" HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}"> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml index 037fa6d96..8a8e6546e 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml @@ -60,7 +60,7 @@ </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> - <DataGridTextColumn Header="STARTED" Binding="{Binding StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" /> + <DataGridTextColumn Header="STARTED" Binding="{Binding StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="120" /> <DataGridTextColumn Header="APPLICATION" Binding="{Binding ApplicationVersion}" Width="Auto" /> <DataGridTextColumn Header="FIRMWARE" Binding="{Binding FirmwareVersion}" Width="Auto" /> <DataGridTextColumn Header="ENDED" Binding="{Binding EndDate,TargetNullValue='Never',FallbackValue='Never',Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" /> |
