From 024eb7867d2b400212ce4ce0e4845d99bf532568 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 4 Nov 2020 13:01:49 +0200 Subject: First steps on FSE configuration module. --- .../ViewModels/ConfigurationViewVM.cs | 44 ++++++++++++++++ .../ViewModels/DataStoreViewVM.cs | 13 +++++ .../ViewModels/MachineViewVM.cs | 60 ++++++++++++++++++++++ .../ViewModels/MainViewVM.cs | 60 ++++++++++++++++++++++ .../ViewModels/SelectionViewVM.cs | 48 +++++++++++++++++ 5 files changed, 225 insertions(+) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs new file mode 100644 index 000000000..1540a4e67 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.FSE.Common; +using Tango.FSE.Common.AutoComplete; +using Tango.FSE.MachineConfiguration.Messages; + +namespace Tango.FSE.MachineConfiguration.ViewModels +{ + public class ConfigurationViewVM : FSEViewModel + { + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + private List _organizations; + public List Organizations + { + get { return _organizations; } + set { _organizations = value; RaisePropertyChangedAuto(); } + } + + public ConfigurationViewVM() + { + RegisterForMessage(HandleMachineLoadedMessage); + } + + private async void HandleMachineLoadedMessage(MachineLoadedMessage msg) + { + using (NotificationProvider.PushTaskItem("Loading configuration options...")) + { + Machine = msg.Machine; + Organizations = await Services.OrganizationsService.GetCurrentUserOrganizations(); + Machine.Organization = Organizations.SingleOrDefault(x => x.Guid == Machine.OrganizationGuid); + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs new file mode 100644 index 000000000..f321cd061 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Common; + +namespace Tango.FSE.MachineConfiguration.ViewModels +{ + public class DataStoreViewVM : FSEViewModel + { + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs new file mode 100644 index 000000000..cbd6c1cf1 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.FSE.Common; +using Tango.FSE.Common.Navigation; +using Tango.FSE.MachineConfiguration.Messages; +using static Tango.FSE.MachineConfiguration.ViewModels.MachineViewVM; + +namespace Tango.FSE.MachineConfiguration.ViewModels +{ + public class MachineViewVM : ConfigurationViewModel, INavigationObjectReceiver + { + public class NavigationObject + { + public String MachineSerialNumber { get; set; } + } + + public enum NavigationView + { + ConfigurationView, + DataStoreView, + } + + private NavigationView _selectedView; + public NavigationView SelectedView + { + get { return _selectedView; } + set + { + _selectedView = value; + RaisePropertyChangedAuto(); + } + } + + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + public void OnNavigatedToWithObject(NavigationObject obj) + { + SelectedView = NavigationView.ConfigurationView; + LoadMachine(obj.MachineSerialNumber); + } + + private async void LoadMachine(String serialNumber) + { + using (NotificationProvider.PushTaskItem("Loading machine configuration...")) + { + Machine = await Services.MachinesService.GetMachineFull(serialNumber); + RaiseMessage(new MachineLoadedMessage() { Machine = Machine }); + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs new file mode 100644 index 000000000..efb2fc3cc --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Common; +using Tango.FSE.Common.Navigation; +using Tango.FSE.MachineConfiguration.Navigation; +using Tango.SharedUI.Helpers; + +namespace Tango.FSE.MachineConfiguration.ViewModels +{ + [ModularNavigationContainer] + public class MainViewVM : ConfigurationViewModel + { + public override void OnApplicationStarted() + { + InvokeUI(() => + { + NavigationManager.MenuItems.Add(new NavigationMenuItem(() => + { + NavigationManager.NavigateTo(); + }) + { + Name = "Configuration", + Index = 8, + Description = "Access to the organization machines configuration and settings", + Image = ResourceHelper.GetImageFromResources("Images/configuration.png"), + }); + }); + } + + public async override Task OnApplicationLogout() + { + while (ModularNavigationManager.CurrentView != ConfigurationView.SelectionView) + { + if (!await ModularNavigationManager.NavigateBack()) + { + return false; + } + } + + return await base.OnApplicationLogout(); + } + + public async override Task OnNavigateBackRequest() + { + if (ModularNavigationManager.CurrentView == ConfigurationView.SelectionView) + { + return await base.OnNavigateBackRequest(); + } + else + { + await ModularNavigationManager.NavigateBack(); + return false; + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs new file mode 100644 index 000000000..c62ade6fb --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.FSE.Common; +using Tango.FSE.MachineConfiguration.Navigation; + +namespace Tango.FSE.MachineConfiguration.ViewModels +{ + public class SelectionViewVM : ConfigurationViewModel + { + private Machine _selectedMachine; + /// + /// Gets or sets the selected machine. + /// + public Machine SelectedMachine + { + get { return _selectedMachine; } + set { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + public RelayCommand ManageMachineCommand { get; set; } + + public SelectionViewVM() + { + ManageMachineCommand = new RelayCommand(ManageSelectedMachine, () => SelectedMachine != null); + } + + private void ManageSelectedMachine() + { + if (SelectedMachine == null) + { + NotificationProvider.ShowError("No machine selected."); + return; + } + + ModularNavigationManager.NavigateTo(ConfigurationView.MachineView, new MachineViewVM.NavigationObject() + { + MachineSerialNumber = SelectedMachine.SerialNumber + }); + } + } +} + + -- cgit v1.3.1 From d6db3244c15e3937d339064da0a5c7186f32daa1 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 9 Nov 2020 07:00:47 +0200 Subject: Working on machine configuration. --- .../Messages/EditingCompositionLoadedMessage.cs | 16 ++ .../Messages/MachineLoadedMessage.cs | 14 -- .../Tango.FSE.MachineConfiguration.csproj | 2 +- .../ViewModels/ConfigurationViewVM.cs | 85 ++++++-- .../ViewModels/MachineViewVM.cs | 19 +- .../ViewModels/MainViewVM.cs | 2 +- .../ViewModels/SelectionViewVM.cs | 19 +- .../Views/ConfigurationView.xaml | 234 ++++++++++++++------- .../Views/MachineView.xaml | 4 +- .../FSE/Tango.FSE.BL/FSEServicesContainer.cs | 6 + .../Services/MachineConfigurationService.cs | 88 ++++++++ .../FSE/Tango.FSE.BL/Tango.FSE.BL.csproj | 1 + .../Connection/IMachineProvider.cs | 2 +- .../FSE/Tango.FSE.Common/Controls/MachineView.xaml | 12 +- .../FSE/Tango.FSE.Common/Resources/Styles.xaml | 197 +++++++++++++++-- .../Connection/DefaultMachineProvider.cs | 1 + .../DefaultFileAssociationProvider.cs | 5 + .../Tango.BL/Entities/HardwareVersion.cs | 11 + 18 files changed, 578 insertions(+), 140 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/EditingCompositionLoadedMessage.cs delete mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/MachineLoadedMessage.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/EditingCompositionLoadedMessage.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/EditingCompositionLoadedMessage.cs new file mode 100644 index 000000000..b858c34e0 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/EditingCompositionLoadedMessage.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.FSE.BL.Services; +using static Tango.FSE.BL.Services.MachineConfigurationService; + +namespace Tango.FSE.MachineConfiguration.Messages +{ + public class EditingCompositionLoadedMessage + { + public MachineEditingComposition EditingComposition { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/MachineLoadedMessage.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/MachineLoadedMessage.cs deleted file mode 100644 index 4a703b2a9..000000000 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Messages/MachineLoadedMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.BL.Entities; - -namespace Tango.FSE.MachineConfiguration.Messages -{ - public class MachineLoadedMessage - { - public Machine Machine { get; set; } - } -} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj index e7adc1d3f..c5aa8c4bf 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj @@ -79,7 +79,7 @@ - + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs index 1540a4e67..63e3f22d9 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs @@ -4,41 +4,96 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.Core.DI; using Tango.FSE.Common; using Tango.FSE.Common.AutoComplete; +using Tango.FSE.Common.SQL; using Tango.FSE.MachineConfiguration.Messages; +using static Tango.FSE.BL.Services.MachineConfigurationService; namespace Tango.FSE.MachineConfiguration.ViewModels { public class ConfigurationViewVM : FSEViewModel { - private Machine _machine; - public Machine Machine + [TangoInject] + private IRemoteSqlProvider RemoteSqlProvider { get; set; } + + private MachineEditingComposition _editingComposition; + public MachineEditingComposition EditingComposition { - get { return _machine; } - set { _machine = value; RaisePropertyChangedAuto(); } + get { return _editingComposition; } + set { _editingComposition = value; RaisePropertyChangedAuto(); } } - private List _organizations; - public List Organizations + public RelayCommand SaveCommand { get; set; } + public RelayCommand ResetCountersCommand { get; set; } + public RelayCommand ResetDeviceRegistrationCommand { get; set; } + + + public ConfigurationViewVM() { - get { return _organizations; } - set { _organizations = value; RaisePropertyChangedAuto(); } + RegisterForMessage(OnEditingCompositionLoaded); + SaveCommand = new RelayCommand(SaveConfiguration); + ResetCountersCommand = new RelayCommand(ResetCounters); + ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); } - public ConfigurationViewVM() + private void OnEditingCompositionLoaded(EditingCompositionLoadedMessage msg) { - RegisterForMessage(HandleMachineLoadedMessage); + using (NotificationProvider.PushTaskItem("Loading machine configuration...")) + { + EditingComposition = msg.EditingComposition; + } } - private async void HandleMachineLoadedMessage(MachineLoadedMessage msg) + private async void SaveConfiguration() { - using (NotificationProvider.PushTaskItem("Loading configuration options...")) + using (NotificationProvider.PushTaskItem("Saving machine configuration...")) { - Machine = msg.Machine; - Organizations = await Services.OrganizationsService.GetCurrentUserOrganizations(); - Machine.Organization = Organizations.SingleOrDefault(x => x.Guid == Machine.OrganizationGuid); + EditingComposition = await Services.MachineConfigurationService.SaveMachineEditingComposition(EditingComposition); + await NotificationProvider.ShowSuccess("Machine configuration saved successfully."); } } + + private async void ResetCounters() + { + if (!MachineProvider.IsPPCAvailable) + { + await NotificationProvider.ShowError("Resetting the machine counters requires an active connection to this machine."); + return; + } + + if (!await NotificationProvider.ShowWarningQuestion("Resetting the machine counters will delete the entire job runs history. Are you sure?", "RESET COUNTERS", "CANCEL")) return; + + using (var task = NotificationProvider.PushTaskItem("Resetting machine counters...")) + { + task.UpdateProgress("Resetting local machine counters..."); + + var result = await RemoteSqlProvider.ExecuteSqlCommandAsync(new RemoteSqlCommand() + { + Mode = RemoteSqlCommandMode.Local, + Timeout = 30, + SQL = "DELETE FROM JOB_RUNS" + }); + + int localJobRuns = result.LocalAffectedRecords; + + task.UpdateProgress("Resetting global machine counters..."); + + int remoteJobRuns = await Services.MachineConfigurationService.ResetCounters(EditingComposition.Machine.Guid); + + await NotificationProvider.ShowSuccess("Machine counters deleted successfully."); + } + } + + private async void ResetDeviceRegistration() + { + if (!await NotificationProvider.ShowWarningQuestion("Resetting the machine's device registration will allow other panel PCs to perform a machine setup for this machine. Are you sure?", "RESET", "CANCEL")) return; + + EditingComposition.Machine.IsDeviceRegistered = false; + EditingComposition.Machine.DeviceId = null; + EditingComposition.Machine.DeviceName = null; + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs index cbd6c1cf1..24a0cbc42 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MachineViewVM.cs @@ -7,6 +7,7 @@ using Tango.BL.Entities; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; using Tango.FSE.MachineConfiguration.Messages; +using static Tango.FSE.BL.Services.MachineConfigurationService; using static Tango.FSE.MachineConfiguration.ViewModels.MachineViewVM; namespace Tango.FSE.MachineConfiguration.ViewModels @@ -15,7 +16,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels { public class NavigationObject { - public String MachineSerialNumber { get; set; } + public String MachineGuid { get; set; } } public enum NavigationView @@ -35,25 +36,25 @@ namespace Tango.FSE.MachineConfiguration.ViewModels } } - private Machine _machine; - public Machine Machine + private MachineEditingComposition _editingComposition; + public MachineEditingComposition EditingComposition { - get { return _machine; } - set { _machine = value; RaisePropertyChangedAuto(); } + get { return _editingComposition; } + set { _editingComposition = value; RaisePropertyChangedAuto(); } } public void OnNavigatedToWithObject(NavigationObject obj) { SelectedView = NavigationView.ConfigurationView; - LoadMachine(obj.MachineSerialNumber); + LoadMachine(obj.MachineGuid); } - private async void LoadMachine(String serialNumber) + private async void LoadMachine(String machineGuid) { using (NotificationProvider.PushTaskItem("Loading machine configuration...")) { - Machine = await Services.MachinesService.GetMachineFull(serialNumber); - RaiseMessage(new MachineLoadedMessage() { Machine = Machine }); + EditingComposition = await Services.MachineConfigurationService.GetMachineEditingComposition(machineGuid); + RaiseMessage(new EditingCompositionLoadedMessage() { EditingComposition = EditingComposition }); } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs index efb2fc3cc..5b8ca21ac 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/MainViewVM.cs @@ -14,7 +14,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels [ModularNavigationContainer] public class MainViewVM : ConfigurationViewModel { - public override void OnApplicationStarted() + public override void OnApplicationReady() { InvokeUI(() => { diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs index c62ade6fb..b65ad7102 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs @@ -39,9 +39,26 @@ namespace Tango.FSE.MachineConfiguration.ViewModels ModularNavigationManager.NavigateTo(ConfigurationView.MachineView, new MachineViewVM.NavigationObject() { - MachineSerialNumber = SelectedMachine.SerialNumber + MachineGuid = SelectedMachine.Guid }); } + + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (SelectedMachine == null && MachineProvider.Machine != null) + { + SelectedMachine = MachineProvider.Machine; + } + } + + public override Task OnApplicationLogout() + { + ModularNavigationManager.NavigateTo(ConfigurationView.SelectionView); + SelectedMachine = null; + return base.OnApplicationLogout(); + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml index 8d8aa7b0e..9c8b2d878 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml @@ -5,111 +5,191 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.FSE.MachineConfiguration.Views" xmlns:global="clr-namespace:Tango.FSE.MachineConfiguration" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:vm="clr-namespace:Tango.FSE.MachineConfiguration.ViewModels" + xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" mc:Ignorable="d" - d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:ConfigurationViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ConfigurationViewVM}" d:DesignStyle="{StaticResource FSE_User_Control_Designer}"> - + d:DesignHeight="2000" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:ConfigurationViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ConfigurationViewVM}" d:DesignStyle="{StaticResource FSE_User_Control_Designer}"> - - + - - - - - Activate Windows License - + - - License Key - - + + + + + - - - Setup Team Viewer - + - - - Activate Disk Protection - + - - - Use Firmware Emulator (Demo Machine) - - - Device Registration + + + + + Activate Windows License + + + + License Key + + + + + + Setup Team Viewer + + + + + Activate Disk Protection + + + + + Use Firmware Emulator (Demo Machine) + + + + - - + Device Registration - + + + + Registered: - - + + - + Device ID: - - + + - + Device Name: - - - + + + - - - - - - - - - - - Perform Firmware Upgrade - + + + - - - Force Version Update - + - - - Suspend Version Update - - - + - - + Machine Counters - - Serial Number - - + + + + + Total Dye Time: + + - - Name - + + Total Dye Meters: + + + + + + + + + + + + + + Perform Firmware Upgrade + + + + + Force Version Update + - - Organization - + + + Suspend Version Update + - - - + + + + + + + Serial Number + + + + + Name + + + + + Organization + + + + + Site + + + + + + + + + Head Type + + + + + Hardware Version + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml index ba9418d5d..9f81f82e4 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml @@ -29,8 +29,8 @@ - - + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs index e5487bc1e..14b74fd9c 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs @@ -62,6 +62,11 @@ namespace Tango.FSE.BL /// public OrganizationsService OrganizationsService { get; set; } + /// + /// Gets or sets the machine configuration service. + /// + public MachineConfigurationService MachineConfigurationService { get; set; } + /// /// Initializes a new instance of the class. /// @@ -78,6 +83,7 @@ namespace Tango.FSE.BL PublishedProcedureProjectsService = new PublishedProcedureProjectsService(); MachineEventsService = new MachineEventsService(); OrganizationsService = new OrganizationsService(); + MachineConfigurationService = new MachineConfigurationService(); } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs new file mode 100644 index 000000000..e6798e197 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using System.Data.Entity; +using Tango.BL.Builders; + +namespace Tango.FSE.BL.Services +{ + public class MachineConfigurationService : FSEServiceBase + { + public class MachineEditingComposition : IDisposable + { + public Machine Machine { get; set; } + public List Organizations { get; set; } + public List HardwareVersions { get; set; } + public String TotalDyeTime { get; set; } + public String TotalDyeMeters { get; set; } + internal ObservablesContext Context { get; set; } + + public MachineEditingComposition() + { + Organizations = new List(); + HardwareVersions = new List(); + } + + public void Dispose() + { + Context?.Dispose(); + Context = null; + } + } + + public Task GetMachineEditingComposition(String machineGuid) + { + return Task.Factory.StartNew(() => + { + ObservablesContext db = ObservablesContext.CreateDefault(); + + MachineEditingComposition composition = new MachineEditingComposition(); + + //Organizations + bool allowAll = CurrentUser.HasPermission(Tango.BL.Enumerations.Permissions.FSE_ManageAllOrganizationsUsersAndRoles); + composition.Organizations = db.Organizations.Where(x => allowAll || x.Guid == CurrentUser.OrganizationGuid).Include(x => x.Sites).ToList(); + + //Machine + composition.Machine = new MachineBuilder(db).Set(machineGuid).WithConfiguration().Build(); + + //Hardware Versions + composition.HardwareVersions = db.HardwareVersions.OrderByDescending(x => x.Version).ToList(); + + //Counters + var jobRuns = db.JobRuns.Where(x => x.MachineGuid == machineGuid).Select(x => new { x.StartDate, x.EndDate, x.EndPosition }).ToList(); + composition.TotalDyeTime = TimeSpan.FromHours(jobRuns.Select(x => x.EndDate - x.StartDate).Sum(x => x.TotalHours)).ToStringUnlimitedHours(); + int meters = (int)jobRuns.Select(x => x.EndPosition).Sum(); + composition.TotalDyeMeters = $"{meters.ToString("N0")} meters"; + + composition.Context = db; + + return composition; + }); + } + + public Task SaveMachineEditingComposition(MachineEditingComposition composition) + { + return Task.Factory.StartNew(() => + { + composition.Context.SaveChanges(); + composition.Context.Dispose(); + return GetMachineEditingComposition(composition.Machine.Guid).Result; + }); + } + + public Task ResetCounters(String machineGuid) + { + return Task.Factory.StartNew(() => + { + using (ObservablesContext db = new ObservablesContext()) + { + return db.JobRuns.Where(x => x.MachineGuid == machineGuid).DeleteFromQuery(); + } + }); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj b/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj index 39257df86..fba87644b 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj @@ -119,6 +119,7 @@ + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs index 9a98477b8..8c4512c41 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs @@ -41,7 +41,7 @@ namespace Tango.FSE.Common.Connection MachineConnectionTypes ConnectionType { get; } /// - /// Gets a value indicating whether the equals or . + /// Gets a value indicating whether the machine is connected and the equals or . /// bool IsPPCAvailable { get; } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/MachineView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/MachineView.xaml index c37613e3e..8d375cc6d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/MachineView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/MachineView.xaml @@ -47,11 +47,11 @@ - Hardware + 1 @@ -217,17 +217,17 @@ - Mid Tanks + - Cartridges + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml index 8d5e5ae0d..2b7ea3640 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml @@ -9,6 +9,8 @@ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:Tango.FSE.Common.Resources"> + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs index 94b035ab5..aad63fdf9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs @@ -342,6 +342,7 @@ namespace Tango.FSE.UI.Connection { IsConnected = false; IsBusy = false; + Machine = null; OnMachineDisconnected(MachineOperator, null); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs index 0d582cb11..89364cbbd 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs @@ -19,6 +19,7 @@ namespace Tango.FSE.UI.FileAssociation { private Dictionary> _handlers; private IpcServer _ipcServer; + private bool _initialized; public const string FILE_ASSOCIATION_PREFIX = "-file"; public const int FILE_ASSOCIATION_ARGS_COUNT = 3; @@ -44,6 +45,10 @@ namespace Tango.FSE.UI.FileAssociation public async void OnApplicationReady(IFSEApplicationManager applicationManager) { + if (!_initialized) return; + + _initialized = true; + try { LogManager.Log("Starting file association IPC service..."); diff --git a/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs b/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs index 590fe9e13..bc65c33ce 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs @@ -109,5 +109,16 @@ namespace Tango.BL.Entities { } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return FullName; + } } } -- cgit v1.3.1 From 775f0015321f91aa5be3aca079e289e89d4719f5 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 10 Nov 2020 11:06:48 +0200 Subject: DataStore editing.. --- .../Converters/DataStoreValueToStringConverter.cs | 32 ++++++ .../Tango.FSE.MachineConfiguration.csproj | 17 +++ .../ViewModels/DataStoreViewVM.cs | 74 +++++++++++- .../Views/DataStoreView.xaml | 66 ++++++++++- .../FSE/Tango.FSE.BL/FSEServicesContainer.cs | 6 + .../FSE/Tango.FSE.BL/Services/DataStoreService.cs | 36 ++++++ .../FSE/Tango.FSE.BL/Tango.FSE.BL.csproj | 9 ++ .../DataStore/IDataStoreProvider.cs | 14 +++ .../DataStore/IRemoteDataStoreManager.cs | 2 +- .../FSE/Tango.FSE.Common/Tango.FSE.Common.csproj | 5 + .../DataStore/DefaultDataStoreProvider.cs | 124 +++++++++++++++++++++ .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 9 ++ .../FSE/Tango.FSE.UI/ViewModelLocator.cs | 2 + .../DataStore/DefaultDataStoreService.cs | 29 +++++ .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 2 +- .../Tango.DataStore.Editing/CustomControl1.cs | 25 +++++ .../DataStoreCollectionModel.cs | 21 ++++ .../Tango.DataStore.Editing/DataStoreItemModel.cs | 89 +++++++++++++++ .../Tango.DataStore.Editing/DataStoreModel.cs | 20 ++++ .../Properties/AssemblyInfo.cs | 55 +++++++++ .../Properties/Resources.Designer.cs | 62 +++++++++++ .../Properties/Resources.resx | 117 +++++++++++++++++++ .../Properties/Settings.Designer.cs | 30 +++++ .../Properties/Settings.settings | 7 ++ .../Tango.DataStore.Editing.csproj | 100 +++++++++++++++++ .../Tango.DataStore.Editing/Themes/Generic.xaml | 18 +++ .../RemoteDataStoreCollection.cs | 19 ++++ .../RemoteDataStoreGetAllItemsRequest.cs | 12 ++ .../RemoteDataStoreGetAllItemsResponse.cs | 18 +++ .../Tango.DataStore.Remote.csproj | 3 + .../Tango.DataStore/DataStoreHelper.cs | 4 +- Software/Visual_Studio/Tango.sln | 34 +++++- 32 files changed, 1047 insertions(+), 14 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/CustomControl1.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/DataStoreModel.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.Designer.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.resx create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.Designer.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.settings create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/Themes/Generic.xaml create mode 100644 Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreCollection.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsRequest.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsResponse.cs (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs new file mode 100644 index 000000000..6b3c8e28c --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.DataStore; + +namespace Tango.FSE.MachineConfiguration.Converters +{ + public class DataStoreValueToStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is IDataStoreItem item) + { + if (item != null) + { + return DataStoreHelper.FormatDataStoreItem(item); + } + } + + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj index c5aa8c4bf..af67b0d74 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj @@ -79,6 +79,7 @@ + @@ -143,6 +144,22 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {ee088ff7-04d1-41fb-9d6a-cedeee7a7b9c} + Tango.DataStore.Editing + + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + + + {29448f3c-9b3e-4da6-8555-46a8b9a6b3aa} + Tango.DataStore.Remote + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + {4206ac58-3b57-4699-8835-90bf6db01a61} Tango.Integration diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs index f321cd061..4a75c137b 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -3,11 +3,83 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.DataStore.Editing; using Tango.FSE.Common; +using Tango.FSE.Common.DataStore; +using Tango.FSE.MachineConfiguration.Messages; +using static Tango.SharedUI.Controls.NavigationControl; namespace Tango.FSE.MachineConfiguration.ViewModels { - public class DataStoreViewVM : FSEViewModel + public class DataStoreViewVM : FSEViewModel, INavigationViewModel { + private String machineGuid; + + [TangoInject] + private IDataStoreProvider DataStoreProvider { get; set; } + + private DataStoreModel _dataStore; + public DataStoreModel DataStore + { + get { return _dataStore; } + set { _dataStore = value; RaisePropertyChangedAuto(); } + } + + private DataStoreCollectionModel _selectedCollection; + public DataStoreCollectionModel SelectedCollection + { + get { return _selectedCollection; } + set { _selectedCollection = value; RaisePropertyChangedAuto(); } + } + + private DataStoreItemModel _selectedItem; + public DataStoreItemModel SelectedItem + { + get { return _selectedItem; } + set { _selectedItem = value; RaisePropertyChangedAuto(); } + } + + private bool _isLoading; + public bool IsLoading + { + get { return _isLoading; } + set { _isLoading = value; RaisePropertyChangedAuto(); } + } + + public DataStoreViewVM() + { + RegisterForMessage(OnEditingCompositionLoaded); + } + + private void OnEditingCompositionLoaded(EditingCompositionLoadedMessage obj) + { + DataStore = null; + machineGuid = obj.EditingComposition.Machine.Guid; + } + + public async override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (DataStore == null) + { + try + { + IsLoading = true; + IsFree = false; + DataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading data store."); + } + finally + { + IsLoading = false; + IsFree = true; + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml index ac26bf445..f078efcee 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml @@ -6,11 +6,71 @@ xmlns:local="clr-namespace:Tango.FSE.MachineConfiguration.Views" xmlns:global="clr-namespace:Tango.FSE.MachineConfiguration" xmlns:vm="clr-namespace:Tango.FSE.MachineConfiguration.ViewModels" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" + xmlns:converters="clr-namespace:Tango.FSE.MachineConfiguration.Converters" mc:Ignorable="d" - d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:DataStoreViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.DataStoreViewVM}"> - - + d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:DataStoreViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.DataStoreViewVM}" d:DesignStyle="{StaticResource FSE_User_Control_Designer}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs index 14b74fd9c..c8773eccd 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/FSEServicesContainer.cs @@ -67,6 +67,11 @@ namespace Tango.FSE.BL /// public MachineConfigurationService MachineConfigurationService { get; set; } + /// + /// Gets or sets the data store service. + /// + public DataStoreService DataStoreService { get; set; } + /// /// Initializes a new instance of the class. /// @@ -84,6 +89,7 @@ namespace Tango.FSE.BL MachineEventsService = new MachineEventsService(); OrganizationsService = new OrganizationsService(); MachineConfigurationService = new MachineConfigurationService(); + DataStoreService = new DataStoreService(); } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs new file mode 100644 index 000000000..41ab7725b --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.DataStore; + +namespace Tango.FSE.BL.Services +{ + public class DataStoreService : FSEServiceBase + { + public Task> GetGlobalDataStoreItems() + { + return Task.Factory.StartNew>(() => + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + return db.GlobalDataStoreItems.ToList().OrderBy(x => x.CollectionName).OrderBy(x => x.Key).ToList(); + } + }); + } + + public Task> GetMachinelDataStoreItems(String machineGuid) + { + return Task.Factory.StartNew>(() => + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.MachineGuid == machineGuid).ToList().OrderBy(x => x.CollectionName).OrderBy(x => x.Key).ToList(); + } + }); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj b/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj index fba87644b..d15611e91 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Tango.FSE.BL.csproj @@ -119,6 +119,7 @@ + @@ -146,6 +147,14 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} Tango.Logging diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs new file mode 100644 index 000000000..bab513e36 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.DataStore.Editing; + +namespace Tango.FSE.Common.DataStore +{ + public interface IDataStoreProvider + { + Task GetDataStoreModel(String machineGuid); + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IRemoteDataStoreManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IRemoteDataStoreManager.cs index 02cc3ac9d..162c109be 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IRemoteDataStoreManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IRemoteDataStoreManager.cs @@ -9,6 +9,6 @@ namespace Tango.FSE.Common.DataStore { public interface IRemoteDataStoreManager : IDataStoreManager { - + } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj index 4f0cb622b..bb44045b7 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj @@ -188,6 +188,7 @@ + @@ -505,6 +506,10 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {ee088ff7-04d1-41fb-9d6a-cedeee7a7b9c} + Tango.DataStore.Editing + {e0364dfa-0721-4637-9d32-9d22aac109d6} Tango.DataStore diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs new file mode 100644 index 000000000..6239a33d9 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.DI; +using Tango.DataStore; +using Tango.DataStore.Editing; +using Tango.DataStore.Remote; +using Tango.FSE.BL; +using Tango.FSE.Common.Connection; +using Tango.FSE.Common.DataStore; + +namespace Tango.FSE.UI.DataStore +{ + public class DefaultDataStoreProvider : IDataStoreProvider + { + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private FSEServicesContainer Services { get; set; } + + public Task GetDataStoreModel(String machineGuid) + { + return Task.Factory.StartNew(() => + { + DataStoreModel model = new DataStoreModel(); + + List globalItems = Services.DataStoreService.GetGlobalDataStoreItems().Result; + List localItems = Services.DataStoreService.GetMachinelDataStoreItems(machineGuid).Result; + + List itemsModels = new List(); + + //Get machine items from db. + foreach (var collection in localItems.GroupBy(x => x.CollectionName)) + { + DataStoreCollectionModel collectionModel = new DataStoreCollectionModel(); + collectionModel.Name = collection.First().CollectionName; + + foreach (var item in collection) + { + GlobalDataStoreItem globalItem = globalItems.FirstOrDefault(x => x.CollectionName == item.CollectionName && x.Key == item.Key); + + if (globalItem != null) + { + globalItems.Remove(globalItem); + } + + DataStoreItemModel itemModel = DataStoreItemModel.FromLocalDataStoreItem(item.ToDataStoreItem(), globalItem?.ToDataStoreItem()); + collectionModel.Items.Add(itemModel); + } + + model.Collections.Add(collectionModel); + } + + //Get machine items from connected machine. + if (MachineProvider.IsPPCAvailable) + { + var response = MachineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetAllItemsRequest(), new Transport.TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }).Result; + + foreach (var collection in response.Collections) + { + DataStoreCollectionModel collectionModel = model.Collections.FirstOrDefault(x => x.Name == collection.Name); + + if (collectionModel == null) + { + collectionModel = new DataStoreCollectionModel(); + collectionModel.Name = collection.Name; + model.Collections.Add(collectionModel); + } + + foreach (var remoteItem in collection.Items) + { + var localItem = collectionModel.Items.FirstOrDefault(x => x.Key == remoteItem.Key); + + if (localItem != null && remoteItem.Date > localItem.Date) + { + localItem.Value = remoteItem.Value; + localItem.Type = remoteItem.Type; + localItem.Date = remoteItem.Date; + } + else if (localItem == null) + { + GlobalDataStoreItem globalItem = globalItems.FirstOrDefault(x => x.CollectionName == collection.Name && x.Key == remoteItem.Key); + + if (globalItem != null) + { + globalItems.Remove(globalItem); + } + + DataStoreItemModel itemModel = DataStoreItemModel.FromLocalDataStoreItem(remoteItem, globalItem?.ToDataStoreItem()); + collectionModel.Items.Add(itemModel); + } + + } + } + } + + //Get global items without overrides from db. + foreach (var collection in globalItems.GroupBy(x => x.CollectionName)) + { + DataStoreCollectionModel collectionModel = model.Collections.FirstOrDefault(x => x.Name == collection.First().CollectionName); + + if (collectionModel == null) + { + collectionModel = new DataStoreCollectionModel(); + collectionModel.Name = collection.First().CollectionName; + model.Collections.Add(collectionModel); + } + + foreach (var item in collection) + { + DataStoreItemModel itemModel = DataStoreItemModel.FromGlobalDataStoreItem(item.ToDataStoreItem()); + collectionModel.Items.Add(itemModel); + } + } + + return model; + }); + } + } +} 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 1434e13cd..baff92208 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 @@ -261,6 +261,7 @@ + @@ -640,6 +641,14 @@ {38197109-8610-4d3f-92b9-16d48df94d7c} Tango.DAL.Remote + + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C} + Tango.DataStore.Editing + + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + {29448f3c-9b3e-4da6-8555-46a8b9a6b3aa} Tango.DataStore.Remote diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs index fd514b7ac..e9d18d777 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs @@ -117,6 +117,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); @@ -160,6 +161,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index ddc0f6cdb..7c8cf4158 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -17,6 +17,7 @@ using Tango.PPC.Common.ExternalBridge; using Tango.Transport; using Tango.Core.ExtensionMethods; using Newtonsoft.Json.Linq; +using Tango.BL; namespace Tango.PPC.Common.DataStore { @@ -132,6 +133,34 @@ namespace Tango.PPC.Common.DataStore }, token); } + [ExternalBridgeRequestHandlerMethod(typeof(RemoteDataStoreGetAllItemsRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task RemoteDataStoreGetAllItemsRequest(RemoteDataStoreGetAllItemsRequest request, String token, ExternalBridgeReceiver receiver) + { + List collections = new List(); + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + var items = db.DataStoreItems.ToList(); + + foreach (var itemsGroup in items.GroupBy(x => x.CollectionName)) + { + RemoteDataStoreCollection collection = new RemoteDataStoreCollection(); + collection.Name = itemsGroup.First().CollectionName; + collections.Add(collection); + + foreach (var item in itemsGroup) + { + collection.Items.Add(CreateRemoteItem(item.ToDataStoreItem())); + } + } + } + + await receiver.SendGenericResponse(new RemoteDataStoreGetAllItemsResponse() + { + Collections = collections + }, token); + } + private RemoteDataStoreItem CreateRemoteItem(IDataStoreItem item) { RemoteDataStoreItem remote = new RemoteDataStoreItem(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index 0a6e57f5d..3d7f11809 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -511,7 +511,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/CustomControl1.cs b/Software/Visual_Studio/Tango.DataStore.Editing/CustomControl1.cs new file mode 100644 index 000000000..fab0127e8 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/CustomControl1.cs @@ -0,0 +1,25 @@ +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.DataStore.Editing +{ + public class CustomControl1 : Control + { + static CustomControl1() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs new file mode 100644 index 000000000..a5c9ba4a7 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; + +namespace Tango.DataStore.Editing +{ + public class DataStoreCollectionModel : ExtendedObject + { + public String Name { get; set; } + public ObservableCollection Items { get; set; } + + public DataStoreCollectionModel() + { + Items = new ObservableCollection(); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs new file mode 100644 index 000000000..36dd44f22 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; + +namespace Tango.DataStore.Editing +{ + public class DataStoreItemModel : ExtendedObject, IDataStoreItem + { + public IDataStoreItem GlobalItem { get; set; } + + private Object _value; + public Object Value + { + get { return _value; } + set { _value = value; RaisePropertyChangedAuto(); EditingValue = value; } + } + + private Object _editingValue; + public Object EditingValue + { + get { return _editingValue; } + set { _editingValue = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasDifference)); } + } + + public bool HasDifference + { + get { return EditingValue != Value || (IsGlobal && GlobalItem.Value != Value); } + } + + public string Guid { get; set; } + public string Key { get; set; } + public DataType Type { get; set; } + public DateTime Date { get; set; } + public bool IsGlobal { get; set; } + public bool IsSynchronized { get; set; } + + public void Apply() + { + Value = EditingValue; + } + + public static DataStoreItemModel FromLocalDataStoreItem(IDataStoreItem local, IDataStoreItem globalItem) + { + DataStoreItemModel model = new DataStoreItemModel(); + + model.Value = local.Value; + model.Guid = local.Guid; + model.Key = local.Key; + model.Type = local.Type; + model.Date = local.Date; + model.IsGlobal = false; + model.IsSynchronized = local.IsSynchronized; + + model.GlobalItem = globalItem; + + return model; + } + + public static DataStoreItemModel FromGlobalDataStoreItem(IDataStoreItem global) + { + DataStoreItemModel model = new DataStoreItemModel(); + + model.GlobalItem = global; + model.Guid = global.Guid; + model.Key = global.Key; + model.Type = global.Type; + model.Date = global.Date; + model.IsGlobal = true; + model.IsSynchronized = global.IsSynchronized; + + return model; + } + + public override string ToString() + { + if (!IsGlobal) + { + return DataStoreHelper.FormatDataStoreItem(this); + } + else + { + return null; + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreModel.cs b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreModel.cs new file mode 100644 index 000000000..a68cc0af9 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; + +namespace Tango.DataStore.Editing +{ + public class DataStoreModel : ExtendedObject + { + public ObservableCollection Collections { get; set; } + + public DataStoreModel() + { + Collections = new ObservableCollection(); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9f04af8ea --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tango.DataStore.Editing")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tango.DataStore.Editing")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.Designer.cs b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.Designer.cs new file mode 100644 index 000000000..c23f8f4eb --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.DataStore.Editing.Properties { + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.DataStore.Editing.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.resx b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.Designer.cs b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.Designer.cs new file mode 100644 index 000000000..28f49dcd4 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.DataStore.Editing.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.settings b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj b/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj new file mode 100644 index 000000000..98df18ac3 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj @@ -0,0 +1,100 @@ + + + + + Debug + AnyCPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C} + library + Tango.DataStore.Editing + Tango.DataStore.Editing + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + Code + + + + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + + + {8491d07b-c1f6-4b62-a412-41b9fd2d6538} + Tango.SharedUI + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Themes/Generic.xaml b/Software/Visual_Studio/Tango.DataStore.Editing/Themes/Generic.xaml new file mode 100644 index 000000000..795842292 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Themes/Generic.xaml @@ -0,0 +1,18 @@ + + + diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreCollection.cs new file mode 100644 index 000000000..e4453fafc --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreCollection.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.Remote +{ + public class RemoteDataStoreCollection + { + public String Name { get; set; } + public List Items { get; set; } + + public RemoteDataStoreCollection() + { + Items = new List(); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsRequest.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsRequest.cs new file mode 100644 index 000000000..a285cd5c1 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.Remote +{ + public class RemoteDataStoreGetAllItemsRequest + { + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsResponse.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsResponse.cs new file mode 100644 index 000000000..3afb22c1e --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetAllItemsResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.Remote +{ + public class RemoteDataStoreGetAllItemsResponse + { + public List Collections { get; set; } + + public RemoteDataStoreGetAllItemsResponse() + { + Collections = new List(); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj b/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj index 4d0d04054..c01607af0 100644 --- a/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj +++ b/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj @@ -50,12 +50,15 @@ GlobalVersionInfo.cs + + + diff --git a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs index 96a905120..7167648b4 100644 --- a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs +++ b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs @@ -95,11 +95,11 @@ namespace Tango.DataStore } else if (item.Type == DataType.Proto) { - return (item.Value as DataStoreProtoObject).Message.ToJsonString(); + return (item.Value as DataStoreProtoObject).Message.ToString(); } else { - return $"{item.Key}: {item.Value}"; + return item.Value.ToStringSafe(); } } } diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index 893e7f945..64f19da67 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -429,6 +429,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.EF", "Tango EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.MachineConfiguration", "FSE\Modules\Tango.FSE.MachineConfiguration\Tango.FSE.MachineConfiguration.csproj", "{15BCB5BB-731E-4E2D-AA28-75485050A8DC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Editing", "Tango.DataStore.Editing\Tango.DataStore.Editing.csproj", "{EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4056,6 +4058,26 @@ Global {15BCB5BB-731E-4E2D-AA28-75485050A8DC}.Release|x64.Build.0 = Release|Any CPU {15BCB5BB-731E-4E2D-AA28-75485050A8DC}.Release|x86.ActiveCfg = Release|Any CPU {15BCB5BB-731E-4E2D-AA28-75485050A8DC}.Release|x86.Build.0 = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|ARM.Build.0 = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|ARM64.Build.0 = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|x64.ActiveCfg = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|x64.Build.0 = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|x86.ActiveCfg = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Debug|x86.Build.0 = Debug|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|Any CPU.Build.0 = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|ARM.ActiveCfg = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|ARM.Build.0 = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|ARM64.ActiveCfg = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|ARM64.Build.0 = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x64.ActiveCfg = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x64.Build.0 = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x86.ActiveCfg = Release|Any CPU + {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4202,12 +4224,12 @@ Global {15BCB5BB-731E-4E2D-AA28-75485050A8DC} = {4EE6DBA1-71BC-49E2-8DC7-266487E61050} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} - BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear - BuildVersion_UpdateAssemblyVersion = True - BuildVersion_UpdateFileVersion = False - BuildVersion_StartDate = 2000/1/1 - BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs BuildVersion_UseGlobalSettings = False + BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs + BuildVersion_StartDate = 2000/1/1 + BuildVersion_UpdateFileVersion = False + BuildVersion_UpdateAssemblyVersion = True + BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear + SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} EndGlobalSection EndGlobal -- cgit v1.3.1 From 14e4bd850fa6730eecd7d15bd7044f364b41c986 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 12 Nov 2020 20:38:57 +0200 Subject: Working on data store view. --- Software/PMR/Messages/Common/MessageType.proto | 2 + .../DataStore/DataStoreItemModifiedRequest.proto | 10 + .../DataStore/DataStoreItemModifiedResponse.proto | 9 + .../Tango.FSE.Firmware_0qifchtm_wpftmp.csproj | 203 ++++++++++++++++ .../Converters/DataStoreValueToStringConverter.cs | 2 +- .../Dialogs/DataStoreItemEditDialogView.xaml | 53 +++++ .../Dialogs/DataStoreItemEditDialogView.xaml.cs | 28 +++ .../Dialogs/DataStoreItemEditDialogViewVM.cs | 173 ++++++++++++++ .../Images/data_collection.png | Bin 0 -> 1963 bytes .../Tango.FSE.MachineConfiguration.csproj | 11 + .../ViewModels/ConfigurationViewVM.cs | 2 + .../ViewModels/DataStoreViewVM.cs | 216 +++++++++++++++-- .../Views/ConfigurationView.xaml | 10 +- .../Views/DataStoreView.xaml | 258 ++++++++++++++++----- .../Views/MachineView.xaml | 6 +- .../Tango.FSE.Procedures/Themes/Generic.xaml | 1 - .../FSE/Tango.FSE.BL/Services/DataStoreService.cs | 2 +- .../Services/MachineConfigurationService.cs | 2 + .../FSE/Tango.FSE.BL/Services/MachinesService.cs | 28 ++- .../DataStore/IDataStoreProvider.cs | 1 + .../Notifications/INotificationProvider.cs | 2 +- .../Tango.FSE.Common/Notifications/InputBoxVM.cs | 38 ++- .../FSE/Tango.FSE.Common/Resources/Styles.xaml | 2 +- .../Controls/NotificationsControl.xaml | 12 +- .../DataStore/DefaultDataStoreProvider.cs | 140 +++++++++++ .../Notifications/DefaultNotificationProvider.cs | 4 +- .../DataStore/DefaultDataStoreService.cs | 75 +++++- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 6 +- .../Connectivity/DefaultConnectivityProvider.cs | 2 +- .../Tango.BL/DTO/DataStoreItemDTOBase.cs | 8 + .../Tango.BL/Entities/DataStoreItemBase.cs | 38 +++ .../ExtensionMethods/StringExtensions.cs | 5 + .../Tango.DAL.Remote/DB/DATA_STORE_ITEMS.cs | 1 + .../Tango.DAL.Remote/DB/RemoteADO.edmx | 3 + .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 146 ++++++------ .../DataStoreCollectionModel.cs | 1 + .../Tango.DataStore.Editing/DataStoreItemModel.cs | 53 ++++- .../Tango.DataStore.Editing.csproj | 6 + .../UpdateDataStoreRequest.cs | 21 ++ .../UpdateDataStoreResponse.cs | 13 ++ .../Tango.DataStore/DataStoreHelper.cs | 72 +++++- .../Tango.DataStore/DataStoreProtoObject.cs | 6 + .../Visual_Studio/Tango.PMR/Common/MessageType.cs | 9 +- .../DataStore/DataStoreItemModifiedRequest.cs | 188 +++++++++++++++ .../DataStore/DataStoreItemModifiedResponse.cs | 131 +++++++++++ Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj | 4 +- .../Tango.SharedUI/Controls/SearchComboBox.cs | 24 +- .../Converters/EnumToItemsSourceConverter.cs | 13 +- .../Controllers/PPCController.cs | 11 +- .../Properties/AssemblyInfo.cs | 2 +- 50 files changed, 1852 insertions(+), 201 deletions(-) create mode 100644 Software/PMR/Messages/DataStore/DataStoreItemModifiedRequest.proto create mode 100644 Software/PMR/Messages/DataStore/DataStoreItemModifiedResponse.proto create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreRequest.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreResponse.cs create mode 100644 Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedRequest.cs create mode 100644 Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedResponse.cs (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels') diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto index e8ad94156..4fe8a5e6f 100644 --- a/Software/PMR/Messages/Common/MessageType.proto +++ b/Software/PMR/Messages/Common/MessageType.proto @@ -313,4 +313,6 @@ enum MessageType PutDataStoreItemResponse = 13001; GetDataStoreItemRequest = 13002; GetDataStoreItemResponse = 13003; + DataStoreItemModifiedRequest = 13004; + DataStoreItemModifiedResponse = 13005; } diff --git a/Software/PMR/Messages/DataStore/DataStoreItemModifiedRequest.proto b/Software/PMR/Messages/DataStore/DataStoreItemModifiedRequest.proto new file mode 100644 index 000000000..c86d9e016 --- /dev/null +++ b/Software/PMR/Messages/DataStore/DataStoreItemModifiedRequest.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package Tango.PMR.DataStore; +option java_package = "com.twine.tango.pmr.datastore"; + +message DataStoreItemModifiedRequest +{ + string Collection = 1; + string Key = 2; +} \ No newline at end of file diff --git a/Software/PMR/Messages/DataStore/DataStoreItemModifiedResponse.proto b/Software/PMR/Messages/DataStore/DataStoreItemModifiedResponse.proto new file mode 100644 index 000000000..d6a597fb5 --- /dev/null +++ b/Software/PMR/Messages/DataStore/DataStoreItemModifiedResponse.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Tango.PMR.DataStore; +option java_package = "com.twine.tango.pmr.datastore"; + +message DataStoreItemModifiedResponse +{ + +} \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj new file mode 100644 index 000000000..8708fb9b0 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj @@ -0,0 +1,203 @@ + + + + + Debug + AnyCPU + {7CB96D74-8B71-4A81-B4E1-6DE7BFCA6174} + library + Tango.FSE.Firmware + Tango.FSE.Firmware + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + + + true + full + false + ..\..\..\Build\FSE\Debug\ + DEBUG;TRACE + prompt + 4 + Off + + + pdbonly + true + ..\..\..\Build\FSE\Release\ + TRACE + prompt + 4 + + + + + + + FirmwareUpdateView.xaml + + + + + + + + + + + FileSystemView.xaml + + + LogsView.xaml + + + MainView.xaml + + + UpdatesView.xaml + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {208C8BD8-72C6-4E3C-ACAA-351091A2ACC7} + Tango.PPC.Shared + + + {bb2abb74-ba58-4812-83aa-ec8171f42df4} + Tango.AutoComplete + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {c6ebbbbe-2123-44dc-aef7-a0d47d736ac0} + Tango.FileSystem + + + {4206ac58-3b57-4699-8835-90bf6db01a61} + Tango.Integration + + + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} + Tango.Logging + + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + + + {d8f1ad85-526a-4f50-b6dc-d437af63d8d8} + Tango.Settings + + + {8491d07b-c1f6-4b62-a412-41b9fd2d6538} + Tango.SharedUI + + + {74e700b0-1156-4126-be40-ee450d3c3026} + Tango.Transport + + + {834c81c3-09b5-45d7-be12-e7d1e6655a7c} + Tango.FSE.BL + + + {bc37cccb-7392-4f78-8d1c-e9629e6e046e} + Tango.FSE.Common + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs index 6b3c8e28c..4acf7fd8e 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs @@ -17,7 +17,7 @@ namespace Tango.FSE.MachineConfiguration.Converters { if (item != null) { - return DataStoreHelper.FormatDataStoreItem(item); + return DataStoreHelper.FormatDataStoreItem(item).ToOneLine().Ellipsis(100); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml new file mode 100644 index 000000000..2fd3b9cdf --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml @@ -0,0 +1,53 @@ + + + + + + + + + + + + Data Type + + + + + + + + + Message Type + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs new file mode 100644 index 000000000..b0f741759 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.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.MachineConfiguration.Dialogs +{ + /// + /// Interaction logic for DataStoreItemEditDialogView.xaml + /// + public partial class DataStoreItemEditDialogView : UserControl + { + public DataStoreItemEditDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs new file mode 100644 index 000000000..29ec03942 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Core.ExtensionMethods; +using Tango.Core.Helpers; +using Tango.DataStore; +using Tango.DataStore.Editing; +using Tango.FSE.Common; +using Tango.FSE.Common.Storage; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.FSE.MachineConfiguration.Dialogs +{ + public class DataStoreItemEditDialogViewVM : FSEDialogViewVM + { + private const int MAX_FILE_SIZE_KB = 100; + + [TangoInject] + private IStorageProvider StorageProvider { get; set; } + + [TangoInject] + private Common.Notifications.INotificationProvider NotificationProvider { get; set; } + + private DataStoreItemModel _item; + public DataStoreItemModel Item + { + get { return _item; } + set + { + _item = value; + RaisePropertyChangedAuto(); + + if (_item.IsGlobal) + { + Value = _item.GlobalItem.Value; + } + else + { + Value = _item.Value; + } + + Type = _item.Type; + + if (Type == DataType.Proto) + { + ProtoMessageType = (Value as DataStoreProtoObject).MessageType; + } + + if (_item.IsGlobal) + { + EditingValue = _item.GlobalItem.ToString(); + } + else + { + EditingValue = _item.ToString(); + } + } + } + + public bool EnableTypeChange { get; set; } + + private Object _value; + public Object Value + { + get { return _value; } + set { _value = value; RaisePropertyChangedAuto(); } + } + + private DataType _type; + public DataType Type + { + get { return _type; } + set { _type = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private MessageType _protoMessageType; + public MessageType ProtoMessageType + { + get { return _protoMessageType; } + set { _protoMessageType = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private String _editingValue; + public String EditingValue + { + get { return _editingValue; } + set { _editingValue = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private String _error; + public String Error + { + get { return _error; } + set { _error = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasError)); InvalidateRelayCommands(); } + } + + public bool HasError + { + get { return Error != null; } + } + + public RelayCommand LoadFileCommand { get; set; } + + public RelayCommand InitProtoCommand { get; set; } + + public DataStoreItemEditDialogViewVM() + { + EnableTypeChange = true; + LoadFileCommand = new RelayCommand(LoadFile); + InitProtoCommand = new RelayCommand(InitProto); + TangoIOC.Default.Inject(this); + } + + private void InitProto() + { + if (Type == DataType.Proto) + { + var type = MessageFactory.GetPMRTypeFromMessageType(ProtoMessageType); + var instance = Activator.CreateInstance(type); + EditingValue = instance.ToJsonString(); + } + } + + private async void LoadFile() + { + if (Type == DataType.Bytes) + { + var result = await StorageProvider.OpenFile("Load a file"); + if (result) + { + if ((new FileInfo(result.SelectedItem).Length / 1024) > MAX_FILE_SIZE_KB) + { + await NotificationProvider.ShowError($"The selected file size exceeds the maximum {MAX_FILE_SIZE_KB}kb allowed."); + return; + } + + var bytes = File.ReadAllBytes(result.SelectedItem); + Value = bytes; + _editingValue = DataStoreHelper.GetByteArrayHexString(bytes); + RaisePropertyChanged(nameof(EditingValue)); + } + } + } + + private void OnEditingValueChanged() + { + if (EditingValue != null) + { + try + { + Value = DataStoreHelper.ParseDataStoreValue(Type, EditingValue, ProtoMessageType); + Error = null; + } + catch (Exception ex) + { + Error = ex.Message; + } + } + } + + protected override bool CanOK() + { + return base.CanOK() && !HasError; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png new file mode 100644 index 000000000..95163a226 Binary files /dev/null and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj index af67b0d74..2e876db16 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj @@ -80,6 +80,10 @@ + + DataStoreItemEditDialogView.xaml + + @@ -198,6 +202,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -222,6 +230,9 @@ + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs index 63e3f22d9..61eef2bdc 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs @@ -44,6 +44,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels using (NotificationProvider.PushTaskItem("Loading machine configuration...")) { EditingComposition = msg.EditingComposition; + EditingComposition.Machine.ForceVersionUpdateChanged += (x, value) => { if (value) EditingComposition.Machine.SuspendVersionUpdate = false; }; + EditingComposition.Machine.SuspendVersionUpdateChanged += (x, value) => { if (value) EditingComposition.Machine.ForceVersionUpdate = false; }; } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs index 4a75c137b..76aee9cde 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -1,12 +1,17 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Data; +using Tango.Core.Commands; using Tango.Core.DI; +using Tango.DataStore; using Tango.DataStore.Editing; using Tango.FSE.Common; using Tango.FSE.Common.DataStore; +using Tango.FSE.MachineConfiguration.Dialogs; using Tango.FSE.MachineConfiguration.Messages; using static Tango.SharedUI.Controls.NavigationControl; @@ -15,6 +20,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public class DataStoreViewVM : FSEViewModel, INavigationViewModel { private String machineGuid; + private ICollectionView _selectedCollectionView; + private ICollectionView _collectionsView; [TangoInject] private IDataStoreProvider DataStoreProvider { get; set; } @@ -30,7 +37,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public DataStoreCollectionModel SelectedCollection { get { return _selectedCollection; } - set { _selectedCollection = value; RaisePropertyChangedAuto(); } + set { _selectedCollection = value; RaisePropertyChangedAuto(); OnSelectedCollectionChanged(); } } private DataStoreItemModel _selectedItem; @@ -40,16 +47,134 @@ namespace Tango.FSE.MachineConfiguration.ViewModels set { _selectedItem = value; RaisePropertyChangedAuto(); } } - private bool _isLoading; - public bool IsLoading + private String _filter; + public String Filter { - get { return _isLoading; } - set { _isLoading = value; RaisePropertyChangedAuto(); } + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); _selectedCollectionView?.Refresh(); } } + public RelayCommand RemoveItemCommand { get; set; } + public RelayCommand RemoveCollectionCommand { get; set; } + public RelayCommand AddItemCommand { get; set; } + public RelayCommand AddCollectionCommand { get; set; } + public RelayCommand EditItemCommand { get; set; } + public RelayCommand SaveCommand { get; set; } + public RelayCommand ReloadCommand { get; set; } + public DataStoreViewVM() { RegisterForMessage(OnEditingCompositionLoaded); + RemoveItemCommand = new RelayCommand(RemoveItem); + RemoveCollectionCommand = new RelayCommand(RemoveCollection); + AddItemCommand = new RelayCommand(AddItem); + AddCollectionCommand = new RelayCommand(AddCollection); + EditItemCommand = new RelayCommand(EditItem); + SaveCommand = new RelayCommand(SaveModel); + ReloadCommand = new RelayCommand(ReloadDataStore); + } + + private async void ReloadDataStore() + { + if (DataStore != null) + { + if (DataStore.Collections.SelectMany(x => x.Items).Any(x => x.HasDifference)) + { + if (!await NotificationProvider.ShowWarningQuestion("Reloading the data store will discard all the current changes. Are you sure?", "RELOAD")) + { + return; + } + } + } + + await LoadDataStore(); + } + + private async void EditItem(DataStoreItemModel item) + { + var vm = await NotificationProvider.ShowDialog(new DataStoreItemEditDialogViewVM() { Item = item, EnableTypeChange = !item.IsGlobal }); + + if (vm.DialogResult) + { + item.IsDeleted = false; + item.IsGlobal = false; + item.Type = vm.Type; + item.Value = vm.Value; + } + } + + private async void AddCollection() + { + var result = await NotificationProvider.ShowInputBox("Add Collection", "Please enter the collection name", MaterialDesignThemes.Wpf.PackIconKind.Collection, null, null, 20, null, null, (input) => + { + if (DataStore.Collections.ToList().Exists(x => x.Name.ToLower() == input.ToLower())) + { + return "The specified collection already exists."; + } + + return null; + }); + + if (result.Confirmed) + { + if (DataStore.Collections.ToList().Exists(x => x.Name.ToLower() == result.Input.ToLower())) + { + await NotificationProvider.ShowError("The specified collection already exists."); + AddCollection(); + return; + } + + DataStore.Collections.Add(new DataStoreCollectionModel() + { + Name = result.Input + }); + + SelectedCollection = DataStore.Collections.Last(); + } + } + + private async void AddItem() + { + var result = await NotificationProvider.ShowInputBox("Add Item", "Please enter the item key", MaterialDesignThemes.Wpf.PackIconKind.KeyAdd, null, null, 20, null, null, (input) => + { + if (SelectedCollection.Items.ToList().Exists(x => x.Key.ToLower() == input.ToLower())) + { + return "The specified key already exists in the collection."; + } + + return null; + }); + + if (result.Confirmed) + { + if (SelectedCollection.Items.ToList().Exists(x => x.Key == result.Input)) + { + await NotificationProvider.ShowError("The specified key already exists in the collection."); + AddItem(); + return; + } + + SelectedCollection.Items.Add(new DataStoreItemModel() + { + Date = DateTime.UtcNow, + Guid = Guid.NewGuid().ToString(), + Key = result.Input, + Type = DataType.Int32, + Value = 10 + }); + } + } + + private void RemoveCollection(DataStoreCollectionModel collection) + { + collection.IsDeleted = true; + _collectionsView?.Refresh(); + } + + private void RemoveItem(DataStoreItemModel item) + { + item.IsDeleted = true; + _selectedCollectionView.Refresh(); } private void OnEditingCompositionLoaded(EditingCompositionLoadedMessage obj) @@ -58,28 +183,87 @@ namespace Tango.FSE.MachineConfiguration.ViewModels machineGuid = obj.EditingComposition.Machine.Guid; } - public async override void OnNavigatedTo() + private void OnSelectedCollectionChanged() { - base.OnNavigatedTo(); + if (SelectedCollection != null) + { + _selectedCollectionView = CollectionViewSource.GetDefaultView(SelectedCollection.Items); + _selectedCollectionView.Filter = (x) => FilterItems(x as DataStoreItemModel); + _selectedCollectionView.Refresh(); + } + } - if (DataStore == null) + private bool FilterItems(DataStoreItemModel itemModel) + { + return (!itemModel.IsDeleted || itemModel.GlobalItem != null) && (String.IsNullOrWhiteSpace(Filter) || itemModel.Key.ToLower().Contains(Filter.ToLower())); + } + + private async void SaveModel() + { + try { - try + using (NotificationProvider.PushTaskItem("Updating data store...")) { - IsLoading = true; - IsFree = false; - DataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + await DataStoreProvider.UpdateDataStoreModel(DataStore, machineGuid); } - catch (Exception ex) + + if (MachineProvider.IsPPCAvailable) { - LogManager.Log(ex, "Error loading data store."); + await NotificationProvider.ShowSuccess("The connected machine is now synchronized with the data store."); } - finally + else { - IsLoading = false; + await NotificationProvider.ShowInfo("Data store save successfully.\nThe machine will be updated on the next synchronization pass."); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving data store."); + await NotificationProvider.ShowError($"Error occurred while trying to save the data store.\n{ex.FlattenMessage()}"); + return; + } + + await LoadDataStore(); + } + + private async Task LoadDataStore() + { + try + { + using (NotificationProvider.PushTaskItem("Loading data store...")) + { + IsFree = false; + var dataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + + _collectionsView = CollectionViewSource.GetDefaultView(dataStore.Collections); + _collectionsView.Filter = (x) => { return !(x as DataStoreCollectionModel).IsDeleted; }; + _collectionsView.Refresh(); + + DataStore = dataStore; + SelectedCollection = DataStore.Collections.FirstOrDefault(); + IsFree = true; } } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading data store."); + if (await NotificationProvider.ShowWarningQuestion($"Error occurred while trying to load the data store.\n{ex.FlattenMessage()}", "RETRY", "CANCEL")) + { + await LoadDataStore(); + return; + } + } + } + + public async override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (DataStore == null) + { + await LoadDataStore(); + } } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml index 9c8b2d878..ed24c3a67 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml @@ -114,18 +114,18 @@ - - - Perform Firmware Upgrade + + + Disable Firmware Upgrade - + Force Version Update - + Suspend Version Update diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml index f078efcee..f4029e30c 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml @@ -4,7 +4,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.FSE.MachineConfiguration.Views" + xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI" xmlns:global="clr-namespace:Tango.FSE.MachineConfiguration" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:vm="clr-namespace:Tango.FSE.MachineConfiguration.ViewModels" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" @@ -16,61 +18,213 @@ - - - - - - + + + + + + + + + The data store contains global and local (machine) configuration and calibration parameters. + + Updating the data store parameters will take effect on the next machine cloud synchronization pass. + + If this is the currently connected machine, updating the data store will take effect immediately. + + + + + + + + + + + + Machine is connected, updating the data store will be take effect immediately. + + + + + + + + + + + + + + + + + + + + + + + + + ADD ITEM + + + + + + + + + + + ADD COLLECTION + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml index 9f81f82e4..ca6470db3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml @@ -12,14 +12,14 @@ d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MachineViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MachineViewVM}" d:DesignStyle="{StaticResource FSE_User_Control_Designer}"> - + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml index 3917368f2..0e055d730 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml @@ -635,7 +635,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogView.xaml.cs new file mode 100644 index 000000000..4ee37908c --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogView.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.MachineConfiguration.Dialogs +{ + /// + /// Interaction logic for ImportDialogView.xaml + /// + public partial class ExportDialogView : UserControl + { + public ExportDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogViewVM.cs new file mode 100644 index 000000000..9f605c79e --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ExportDialogViewVM.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.DataStore.Editing; +using Tango.FSE.Common; + +namespace Tango.FSE.MachineConfiguration.Dialogs +{ + public class ExportDialogViewVM : FSEDialogViewVM + { + public DataStoreModel DataStore { get; set; } + + public ExportDialogViewVM() + { + OKText = "EXPORT"; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.xaml new file mode 100644 index 000000000..5d9653eb4 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.xaml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.xaml.cs new file mode 100644 index 000000000..bc729601f --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogView.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.MachineConfiguration.Dialogs +{ + /// + /// Interaction logic for ImportDialogView.xaml + /// + public partial class ImportDialogView : UserControl + { + public ImportDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogViewVM.cs new file mode 100644 index 000000000..a4e53e85b --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/ImportDialogViewVM.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.DataStore.Editing; +using Tango.FSE.Common; + +namespace Tango.FSE.MachineConfiguration.Dialogs +{ + public class ImportDialogViewVM : FSEDialogViewVM + { + public DataStoreModel DataStore { get; set; } + + public ImportDialogViewVM() + { + OKText = "IMPORT"; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Models/CsvModel.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Models/CsvModel.cs new file mode 100644 index 000000000..1e12fda4b --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Models/CsvModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.MachineConfiguration.Models +{ + public class CsvModel + { + public String Date { get; set; } + public String Collection { get; set; } + public String Key { get; set; } + public String Type { get; set; } + public String MessageType { get; set; } + public String Value { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj index 2e876db16..db7b7d12d 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj @@ -84,7 +84,16 @@ DataStoreItemEditDialogView.xaml + + ExportDialogView.xaml + + + ImportDialogView.xaml + + + + @@ -148,6 +157,10 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {58e8825f-0c96-449c-b320-1e82b0aa876b} + Tango.CSV + {ee088ff7-04d1-41fb-9d6a-cedeee7a7b9c} Tango.DataStore.Editing @@ -206,6 +219,14 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -233,6 +254,7 @@ + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs index 76aee9cde..198f1bd9b 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -7,24 +7,30 @@ using System.Threading.Tasks; using System.Windows.Data; using Tango.Core.Commands; using Tango.Core.DI; +using Tango.CSV; using Tango.DataStore; using Tango.DataStore.Editing; using Tango.FSE.Common; +using Tango.FSE.Common.Connection; using Tango.FSE.Common.DataStore; +using Tango.FSE.Common.Notifications; using Tango.FSE.MachineConfiguration.Dialogs; using Tango.FSE.MachineConfiguration.Messages; +using Tango.FSE.MachineConfiguration.Models; +using static Tango.FSE.BL.Services.MachineConfigurationService; using static Tango.SharedUI.Controls.NavigationControl; namespace Tango.FSE.MachineConfiguration.ViewModels { public class DataStoreViewVM : FSEViewModel, INavigationViewModel { - private String machineGuid; + private String _machineGuid; + private MachineEditingComposition _editingComposition; private ICollectionView _selectedCollectionView; private ICollectionView _collectionsView; [TangoInject] - private IDataStoreProvider DataStoreProvider { get; set; } + public IDataStoreProvider DataStoreProvider { get; set; } private DataStoreModel _dataStore; public DataStoreModel DataStore @@ -54,6 +60,11 @@ namespace Tango.FSE.MachineConfiguration.ViewModels set { _filter = value; RaisePropertyChangedAuto(); _selectedCollectionView?.Refresh(); } } + public bool CanSync + { + get { return MachineProvider.IsPPCAvailable && MachineProvider.Machine != null && _machineGuid == MachineProvider.Machine.Guid; } + } + public RelayCommand RemoveItemCommand { get; set; } public RelayCommand RemoveCollectionCommand { get; set; } public RelayCommand AddItemCommand { get; set; } @@ -61,6 +72,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public RelayCommand EditItemCommand { get; set; } public RelayCommand SaveCommand { get; set; } public RelayCommand ReloadCommand { get; set; } + public RelayCommand ImportCommand { get; set; } + public RelayCommand ExportCommand { get; set; } public DataStoreViewVM() { @@ -72,6 +85,15 @@ namespace Tango.FSE.MachineConfiguration.ViewModels EditItemCommand = new RelayCommand(EditItem); SaveCommand = new RelayCommand(SaveModel); ReloadCommand = new RelayCommand(ReloadDataStore); + ExportCommand = new RelayCommand(ExportDataStore); + ImportCommand = new RelayCommand(ImportDataStore); + } + + [TangoInject] + public DataStoreViewVM(IMachineProvider machineProvider) : this() + { + machineProvider.MachineConnected += (_, __) => RaisePropertyChanged(nameof(CanSync)); + machineProvider.MachineDisconnected += (_, __) => RaisePropertyChanged(nameof(CanSync)); } private async void ReloadDataStore() @@ -180,7 +202,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels private void OnEditingCompositionLoaded(EditingCompositionLoadedMessage obj) { DataStore = null; - machineGuid = obj.EditingComposition.Machine.Guid; + _editingComposition = obj.EditingComposition; + _machineGuid = obj.EditingComposition.Machine.Guid; } private void OnSelectedCollectionChanged() @@ -204,7 +227,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels { using (NotificationProvider.PushTaskItem("Updating data store...")) { - await DataStoreProvider.UpdateDataStoreModel(DataStore, machineGuid); + await DataStoreProvider.UpdateDataStoreModel(DataStore, _machineGuid); } if (MachineProvider.IsPPCAvailable) @@ -213,7 +236,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels } else { - await NotificationProvider.ShowInfo("Data store save successfully.\nThe machine will be updated on the next synchronization pass."); + await NotificationProvider.ShowSuccess("Data store saved successfully.\nThe machine will be updated on the next synchronization pass."); } } catch (Exception ex) @@ -233,7 +256,9 @@ namespace Tango.FSE.MachineConfiguration.ViewModels using (NotificationProvider.PushTaskItem("Loading data store...")) { IsFree = false; - var dataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + RaisePropertyChanged(nameof(CanSync)); + + var dataStore = await DataStoreProvider.GetDataStoreModel(_machineGuid); _collectionsView = CollectionViewSource.GetDefaultView(dataStore.Collections); _collectionsView.Filter = (x) => { return !(x as DataStoreCollectionModel).IsDeleted; }; @@ -265,5 +290,176 @@ namespace Tango.FSE.MachineConfiguration.ViewModels await LoadDataStore(); } } + + private async void ImportDataStore() + { + var result = await StorageProvider.OpenFile("Import data store", "CSV Files|*.csv"); + + if (result) + { + try + { + DataStoreModel model = new DataStoreModel(); + + using (NotificationProvider.PushTaskItem("Analyzing file...")) + { + await Task.Delay(1000); + + await Task.Factory.StartNew(() => + { + var items = CsvFile.Read(new CsvSource(result.SelectedItem)).ToList(); + + foreach (var collection in items.GroupBy(x => x.Collection)) + { + DataStoreCollectionModel collectionModel = new DataStoreCollectionModel(); + + collectionModel = new DataStoreCollectionModel(); + collectionModel.Name = collection.First().Collection; + collectionModel.IsSelected = true; + model.Collections.Add(collectionModel); + + foreach (var item in collection) + { + DataStoreItemModel itemModel = new DataStoreItemModel(); + itemModel.Guid = Guid.NewGuid().ToString(); + itemModel.Key = item.Key; + itemModel.Date = DateTime.Parse(item.Date); + itemModel.IsSelected = true; + + DataType type = (DataType)Enum.Parse(typeof(DataType), item.Type); + itemModel.OriginalType = type; + itemModel.Type = type; + + PMR.Common.MessageType? messageType = null; + if (type == DataType.Proto && item.MessageType.IsNotNullOrEmpty()) + { + messageType = (PMR.Common.MessageType)Enum.Parse(typeof(PMR.Common.MessageType), item.MessageType); + } + + itemModel.OriginalValue = DataStoreHelper.ParseDataStoreValue(type, item.Value, messageType); + itemModel.Value = itemModel.OriginalValue; + + collectionModel.Items.Add(itemModel); + } + } + }); + } + + var vm = await NotificationProvider.ShowDialog(new ImportDialogViewVM() { DataStore = model }); + + if (vm.DialogResult) + { + if (!vm.DataStore.Collections.SelectMany(x => x.Items).Any(x => x.IsSelected)) + { + await NotificationProvider.ShowInfo("No items selected to import."); + return; + } + + foreach (var collection in vm.DataStore.Collections.Where(x => x.Items.Any(y => y.IsSelected))) + { + var collectionModel = DataStore.Collections.FirstOrDefault(x => x.Name == collection.Name); + + if (collectionModel == null) + { + DataStore.Collections.Add(collection); + } + else + { + foreach (var item in collection.Items.Where(x => x.IsSelected)) + { + var itemModel = collectionModel.Items.FirstOrDefault(x => x.Key == item.Key); + + if (itemModel == null) + { + itemModel = new DataStoreItemModel(); + itemModel.Guid = item.Guid; + itemModel.Key = item.Key; + collectionModel.Items.Add(itemModel); + } + + itemModel.Date = DateTime.UtcNow; + itemModel.IsDeleted = false; + itemModel.IsGlobal = false; + itemModel.Type = item.Type; + itemModel.Value = item.Value; + } + } + } + + await NotificationProvider.ShowSuccess("Data store imported successfully."); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error importing data store."); + await NotificationProvider.ShowError($"Error importing the data store.\n{ex.FlattenMessage()}"); + } + } + } + + private async void ExportDataStore() + { + var vm = await NotificationProvider.ShowDialog(new ExportDialogViewVM() { DataStore = DataStore }); + + if (vm.DialogResult) + { + if (!vm.DataStore.Collections.SelectMany(x => x.Items).Any(x => x.IsSelected)) + { + await NotificationProvider.ShowInfo("No items selected to export."); + return; + } + + var result = await StorageProvider.SaveFile("Export data store", "CSV Files|*.csv", $"{_editingComposition.Machine.SerialNumber}_datastore_{DateTime.Now.ToFileName()}.csv", ".csv"); + + if (result) + { + try + { + using (NotificationProvider.PushTaskItem("Exporting data store...")) + { + await Task.Delay(1000); + + await Task.Factory.StartNew(() => + { + using (DynamicCsvFile csvFile = new DynamicCsvFile(result.SelectedItem)) + { + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "Date" }); + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "Collection" }); + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "Key" }); + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "Type" }); + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "MessageType" }); + csvFile.Columns.Add(new DynamicCsvFileColumn() { Name = "Value" }); + + foreach (var collection in DataStore.Collections) + { + foreach (var item in collection.Items.Where(x => x.IsSelected && !x.IsGlobal && x.Value != null)) + { + PMR.Common.MessageType? messageType = null; + + if (item.Type == DataType.Proto) + { + messageType = (item.Value as DataStoreProtoObject).MessageType; + } + + csvFile.Append(item.Date, $"\"{collection.Name}\"", $"\"{item.Key}\"", item.Type, messageType.ToStringSafe(), $"\"{item.FormattedValue.Replace("\"", "\"\"")}\""); + } + } + } + }); + } + + NotificationProvider.PushSnackbarItem(MessageType.Success, "Export Data Store", true, "Data store exported successfully.", TimeSpan.FromSeconds(8), null, () => + { + StorageProvider.ShowInExplorer(result.SelectedItem); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting data store."); + await NotificationProvider.ShowError($"Error exporting the data store.\n{ex.FlattenMessage()}"); + } + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml index f4029e30c..52a140c81 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml @@ -22,7 +22,7 @@ - + @@ -34,13 +34,22 @@ + + + + Accept Real-Time Firmware Updates + + + + + - + Machine is connected, updating the data store will be take effect immediately. @@ -67,7 +76,7 @@