diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2024-05-05 17:24:14 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2024-05-05 17:24:14 +0300 |
| commit | 2e752ce186fc34f5530841bdac7537ee775ed3f6 (patch) | |
| tree | ab4fad972fac8f8fc530b233f567ef33453f36a9 | |
| parent | 5ebb5e6092a74190654bf6d9e5d7d46f9db775a6 (diff) | |
| download | Tango-2e752ce186fc34f5530841bdac7537ee775ed3f6.tar.gz Tango-2e752ce186fc34f5530841bdac7537ee775ed3f6.zip | |
Job uploader from FSE/RSM.
User password reset from FSE.
Connectivity check method set to Windows by default.
16 files changed, 374 insertions, 9 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs index 9f021ddb1..701e67aa8 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs @@ -36,6 +36,20 @@ namespace Tango.FSE.UsersAndRoles.ViewModels set { _organization = value; RaisePropertyChangedAuto(); } } + private bool _isResetUserPassword; + public bool IsResetUserPassword + { + get { return _isResetUserPassword; } + set { _isResetUserPassword = value; RaisePropertyChangedAuto(); } + } + + private String _resetPassword; + public String ResetPassword + { + get { return _resetPassword; } + set { _resetPassword = value; RaisePropertyChangedAuto(); } + } + private bool _isNewUser; public bool IsNewUser { @@ -121,11 +135,26 @@ namespace Tango.FSE.UsersAndRoles.ViewModels public RelayCommand GeneratePasswordCommand { get; set; } + public RelayCommand ResetPasswordCommand { get; set; } + + public RelayCommand GenerateResetPasswordCommand { get; set; } + public UserDetailsViewVM() { SaveCommand = new RelayCommand(Save, () => IsFree); GeneratePasswordCommand = new RelayCommand(GeneratePassword); SendInvitation = true; + + ResetPasswordCommand = new RelayCommand(() => { IsResetUserPassword = true; GenerateResetPassword(); }); + GenerateResetPasswordCommand = new RelayCommand(GenerateResetPassword); + } + + private void GenerateResetPassword() + { + if (IsResetUserPassword) + { + ResetPassword = Services.OrganizationsService.GenerateRandomPassword(); + } } private void GeneratePassword() @@ -190,7 +219,7 @@ namespace Tango.FSE.UsersAndRoles.ViewModels bool user_is_current_user_and_fse_admin_and_not_twine_admin = user.Guid == CurrentUser.Guid && user.HasRole(Roles.FSEAdministrator) && !user.HasRole(Roles.FSETwineAdministrator); var collection = new RolesCollection(); - collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETechnician)) { IsSelected = isNew}); + collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETechnician)) { IsSelected = isNew }); collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSEAdvancedTechnician), Roles.FSETechnician)); collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSEAdministrator), Roles.FSETechnician, Roles.FSEAdvancedTechnician) { IsEnabled = !user_is_current_user_and_fse_admin_and_not_twine_admin }); @@ -273,7 +302,7 @@ namespace Tango.FSE.UsersAndRoles.ViewModels if (!IsNewUser) { - await Services.OrganizationsService.UpdateUser(User); + await Services.OrganizationsService.UpdateUser(User, IsResetUserPassword, ResetPassword); } else { @@ -386,6 +415,8 @@ namespace Tango.FSE.UsersAndRoles.ViewModels public void OnNavigatedToWithObject(NavigationObject obj) { + IsResetUserPassword = false; + ResetPassword = null; User = null; IsNewUser = obj.IsNewUser; Organization = obj.Organization; diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml index fe6ba4ea3..0df85dea8 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml @@ -71,6 +71,12 @@ <Button Margin="20 0 0 0" HorizontalAlignment="Left" Width="120" Style="{StaticResource FSE_RaisedButton_Dark_Hover_Accent_Foreground}" Command="{Binding GeneratePasswordCommand}" >GENERATE</Button> </UniformGrid> + <UniformGrid Columns="2" Margin="0 30 0 0" Visibility="{Binding IsResetUserPassword,Converter={StaticResource BooleanToVisibilityConverter}}"> + <TextBox Margin="0 0 0 0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Password" IsReadOnly="True" Text="{Binding ResetPassword,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + + <Button Margin="20 0 0 0" HorizontalAlignment="Left" Width="120" Style="{StaticResource FSE_RaisedButton_Dark_Hover_Accent_Foreground}" Command="{Binding GenerateResetPasswordCommand}" >GENERATE</Button> + </UniformGrid> + <UniformGrid Columns="2" Margin="0 30 0 0"> <TextBox Margin="0 0 0 0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="First Name" Text="{Binding FirstName,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> @@ -155,6 +161,10 @@ <CheckBox IsChecked="{Binding SendInvitation}" ToolTip="Send the new user invitation to login to this system with the initial password" Foreground="{StaticResource FSE_PrimaryAccentBrush}">Send invitation via email</CheckBox> </DockPanel> + <DockPanel Margin="0 50 0 0" HorizontalAlignment="Center" Visibility="{Binding IsNewUser,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <Button Style="{StaticResource FSE_FlatButton_ForegroundAccentHover}" Foreground="{StaticResource FSE_RedBrush}" Command="{Binding ResetPasswordCommand}" IsEnabled="{Binding IsResetUserPassword,Converter={StaticResource BooleanInverseConverter}}">RESET PASSWORD</Button> + </DockPanel> + <Button Margin="0 60 0 0" material:ButtonAssist.CornerRadius="25" Width="250" Height="50" Padding="12" Command="{Binding SaveCommand}"> <DockPanel> <material:PackIcon Kind="ContentSave"/> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/OrganizationsService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/OrganizationsService.cs index 7337ac9a5..2b86caddd 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/OrganizationsService.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/OrganizationsService.cs @@ -85,7 +85,7 @@ namespace Tango.FSE.BL.Services .BuildExecuteAsync(); } - public Task<User> UpdateUser(User user) + public Task<User> UpdateUser(User user, bool resetPassword = false, String temporaryResetPassword = null) { return Task.Factory.StartNew(() => { @@ -121,6 +121,12 @@ namespace Tango.FSE.BL.Services } } + if (resetPassword) + { + user.Password = User.GetPasswordHash(temporaryResetPassword); + user.PasswordChangeRequired = true; + } + db.SaveChanges(); } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs index f518ef2d2..ce14fa684 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs @@ -195,6 +195,11 @@ namespace Tango.FSE.Common public int LastConnectedMachineType { get; set; } /// <summary> + /// Gets or sets the last job upload thread unique identifier. + /// </summary> + public String LastJobUploadThreadGuid { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="FSESettings"/> class. /// </summary> public FSESettings() @@ -212,7 +217,7 @@ namespace Tango.FSE.Common EnableAdaptiveScaling = true; TerminatedExpectedly = true; FileAssociationServicePort = 1800; - ConnectivityVerificationMethod = ConnectivityVerificationMethod.Default; + ConnectivityVerificationMethod = ConnectivityVerificationMethod.Windows; ForceExternalBridgeProtocolConfiguration = true; EnableHotFolder = true; StatisticsStreamingConfig = new StatisticsStreamingConfiguration(); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJobUpload/IRemoteJobUploadProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJobUpload/IRemoteJobUploadProvider.cs index a38feed53..b27694f19 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJobUpload/IRemoteJobUploadProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJobUpload/IRemoteJobUploadProvider.cs @@ -18,7 +18,8 @@ namespace Tango.FSE.Common.RemoteJobUpload /// </summary> /// <param name="filePath">The job file path.</param> /// <param name="jobType">Remote job type.</param> + /// <param name="name">Optional job name</param> /// <returns></returns> - Task UploadJob(String filePath, RemoteJobUploadType jobType); + Task UploadJob(String filePath, RemoteJobUploadType jobType, String name = null); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml new file mode 100644 index 000000000..c806be854 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml @@ -0,0 +1,63 @@ +<UserControl x:Class="Tango.FSE.UI.Dialogs.JobUploadView" + 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:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.FSE.UI.Dialogs" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + mc:Ignorable="d" + Width="400" Height="500" d:DataContext="{d:DesignInstance Type=local:JobUploadViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + <DockPanel Margin="10"> + + <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> + <Image Source="/Images/job_upload.png" Width="42" Height="42" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="Fant" /> + <TextBlock VerticalAlignment="Center" Margin="10 0 0 0" FontSize="{StaticResource FSE_LargeFontSize}"> + <Run Text="{Binding BuildProvider.BuildName,Mode=OneWay}"></Run> + <Run>Remote Job Upload</Run> + </TextBlock> + </StackPanel> + + <Grid Margin="0 20 0 0" DockPanel.Dock="Top"> + + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock>Job Name</TextBlock> + <TextBox Text="{Binding Name}" Margin="0 5 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}"></TextBox> + </StackPanel> + + <StackPanel DockPanel.Dock="Top" Margin="0 20 0 0"> + <TextBlock>Selected Thread</TextBlock> + <ComboBox Foreground="{StaticResource FSE_PrimaryAccentDarkBrush}" Margin="0 5 0 0" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}" DisplayMemberPath="Name"></ComboBox> + </StackPanel> + + <StackPanel DockPanel.Dock="Top" Margin="0 20 0 0"> + <TextBlock>Length</TextBlock> + <mahapps:NumericUpDown Margin="0 5 0 0" Padding="5 0 0 0" Minimum="1" Maximum="1000000" HasDecimals="False" Style="{StaticResource FSE_NumericUpDown_Flat_Dark}" HideUpDownButtons="True" Value="{Binding Length}"></mahapps:NumericUpDown> + </StackPanel> + + <UniformGrid Columns="4" Height="100"> + <StackPanel> + <TextBlock HorizontalAlignment="Center" Foreground="Cyan">C</TextBlock> + <mahapps:NumericUpDown x:Name="numC" PreviewKeyDown="Num_PreviewKeyDown" Minimum="0" Maximum="200" Margin="0 5 0 0" BorderBrush="Cyan" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Height="60" HasDecimals="True" Style="{StaticResource FSE_NumericUpDown_Flat_Dark}" HideUpDownButtons="True" Value="{Binding C}"></mahapps:NumericUpDown> + </StackPanel> + + <StackPanel> + <TextBlock HorizontalAlignment="Center" Foreground="Magenta">M</TextBlock> + <mahapps:NumericUpDown x:Name="numM" PreviewKeyDown="Num_PreviewKeyDown" Minimum="0" Maximum="200" Margin="0 5 0 0" BorderBrush="Magenta" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Height="60" HasDecimals="True" Style="{StaticResource FSE_NumericUpDown_Flat_Dark}" HideUpDownButtons="True" Value="{Binding M}"></mahapps:NumericUpDown> + </StackPanel> + + <StackPanel> + <TextBlock HorizontalAlignment="Center" Foreground="Yellow">Y</TextBlock> + <mahapps:NumericUpDown x:Name="numY" PreviewKeyDown="Num_PreviewKeyDown" Minimum="0" Maximum="200" Margin="0 5 0 0" BorderBrush="Yellow" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Height="60" HasDecimals="True" Style="{StaticResource FSE_NumericUpDown_Flat_Dark}" HideUpDownButtons="True" Value="{Binding Y}"></mahapps:NumericUpDown> + </StackPanel> + + <StackPanel> + <TextBlock HorizontalAlignment="Center" Foreground="Black">K</TextBlock> + <mahapps:NumericUpDown x:Name="numK" PreviewKeyDown="Num_PreviewKeyDown" Minimum="0" Maximum="200" Margin="0 5 0 0" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Height="60" HasDecimals="True" Style="{StaticResource FSE_NumericUpDown_Flat_Dark}" HideUpDownButtons="True" Value="{Binding K}"></mahapps:NumericUpDown> + </StackPanel> + </UniformGrid> + </DockPanel> + </Grid> + </DockPanel> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml.cs new file mode 100644 index 000000000..98d1d8878 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadView.xaml.cs @@ -0,0 +1,74 @@ +using MahApps.Metro.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +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.UI.Dialogs +{ + /// <summary> + /// Interaction logic for ApplicationUpdateView.xaml + /// </summary> + public partial class JobUploadView : UserControl + { + private List<NumericUpDown> nums; + + public JobUploadView() + { + InitializeComponent(); + nums = new List<NumericUpDown>(); + nums.Add(numC); + nums.Add(numM); + nums.Add(numY); + nums.Add(numK); + } + + private void Num_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) + { + if (e.Key == Key.V) + { + try + { + DataObject o = (DataObject)Clipboard.GetDataObject(); + if (o.GetDataPresent(DataFormats.Text)) + { + string[] cells = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\t"); + + if (cells.Length > 1) + { + e.Handled = true; + + int indexOfSender = nums.IndexOf(sender as NumericUpDown); + + for (int i = indexOfSender; i < nums.Count; i++) + { + if (i - indexOfSender < cells.Length) + { + if (int.TryParse(cells[i - indexOfSender], out int value)) + { + nums[i].Value = value; + } + } + } + } + } + } + catch { } + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadViewVM.cs new file mode 100644 index 000000000..f12e4edf1 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/JobUploadViewVM.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.FSE.Common; +using Tango.FSE.Common.Build; +using Tango.PPC.Shared.Statistics; + +namespace Tango.FSE.UI.Dialogs +{ + public class JobUploadViewVM : FSEDialogViewVM + { + private String _name; + public String Name + { + get { return _name; } + set { _name = value; InvalidateRelayCommands(); } + } + + public List<ThreadFilterData> Rmls { get; set; } + + public ThreadFilterData SelectedRML { get; set; } + + public int Length { get; set; } + + public double C { get; set; } + + public double M { get; set; } + + public double Y { get; set; } + + public double K { get; set; } + + public JobUploadViewVM() + { + Rmls = new List<ThreadFilterData>(); + + TangoIOC.Default.Inject(this); + + OKText = "UPLOAD"; + CancelText = "CANCEL"; + } + + protected override bool CanOK() + { + return base.CanOK() && Name.IsNotNullOrEmpty(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload.png b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload.png Binary files differnew file mode 100644 index 000000000..7f5fb82db --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload.png diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload_disabled.png b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload_disabled.png Binary files differnew file mode 100644 index 000000000..90b115604 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/job_upload_disabled.png diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJobUpload/DefaultRemoteJobUploadProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJobUpload/DefaultRemoteJobUploadProvider.cs index bc2c6e84f..f223e873b 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJobUpload/DefaultRemoteJobUploadProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJobUpload/DefaultRemoteJobUploadProvider.cs @@ -31,15 +31,16 @@ namespace Tango.FSE.UI.RemoteJobUpload /// </summary> /// <param name="filePath">The job file path.</param> /// <param name="jobType">Remote job type.</param> + /// <param name="name">Optional job name</param> /// <returns></returns> - public async Task UploadJob(string filePath, RemoteJobUploadType jobType) + public async Task UploadJob(string filePath, RemoteJobUploadType jobType, String name = null) { LogManager.Log($"Uploading job '{filePath}' to the remote machine..."); var uploadResponse = await MachineProvider.MachineOperator.SendGenericRequest<RemoteJobUploadRequest, RemoteJobUploadResponse>(new RemoteJobUploadRequest() { Type = jobType, - Name = Path.GetFileNameWithoutExtension(filePath) + Name = name ?? Path.GetFileNameWithoutExtension(filePath) }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); var handler = await FileSystemProvider.Upload(filePath, uploadResponse.TargetFilePath, true); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index a9e4abc33..9816ca740 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -301,6 +301,10 @@ </Compile> <Compile Include="DemoMode\DemoModeWindowVM.cs" /> <Compile Include="Diagnostics\DefaultDiagnosticsProvider.cs" /> + <Compile Include="Dialogs\JobUploadView.xaml.cs"> + <DependentUpon>JobUploadView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\JobUploadViewVM.cs" /> <Compile Include="Dialogs\HotFolderConfigurationViewVM.cs" /> <Compile Include="Dialogs\HotFolderConfigurationView.xaml.cs"> <DependentUpon>HotFolderConfigurationView.xaml</DependentUpon> @@ -476,6 +480,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Dialogs\JobUploadView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Dialogs\HotFolderConfigurationView.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -694,6 +702,10 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58E8825F-0C96-449C-B320-1E82B0AA876B}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.DAL.Remote\Tango.DAL.Remote.csproj"> <Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project> <Name>Tango.DAL.Remote</Name> @@ -935,6 +947,8 @@ <None Include="hot_folder.ico"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <Resource Include="Images\job_upload.png" /> + <Resource Include="Images\job_upload_disabled.png" /> <Content Include="rc.exe"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs index 778297cbe..33297d103 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs @@ -4,19 +4,26 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Enumerations; +using Tango.BL.Helpers; using Tango.Core.Commands; using Tango.Core.DI; +using Tango.Core.IO; using Tango.Core.Threading; +using Tango.CSV; using Tango.FSE.Common; using Tango.FSE.Common.HotFolder; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.Notifications; +using Tango.FSE.Common.RemoteJobUpload; using Tango.FSE.UI.Dialogs; using Tango.FSE.UI.Panes; using Tango.FSE.UI.Views; using Tango.Integration.ExternalBridge; +using Tango.PPC.Shared.Statistics; using Tango.SharedUI.Helpers; using Tango.Transport; +using static Tango.BL.Helpers.SegmentsCsvHelper; namespace Tango.FSE.UI.ViewModels { @@ -114,6 +121,9 @@ namespace Tango.FSE.UI.ViewModels [TangoInject] public IHotFolderService HotFolderService { get; set; } + [TangoInject] + public IRemoteJobUploadProvider RemoteJobUploadProvider { get; set; } + #endregion #region Commands @@ -148,6 +158,11 @@ namespace Tango.FSE.UI.ViewModels /// </summary> public RelayCommand ConfigureHotFolderCommand { get; set; } + /// <summary> + /// Opens the job upload dialog. + /// </summary> + public RelayCommand UploadJobCommand { get; set; } + #endregion #region Constructors @@ -176,6 +191,8 @@ namespace Tango.FSE.UI.ViewModels NavigateToEventsCommand = new RelayCommand(NavigateToEvents); NavigateHomeCommand = new RelayCommand(NavigateHome); ConfigureHotFolderCommand = new RelayCommand(ConfigureHotFolder); + + UploadJobCommand = new RelayCommand(UploadJob); } #endregion @@ -351,6 +368,81 @@ namespace Tango.FSE.UI.ViewModels await NotificationProvider.ShowDialog<HotFolderConfigurationViewVM>(); } + private async void UploadJob() + { + RequiredFiltersData data = null; + try + { + using (NotificationProvider.PushTaskItem("Preparing job upload requirements...")) + { + await Task.Delay(1500); + data = await StatisticsProvider.GetRequiredFiltersData(); + } + } + catch (Exception ex) + { + await NotificationProvider.ShowError($"Error preparing job upload requirements.\n{ex.FlattenMessage()}"); + return; + } + + var lastSelectedRml = data.Rmls.FirstOrDefault(x => x.Guid == Settings.LastJobUploadThreadGuid); + if (lastSelectedRml == null) lastSelectedRml = data.Rmls.FirstOrDefault(); + var vm = await NotificationProvider.ShowDialog(new JobUploadViewVM() { Rmls = data.Rmls, SelectedRML = lastSelectedRml }); + + if (vm.DialogResult) + { + TemporaryFile tmpFile = TemporaryManager.CreateFile(".csv"); + + try + { + Settings.LastJobUploadThreadGuid = vm.SelectedRML.Guid; + Settings.Save(); + + SegmentCsvModel model = new SegmentCsvModel(); + List<string> columnNames = model.GetType().GetProperties().Select(x => x.Name).ToList(); + CsvFile<SegmentCsvModel> csvFile = new CsvFile<SegmentCsvModel>(new CsvDestination(tmpFile), new CsvDefinition() + { + Columns = columnNames + }); + + model.Index = "1"; + model.ThreadName = vm.SelectedRML.Name; + model.ColorSpace = ColorSpaces.Volume.ToDescription(); + model.Length = vm.Length.ToString(); + model.Cyan1 = vm.C.ToString(); + model.Magenta1 = vm.M.ToString(); + model.Yellow1 = vm.Y.ToString(); + model.Black1 = vm.K.ToString(); + + csvFile.Append(model); + csvFile.Dispose(); + } + catch (Exception ex) + { + await NotificationProvider.ShowError($"Error creating job upload file.\n{ex.FlattenMessage()}"); + tmpFile.Delete(); + return; + } + + SnackbarItem progress = null; + + try + { + progress = NotificationProvider.PushProgressSnackbar("Job Upload", $"Uploading job '{vm.Name}'..."); + await Task.Delay(1500); + await RemoteJobUploadProvider.UploadJob(tmpFile, PPC.Shared.RemoteJobUpload.RemoteJobUploadType.CSV, vm.Name); + + progress.ProgressCompleted("Job uploaded successfully", TimeSpan.FromSeconds(2)); + } + catch (Exception ex) + { + progress.ProgressFailed($"Error uploading job.\n{ex.Message}"); + return; + } + } + + } + #endregion } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml index d4310bb27..e1cc8225f 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml @@ -112,6 +112,22 @@ </Image.Style> </Image> </Button> + + <Rectangle Margin="10 0" Stroke="{StaticResource FSE_BorderBrush}" /> + <Button IsEnabled="{Binding MachineProvider.IsPPCAvailable}" Padding="0" Style="{StaticResource FSE_FlatButton_OpacityHover}" Command="{Binding UploadJobCommand}" material:RippleAssist.IsDisabled="True"> + <Image ToolTip="Upload job to the connected machine" Stretch="Fill" RenderOptions.BitmapScalingMode="Fant" Margin="0 -14 0 0" Width="18" Height="18"> + <Image.Style> + <Style TargetType="Image"> + <Setter Property="Source" Value="/Images/job_upload_disabled.png"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding MachineProvider.IsPPCAvailable}" Value="True"> + <Setter Property="Source" Value="/Images/job_upload.png"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Image.Style> + </Image> + </Button> </StackPanel> <Rectangle Margin="10 6" Stroke="{StaticResource FSE_BorderBrush}" /> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest index d72e75011..efc5f8179 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest @@ -16,7 +16,7 @@ Remove this element if your application requires this virtualization for backwards compatibility. --> - <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> + <!--<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />--> </requestedPrivileges> </security> </trustInfo> diff --git a/Software/Visual_Studio/Tango.BL/Helpers/SegmentsCsvHelper.cs b/Software/Visual_Studio/Tango.BL/Helpers/SegmentsCsvHelper.cs index 18dde341b..28c227a8d 100644 --- a/Software/Visual_Studio/Tango.BL/Helpers/SegmentsCsvHelper.cs +++ b/Software/Visual_Studio/Tango.BL/Helpers/SegmentsCsvHelper.cs @@ -476,7 +476,7 @@ namespace Tango.BL.Helpers }); } - static async void ToFile(String filePath, List<Segment> segments) + public static async void ToFile(String filePath, List<Segment> segments) { await Task.Factory.StartNew(() => { |
