aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorAvi Levkovich <avi@twine-s.com>2020-02-17 17:00:29 +0200
committerAvi Levkovich <avi@twine-s.com>2020-02-17 17:00:29 +0200
commitcbc80e71fac7d2896ac496b0fbf22051c0cdcff7 (patch)
tree9f898e565748f5581e900491ca36ce21c6462846 /Software/Visual_Studio
parentef657b4a3ae76e99ab077d6b4fc19691c2a0da4a (diff)
downloadTango-cbc80e71fac7d2896ac496b0fbf22051c0cdcff7.tar.gz
Tango-cbc80e71fac7d2896ac496b0fbf22051c0cdcff7.zip
merge
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/AzureDashboardViewModel.cs12
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml2
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs13
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj8
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModelLocator.cs9
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentFirmwareUpgradeViewVM.cs14
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRemovalViewVM.cs9
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRollbackViewVM.cs86
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentUpgradeViewVM.cs20
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml44
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml.cs28
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/MainView.xaml3
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs30
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs56
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/RollbackEnvironmentConfiguration.cs15
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs34
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj1
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsModule.cs26
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/AssemblyInfo.cs55
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.Designer.cs62
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj123
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModelLocator.cs26
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/MainViewVM.cs17
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml14
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/app.config85
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/App.config85
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/App.xaml11
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/AuthenticationResult.cs16
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/IAuthenticationProvider.cs40
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs86
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleAttribute.cs61
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleBase.cs69
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs56
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs248
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/GatewayClient.cs2693
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/IGatewayService.cs17
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEModule.cs48
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEView.cs16
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Modules/IFSEModuleLoader.cs43
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs28
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs119
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationObjectReceiver.cs21
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationResultProvider.cs28
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/NavigationView.cs21
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppBarItem.cs18
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppButton.cs112
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs229
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/ItemBase.cs82
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageBoxVM.cs22
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageType.cs16
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/NotificationItem.cs73
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/TaskBarItem.cs13
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/AssemblyInfo.cs55
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.Designer.cs62
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml43
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj191
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml44
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Threading/IDispatcherProvider.cs26
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClient.cs29
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClientBase.cs43
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/packages.config9
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/App.config91
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml63
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs18
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Authentication/DefaultAuthenticationProvider.cs170
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs370
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Gateway/DefaultGatewayService.cs36
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml22
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml.cs32
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Modules/DefaultFSEModuleLoader.cs146
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs539
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs547
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DialogAndView.cs45
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/PendingNotification.cs45
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs55
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj218
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Threading/DefaultDispatcherProvider.cs46
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs95
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs17
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs33
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs72
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/MainViewVM.cs19
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml17
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml.cs31
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml14
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml23
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml94
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs31
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config9
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginRequest.cs16
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginResponse.cs18
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Web/Properties/AssemblyInfo.cs36
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj63
-rw-r--r--Software/Visual_Studio/Installers/Nswag/NSwagStudio.msibin0 -> 49216459 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj4
-rw-r--r--Software/Visual_Studio/Notes/Tango.Notes/Nswag/Pre-Build Example.txt1
-rw-r--r--Software/Visual_Studio/Notes/Tango.Notes/Tango.Notes.csproj3
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs (renamed from Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs)0
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj4
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj4
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/TangoWebClientv2CodeFile.cs30
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/Templates/TangoWebClientv2CodeFile.cshtml59
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs5
-rw-r--r--Software/Visual_Studio/Tango.Web/Tango.Web.csproj1
-rw-r--r--Software/Visual_Studio/Tango.Web/TangoWebClientv2.cs125
-rw-r--r--Software/Visual_Studio/Tango.sln177
-rw-r--r--Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs26
-rw-r--r--Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Tango.WebClientGenerator.csproj4
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Controllers/GatewayController.cs28
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/ENVIRONMENT.cs24
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/GatewayDbContext.cs38
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/DTO/EnvironmentConfiguration.cs15
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/GatewayConfig.cs5
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsRequest.cs12
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsResponse.cs17
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Nswag/GatewayClient.nswag140
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Tango.MachineService.Gateway.csproj24
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/Web.config23
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService.Gateway/packages.config1
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs113
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj7
138 files changed, 10085 insertions, 34 deletions
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/AzureDashboardViewModel.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/AzureDashboardViewModel.cs
index eddc7d009..9d3a07b7b 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/AzureDashboardViewModel.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/AzureDashboardViewModel.cs
@@ -27,7 +27,7 @@ namespace Tango.AzureUtils.UI
public virtual void OnApplicationReady()
{
-
+
}
public virtual void OnAuthenticated(IAzure azure, List<IWebAppBase> apps)
@@ -47,6 +47,16 @@ namespace Tango.AzureUtils.UI
}
}
+ protected void RequireRefresh()
+ {
+ TangoIOC.Default.GetAllInstancesByBase<AzureDashboardViewModel>().ToList().ForEach(x => x.OnRefreshRequired());
+ }
+
+ protected virtual void OnRefreshRequired()
+ {
+
+ }
+
public void ProgressHandler(object sender, AzureUtilsProgressEventArgs e)
{
StatusManager.UpdateStatus(e);
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml
index 5adec916a..fe8b4bdef 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml
@@ -63,5 +63,7 @@
<TextBlock Text="{Binding ElementName=control,Path=TangoVersion.FirmwareVersion}"></TextBlock>
</controls:TableGrid>
</StackPanel>
+
+ <ProgressBar VerticalAlignment="Bottom" Height="5" Background="Transparent" BorderThickness="0" Foreground="Silver" IsIndeterminate="{Binding ElementName=control,Path=IsBusy}"></ProgressBar>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs
index f71f236c7..ea7475fb1 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs
@@ -55,6 +55,13 @@ namespace Tango.AzureUtils.UI.Controls
public static readonly DependencyProperty MachineStudioVersionProperty =
DependencyProperty.Register("MachineStudioVersion", typeof(MachineStudioVersion), typeof(WebAppPropertiesControl), new PropertyMetadata(null));
+ public bool IsBusy
+ {
+ get { return (bool)GetValue(IsBusyProperty); }
+ set { SetValue(IsBusyProperty, value); }
+ }
+ public static readonly DependencyProperty IsBusyProperty =
+ DependencyProperty.Register("IsBusy", typeof(bool), typeof(WebAppPropertiesControl), new PropertyMetadata(false));
public WebAppPropertiesControl()
{
@@ -71,6 +78,8 @@ namespace Tango.AzureUtils.UI.Controls
try
{
+ IsBusy = true;
+
HostNames = app.HostNames.Select(x => x).ToList();
Settings = await app.GetMachineServiceSettingsAsync(false);
@@ -81,6 +90,10 @@ namespace Tango.AzureUtils.UI.Controls
MachineStudioVersion = await databaseManager.GetLatestMachineStudioVersion(app);
}
catch { }
+ finally
+ {
+ IsBusy = false;
+ }
}
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj
index 985c54c00..b88b39c6f 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj
@@ -207,9 +207,13 @@
<Compile Include="ViewModels\EnvironmentCreationViewVM.cs" />
<Compile Include="ViewModels\EnvironmentLogStreamViewVM.cs" />
<Compile Include="ViewModels\EnvironmentRemovalViewVM.cs" />
+ <Compile Include="ViewModels\EnvironmentRollbackViewVM.cs" />
<Compile Include="ViewModels\EnvironmentUpgradeViewVM.cs" />
<Compile Include="ViewModels\EnvironmentFirmwareUpgradeViewVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="Views\EnvironmentRollbackView.xaml.cs">
+ <DependentUpon>EnvironmentRollbackView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\EnvironmentCreationView.xaml.cs">
<DependentUpon>EnvironmentCreationView.xaml</DependentUpon>
</Compile>
@@ -252,6 +256,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\EnvironmentRollbackView.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Views\EnvironmentCreationView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModelLocator.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModelLocator.cs
index 4fd7293c9..ef765f93a 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModelLocator.cs
@@ -24,6 +24,7 @@ namespace Tango.AzureUtils.UI
TangoIOC.Default.Register<EnvironmentRemovalViewVM>();
TangoIOC.Default.Register<EnvironmentFirmwareUpgradeViewVM>();
TangoIOC.Default.Register<EnvironmentLogStreamViewVM>();
+ TangoIOC.Default.Register<EnvironmentRollbackViewVM>();
TangoIOC.Default.Register<IStatusManager, DefaultStatusManager>();
}
@@ -76,5 +77,13 @@ namespace Tango.AzureUtils.UI
return TangoIOC.Default.GetInstance<EnvironmentLogStreamViewVM>();
}
}
+
+ public static EnvironmentRollbackViewVM EnvironmentRollbackViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<EnvironmentRollbackViewVM>();
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentFirmwareUpgradeViewVM.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentFirmwareUpgradeViewVM.cs
index 54576cda7..964febbd8 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentFirmwareUpgradeViewVM.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentFirmwareUpgradeViewVM.cs
@@ -94,10 +94,6 @@ namespace Tango.AzureUtils.UI.ViewModels
IsFree = false;
await _firmwareManager.InjectFirmwarePackage(SelectedDeploymentSlot, FilePath);
-
- var old = SelectedDeploymentSlot;
- SelectedDeploymentSlot = null;
- SelectedDeploymentSlot = old;
}
catch (Exception ex)
{
@@ -105,8 +101,18 @@ namespace Tango.AzureUtils.UI.ViewModels
}
finally
{
+ RequireRefresh();
IsFree = true;
}
}
+
+ protected override void OnRefreshRequired()
+ {
+ base.OnRefreshRequired();
+
+ var old = SelectedDeploymentSlot;
+ SelectedDeploymentSlot = null;
+ SelectedDeploymentSlot = old;
+ }
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRemovalViewVM.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRemovalViewVM.cs
index 0917b012d..e296ac16e 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRemovalViewVM.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRemovalViewVM.cs
@@ -77,8 +77,6 @@ namespace Tango.AzureUtils.UI.ViewModels
Config.Password = Settings.Password;
await _environmentManager.RemoveEnvironment(SelectedDeploymentSlot, SlotName, Config);
-
- SelectedDeploymentSlot = null;
}
catch (Exception ex)
{
@@ -86,8 +84,15 @@ namespace Tango.AzureUtils.UI.ViewModels
}
finally
{
+ RequireRefresh();
IsFree = true;
}
}
+
+ protected override void OnRefreshRequired()
+ {
+ base.OnRefreshRequired();
+ SelectedDeploymentSlot = null;
+ }
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRollbackViewVM.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRollbackViewVM.cs
new file mode 100644
index 000000000..69e18b51d
--- /dev/null
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentRollbackViewVM.cs
@@ -0,0 +1,86 @@
+using Microsoft.Azure.Management.AppService.Fluent;
+using Microsoft.Azure.Management.Fluent;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.AzureUtils.Environment;
+using Tango.Core.Commands;
+
+namespace Tango.AzureUtils.UI.ViewModels
+{
+ public class EnvironmentRollbackViewVM : AzureDashboardViewModel
+ {
+ private IWebAppBase _machineServiceApp;
+ private EnvironmentManager _environmentManager;
+
+ private List<IDeploymentSlot> _deploymentSlots;
+ public List<IDeploymentSlot> DeploymentSlots
+ {
+ get { return _deploymentSlots; }
+ set { _deploymentSlots = value; RaisePropertyChangedAuto(); }
+ }
+
+ private IDeploymentSlot _selectedDeploymentSlot;
+ public IDeploymentSlot SelectedDeploymentSlot
+ {
+ get { return _selectedDeploymentSlot; }
+ set { _selectedDeploymentSlot = value; RaisePropertyChangedAuto(); }
+ }
+
+ private RollbackEnvironmentConfiguration _config;
+ public RollbackEnvironmentConfiguration Config
+ {
+ get { return _config; }
+ set { _config = value; RaisePropertyChangedAuto(); }
+ }
+
+ public RelayCommand RollbackEnvironmentCommand { get; set; }
+
+ public EnvironmentRollbackViewVM()
+ {
+ RollbackEnvironmentCommand = new RelayCommand(RollbackEnvironment);
+ Config = new RollbackEnvironmentConfiguration();
+ }
+
+ public override void OnAuthenticated(IAzure azure, List<IWebAppBase> apps)
+ {
+ _machineServiceApp = apps.SingleOrDefault(x => x.Name == "MachineService");
+ DeploymentSlots = apps.OfType<IDeploymentSlot>().Where(x => x.Parent == _machineServiceApp).ToList();
+ SelectedDeploymentSlot = DeploymentSlots.FirstOrDefault();
+
+ _environmentManager = new EnvironmentManager(azure);
+ _environmentManager.ConfirmationRequired += ConfirmationHandler;
+ _environmentManager.Progress += ProgressHandler;
+ }
+
+ private async void RollbackEnvironment()
+ {
+ try
+ {
+ IsFree = false;
+
+ await _environmentManager.RollbackEnvironment(SelectedDeploymentSlot, Config);
+ }
+ catch (Exception ex)
+ {
+ StatusManager.UpdateStatus(ex);
+ }
+ finally
+ {
+ RequireRefresh();
+ IsFree = true;
+ }
+ }
+
+ protected override void OnRefreshRequired()
+ {
+ base.OnRefreshRequired();
+
+ var old = SelectedDeploymentSlot;
+ SelectedDeploymentSlot = null;
+ SelectedDeploymentSlot = old;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentUpgradeViewVM.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentUpgradeViewVM.cs
index 14e4bf196..3f353d54d 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentUpgradeViewVM.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentUpgradeViewVM.cs
@@ -112,13 +112,6 @@ namespace Tango.AzureUtils.UI.ViewModels
{
IsFree = false;
await EnvironmentManager.UpgradeEnvironment(SelectedSourceApp, SelectedTargetApp, Config);
-
- var oldSource = SelectedSourceApp;
- var oldTarget = SelectedTargetApp;
- SelectedSourceApp = null;
- SelectedTargetApp = null;
- SelectedSourceApp = oldSource;
- SelectedTargetApp = oldTarget;
}
catch (Exception ex)
{
@@ -126,8 +119,21 @@ namespace Tango.AzureUtils.UI.ViewModels
}
finally
{
+ RequireRefresh();
IsFree = true;
}
}
+
+ protected override void OnRefreshRequired()
+ {
+ base.OnRefreshRequired();
+
+ var oldSource = SelectedSourceApp;
+ var oldTarget = SelectedTargetApp;
+ SelectedSourceApp = null;
+ SelectedTargetApp = null;
+ SelectedSourceApp = oldSource;
+ SelectedTargetApp = oldTarget;
+ }
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml
new file mode 100644
index 000000000..d3a198e21
--- /dev/null
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml
@@ -0,0 +1,44 @@
+<UserControl x:Class="Tango.AzureUtils.UI.Views.EnvironmentRollbackView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:vm="clr-namespace:Tango.AzureUtils.UI.ViewModels"
+ xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
+ xmlns:global="clr-namespace:Tango.AzureUtils.UI"
+ xmlns:local="clr-namespace:Tango.AzureUtils.UI.Views"
+ xmlns:localControls="clr-namespace:Tango.AzureUtils.UI.Controls"
+ mc:Ignorable="d"
+ d:DesignHeight="700"
+ d:DesignWidth="1100"
+ d:DataContext="{d:DesignInstance Type=vm:EnvironmentRollbackViewVM, IsDesignTimeCreatable=False}"
+ DataContext="{x:Static global:ViewModelLocator.EnvironmentRollbackViewVM}"
+ Background="{StaticResource PrimaryBackgroundBrush}"
+ Foreground="{StaticResource PrimaryForegroundBrush}">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="50*"/>
+ <ColumnDefinition Width="60*"/>
+ </Grid.ColumnDefinitions>
+
+ <GroupBox Header="Source Deployment Slot" Padding="5" Margin="10">
+ <DockPanel>
+ <ComboBox DockPanel.Dock="Top" ItemsSource="{Binding DeploymentSlots}" SelectedItem="{Binding SelectedDeploymentSlot}" DisplayMemberPath="Name"></ComboBox>
+
+ <localControls:WebAppPropertiesControl VerticalAlignment="Top" Margin="0 20 0 0" DataContext="{Binding SelectedDeploymentSlot}" />
+ </DockPanel>
+ </GroupBox>
+
+ <Grid Grid.Column="1">
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
+ <GroupBox DockPanel.Dock="Top" Header="Configuration" Padding="10 20">
+ <StackPanel>
+ <CheckBox Margin="0 5 0 0" IsChecked="{Binding Config.RollbackMachineStudio}" >Rollback Machine Studio Version</CheckBox>
+ <CheckBox Margin="0 5 0 0" IsChecked="{Binding Config.RollbackPPC}" >Rollback PPC Version</CheckBox>
+ </StackPanel>
+ </GroupBox>
+ <Button Margin="0 20 0 0" Padding="20" Command="{Binding RollbackEnvironmentCommand}">ROLLBACK VERSION</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.xaml.cs
new file mode 100644
index 000000000..aa38c19d0
--- /dev/null
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentRollbackView.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.AzureUtils.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for EnvironmentCreationView.xaml
+ /// </summary>
+ public partial class EnvironmentRollbackView : UserControl
+ {
+ public EnvironmentRollbackView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/MainView.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/MainView.xaml
index b79d306d1..aa3623f4b 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/MainView.xaml
@@ -55,6 +55,9 @@
<TabItem Header="Environment Firmware Injection" Padding="5">
<views:EnvironmentFirmwareUpgradeView/>
</TabItem>
+ <TabItem Header="Environment Rollback" Padding="5">
+ <views:EnvironmentRollbackView/>
+ </TabItem>
<TabItem Header="Environment Log Stream" Padding="5">
<views:EnvironmentLogStreamView/>
</TabItem>
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs
index 0c2e56edf..cb1a608a8 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs
@@ -231,6 +231,36 @@ namespace Tango.AzureUtils.Database
}
}
+ public async Task DowngradeMachineStudioVersion(IWebAppBase app)
+ {
+ var latestMachineStudioVersion = await GetLatestMachineStudioVersion(app);
+ var dataSource = (await app.GetMachineServiceSettingsAsync()).ToDataSource();
+
+ OnProgress(AzureUtilsStage.Database, $"Removing machine studio database entry for version '{latestMachineStudioVersion.Version}'...");
+
+ using (var db = ObservablesContext.CreateDefault(dataSource))
+ {
+ var latest = await db.MachineStudioVersions.SingleOrDefaultAsync(x => x.Guid == latestMachineStudioVersion.Guid);
+ db.MachineStudioVersions.Remove(latest);
+ await db.SaveChangesAsync();
+ }
+ }
+
+ public async Task DowngradePPCVersion(IWebAppBase app)
+ {
+ var latestPPCVersion = await GetLatestPPCVersion(app);
+ var dataSource = (await app.GetMachineServiceSettingsAsync()).ToDataSource();
+
+ OnProgress(AzureUtilsStage.Database, $"Removing PPC database entry for version '{latestPPCVersion.Version}'...");
+
+ using (var db = ObservablesContext.CreateDefault(dataSource))
+ {
+ var latest = await db.TangoVersions.SingleOrDefaultAsync(x => x.Guid == latestPPCVersion.Guid);
+ db.TangoVersions.Remove(latest);
+ await db.SaveChangesAsync();
+ }
+ }
+
public async Task<MachineStudioVersion> GetLatestMachineStudioVersion(IWebAppBase app)
{
OnProgress(AzureUtilsStage.Database, $"Getting latest machine studio version on '{app.Name}'...");
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
index 83b0c29ee..53665a73d 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
@@ -453,5 +453,61 @@ namespace Tango.AzureUtils.Environment
}
#endregion
+
+ #region Rollback
+
+ public async Task RollbackEnvironment(IWebAppBase app, RollbackEnvironmentConfiguration config)
+ {
+ OnProgress(AzureUtilsStage.Environment, $"Retrieving settings for '{app.Name}'...");
+
+ var settings = await app.GetMachineServiceSettingsAsync();
+ await _storageManager.Connect(settings.STORAGE_ACCOUNT);
+
+ if (config.RollbackMachineStudio)
+ {
+ try
+ {
+ await _storageManager.DowngradeMachineStudioStorage(app);
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error occurred while trying to remove machine studio storage blobs.\n{ex.FlattenMessage()}\nDo you wish to continue?");
+ }
+
+ try
+ {
+ await _databaseManager.DowngradeMachineStudioVersion(app);
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error occurred while trying to remove machine studio database version.\n{ex.FlattenMessage()}\nDo you wish to continue?");
+ }
+ }
+
+ if (config.RollbackPPC)
+ {
+ try
+ {
+ await _storageManager.DowngradePPCStorage(app);
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error occurred while trying to remove PPC storage blobs.\n{ex.FlattenMessage()}\nDo you wish to continue?");
+ }
+
+ try
+ {
+ await _databaseManager.DowngradePPCVersion(app);
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error occurred while trying to remove PPC database version.\n{ex.FlattenMessage()}\nDo you wish to continue?");
+ }
+ }
+
+ OnCompleted("Environment rollback completed successfully.");
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/RollbackEnvironmentConfiguration.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/RollbackEnvironmentConfiguration.cs
new file mode 100644
index 000000000..da0f68aac
--- /dev/null
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/RollbackEnvironmentConfiguration.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.AzureUtils.Environment
+{
+ public class RollbackEnvironmentConfiguration
+ {
+ public bool RollbackMachineStudio { get; set; }
+
+ public bool RollbackPPC { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs
index 3551bf4f4..77a0aaf6d 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs
@@ -68,6 +68,14 @@ namespace Tango.AzureUtils.Storage
await container.DeleteAsync();
}
+ public async Task RemoveBlob(String containerName, String blobName)
+ {
+ OnProgress(AzureUtilsStage.Storage, $"Removing blob '{blobName}'...");
+ var container = _client.GetContainerReference(containerName);
+ var blob = container.GetBlockBlobReference(blobName);
+ await blob.DeleteAsync();
+ }
+
public async Task UpgradePPCStorage(IWebAppBase sourceApp, IWebAppBase targetApp)
{
OnProgress(AzureUtilsStage.Storage, $"Retrieving source and target settings...");
@@ -134,6 +142,32 @@ namespace Tango.AzureUtils.Storage
});
}
+ public async Task DowngradeMachineStudioStorage(IWebAppBase app)
+ {
+ OnProgress(AzureUtilsStage.Storage, $"Retrieving settings...");
+
+ var latestMachineStudioVersion = await _databaseManager.GetLatestMachineStudioVersion(app);
+ var settings = await app.GetMachineServiceSettingsAsync();
+
+ await RemoveBlob(settings.MACHINE_STUDIO_VERSIONS_CONTAINER, latestMachineStudioVersion.BlobName);
+ await RemoveBlob(settings.MACHINE_STUDIO_VERSIONS_CONTAINER, latestMachineStudioVersion.InstallerBlobName);
+
+ OnCompleted("Latest Machine Studio storage blobs removed.");
+ }
+
+ public async Task DowngradePPCStorage(IWebAppBase app)
+ {
+ OnProgress(AzureUtilsStage.Storage, $"Retrieving settings...");
+
+ var latestPPCVersion = await _databaseManager.GetLatestPPCVersion(app);
+ var settings = await app.GetMachineServiceSettingsAsync();
+
+ await RemoveBlob(settings.TANGO_VERSIONS_CONTAINER, latestPPCVersion.BlobName);
+ await RemoveBlob(settings.TANGO_VERSIONS_CONTAINER, latestPPCVersion.InstallerBlobName);
+
+ OnCompleted("Latest PPC storage blobs removed.");
+ }
+
public async Task ValidatePPCStorageUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp)
{
OnProgress(AzureUtilsStage.Validating, "Validating PPC database upgrade...");
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
index 4a8daf233..896c34635 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
@@ -241,6 +241,7 @@
<Compile Include="AzureUtilsProgressEventArgs.cs" />
<Compile Include="AzureUtilsStage.cs" />
<Compile Include="Environment\CreateEnvironmentConfiguration.cs" />
+ <Compile Include="Environment\RollbackEnvironmentConfiguration.cs" />
<Compile Include="Environment\RemoveEnvironmentConfiguration.cs" />
<Compile Include="Environment\EnvironmentSettings.cs" />
<Compile Include="Environment\UpgradeEnvironmentConfiguration.cs" />
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsModule.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsModule.cs
new file mode 100644
index 000000000..786cbb773
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsModule.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+using Tango.FSE.Common;
+using Tango.FSE.Diagnostics.Views;
+
+namespace Tango.FSE.Diagnostics
+{
+ [FSEModule(index: 0, HomeViewName = "MainView")]
+ public class DiagnosticsModule : FSEModuleBase
+ {
+ public override string Name { get; } = "Diagnostics";
+ public override string Description { get; } = "Diagnostics module";
+ public override BitmapSource Image { get; }
+ public override Type MainViewType { get; } = typeof(MainView);
+ public override Tango.BL.Enumerations.Permissions Permission { get; } = BL.Enumerations.Permissions.RunPPC;
+
+ public override void Dispose()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..9bd7d7e19
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/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.FSE.Diagnostics")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tango.FSE.Diagnostics")]
+[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
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>. For example, if you are using US english
+//in your source files, set the <UICulture> 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/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.Designer.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..67455de79
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.Diagnostics.Properties {
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // 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() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [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.FSE.Diagnostics.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [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/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.resx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.Designer.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..db45a4faf
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.Diagnostics.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/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.settings b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj
new file mode 100644
index 000000000..524b2c315
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <RootNamespace>Tango.FSE.Diagnostics</RootNamespace>
+ <AssemblyName>Tango.FSE.Diagnostics</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\Build\FSE\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\..\Build\FSE\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ViewModelLocator.cs" />
+ <Compile Include="DiagnosticsModule.cs" />
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="app.config" />
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj">
+ <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
+ <Name>Tango.BL</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Settings\Tango.Settings.csproj">
+ <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
+ <Name>Tango.Settings</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.FSE.Common\Tango.FSE.Common.csproj">
+ <Project>{bc37cccb-7392-4f78-8d1c-e9629e6e046e}</Project>
+ <Name>Tango.FSE.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModelLocator.cs
new file mode 100644
index 000000000..6cb3edceb
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModelLocator.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.DI;
+using Tango.FSE.Diagnostics.ViewModels;
+
+namespace Tango.FSE.Diagnostics
+{
+ public static class ViewModelLocator
+ {
+ static ViewModelLocator()
+ {
+ TangoIOC.Default.Register<MainViewVM>();
+ }
+
+ public static MainViewVM MainViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<MainViewVM>();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..6e2e888a0
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/MainViewVM.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FSE.Common;
+
+namespace Tango.FSE.Diagnostics.ViewModels
+{
+ public class MainViewVM : FSEViewModel
+ {
+ public override void OnApplicationStarted()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml
new file mode 100644
index 000000000..e04aaeb98
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml
@@ -0,0 +1,14 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Views.MainView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:global="clr-namespace:Tango.FSE.Diagnostics"
+ xmlns:vm="clr-namespace:Tango.FSE.Diagnostics.ViewModels"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
+ <Grid>
+ <TextBlock FontSize="60" HorizontalAlignment="Center" VerticalAlignment="Center">Diagnostics View</TextBlock>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.xaml.cs
new file mode 100644
index 000000000..7ff873fe8
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/MainView.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.Diagnostics.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public MainView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/app.config b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/app.config
new file mode 100644
index 000000000..36bc04f85
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/app.config
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.0.5.0" newVersion="5.0.5.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config
new file mode 100644
index 000000000..b3daf0d6c
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/App.config b/Software/Visual_Studio/FSE/Tango.FSE.Common/App.config
new file mode 100644
index 000000000..a9375f6a2
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/App.config
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.0.5.0" newVersion="5.0.5.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/App.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/App.xaml
new file mode 100644
index 000000000..42b782f1e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/App.xaml
@@ -0,0 +1,11 @@
+<Application x:Class="Tango.PPC.Browser.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Themes/Generic.xaml" />
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/AuthenticationResult.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/AuthenticationResult.cs
new file mode 100644
index 000000000..d72413521
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/AuthenticationResult.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.Web.Messages;
+
+namespace Tango.FSE.Common.Authentication
+{
+ public class AuthenticationResult
+ {
+ public LoginResponse Response { get; set; }
+ public User User { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/IAuthenticationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/IAuthenticationProvider.cs
new file mode 100644
index 000000000..fd51a793c
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authentication/IAuthenticationProvider.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.BL.Entities;
+using Tango.MachineService.Gateway;
+
+namespace Tango.FSE.Common.Authentication
+{
+ /// <summary>
+ /// Represents the user authentication provider responsible for the current logged-in user.
+ /// </summary>
+ public interface IAuthenticationProvider
+ {
+ /// <summary>
+ /// Occurs when the current logged-in user has changed.
+ /// </summary>
+ event EventHandler<User> CurrentUserChanged;
+
+ /// <summary>
+ /// Gets the current logged-in user.
+ /// </summary>
+ User CurrentUser { get; }
+
+ /// <summary>
+ /// Performs a user login by the specified email and password.
+ /// </summary>
+ /// <param name="email">The email.</param>
+ /// <param name="password">The password.</param>
+ /// <param name="environment">The environment.</param>
+ /// <returns></returns>
+ Task<AuthenticationResult> Login(String email, String password, EnvironmentConfiguration environment);
+
+ /// <summary>
+ /// Logs-out the current logged-in user.
+ /// </summary>
+ void LogOut();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs
new file mode 100644
index 000000000..56a95ea70
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+
+namespace Tango.FSE.Common.FSEApplication
+{
+ /// <summary>
+ /// Represents the application manager.
+ /// </summary>
+ public interface IFSEApplicationManager
+ {
+ /// <summary>
+ /// Occurs when the application has started.
+ /// </summary>
+ event EventHandler ApplicationStarted;
+
+ /// <summary>
+ /// Occurs when the application is ready and all modules are views are loaded.
+ /// </summary>
+ event EventHandler ApplicationReady;
+
+ /// <summary>
+ /// Occurs when the main window content has been rendered.
+ /// </summary>
+ event EventHandler ContentRendered;
+
+ /// <summary>
+ /// Occurs when all PPC modules are ready and initialized.
+ /// </summary>
+ event EventHandler ModulesInitialized;
+
+ /// <summary>
+ /// Occurs when the application has encountered an error when initializing.
+ /// </summary>
+ event EventHandler<Exception> ApplicationInitializationError;
+
+ /// <summary>
+ /// Gets a value indicating whether the application is shutting down.
+ /// </summary>
+ bool IsShuttingDown { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether an update has occurred before the application started.
+ /// </summary>
+ bool IsAfterUpdate { get; }
+
+ /// <summary>
+ /// Gets the application startup arguments.
+ /// </summary>
+ List<String> StartupArgs { get; }
+
+ /// <summary>
+ /// Shutdown the application.
+ /// </summary>
+ void ShutDown();
+
+ /// <summary>
+ /// Restarts the application.
+ /// </summary>
+ void Restart();
+
+ /// <summary>
+ /// Gets the application version.
+ /// </summary>
+ Version Version { get; }
+
+ /// <summary>
+ /// Gets the application build date.
+ /// </summary>
+ String BuildDate { get; }
+
+ /// <summary>
+ /// Gets the application startup date.
+ /// </summary>
+ DateTime StartUpDate { get; }
+
+ /// <summary>
+ /// Gets or sets the application folder.
+ /// </summary>
+ String StartPath { get; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleAttribute.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleAttribute.cs
new file mode 100644
index 000000000..6e5f679bd
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleAttribute.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common
+{
+ /// <summary>
+ /// Represents a <see cref="IPPCModule"/> attribute
+ /// </summary>
+ /// <seealso cref="System.Attribute" />
+ [AttributeUsage(AttributeTargets.Class)]
+ public class FSEModuleAttribute : Attribute
+ {
+ /// <summary>
+ /// Gets or sets the module index.
+ /// </summary>
+ public int Index { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the home view.
+ /// </summary>
+ public String HomeViewName { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to dock this module menu item to the bottom..
+ /// </summary>
+ public bool DockToBottom { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PPCModuleAttribute"/> class.
+ /// </summary>
+ /// <param name="index">The module index.</param>
+ public FSEModuleAttribute(int index)
+ {
+ Index = index;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PPCModuleAttribute"/> class.
+ /// </summary>
+ /// <param name="index">The module index.</param>
+ /// <param name="homeViewName">Name of the home view.</param>
+ public FSEModuleAttribute(int index, String homeViewName) : this(index)
+ {
+ HomeViewName = homeViewName;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PPCModuleAttribute"/> class.
+ /// </summary>
+ /// <param name="index">The module index.</param>
+ /// <param name="homeViewName">Name of the home view.</param>
+ public FSEModuleAttribute(int index, String homeViewName, bool dockToBottom) : this(index, homeViewName)
+ {
+ HomeViewName = homeViewName;
+ DockToBottom = dockToBottom;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleBase.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleBase.cs
new file mode 100644
index 000000000..cdbc48bfc
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEModuleBase.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using Tango.Core;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using System.Reflection;
+
+namespace Tango.FSE.Common
+{
+ /// <summary>
+ /// Represents a base class for PPC modules.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.IStudioModule" />
+ public abstract class FSEModuleBase : ExtendedObject, IFSEModule
+ {
+ private bool _isVisibleInMenu = true;
+ /// <summary>
+ /// Gets a value indicating whether this module should be displayed in the application menu.
+ /// </summary>
+ public bool IsVisibleInMenu
+ {
+ get { return _isVisibleInMenu; }
+ protected set { _isVisibleInMenu = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether to dock this module menu item to the bottom.
+ /// </summary>
+ public bool DockToBottom
+ {
+ get { return this.GetType().GetCustomAttribute<FSEModuleAttribute>().DockToBottom; }
+ }
+
+ /// <summary>
+ /// Gets the module name.
+ /// </summary>
+ public abstract string Name { get; }
+
+ /// <summary>
+ /// Gets the module description.
+ /// </summary>
+ public abstract string Description { get; }
+
+ /// <summary>
+ /// Gets the module cover image.
+ /// </summary>
+ public abstract BitmapSource Image { get; }
+
+ /// <summary>
+ /// Gets the module entry point view type.
+ /// </summary>
+ public abstract Type MainViewType { get; }
+
+ /// <summary>
+ /// Gets the permission required to see and load this module.
+ /// </summary>
+ public abstract Permissions Permission { get; }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public abstract void Dispose();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs
new file mode 100644
index 000000000..24a08c55e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Settings;
+
+namespace Tango.FSE.Common
+{
+ public class FSESettings : SettingsBase
+ {
+ public enum WorkingEnvironment
+ {
+ Remote,
+ Local
+ }
+
+ /// <summary>
+ /// Gets or sets the working environment.
+ /// </summary>
+ public WorkingEnvironment Environment { get; set; }
+
+ /// <summary>
+ /// Gets or sets the last login email.
+ /// </summary>
+ public String LastLoginEmail { get; set; }
+
+ /// <summary>
+ /// Gets or sets the last login password.
+ /// </summary>
+ public String LastLoginPassword { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to save the user credentials.
+ /// </summary>
+ public bool RememberMe { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to force the application version update.
+ /// </summary>
+ public bool ForceVersionUpdate { get; set; }
+
+ /// <summary>
+ /// Gets or sets the last environment identifier.
+ /// </summary>
+ public String LastEnvironmentId { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FSESettings"/> class.
+ /// </summary>
+ public FSESettings()
+ {
+ Environment = WorkingEnvironment.Remote;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
new file mode 100644
index 000000000..d277d0bdb
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
@@ -0,0 +1,248 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.BL;
+using Tango.Core.DI;
+using Tango.FSE.Common.Authentication;
+using Tango.FSE.Common.FSEApplication;
+using Tango.FSE.Common.Gateway;
+using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.Notifications;
+using Tango.Settings;
+using Tango.SharedUI;
+using static Tango.SharedUI.Controls.NavigationControl;
+
+namespace Tango.FSE.Common
+{
+ /// <summary>
+ /// Represents a PPC view model base class.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public abstract class FSEViewModel : ViewModel, INavigationBlocker
+ {
+ /// <summary>
+ /// Gets the static observable entities adapter.
+ /// </summary>
+ public ObservablesStaticCollections Adapter
+ {
+ get { return ObservablesStaticCollections.Instance; }
+ }
+
+ /// <summary>
+ /// Gets or sets the application manager.
+ /// </summary>
+ [TangoInject]
+ public IGatewayService GatewayService { get; set; }
+
+ /// <summary>
+ /// Gets or sets the application manager.
+ /// </summary>
+ [TangoInject]
+ public IFSEApplicationManager ApplicationManager { get; set; }
+
+ /// <summary>
+ /// Gets or sets the authentication provider.
+ /// </summary>
+ [TangoInject]
+ public IAuthenticationProvider AuthenticationProvider { get; set; }
+
+ /// <summary>
+ /// Gets or sets the navigation manager.
+ /// </summary>
+ [TangoInject]
+ public INavigationManager NavigationManager { get; set; }
+
+ /// <summary>
+ /// Gets or sets the notification provider.
+ /// </summary>
+ [TangoInject]
+ public INotificationProvider NotificationProvider { get; set; }
+
+ private FSESettings _settings;
+ /// <summary>
+ /// Gets the main PPC settings.
+ /// </summary>
+ public FSESettings Settings
+ {
+ get
+ {
+ if (_settings == null)
+ {
+ _settings = SettingsManager.Default.GetOrCreate<FSESettings>();
+ }
+
+ return _settings;
+ }
+ private set { _settings = value; }
+ }
+
+ private bool _isVisible;
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="PPCViewModel"/> view is visible.
+ /// </summary>
+ public bool IsVisible
+ {
+ get { return _isVisible; }
+ private set { _isVisible = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Called when the application has been started.
+ /// </summary>
+ public abstract void OnApplicationStarted();
+
+ /// <summary>
+ /// Called when the application is shutting down.
+ /// </summary>
+ public virtual void OnApplicationShuttingDown()
+ {
+
+ }
+
+ /// <summary>
+ /// Called when the navigation system has navigated to this VM view.
+ /// </summary>
+ public virtual void OnNavigatedTo()
+ {
+ IsVisible = true;
+ }
+
+ /// <summary>
+ /// Called when the navigation system has navigated to this VM view.
+ /// </summary>
+ /// <param name="fromVM">The view model instance of the previous view model</param>
+ public virtual void OnNavigatedTo(FSEViewModel fromVM)
+ {
+
+ }
+
+ /// <summary>
+ /// Called when the navigation system has navigated from this VM view.
+ /// </summary>
+ public virtual void OnNavigatedFrom()
+ {
+ IsVisible = false;
+ }
+
+ /// <summary>
+ /// Called before the navigation system has navigated to this VM view.
+ /// </summary>
+ public virtual void OnBeforeNavigatedTo()
+ {
+
+ }
+
+ /// <summary>
+ /// Called before the navigation system has navigated from this VM view.
+ /// </summary>
+ public virtual void OnBeforeNavigatedFrom()
+ {
+ IsVisible = false;
+ }
+
+ /// <summary>
+ /// Raises the specified message using the default <see cref="TangoMessenger"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="message">The message.</param>
+ protected void RaiseMessage<T>(T message) where T : class
+ {
+ TangoMessenger.Default.Send<T>(message);
+ }
+
+ /// <summary>
+ /// Raises the specified message using the default <see cref="TangoMessenger"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ protected void RaiseMessage<T>() where T : class
+ {
+ TangoMessenger.Default.Send<T>(Activator.CreateInstance<T>());
+ }
+
+ /// <summary>
+ /// Registers a message handle for the specified message type T.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="handler">The handler.</param>
+ protected void RegisterForMessage<T>(Action<T> handler)
+ {
+ TangoMessenger.Default.Register<T>(handler);
+ }
+
+ /// <summary>
+ /// Called before the navigation system navigates from this object.
+ /// Return false to abort the navigation.
+ /// </summary>
+ /// <returns></returns>
+ public virtual Task<bool> OnNavigateOutRequest()
+ {
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Called before the navigation system navigates back from this object.
+ /// Return false to abort the navigation.
+ /// </summary>
+ /// <returns></returns>
+ public virtual Task<bool> OnNavigateBackRequest()
+ {
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Called when the application is ready and all modules views are loaded.
+ /// </summary>
+ public virtual void OnApplicationReady()
+ {
+
+ }
+ }
+
+ /// <summary>
+ /// Represents a PPC view model base class a View property as an instance of a <see cref="IPPCView"/> contract.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public abstract class FSEViewModel<T> : FSEViewModel where T : IFSEView
+ {
+ private T _view;
+ /// <summary>
+ /// Gets the IPPCView instance.
+ /// </summary>
+ [TangoInject(TangoInjectMode.WhenAvailable)]
+ public T View
+ {
+ get { return _view; }
+ set
+ {
+ _view = value;
+ ViewAttached = true;
+ OnViewAttached();
+ }
+ }
+
+
+ /// <summary>
+ /// Gets a value indicating whether the instance of IPPCView is available.
+ /// </summary>
+ public bool ViewAttached { get; private set; }
+
+ /// <summary>
+ /// Called when the application has been started.
+ /// </summary>
+ public override void OnApplicationStarted()
+ {
+
+ }
+
+ /// <summary>
+ /// Called when the instance of IPPCView is available.
+ /// </summary>
+ public virtual void OnViewAttached()
+ {
+
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/GatewayClient.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/GatewayClient.cs
new file mode 100644
index 000000000..f63ab354b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/GatewayClient.cs
@@ -0,0 +1,2693 @@
+//----------------------
+// <auto-generated>
+// Generated using the NSwag toolchain v13.2.3.0 (NJsonSchema v10.1.5.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
+// </auto-generated>
+//----------------------
+
+#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
+#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
+#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
+#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
+#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
+
+namespace Tango.MachineService.Gateway
+{
+ using System = global::System;
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.2.3.0 (NJsonSchema v10.1.5.0 (Newtonsoft.Json v11.0.0.0))")]
+ public partial class GatewayClient
+ {
+ private string _baseUrl = "";
+ private System.Net.Http.HttpClient _httpClient;
+ private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
+
+ public GatewayClient(string baseUrl, System.Net.Http.HttpClient httpClient)
+ {
+ BaseUrl = baseUrl;
+ _httpClient = httpClient;
+ _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
+ }
+
+ private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
+ {
+ var settings = new Newtonsoft.Json.JsonSerializerSettings();
+ UpdateJsonSerializerSettings(settings);
+ return settings;
+ }
+
+ public string BaseUrl
+ {
+ get { return _baseUrl; }
+ set { _baseUrl = value; }
+ }
+
+ protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
+
+ partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
+ partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
+ partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
+ partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
+
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public System.Threading.Tasks.Task<EnvironmentsResponse> GetEnvironmentsAsync(EnvironmentsRequest request)
+ {
+ return GetEnvironmentsAsync(request, System.Threading.CancellationToken.None);
+ }
+
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public EnvironmentsResponse GetEnvironments(EnvironmentsRequest request)
+ {
+ return System.Threading.Tasks.Task.Run(async () => await GetEnvironmentsAsync(request, System.Threading.CancellationToken.None)).GetAwaiter().GetResult();
+ }
+
+ /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public async System.Threading.Tasks.Task<EnvironmentsResponse> GetEnvironmentsAsync(EnvironmentsRequest request, System.Threading.CancellationToken cancellationToken)
+ {
+ var urlBuilder_ = new System.Text.StringBuilder();
+ urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Gateway/GetEnvironments");
+
+ var client_ = _httpClient;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value));
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ PrepareRequest(client_, request_, urlBuilder_);
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ try
+ {
+ var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = ((int)response_.StatusCode).ToString();
+ if (status_ == "200")
+ {
+ var objectResponse_ = await ReadObjectResponseAsync<EnvironmentsResponse>(response_, headers_).ConfigureAwait(false);
+ return objectResponse_.Object;
+ }
+ else
+ if (status_ != "200" && status_ != "204")
+ {
+ var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
+ }
+
+ return default(EnvironmentsResponse);
+ }
+ finally
+ {
+ if (response_ != null)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ }
+ }
+
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public System.Threading.Tasks.Task<FileResponse> ExecuteAsync(HttpControllerContext context)
+ {
+ return ExecuteAsync(context, System.Threading.CancellationToken.None);
+ }
+
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public FileResponse Execute(HttpControllerContext context)
+ {
+ return System.Threading.Tasks.Task.Run(async () => await ExecuteAsync(context, System.Threading.CancellationToken.None)).GetAwaiter().GetResult();
+ }
+
+ /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
+ /// <exception cref="ApiException">A server side error occurred.</exception>
+ public async System.Threading.Tasks.Task<FileResponse> ExecuteAsync(HttpControllerContext context, System.Threading.CancellationToken cancellationToken)
+ {
+ var urlBuilder_ = new System.Text.StringBuilder();
+ urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Gateway/Execute");
+
+ var client_ = _httpClient;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(context, _settings.Value));
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ PrepareRequest(client_, request_, urlBuilder_);
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ try
+ {
+ var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = ((int)response_.StatusCode).ToString();
+ if (status_ == "200" || status_ == "206")
+ {
+ var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await response_.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ var fileResponse_ = new FileResponse((int)response_.StatusCode, headers_, responseStream_, null, response_);
+ client_ = null; response_ = null; // response and client are disposed by FileResponse
+ return fileResponse_;
+ }
+ else
+ if (status_ != "200" && status_ != "204")
+ {
+ var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
+ }
+
+ return default(FileResponse);
+ }
+ finally
+ {
+ if (response_ != null)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ }
+ }
+
+ protected struct ObjectResponseResult<T>
+ {
+ public ObjectResponseResult(T responseObject, string responseText)
+ {
+ this.Object = responseObject;
+ this.Text = responseText;
+ }
+
+ public T Object { get; }
+
+ public string Text { get; }
+ }
+
+ public bool ReadResponseAsString { get; set; }
+
+ protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
+ {
+ if (response == null || response.Content == null)
+ {
+ return new ObjectResponseResult<T>(default(T), string.Empty);
+ }
+
+ if (ReadResponseAsString)
+ {
+ var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ try
+ {
+ var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
+ return new ObjectResponseResult<T>(typedBody, responseText);
+ }
+ catch (Newtonsoft.Json.JsonException exception)
+ {
+ var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
+ throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
+ }
+ }
+ else
+ {
+ try
+ {
+ using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
+ using (var streamReader = new System.IO.StreamReader(responseStream))
+ using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
+ {
+ var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
+ var typedBody = serializer.Deserialize<T>(jsonTextReader);
+ return new ObjectResponseResult<T>(typedBody, string.Empty);
+ }
+ }
+ catch (Newtonsoft.Json.JsonException exception)
+ {
+ var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
+ throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
+ }
+ }
+ }
+
+ private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
+ {
+ if (value is System.Enum)
+ {
+ string name = System.Enum.GetName(value.GetType(), value);
+ if (name != null)
+ {
+ var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
+ if (field != null)
+ {
+ var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
+ as System.Runtime.Serialization.EnumMemberAttribute;
+ if (attribute != null)
+ {
+ return attribute.Value != null ? attribute.Value : name;
+ }
+ }
+ }
+ }
+ else if (value is bool) {
+ return System.Convert.ToString(value, cultureInfo).ToLowerInvariant();
+ }
+ else if (value is byte[])
+ {
+ return System.Convert.ToBase64String((byte[]) value);
+ }
+ else if (value != null && value.GetType().IsArray)
+ {
+ var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
+ return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
+ }
+
+ return System.Convert.ToString(value, cultureInfo);
+ }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class EnvironmentsResponse
+ {
+ [Newtonsoft.Json.JsonProperty("Environments", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<EnvironmentConfiguration> Environments { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class EnvironmentConfiguration
+ {
+ [Newtonsoft.Json.JsonProperty("ID", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ID { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Description", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Description { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MachineServiceAddress", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string MachineServiceAddress { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class EnvironmentsRequest
+ {
+ [Newtonsoft.Json.JsonProperty("AppSecret", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string AppSecret { get; set; }
+
+
+ }
+
+ /// <summary>Contains information for a single HTTP operation.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpControllerContext
+ {
+ /// <summary>Gets or sets the configuration.</summary>
+ [Newtonsoft.Json.JsonProperty("Configuration", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpConfiguration Configuration { get; set; }
+
+ /// <summary>Gets or sets the controller descriptor.</summary>
+ [Newtonsoft.Json.JsonProperty("ControllerDescriptor", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpControllerDescriptor ControllerDescriptor { get; set; }
+
+ /// <summary>Gets or sets the HTTP controller.</summary>
+ [Newtonsoft.Json.JsonProperty("Controller", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IHttpController Controller { get; set; }
+
+ /// <summary>Gets or sets the request.</summary>
+ [Newtonsoft.Json.JsonProperty("Request", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpRequestMessage Request { get; set; }
+
+ /// <summary>Gets or sets the request context.</summary>
+ [Newtonsoft.Json.JsonProperty("RequestContext", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpRequestContext RequestContext { get; set; }
+
+ /// <summary>Gets or sets the route data.</summary>
+ [Newtonsoft.Json.JsonProperty("RouteData", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IHttpRouteData RouteData { get; set; }
+
+
+ }
+
+ /// <summary>Represents a configuration of HttpServer instances. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpConfiguration
+ {
+ /// <summary>Gets or sets the action that will perform final initialization of the HttpConfiguration instance before it is used to process requests. </summary>
+ [Newtonsoft.Json.JsonProperty("Initializer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ActionOfHttpConfiguration Initializer { get; set; }
+
+ /// <summary>Gets the list of filters that apply to all requests served using this HttpConfiguration instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Filters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<FilterInfo> Filters { get; set; }
+
+ /// <summary>Gets an ordered list of DelegatingHandler instances to be invoked as an HttpRequestMessage travels up the stack and an HttpResponseMessage travels down in stack in return. </summary>
+ [Newtonsoft.Json.JsonProperty("MessageHandlers", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<DelegatingHandler> MessageHandlers { get; set; }
+
+ /// <summary>Gets the HttpRouteCollection associated with this HttpConfiguration instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Routes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<IHttpRoute> Routes { get; set; }
+
+ /// <summary>Gets the properties associated with this instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Properties", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Properties { get; set; }
+
+ /// <summary>Gets the root virtual path.</summary>
+ [Newtonsoft.Json.JsonProperty("VirtualPathRoot", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string VirtualPathRoot { get; set; }
+
+ /// <summary>Gets or sets the dependency resolver associated with thisinstance.</summary>
+ [Newtonsoft.Json.JsonProperty("DependencyResolver", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IDependencyResolver DependencyResolver { get; set; }
+
+ /// <summary>Gets the container of default services associated with this instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Services", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ServicesContainer Services { get; set; }
+
+ /// <summary>Gets the collection of rules for how parameters should be bound.</summary>
+ [Newtonsoft.Json.JsonProperty("ParameterBindingRules", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ParameterBindingRulesCollection ParameterBindingRules { get; set; }
+
+ /// <summary>Gets or sets a value indicating whether error details should be included in error messages.</summary>
+ [Newtonsoft.Json.JsonProperty("IncludeErrorDetailPolicy", Required = Newtonsoft.Json.Required.Always)]
+ public IncludeErrorDetailPolicy IncludeErrorDetailPolicy { get; set; }
+
+ /// <summary>Gets the media-type formatters for this instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Formatters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MediaTypeFormatterCollection Formatters { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ActionOfHttpConfiguration : MulticastDelegate
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MulticastDelegate : Delegate
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class Delegate
+ {
+ [Newtonsoft.Json.JsonProperty("_target", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object _target { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("_methodBase", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object _methodBase { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("_methodPtr", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public IntPtr _methodPtr { get; set; } = new IntPtr();
+
+ [Newtonsoft.Json.JsonProperty("_methodPtrAux", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public IntPtr _methodPtrAux { get; set; } = new IntPtr();
+
+ [Newtonsoft.Json.JsonProperty("Method", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MethodInfo Method { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Target", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object Target { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class IntPtr
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MethodInfo : MethodBase
+ {
+ [Newtonsoft.Json.JsonProperty("MemberType", Required = Newtonsoft.Json.Required.Always)]
+ public MemberTypes MemberType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReturnType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ReturnType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReturnParameter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ParameterInfo ReturnParameter { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum MemberTypes
+ {
+ Constructor = 1,
+
+ Event = 2,
+
+ Field = 4,
+
+ Method = 8,
+
+ Property = 16,
+
+ TypeInfo = 32,
+
+ Custom = 64,
+
+ NestedType = 128,
+
+ All = 191,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ParameterInfo
+ {
+ [Newtonsoft.Json.JsonProperty("ParameterType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ParameterType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HasDefaultValue", Required = Newtonsoft.Json.Required.Always)]
+ public bool HasDefaultValue { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DefaultValue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object DefaultValue { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("RawDefaultValue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object RawDefaultValue { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Position", Required = Newtonsoft.Json.Required.Always)]
+ public int Position { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Attributes", Required = Newtonsoft.Json.Required.Always)]
+ public ParameterAttributes Attributes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Member", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MemberInfo Member { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsIn", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsIn { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsOut", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsOut { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsLcid", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsLcid { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsRetval", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsRetval { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsOptional", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsOptional { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MetadataToken", Required = Newtonsoft.Json.Required.Always)]
+ public int MetadataToken { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CustomAttributes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeData> CustomAttributes { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum ParameterAttributes
+ {
+ None = 0,
+
+ In = 1,
+
+ Out = 2,
+
+ Lcid = 4,
+
+ Retval = 8,
+
+ Optional = 16,
+
+ HasDefault = 4096,
+
+ HasFieldMarshal = 8192,
+
+ Reserved3 = 16384,
+
+ Reserved4 = 32768,
+
+ ReservedMask = 61440,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MemberInfo
+ {
+ [Newtonsoft.Json.JsonProperty("CustomAttributes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeData> CustomAttributes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MetadataToken", Required = Newtonsoft.Json.Required.Always)]
+ public int MetadataToken { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Module", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Module Module { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class CustomAttributeData
+ {
+ [Newtonsoft.Json.JsonProperty("AttributeType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string AttributeType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Constructor", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ConstructorInfo Constructor { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ConstructorArguments", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeTypedArgument> ConstructorArguments { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NamedArguments", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeNamedArgument> NamedArguments { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class ConstructorInfo : MethodBase
+ {
+ [Newtonsoft.Json.JsonProperty("MemberType", Required = Newtonsoft.Json.Required.Always)]
+ public MemberTypes MemberType { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MethodBase : MemberInfo
+ {
+ [Newtonsoft.Json.JsonProperty("MethodImplementationFlags", Required = Newtonsoft.Json.Required.Always)]
+ public MethodImplAttributes MethodImplementationFlags { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CallingConvention", Required = Newtonsoft.Json.Required.Always)]
+ public CallingConventions CallingConvention { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsGenericMethodDefinition", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsGenericMethodDefinition { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContainsGenericParameters", Required = Newtonsoft.Json.Required.Always)]
+ public bool ContainsGenericParameters { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsGenericMethod", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsGenericMethod { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsSecurityCritical", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsSecurityCritical { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsSecuritySafeCritical", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsSecuritySafeCritical { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsSecurityTransparent", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsSecurityTransparent { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsPublic", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsPublic { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsPrivate", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsPrivate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsFamily", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsFamily { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsAssembly", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsAssembly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsFamilyAndAssembly", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsFamilyAndAssembly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsFamilyOrAssembly", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsFamilyOrAssembly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsStatic", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsStatic { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsFinal", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsFinal { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsVirtual", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsVirtual { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsHideBySig", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsHideBySig { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsAbstract", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsAbstract { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsSpecialName", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsSpecialName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsConstructor", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsConstructor { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum MethodImplAttributes
+ {
+ IL = 0,
+
+ Managed = 0,
+
+ Native = 1,
+
+ OPTIL = 2,
+
+ Runtime = 3,
+
+ CodeTypeMask = 3,
+
+ Unmanaged = 4,
+
+ ManagedMask = 4,
+
+ NoInlining = 8,
+
+ ForwardRef = 16,
+
+ Synchronized = 32,
+
+ NoOptimization = 64,
+
+ PreserveSig = 128,
+
+ AggressiveInlining = 256,
+
+ SecurityMitigations = 1024,
+
+ InternalCall = 4096,
+
+ MaxMethodImplVal = 65535,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum CallingConventions
+ {
+ Standard = 1,
+
+ VarArgs = 2,
+
+ Any = 3,
+
+ HasThis = 32,
+
+ ExplicitThis = 64,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class CustomAttributeTypedArgument
+ {
+ [Newtonsoft.Json.JsonProperty("ArgumentType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ArgumentType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object Value { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class CustomAttributeNamedArgument
+ {
+ [Newtonsoft.Json.JsonProperty("MemberInfo", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MemberInfo MemberInfo { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TypedValue", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public CustomAttributeTypedArgument TypedValue { get; set; } = new CustomAttributeTypedArgument();
+
+ [Newtonsoft.Json.JsonProperty("MemberName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string MemberName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsField", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsField { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class Module
+ {
+ [Newtonsoft.Json.JsonProperty("CustomAttributes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeData> CustomAttributes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MDStreamVersion", Required = Newtonsoft.Json.Required.Always)]
+ public int MDStreamVersion { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FullyQualifiedName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FullyQualifiedName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ModuleVersionId", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public System.Guid ModuleVersionId { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MetadataToken", Required = Newtonsoft.Json.Required.Always)]
+ public int MetadataToken { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ScopeName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ScopeName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Assembly", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Assembly Assembly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ModuleHandle", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public ModuleHandle ModuleHandle { get; set; } = new ModuleHandle();
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class Assembly
+ {
+ [Newtonsoft.Json.JsonProperty("CodeBase", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string CodeBase { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EscapedCodeBase", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string EscapedCodeBase { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FullName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FullName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EntryPoint", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MethodInfo EntryPoint { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ExportedTypes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> ExportedTypes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DefinedTypes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> DefinedTypes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Evidence", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<Evidence> Evidence { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("PermissionSet", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<PermissionSet> PermissionSet { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsFullyTrusted", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsFullyTrusted { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SecurityRuleSet", Required = Newtonsoft.Json.Required.Always)]
+ public SecurityRuleSet SecurityRuleSet { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ManifestModule", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Module ManifestModule { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CustomAttributes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<CustomAttributeData> CustomAttributes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReflectionOnly", Required = Newtonsoft.Json.Required.Always)]
+ public bool ReflectionOnly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Modules", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<Module> Modules { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Location", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Location { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ImageRuntimeVersion", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ImageRuntimeVersion { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("GlobalAssemblyCache", Required = Newtonsoft.Json.Required.Always)]
+ public bool GlobalAssemblyCache { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HostContext", Required = Newtonsoft.Json.Required.Always)]
+ public long HostContext { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsDynamic", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsDynamic { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum SecurityRuleSet
+ {
+ None = 0,
+
+ Level1 = 1,
+
+ Level2 = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ModuleHandle
+ {
+ [Newtonsoft.Json.JsonProperty("MDStreamVersion", Required = Newtonsoft.Json.Required.Always)]
+ public int MDStreamVersion { get; set; }
+
+
+ }
+
+ /// <summary>Provides information about the available action filters.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class FilterInfo
+ {
+ /// <summary>Gets or sets an instance of the FilterInfo.</summary>
+ [Newtonsoft.Json.JsonProperty("Instance", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IFilter Instance { get; set; }
+
+ /// <summary>Gets or sets the scope FilterInfo.</summary>
+ [Newtonsoft.Json.JsonProperty("Scope", Required = Newtonsoft.Json.Required.Always)]
+ public FilterScope Scope { get; set; }
+
+
+ }
+
+ /// <summary>Defines the methods that are used in a filter.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IFilter
+ {
+ /// <summary>Gets or sets a value indicating whether more than one instance of the indicated attribute can be specified for a single program element.</summary>
+ [Newtonsoft.Json.JsonProperty("AllowMultiple", Required = Newtonsoft.Json.Required.Always)]
+ public bool AllowMultiple { get; set; }
+
+
+ }
+
+ /// <summary>Defines values that specify the order in which filters run within the same filter type and filter order.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum FilterScope
+ {
+ Global = 0,
+
+ Controller = 10,
+
+ Action = 20,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class DelegatingHandler : HttpMessageHandler
+ {
+ [Newtonsoft.Json.JsonProperty("InnerHandler", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpMessageHandler InnerHandler { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class HttpMessageHandler
+ {
+
+ }
+
+ /// <summary>IHttpRoute defines the interface for a route expressing how to map an incoming HttpRequestMessage to a particular controller and action. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IHttpRoute
+ {
+ /// <summary>Gets the route template describing the URI pattern to match against. </summary>
+ [Newtonsoft.Json.JsonProperty("RouteTemplate", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string RouteTemplate { get; set; }
+
+ /// <summary>Gets the default values for route parameters if not provided by the incoming HttpRequestMessage. </summary>
+ [Newtonsoft.Json.JsonProperty("Defaults", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Defaults { get; set; }
+
+ /// <summary>Gets the constraints for the route parameters. </summary>
+ [Newtonsoft.Json.JsonProperty("Constraints", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Constraints { get; set; }
+
+ /// <summary>Gets any additional data tokens not used directly to determine whether a route matches an incoming HttpRequestMessage. </summary>
+ [Newtonsoft.Json.JsonProperty("DataTokens", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> DataTokens { get; set; }
+
+ /// <summary>Gets the message handler that will be the recipient of the request.</summary>
+ [Newtonsoft.Json.JsonProperty("Handler", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpMessageHandler Handler { get; set; }
+
+
+ }
+
+ /// <summary>Represents a dependency injection container.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IDependencyResolver
+ {
+
+ }
+
+ /// <summary>An abstract class that provides a container for services used by ASP.NET Web API.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class ServicesContainer
+ {
+
+ }
+
+ /// <summary>Collection of functions that can produce a parameter binding for a given parameter. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ParameterBindingRulesCollection : System.Collections.ObjectModel.Collection<FuncOfHttpParameterDescriptorAndHttpParameterBinding>
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class FuncOfHttpParameterDescriptorAndHttpParameterBinding : MulticastDelegate
+ {
+
+ }
+
+ /// <summary>Specifies whether error details, such as exception messages and stack traces, should be included in error messages.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum IncludeErrorDetailPolicy
+ {
+ Default = 0,
+
+ LocalOnly = 1,
+
+ Always = 2,
+
+ Never = 3,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class MediaTypeFormatterCollection : Anonymous
+ {
+
+ }
+
+ /// <summary>MediaTypeFormatter class to handle Xml. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class XmlMediaTypeFormatter : MediaTypeFormatter
+ {
+ /// <summary>Gets or sets a value indicating whether the XML formatter uses the XmlSerializer as the default serializer, instead of using the DataContractSerializer.</summary>
+ [Newtonsoft.Json.JsonProperty("UseXmlSerializer", Required = Newtonsoft.Json.Required.Always)]
+ public bool UseXmlSerializer { get; set; } = false;
+
+ /// <summary>Gets or sets a value indicating whether to indent elements when writing data.</summary>
+ [Newtonsoft.Json.JsonProperty("Indent", Required = Newtonsoft.Json.Required.Always)]
+ public bool Indent { get; set; }
+
+ /// <summary>Gets the settings to be used while writing.</summary>
+ [Newtonsoft.Json.JsonProperty("WriterSettings", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public XmlWriterSettings WriterSettings { get; set; }
+
+ /// <summary>Gets and sets the maximum nested node depth.</summary>
+ [Newtonsoft.Json.JsonProperty("MaxDepth", Required = Newtonsoft.Json.Required.Always)]
+ public int MaxDepth { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class XmlWriterSettings
+ {
+ [Newtonsoft.Json.JsonProperty("Async", Required = Newtonsoft.Json.Required.Always)]
+ public bool Async { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Encoding", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Encoding Encoding { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("OmitXmlDeclaration", Required = Newtonsoft.Json.Required.Always)]
+ public bool OmitXmlDeclaration { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NewLineHandling", Required = Newtonsoft.Json.Required.Always)]
+ public NewLineHandling NewLineHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NewLineChars", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string NewLineChars { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Indent", Required = Newtonsoft.Json.Required.Always)]
+ public bool Indent { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IndentChars", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string IndentChars { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NewLineOnAttributes", Required = Newtonsoft.Json.Required.Always)]
+ public bool NewLineOnAttributes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CloseOutput", Required = Newtonsoft.Json.Required.Always)]
+ public bool CloseOutput { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ConformanceLevel", Required = Newtonsoft.Json.Required.Always)]
+ public ConformanceLevel ConformanceLevel { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CheckCharacters", Required = Newtonsoft.Json.Required.Always)]
+ public bool CheckCharacters { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NamespaceHandling", Required = Newtonsoft.Json.Required.Always)]
+ public NamespaceHandling NamespaceHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("WriteEndDocumentOnClose", Required = Newtonsoft.Json.Required.Always)]
+ public bool WriteEndDocumentOnClose { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("OutputMethod", Required = Newtonsoft.Json.Required.Always)]
+ public XmlOutputMethod OutputMethod { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DoNotEscapeUriAttributes", Required = Newtonsoft.Json.Required.Always)]
+ public bool DoNotEscapeUriAttributes { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class Encoding
+ {
+ [Newtonsoft.Json.JsonProperty("BodyName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string BodyName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EncodingName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string EncodingName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HeaderName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string HeaderName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("WebName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string WebName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("WindowsCodePage", Required = Newtonsoft.Json.Required.Always)]
+ public int WindowsCodePage { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsBrowserDisplay", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsBrowserDisplay { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsBrowserSave", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsBrowserSave { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsMailNewsDisplay", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsMailNewsDisplay { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsMailNewsSave", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsMailNewsSave { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsSingleByte", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsSingleByte { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EncoderFallback", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public EncoderFallback EncoderFallback { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DecoderFallback", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public DecoderFallback DecoderFallback { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsReadOnly", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsReadOnly { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CodePage", Required = Newtonsoft.Json.Required.Always)]
+ public int CodePage { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class EncoderFallback
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class DecoderFallback
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum NewLineHandling
+ {
+ Replace = 0,
+
+ Entitize = 1,
+
+ None = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum ConformanceLevel
+ {
+ Auto = 0,
+
+ Fragment = 1,
+
+ Document = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum NamespaceHandling
+ {
+ Default = 0,
+
+ OmitDuplicates = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum XmlOutputMethod
+ {
+ Xml = 0,
+
+ Html = 1,
+
+ Text = 2,
+
+ AutoDetect = 3,
+
+ }
+
+ /// <summary>Base class to handle serializing and deserializing strongly-typed objects using ObjectContent. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MediaTypeFormatter
+ {
+ /// <summary>Gets the mutable collection of media types supported bythis MediaTypeFormatter.</summary>
+ [Newtonsoft.Json.JsonProperty("SupportedMediaTypes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<MediaTypeHeaderValue> SupportedMediaTypes { get; set; }
+
+ /// <summary>Gets the mutable collection of character encodings supported bythis MediaTypeFormatter.</summary>
+ [Newtonsoft.Json.JsonProperty("SupportedEncodings", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<Encoding> SupportedEncodings { get; set; }
+
+ /// <summary>Gets the mutable collection of MediaTypeMapping objects that match HTTP requests to media types.</summary>
+ [Newtonsoft.Json.JsonProperty("MediaTypeMappings", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<MediaTypeMapping> MediaTypeMappings { get; set; }
+
+ /// <summary>Gets or sets the IRequiredMemberSelector instance used to determine required members.</summary>
+ [Newtonsoft.Json.JsonProperty("RequiredMemberSelector", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IRequiredMemberSelector RequiredMemberSelector { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class MediaTypeHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("CharSet", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string CharSet { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Parameters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Parameters { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MediaType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string MediaType { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class NameValueHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Value { get; set; }
+
+
+ }
+
+ /// <summary>An abstract base class used to create an association between HttpRequestMessage or HttpResponseMessage instances that have certain characteristics and a specific MediaTypeHeaderValue. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class MediaTypeMapping
+ {
+ /// <summary>Gets the MediaTypeHeaderValue that is associated with HttpRequestMessage or HttpResponseMessage instances that have the given characteristics of the MediaTypeMapping. </summary>
+ [Newtonsoft.Json.JsonProperty("MediaType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MediaTypeHeaderValue MediaType { get; set; }
+
+
+ }
+
+ /// <summary>Defines method that determines whether a given member is required on deserialization.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IRequiredMemberSelector
+ {
+
+ }
+
+ /// <summary>Represents the MediaTypeFormatter class to handle JSON. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class JsonMediaTypeFormatter : BaseJsonMediaTypeFormatter
+ {
+ /// <summary>Gets or sets a value indicating whether to use DataContractJsonSerializer by default. </summary>
+ [Newtonsoft.Json.JsonProperty("UseDataContractJsonSerializer", Required = Newtonsoft.Json.Required.Always)]
+ public bool UseDataContractJsonSerializer { get; set; }
+
+ /// <summary>Gets or sets a value indicating whether to indent elements when writing data. </summary>
+ [Newtonsoft.Json.JsonProperty("Indent", Required = Newtonsoft.Json.Required.Always)]
+ public bool Indent { get; set; }
+
+ /// <summary>Gets or sets the maximum depth allowed by this formatter.</summary>
+ [Newtonsoft.Json.JsonProperty("MaxDepth", Required = Newtonsoft.Json.Required.Always)]
+ public int MaxDepth { get; set; }
+
+
+ }
+
+ /// <summary>Abstract media type formatter class to support Bson and Json.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class BaseJsonMediaTypeFormatter : MediaTypeFormatter
+ {
+ /// <summary>Gets or sets the JsonSerializerSettings used to configure the JsonSerializer.</summary>
+ [Newtonsoft.Json.JsonProperty("SerializerSettings", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public JsonSerializerSettings SerializerSettings { get; set; }
+
+ /// <summary>Gets or sets the maximum depth allowed by this formatter.</summary>
+ [Newtonsoft.Json.JsonProperty("MaxDepth", Required = Newtonsoft.Json.Required.Always)]
+ public int MaxDepth { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class JsonSerializerSettings
+ {
+ [Newtonsoft.Json.JsonProperty("ReferenceLoopHandling", Required = Newtonsoft.Json.Required.Always)]
+ public ReferenceLoopHandling ReferenceLoopHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MissingMemberHandling", Required = Newtonsoft.Json.Required.Always)]
+ public MissingMemberHandling MissingMemberHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ObjectCreationHandling", Required = Newtonsoft.Json.Required.Always)]
+ public ObjectCreationHandling ObjectCreationHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NullValueHandling", Required = Newtonsoft.Json.Required.Always)]
+ public NullValueHandling NullValueHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DefaultValueHandling", Required = Newtonsoft.Json.Required.Always)]
+ public DefaultValueHandling DefaultValueHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Converters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<JsonConverter> Converters { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("PreserveReferencesHandling", Required = Newtonsoft.Json.Required.Always)]
+ public PreserveReferencesHandling PreserveReferencesHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TypeNameHandling", Required = Newtonsoft.Json.Required.Always)]
+ public TypeNameHandling TypeNameHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MetadataPropertyHandling", Required = Newtonsoft.Json.Required.Always)]
+ public MetadataPropertyHandling MetadataPropertyHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TypeNameAssemblyFormat", Required = Newtonsoft.Json.Required.Always)]
+ public FormatterAssemblyStyle TypeNameAssemblyFormat { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TypeNameAssemblyFormatHandling", Required = Newtonsoft.Json.Required.Always)]
+ public TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ConstructorHandling", Required = Newtonsoft.Json.Required.Always)]
+ public ConstructorHandling ConstructorHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContractResolver", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IContractResolver ContractResolver { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EqualityComparer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IEqualityComparer EqualityComparer { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReferenceResolver", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IReferenceResolver ReferenceResolver { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReferenceResolverProvider", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public FuncOfIReferenceResolver ReferenceResolverProvider { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TraceWriter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ITraceWriter TraceWriter { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Binder", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public SerializationBinder Binder { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SerializationBinder", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ISerializationBinder SerializationBinder { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Error", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public EventHandlerOfErrorEventArgs Error { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Context", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public StreamingContext Context { get; set; } = new StreamingContext();
+
+ [Newtonsoft.Json.JsonProperty("DateFormatString", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string DateFormatString { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxDepth", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public int? MaxDepth { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Formatting", Required = Newtonsoft.Json.Required.Always)]
+ public Formatting Formatting { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DateFormatHandling", Required = Newtonsoft.Json.Required.Always)]
+ public DateFormatHandling DateFormatHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DateTimeZoneHandling", Required = Newtonsoft.Json.Required.Always)]
+ public DateTimeZoneHandling DateTimeZoneHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("DateParseHandling", Required = Newtonsoft.Json.Required.Always)]
+ public DateParseHandling DateParseHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FloatFormatHandling", Required = Newtonsoft.Json.Required.Always)]
+ public FloatFormatHandling FloatFormatHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FloatParseHandling", Required = Newtonsoft.Json.Required.Always)]
+ public FloatParseHandling FloatParseHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("StringEscapeHandling", Required = Newtonsoft.Json.Required.Always)]
+ public StringEscapeHandling StringEscapeHandling { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Culture", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Culture { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CheckAdditionalContent", Required = Newtonsoft.Json.Required.Always)]
+ public bool CheckAdditionalContent { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum ReferenceLoopHandling
+ {
+ Error = 0,
+
+ Ignore = 1,
+
+ Serialize = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum MissingMemberHandling
+ {
+ Ignore = 0,
+
+ Error = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum ObjectCreationHandling
+ {
+ Auto = 0,
+
+ Reuse = 1,
+
+ Replace = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum NullValueHandling
+ {
+ Include = 0,
+
+ Ignore = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum DefaultValueHandling
+ {
+ Include = 0,
+
+ Ignore = 1,
+
+ Populate = 2,
+
+ IgnoreAndPopulate = 3,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class JsonConverter
+ {
+ [Newtonsoft.Json.JsonProperty("CanRead", Required = Newtonsoft.Json.Required.Always)]
+ public bool CanRead { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CanWrite", Required = Newtonsoft.Json.Required.Always)]
+ public bool CanWrite { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum PreserveReferencesHandling
+ {
+ None = 0,
+
+ Objects = 1,
+
+ Arrays = 2,
+
+ All = 3,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum TypeNameHandling
+ {
+ None = 0,
+
+ Objects = 1,
+
+ Arrays = 2,
+
+ All = 3,
+
+ Auto = 4,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum MetadataPropertyHandling
+ {
+ Default = 0,
+
+ ReadAhead = 1,
+
+ Ignore = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum FormatterAssemblyStyle
+ {
+ Simple = 0,
+
+ Full = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum TypeNameAssemblyFormatHandling
+ {
+ Simple = 0,
+
+ Full = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum ConstructorHandling
+ {
+ Default = 0,
+
+ AllowNonPublicDefaultConstructor = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IContractResolver
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IEqualityComparer
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IReferenceResolver
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class FuncOfIReferenceResolver : MulticastDelegate
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class ITraceWriter
+ {
+ [Newtonsoft.Json.JsonProperty("LevelFilter", Required = Newtonsoft.Json.Required.Always)]
+ public TraceLevel LevelFilter { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum TraceLevel
+ {
+ Off = 0,
+
+ Error = 1,
+
+ Warning = 2,
+
+ Info = 3,
+
+ Verbose = 4,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class SerializationBinder
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class ISerializationBinder
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class EventHandlerOfErrorEventArgs : MulticastDelegate
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class StreamingContext
+ {
+ [Newtonsoft.Json.JsonProperty("Context", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public object Context { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("State", Required = Newtonsoft.Json.Required.Always)]
+ public StreamingContextStates State { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ [System.Flags]
+ public enum StreamingContextStates
+ {
+ CrossProcess = 1,
+
+ CrossMachine = 2,
+
+ File = 4,
+
+ Persistence = 8,
+
+ Remoting = 16,
+
+ Other = 32,
+
+ Clone = 64,
+
+ CrossAppDomain = 128,
+
+ All = 255,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum Formatting
+ {
+ None = 0,
+
+ Indented = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum DateFormatHandling
+ {
+ IsoDateFormat = 0,
+
+ MicrosoftDateFormat = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum DateTimeZoneHandling
+ {
+ Local = 0,
+
+ Utc = 1,
+
+ Unspecified = 2,
+
+ RoundtripKind = 3,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum DateParseHandling
+ {
+ None = 0,
+
+ DateTime = 1,
+
+ DateTimeOffset = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum FloatFormatHandling
+ {
+ String = 0,
+
+ Symbol = 1,
+
+ DefaultValue = 2,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum FloatParseHandling
+ {
+ Double = 0,
+
+ Decimal = 1,
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public enum StringEscapeHandling
+ {
+ Default = 0,
+
+ EscapeNonAscii = 1,
+
+ EscapeHtml = 2,
+
+ }
+
+ /// <summary>MediaTypeFormatter class for handling HTML form URL-ended data, also known as application/x-www-form-urlencoded. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class FormUrlEncodedMediaTypeFormatter : MediaTypeFormatter
+ {
+ /// <summary>Gets or sets the maximum depth allowed by this formatter.</summary>
+ [Newtonsoft.Json.JsonProperty("MaxDepth", Required = Newtonsoft.Json.Required.Always)]
+ public int MaxDepth { get; set; }
+
+ /// <summary>Gets or sets the size of the buffer when reading the incoming stream.</summary>
+ [Newtonsoft.Json.JsonProperty("ReadBufferSize", Required = Newtonsoft.Json.Required.Always)]
+ public int ReadBufferSize { get; set; }
+
+
+ }
+
+ /// <summary>Represents information that describes the HTTP controller.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpControllerDescriptor
+ {
+ /// <summary>Gets the properties associated with this instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Properties", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Properties { get; set; }
+
+ /// <summary>Gets or sets the configurations associated with the controller.</summary>
+ [Newtonsoft.Json.JsonProperty("Configuration", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpConfiguration Configuration { get; set; }
+
+ /// <summary>Gets or sets the name of the controller.</summary>
+ [Newtonsoft.Json.JsonProperty("ControllerName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ControllerName { get; set; }
+
+ /// <summary>Gets or sets the type of the controller.</summary>
+ [Newtonsoft.Json.JsonProperty("ControllerType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ControllerType { get; set; }
+
+
+ }
+
+ /// <summary>Represents an HTTP controller.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IHttpController
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpRequestMessage
+ {
+ [Newtonsoft.Json.JsonProperty("Version", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Version Version { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Content", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpContent Content { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Method", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpMethod Method { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("RequestUri", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Uri RequestUri { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Headers", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpRequestHeaders Headers { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Properties", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Properties { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Version
+ {
+ [Newtonsoft.Json.JsonProperty("Major", Required = Newtonsoft.Json.Required.Always)]
+ public int Major { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Minor", Required = Newtonsoft.Json.Required.Always)]
+ public int Minor { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Build", Required = Newtonsoft.Json.Required.Always)]
+ public int Build { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Revision", Required = Newtonsoft.Json.Required.Always)]
+ public int Revision { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MajorRevision", Required = Newtonsoft.Json.Required.Always)]
+ public int MajorRevision { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MinorRevision", Required = Newtonsoft.Json.Required.Always)]
+ public int MinorRevision { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class HttpContent
+ {
+ [Newtonsoft.Json.JsonProperty("Headers", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpContentHeaders Headers { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpContentHeaders : Anonymous2
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ContentDispositionHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("DispositionType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string DispositionType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Parameters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Parameters { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FileName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FileName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FileNameStar", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FileNameStar { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CreationDate", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? CreationDate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ModificationDate", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? ModificationDate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReadDate", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? ReadDate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Size", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? Size { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ContentRangeHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Unit", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Unit { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("From", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? From { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("To", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? To { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Length", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? Length { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HasLength", Required = Newtonsoft.Json.Required.Always)]
+ public bool HasLength { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HasRange", Required = Newtonsoft.Json.Required.Always)]
+ public bool HasRange { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class KeyValuePairOfStringAndIEnumerableOfString
+ {
+ [Newtonsoft.Json.JsonProperty("Key", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Key { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> Value { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpMethod
+ {
+ [Newtonsoft.Json.JsonProperty("Method", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Method { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpRequestHeaders : Anonymous3
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class MediaTypeWithQualityHeaderValue : MediaTypeHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Quality", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public double? Quality { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class StringWithQualityHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Value { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Quality", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public double? Quality { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class AuthenticationHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Scheme", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Scheme { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Parameter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Parameter { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class NameValueWithParametersHeaderValue : NameValueHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Parameters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Parameters { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class EntityTagHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Tag", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Tag { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsWeak", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsWeak { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class RangeConditionHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Date", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? Date { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EntityTag", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public EntityTagHeaderValue EntityTag { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class RangeHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Unit", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Unit { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Ranges", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<RangeItemHeaderValue> Ranges { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class RangeItemHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("From", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? From { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("To", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? To { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class TransferCodingWithQualityHeaderValue : TransferCodingHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Quality", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public double? Quality { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class TransferCodingHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Value { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Parameters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Parameters { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ProductInfoHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Product", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ProductHeaderValue Product { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Comment", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Comment { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ProductHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Version", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Version { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class CacheControlHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("NoCache", Required = Newtonsoft.Json.Required.Always)]
+ public bool NoCache { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NoCacheHeaders", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> NoCacheHeaders { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NoStore", Required = Newtonsoft.Json.Required.Always)]
+ public bool NoStore { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxAge", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.TimeSpan? MaxAge { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SharedMaxAge", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.TimeSpan? SharedMaxAge { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxStale", Required = Newtonsoft.Json.Required.Always)]
+ public bool MaxStale { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxStaleLimit", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.TimeSpan? MaxStaleLimit { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MinFresh", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.TimeSpan? MinFresh { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NoTransform", Required = Newtonsoft.Json.Required.Always)]
+ public bool NoTransform { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("OnlyIfCached", Required = Newtonsoft.Json.Required.Always)]
+ public bool OnlyIfCached { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Public", Required = Newtonsoft.Json.Required.Always)]
+ public bool Public { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Private", Required = Newtonsoft.Json.Required.Always)]
+ public bool Private { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("PrivateHeaders", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> PrivateHeaders { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MustRevalidate", Required = Newtonsoft.Json.Required.Always)]
+ public bool MustRevalidate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ProxyRevalidate", Required = Newtonsoft.Json.Required.Always)]
+ public bool ProxyRevalidate { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Extensions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Extensions { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class ViaHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("ProtocolName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ProtocolName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ProtocolVersion", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ProtocolVersion { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ReceivedBy", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ReceivedBy { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Comment", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Comment { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class WarningHeaderValue
+ {
+ [Newtonsoft.Json.JsonProperty("Code", Required = Newtonsoft.Json.Required.Always)]
+ public int Code { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Agent", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Agent { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Text", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Text { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Date", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? Date { get; set; }
+
+
+ }
+
+ /// <summary>Represents the context associated with a request.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class HttpRequestContext
+ {
+ /// <summary>Gets or sets the client certificate.</summary>
+ [Newtonsoft.Json.JsonProperty("ClientCertificate", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public X509Certificate2 ClientCertificate { get; set; }
+
+ /// <summary>Gets or sets the configuration.</summary>
+ [Newtonsoft.Json.JsonProperty("Configuration", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpConfiguration Configuration { get; set; }
+
+ /// <summary>Gets or sets a value indicating whether error details, such as exception messages and stack traces, should be included in the response for this request.</summary>
+ [Newtonsoft.Json.JsonProperty("IncludeErrorDetail", Required = Newtonsoft.Json.Required.Always)]
+ public bool IncludeErrorDetail { get; set; }
+
+ /// <summary>Gets or sets a value indicating whether the request originates from a local address.</summary>
+ [Newtonsoft.Json.JsonProperty("IsLocal", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsLocal { get; set; }
+
+ /// <summary>.Gets or sets the principal</summary>
+ [Newtonsoft.Json.JsonProperty("Principal", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IPrincipal Principal { get; set; }
+
+ /// <summary>Gets or sets the route data.</summary>
+ [Newtonsoft.Json.JsonProperty("RouteData", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IHttpRouteData RouteData { get; set; }
+
+ /// <summary>Gets or sets the factory used to generate URLs to other APIs.</summary>
+ [Newtonsoft.Json.JsonProperty("Url", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public UrlHelper Url { get; set; }
+
+ /// <summary>Gets or sets the virtual path root.</summary>
+ [Newtonsoft.Json.JsonProperty("VirtualPathRoot", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string VirtualPathRoot { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class X509Certificate2 : X509Certificate
+ {
+ [Newtonsoft.Json.JsonProperty("Archived", Required = Newtonsoft.Json.Required.Always)]
+ public bool Archived { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Extensions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<Extensions> Extensions { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FriendlyName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FriendlyName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IssuerName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public X500DistinguishedName IssuerName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NotAfter", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public System.DateTimeOffset NotAfter { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("NotBefore", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public System.DateTimeOffset NotBefore { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("HasPrivateKey", Required = Newtonsoft.Json.Required.Always)]
+ public bool HasPrivateKey { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("PrivateKey", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AsymmetricAlgorithm PrivateKey { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("PublicKey", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public PublicKey PublicKey { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("RawData", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public byte[] RawData { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SerialNumber", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string SerialNumber { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SubjectName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public X500DistinguishedName SubjectName { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SignatureAlgorithm", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Oid SignatureAlgorithm { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Thumbprint", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Thumbprint { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Version", Required = Newtonsoft.Json.Required.Always)]
+ public int Version { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CertContext", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public SafeCertContextHandle CertContext { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class X500DistinguishedName : AsnEncodedData
+ {
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class AsnEncodedData
+ {
+ [Newtonsoft.Json.JsonProperty("Oid", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Oid Oid { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("RawData", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public byte[] RawData { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Oid
+ {
+ [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Value { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("FriendlyName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string FriendlyName { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class AsymmetricAlgorithm
+ {
+ [Newtonsoft.Json.JsonProperty("KeySize", Required = Newtonsoft.Json.Required.Always)]
+ public int KeySize { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("LegalKeySizes", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<KeySizes> LegalKeySizes { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SignatureAlgorithm", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string SignatureAlgorithm { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("KeyExchangeAlgorithm", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string KeyExchangeAlgorithm { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class KeySizes
+ {
+ [Newtonsoft.Json.JsonProperty("MinSize", Required = Newtonsoft.Json.Required.Always)]
+ public int MinSize { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxSize", Required = Newtonsoft.Json.Required.Always)]
+ public int MaxSize { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("SkipSize", Required = Newtonsoft.Json.Required.Always)]
+ public int SkipSize { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class PublicKey
+ {
+ [Newtonsoft.Json.JsonProperty("Key", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AsymmetricAlgorithm Key { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Oid", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public Oid Oid { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EncodedKeyValue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AsnEncodedData EncodedKeyValue { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("EncodedParameters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AsnEncodedData EncodedParameters { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class SafeCertContextHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class SafeHandleZeroOrMinusOneIsInvalid : SafeHandle
+ {
+ [Newtonsoft.Json.JsonProperty("IsInvalid", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsInvalid { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class SafeHandle : CriticalFinalizerObject
+ {
+ [Newtonsoft.Json.JsonProperty("IsClosed", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsClosed { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class CriticalFinalizerObject
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class X509Certificate
+ {
+ [Newtonsoft.Json.JsonProperty("Handle", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public IntPtr Handle { get; set; } = new IntPtr();
+
+ [Newtonsoft.Json.JsonProperty("Issuer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Issuer { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Subject", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Subject { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CertContext", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public SafeCertContextHandle2 CertContext { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class SafeCertContextHandle2 : SafeHandleZeroOrMinusOneIsInvalid
+ {
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IPrincipal
+ {
+ [Newtonsoft.Json.JsonProperty("Identity", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IIdentity Identity { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IIdentity
+ {
+ [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("AuthenticationType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string AuthenticationType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IsAuthenticated", Required = Newtonsoft.Json.Required.Always)]
+ public bool IsAuthenticated { get; set; }
+
+
+ }
+
+ /// <summary>Provides information about a route.</summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public abstract partial class IHttpRouteData
+ {
+ /// <summary>Gets the object that represents the route.</summary>
+ [Newtonsoft.Json.JsonProperty("Route", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public IHttpRoute Route { get; set; }
+
+ /// <summary>Gets a collection of URL parameter values and default values for the route.</summary>
+ [Newtonsoft.Json.JsonProperty("Values", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.IDictionary<string, object> Values { get; set; }
+
+
+ }
+
+ /// <summary>Represents a factory for creating URLs. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class UrlHelper
+ {
+ /// <summary>Gets or sets the HttpRequestMessage of the current UrlHelper instance.</summary>
+ [Newtonsoft.Json.JsonProperty("Request", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public HttpRequestMessage Request { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Evidence
+ {
+ private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
+ {
+ get { return _additionalProperties; }
+ set { _additionalProperties = value; }
+ }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class PermissionSet
+ {
+ private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
+ {
+ get { return _additionalProperties; }
+ set { _additionalProperties = value; }
+ }
+
+
+ }
+
+ /// <summary>Collection class that contains MediaTypeFormatter instances. </summary>
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Anonymous
+ {
+ /// <summary>Gets the MediaTypeFormatter to use for XML.</summary>
+ [Newtonsoft.Json.JsonProperty("XmlFormatter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public XmlMediaTypeFormatter XmlFormatter { get; set; }
+
+ /// <summary>Gets the MediaTypeFormatter to use for JSON.</summary>
+ [Newtonsoft.Json.JsonProperty("JsonFormatter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public JsonMediaTypeFormatter JsonFormatter { get; set; }
+
+ /// <summary>Gets the MediaTypeFormatter to use for application/x-www-form-urlencoded data.</summary>
+ [Newtonsoft.Json.JsonProperty("FormUrlEncodedFormatter", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public FormUrlEncodedMediaTypeFormatter FormUrlEncodedFormatter { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("WritingFormatters", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<MediaTypeFormatter> WritingFormatters { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Anonymous2
+ {
+ [Newtonsoft.Json.JsonProperty("Allow", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> Allow { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentDisposition", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ContentDispositionHeaderValue ContentDisposition { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentEncoding", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> ContentEncoding { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentLanguage", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> ContentLanguage { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentLength", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public long? ContentLength { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentLocation", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Uri ContentLocation { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentMD5", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public byte[] ContentMD5 { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentRange", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public ContentRangeHeaderValue ContentRange { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ContentType", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public MediaTypeHeaderValue ContentType { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Expires", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? Expires { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("LastModified", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? LastModified { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Anonymous3
+ {
+ [Newtonsoft.Json.JsonProperty("Accept", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<MediaTypeWithQualityHeaderValue> Accept { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("AcceptCharset", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<StringWithQualityHeaderValue> AcceptCharset { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("AcceptEncoding", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<StringWithQualityHeaderValue> AcceptEncoding { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("AcceptLanguage", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<StringWithQualityHeaderValue> AcceptLanguage { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Authorization", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AuthenticationHeaderValue Authorization { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Expect", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueWithParametersHeaderValue> Expect { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ExpectContinue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public bool? ExpectContinue { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("From", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string From { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Host", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Host { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IfMatch", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<EntityTagHeaderValue> IfMatch { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IfModifiedSince", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? IfModifiedSince { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IfNoneMatch", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<EntityTagHeaderValue> IfNoneMatch { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IfRange", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public RangeConditionHeaderValue IfRange { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("IfUnmodifiedSince", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? IfUnmodifiedSince { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("MaxForwards", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public int? MaxForwards { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ProxyAuthorization", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public AuthenticationHeaderValue ProxyAuthorization { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Range", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public RangeHeaderValue Range { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Referrer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Uri Referrer { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TE", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<TransferCodingWithQualityHeaderValue> TE { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("UserAgent", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<ProductInfoHeaderValue> UserAgent { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("CacheControl", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public CacheControlHeaderValue CacheControl { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Connection", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> Connection { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("ConnectionClose", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public bool? ConnectionClose { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Date", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.DateTimeOffset? Date { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Pragma", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<NameValueHeaderValue> Pragma { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Trailer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<string> Trailer { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TransferEncoding", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<TransferCodingHeaderValue> TransferEncoding { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("TransferEncodingChunked", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public bool? TransferEncodingChunked { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Upgrade", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<ProductHeaderValue> Upgrade { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Via", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<ViaHeaderValue> Via { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("Warning", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection<WarningHeaderValue> Warning { get; set; }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.5.0 (Newtonsoft.Json v11.0.0.0)")]
+ public partial class Extensions
+ {
+ private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
+ {
+ get { return _additionalProperties; }
+ set { _additionalProperties = value; }
+ }
+
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.2.3.0 (NJsonSchema v10.1.5.0 (Newtonsoft.Json v11.0.0.0))")]
+ public partial class FileResponse : System.IDisposable
+ {
+ private System.IDisposable _client;
+ private System.IDisposable _response;
+
+ public int StatusCode { get; private set; }
+
+ public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
+
+ public System.IO.Stream Stream { get; private set; }
+
+ public bool IsPartial
+ {
+ get { return StatusCode == 206; }
+ }
+
+ public FileResponse(int statusCode, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.IO.Stream stream, System.IDisposable client, System.IDisposable response)
+ {
+ StatusCode = statusCode;
+ Headers = headers;
+ Stream = stream;
+ _client = client;
+ _response = response;
+ }
+
+ public void Dispose()
+ {
+ if (Stream != null)
+ Stream.Dispose();
+ if (_response != null)
+ _response.Dispose();
+ if (_client != null)
+ _client.Dispose();
+ }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.2.3.0 (NJsonSchema v10.1.5.0 (Newtonsoft.Json v11.0.0.0))")]
+ public partial class ApiException : System.Exception
+ {
+ public int StatusCode { get; private set; }
+
+ public string Response { get; private set; }
+
+ public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
+
+ public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException)
+ : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + response.Substring(0, response.Length >= 512 ? 512 : response.Length), innerException)
+ {
+ StatusCode = statusCode;
+ Response = response;
+ Headers = headers;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
+ }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.2.3.0 (NJsonSchema v10.1.5.0 (Newtonsoft.Json v11.0.0.0))")]
+ public partial class ApiException<TResult> : ApiException
+ {
+ public TResult Result { get; private set; }
+
+ public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException)
+ : base(message, statusCode, response, headers, innerException)
+ {
+ Result = result;
+ }
+ }
+
+}
+
+#pragma warning restore 1591
+#pragma warning restore 1573
+#pragma warning restore 472
+#pragma warning restore 114
+#pragma warning restore 108 \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/IGatewayService.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/IGatewayService.cs
new file mode 100644
index 000000000..2149a0264
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Gateway/IGatewayService.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.MachineService.Gateway;
+
+namespace Tango.FSE.Common.Gateway
+{
+ public interface IGatewayService
+ {
+ ReadOnlyObservableCollection<EnvironmentConfiguration> Environments { get; }
+
+ Task<List<EnvironmentConfiguration>> GetEnvironments();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEModule.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEModule.cs
new file mode 100644
index 000000000..81daf08b1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEModule.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+using Tango.BL.Enumerations;
+
+namespace Tango.FSE.Common
+{
+ public interface IFSEModule
+ {
+ /// <summary>
+ /// Gets the module name.
+ /// </summary>
+ String Name { get; }
+
+ /// <summary>
+ /// Gets the module description.
+ /// </summary>
+ String Description { get; }
+
+ /// <summary>
+ /// Gets the module cover image.
+ /// </summary>
+ BitmapSource Image { get; }
+
+ /// <summary>
+ /// Gets the module entry point view type.
+ /// </summary>
+ Type MainViewType { get; }
+
+ /// <summary>
+ /// Gets the permission required to see and load this module.
+ /// </summary>
+ Permissions Permission { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this module should be displayed in the application menu.
+ /// </summary>
+ bool IsVisibleInMenu { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether to dock this module menu item to the bottom.
+ /// </summary>
+ bool DockToBottom { get; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEView.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEView.cs
new file mode 100644
index 000000000..4ed47380f
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/IFSEView.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common
+{
+ /// <summary>
+ /// Represents a PPC view.
+ /// </summary>
+ public interface IFSEView
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Modules/IFSEModuleLoader.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Modules/IFSEModuleLoader.cs
new file mode 100644
index 000000000..a8c2ef401
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Modules/IFSEModuleLoader.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FSE.Common;
+
+namespace Tango.FSE.Common.Modules
+{
+ /// <summary>
+ /// Represents a PPC <see cref="IPPCModule"/> modules loading engine.
+ /// </summary>
+ public interface IFSEModuleLoader
+ {
+ /// <summary>
+ /// Occurs when the user has logged in and user modules are loaded.
+ /// </summary>
+ event EventHandler ModulesLoaded;
+
+ /// <summary>
+ /// Gets all loaded modules.
+ /// </summary>
+ ObservableCollection<IFSEModule> AllModules { get; }
+
+ /// <summary>
+ /// Gets all the user permitted modules.
+ /// </summary>
+ ObservableCollection<IFSEModule> UserModules { get; }
+
+ /// <summary>
+ /// Gets the PPC module of type T if loaded.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ T GetFSEModule<T>() where T : IFSEModule;
+
+ /// <summary>
+ /// Loads all available PPC modules.
+ /// </summary>
+ void LoadModules();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs
new file mode 100644
index 000000000..0a96200ea
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Navigation
+{
+ /// <summary>
+ /// Represents an object which can abort the navigation from it.
+ /// </summary>
+ public interface INavigationBlocker
+ {
+ /// <summary>
+ /// Called before the navigation system navigates from this object.
+ /// Return false to abort the navigation.
+ /// </summary>
+ /// <returns></returns>
+ Task<bool> OnNavigateOutRequest();
+
+ /// <summary>
+ /// Called before the navigation system navigates back from this object.
+ /// Return false to abort the navigation.
+ /// </summary>
+ /// <returns></returns>
+ Task<bool> OnNavigateBackRequest();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs
new file mode 100644
index 000000000..0939516d6
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+
+namespace Tango.FSE.Common.Navigation
+{
+ /// <summary>
+ /// Represents the PPC views navigation manager.
+ /// </summary>
+ public interface INavigationManager
+ {
+ /// <summary>
+ /// Gets the current module.
+ /// </summary>
+ IFSEModule CurrentModule { get; }
+
+ /// <summary>
+ /// Gets the current view model.
+ /// </summary>
+ FSEViewModel CurrentVM { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the navigation system is able to navigate to the previous view.
+ /// </summary>
+ bool CanNavigateBack { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the back should be enabled.
+ /// </summary>
+ bool IsBackEnabled { get; set; }
+
+ /// <summary>
+ /// Navigates to the previous view if <see cref="CanNavigateBack"/> is true.
+ /// </summary>
+ Task<bool> NavigateBack();
+
+ /// <summary>
+ /// Navigates to the previous view..
+ /// </summary>
+ RelayCommand NavigateBackCommand { get; }
+
+ /// <summary>
+ /// Navigates to the specified full path in command parameter.
+ /// </summary>
+ RelayCommand<String> NavigateToCommand { get; }
+
+ /// <summary>
+ /// Navigates to the specified PPC view.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ Task<bool> NavigateTo(NavigationView view, bool pushToHistory = true);
+
+ /// <summary>
+ /// Navigates to the specified PPC view with the specified receive object.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ Task<bool> NavigateWithObject<TPass>(NavigationView view, TPass obj, bool pushToHistory = true);
+
+ /// <summary>
+ /// Navigates to the specified module.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ Task<bool> NavigateTo<T>(bool pushToHistory = true) where T : IFSEModule;
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView.JobsView).
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ Task<bool> NavigateTo<T>(String viewPath, bool pushToHistory = true) where T : IFSEModule;
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView,JobsView).
+ /// This method makes it easy to do stuff like NavigateTo(nameof(MainView),nameof(JobsView));
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ Task<bool> NavigateTo<T>(bool pushToHistory = true, params String[] viewPath) where T : IFSEModule;
+
+ /// <summary>
+ /// Navigates to the specified module and view by full path (e.g Jobs.JobsView).
+ /// </summary>
+ /// <param name="fullPath">The full path.</param>
+ Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<FSEViewModel, FSEViewModel> onNavigating = null, Action<FSEViewModel, FSEViewModel> onNavigated = null);
+
+ /// <summary>
+ /// Navigates to the specified module and view with the specified object and expecting a return parameter.
+ /// The view must be of type INavigationResultProvider<TResult>.
+ /// </summary>
+ /// <param name="fullPath">The full path.</param>
+ Task<TResult> NavigateForResult<TModule, TView, TResult, TPass>(TPass obj, bool pushToHistory = true)
+ where TModule : IFSEModule;
+
+ /// <summary>
+ /// Navigates to the specified module and view with the specified object.
+ /// </summary>
+ /// <typeparam name="TModule">The type of the module.</typeparam>
+ /// <typeparam name="TView">The type of the view.</typeparam>
+ /// <typeparam name="TPass">The type of the pass.</typeparam>
+ /// <param name="obj">The object.</param>
+ /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
+ /// <returns></returns>
+ Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true)
+ where TModule : IFSEModule;
+
+ /// <summary>
+ /// Clears the navigation back history.
+ /// </summary>
+ void ClearHistory();
+
+ /// <summary>
+ /// Clears the navigation back history except the specified view type.
+ /// </summary>
+ void ClearHistoryExcept<T>();
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationObjectReceiver.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationObjectReceiver.cs
new file mode 100644
index 000000000..0a1d94b76
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationObjectReceiver.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Navigation
+{
+ /// <summary>
+ /// Represents an object which supports receiving an object as part of the navigation to it.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public interface INavigationObjectReceiver<T>
+ {
+ /// <summary>
+ /// Called when navigation system is going to navigate to this instance with the specified object.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ void OnNavigatedToWithObject(T obj);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationResultProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationResultProvider.cs
new file mode 100644
index 000000000..81d2545c5
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationResultProvider.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Navigation
+{
+ /// <summary>
+ /// Represents a object which provides a result the navigation system navigates away from it.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result.</typeparam>
+ /// <typeparam name="TPass">The type of the pass.</typeparam>
+ public interface INavigationResultProvider<TResult, TPass>
+ {
+ /// <summary>
+ /// Called when the navigation system requests a result when it is navigating away from this instance.
+ /// </summary>
+ /// <returns></returns>
+ TResult GetNavigationResult();
+
+ /// <summary>
+ /// Called when navigation system is going to navigate to this instance with the specified object.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ void OnNavigationObjectReceived(TPass obj);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/NavigationView.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/NavigationView.cs
new file mode 100644
index 000000000..85bb28510
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/NavigationView.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Navigation
+{
+ /// <summary>
+ /// Represents the main application views to navigate to using the <see cref="INavigationManager"/>.
+ /// </summary>
+ public enum NavigationView
+ {
+ Home,
+ LoadingView,
+ LayoutView,
+ NoPermissionsView,
+ RestartingView,
+ LoginView,
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppBarItem.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppBarItem.cs
new file mode 100644
index 000000000..83c8fabde
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppBarItem.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core.Commands;
+
+namespace Tango.FSE.Common.Notifications
+{
+ /// <summary>
+ /// Represents an AppBar item that can be inserted into the application header.
+ /// </summary>
+ public abstract class AppBarItem : ItemBase
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppButton.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppButton.cs
new file mode 100644
index 000000000..d8081c989
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/AppButton.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.Core.DI;
+
+namespace Tango.FSE.Common.Notifications
+{
+ /// <summary>
+ /// Represents an app button that will be displayed in the layout view.
+ /// </summary>
+ /// <seealso cref="ExtendedObject" />
+ public abstract class AppButton : ExtendedObject
+ {
+ /// <summary>
+ /// Occurs when the button has been pressed.
+ /// </summary>
+ public event Action Pressed;
+
+ private String _text;
+ /// <summary>
+ /// Gets or sets the text.
+ /// </summary>
+ public String Text
+ {
+ get { return _text; }
+ set { _text = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isEnabled;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is enabled.
+ /// </summary>
+ public bool IsEnabled
+ {
+ get { return _isEnabled; }
+ set { _isEnabled = value; RaisePropertyChangedAuto(); }
+ }
+
+ private RelayCommand _command;
+ /// <summary>
+ /// Gets or sets the command.
+ /// </summary>
+ public RelayCommand Command
+ {
+ get { return _command; }
+ set { _command = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AppButton"/> class.
+ /// </summary>
+ public AppButton()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AppButton"/> class.
+ /// </summary>
+ /// <param name="text">The text.</param>
+ /// <param name="isEnabled">if set to <c>true</c> [is enabled].</param>
+ /// <param name="onExecute">The on execute.</param>
+ /// <param name="canExecute">The can execute.</param>
+ public AppButton(String text, bool isEnabled) : this()
+ {
+ Text = text;
+ IsEnabled = isEnabled;
+ Command = new RelayCommand(() =>
+ {
+ Pressed?.Invoke();
+ });
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AppButton"/> class.
+ /// </summary>
+ /// <param name="text">The text.</param>
+ /// <param name="command">The command.</param>
+ public AppButton(String text, RelayCommand command) : this(text, true)
+ {
+ Command = command;
+ }
+
+ /// <summary>
+ /// Invalidates the button state.
+ /// </summary>
+ public void RaiseCanExecute()
+ {
+ Command.RaiseCanExecuteChanged();
+ }
+
+ /// <summary>
+ /// Pops this instance.
+ /// </summary>
+ public void Pop()
+ {
+ TangoIOC.Default.GetInstance<INotificationProvider>().PopAppButton(this);
+ }
+
+ /// <summary>
+ /// Pushes this instance.
+ /// </summary>
+ public void Push()
+ {
+ TangoIOC.Default.GetInstance<INotificationProvider>().PushAppButton(this);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs
new file mode 100644
index 000000000..ce567a354
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs
@@ -0,0 +1,229 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+using Tango.Core.Commands;
+using Tango.SharedUI;
+
+namespace Tango.FSE.Common.Notifications
+{
+ /// <summary>
+ /// Represents the PPC user notification provider responsible for displaying information, alerts and dialogs to the user.
+ /// </summary>
+ public interface INotificationProvider
+ {
+ /// <summary>
+ /// Gets the collection of notification items.
+ /// </summary>
+ ObservableCollection<NotificationItem> NotificationItems { get; }
+
+ /// <summary>
+ /// Gets the notification items view.
+ /// </summary>
+ ICollectionView NotificationItemsView { get; }
+
+ /// <summary>
+ /// Gets the collection of taskbar items.
+ /// </summary>
+ ObservableCollection<TaskBarItem> TaskBarItems { get; }
+
+ /// <summary>
+ /// Gets the current application bar item.
+ /// </summary>
+ AppBarItem CurrentAppBarItem { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has application bar item.
+ /// </summary>
+ bool HasAppBarItem { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has notification items.
+ /// </summary>
+ bool HasNotificationItems { get; }
+
+ /// <summary>
+ /// Gets the current message box.
+ /// </summary>
+ MessageBoxVM CurrentMessageBox { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has message box.
+ /// </summary>
+ bool HasMessageBox { get; }
+
+ /// <summary>
+ /// Gets the current dialog.
+ /// </summary>
+ FrameworkElement CurrentDialog { get; }
+
+ /// <summary>
+ /// Gets the current app button.
+ /// </summary>
+ AppButton CurrentAppButton { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has a dialog.
+ /// </summary>
+ bool HasDialog { get; }
+
+ /// <summary>
+ /// Shows an information message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ Task ShowInfo(String message);
+
+ /// <summary>
+ /// Shows warning message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ Task ShowWarning(String message);
+
+ /// <summary>
+ /// Shows an error message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ Task ShowError(String message);
+
+ /// <summary>
+ /// Shows a success message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ Task ShowSuccess(String message);
+
+ /// <summary>
+ /// Shows a question message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ Task<bool> ShowQuestion(String message);
+
+ /// <summary>
+ /// Inserts the notification item to the bottom of the notifications collection.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ NotificationItem PushNotification(NotificationItem item);
+
+ /// <summary>
+ /// Pushes the notification.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ NotificationItem PushNotification<T>() where T : NotificationItem;
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// </summary>
+ /// <typeparam name="VM"></typeparam>
+ /// <param name="datacontext">The data context.</param>
+ /// <param name="view">The view.</param>
+ /// <returns></returns>
+ Task<VM> ShowDialog<VM>(VM datacontext, FrameworkElement view) where VM : DialogViewVM;
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// The notification provider will try to locate the view automatically using conventions.
+ /// </summary>
+ /// <typeparam name="VM"></typeparam>
+ /// <param name="datacontext">The data context.</param>
+ /// <returns></returns>
+ Task<VM> ShowDialog<VM>(VM datacontext) where VM : DialogViewVM;
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// The data context instance will be automatically created.
+ /// The notification provider will try to locate the view automatically using conventions.
+ /// </summary>
+ /// <typeparam name="VM"></typeparam>
+ /// <returns></returns>
+ Task<VM> ShowDialog<VM>() where VM : DialogViewVM;
+
+ /// <summary>
+ /// Removed the specified notification item.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ void PopNotification(NotificationItem item);
+
+ /// <summary>
+ /// Gets a value indicating whether this instance is in global busy state.
+ /// </summary>
+ bool IsInGlobalBusyState { get; }
+
+ /// <summary>
+ /// Sets the global busy message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ void SetGlobalBusyMessage(String message);
+
+ /// <summary>
+ /// Releases the global busy message.
+ /// </summary>
+ void ReleaseGlobalBusyMessage();
+
+ /// <summary>
+ /// Gets the current global busy message.
+ /// </summary>
+ String GlobalBusyMessage { get; }
+
+ /// <summary>
+ /// Pushes the application bar item.
+ /// </summary>
+ /// <param name="appBarItem">The application bar item.</param>
+ /// <returns></returns>
+ AppBarItem PushAppBarItem(AppBarItem appBarItem);
+
+ /// <summary>
+ /// Pushes the application bar item.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ AppBarItem PushAppBarItem<T>() where T : AppBarItem;
+
+ /// <summary>
+ /// Pops the application bar item.
+ /// </summary>
+ /// <param name="appBarItem">The application bar item.</param>
+ void PopAppBarItem(AppBarItem appBarItem);
+
+ /// <summary>
+ /// Pushes the task bar item.
+ /// </summary>
+ /// <param name="taskBarItem">The task bar item.</param>
+ /// <returns></returns>
+ TaskBarItem PushTaskBarItem(TaskBarItem taskBarItem);
+
+ /// <summary>
+ /// Handles the Push Task Bar Item event.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ TaskBarItem PushTaskBarItem<T>() where T : TaskBarItem;
+
+ /// <summary>
+ /// Pops the task bar item.
+ /// </summary>
+ /// <param name="TaskBarItem">The task bar item.</param>
+ void PopTaskBarItem(TaskBarItem taskBarItem);
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to allow notifications visibility.
+ /// </summary>
+ bool NotificationsVisible { get; set; }
+
+ /// <summary>
+ /// Pushes the app button.
+ /// </summary>
+ /// <param name="appButton">The app button.</param>
+ void PushAppButton(AppButton appButton);
+
+ /// <summary>
+ /// Pops the app button.
+ /// </summary>
+ /// <param name="appButton">The app button.</param>
+ void PopAppButton(AppButton appButton);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/ItemBase.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/ItemBase.cs
new file mode 100644
index 000000000..91e3b0998
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/ItemBase.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.Commands;
+
+namespace Tango.FSE.Common.Notifications
+{
+ /// <summary>
+ /// Represents a base notification item class.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="System.IDisposable" />
+ public abstract class ItemBase : ExtendedObject, IDisposable
+ {
+ /// <summary>
+ /// Occurs when the item has been closed.
+ /// </summary>
+ public event EventHandler Closed;
+
+ /// <summary>
+ /// Occurs when the item has been pressed.
+ /// </summary>
+ public event EventHandler Pressed;
+
+ /// <summary>
+ /// Gets or sets the remove action.
+ /// </summary>
+ public Action RemoveAction { get; set; }
+
+ /// <summary>
+ /// Gets or sets the view type.
+ /// </summary>
+ public abstract Type ViewType { get; }
+
+ /// <summary>
+ /// Gets or sets the close command.
+ /// </summary>
+ public RelayCommand CloseCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the pressed command.
+ /// </summary
+ public RelayCommand PressedCommand { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ItemBase"/> class.
+ /// </summary>
+ public ItemBase()
+ {
+ CloseCommand = new RelayCommand(Close);
+ PressedCommand = new RelayCommand(OnPreesed);
+ }
+
+ /// <summary>
+ /// Called when the item has been pressed.
+ /// </summary>
+ protected virtual void OnPreesed()
+ {
+ Pressed?.Invoke(this, new EventArgs());
+ }
+
+ /// <summary>
+ /// Called after the close command has been raised.
+ /// </summary>
+ public virtual void Close()
+ {
+ RemoveAction?.Invoke();
+ Closed?.Invoke(this, new EventArgs());
+ }
+
+ /// <summary>
+ /// Disposes the item.
+ /// </summary>
+ public void Dispose()
+ {
+ Close();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageBoxVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageBoxVM.cs
new file mode 100644
index 000000000..710939a8a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageBoxVM.cs
@@ -0,0 +1,22 @@
+using MaterialDesignThemes.Wpf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using Tango.SharedUI;
+
+namespace Tango.FSE.Common.Notifications
+{
+ public class MessageBoxVM : DialogViewVM
+ {
+ public MessageType Type { get; set; }
+
+ public String Title { get; set; }
+
+ public String Message { get; set; }
+
+ public bool HasCancel { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageType.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageType.cs
new file mode 100644
index 000000000..2d9edcfd3
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/MessageType.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Notifications
+{
+ public enum MessageType
+ {
+ Info,
+ Warning,
+ Error,
+ Success
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/NotificationItem.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/NotificationItem.cs
new file mode 100644
index 000000000..9708544cd
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/NotificationItem.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Timers;
+using System.Windows.Media;
+using Tango.Core;
+
+namespace Tango.FSE.Common.Notifications
+{
+ /// <summary>
+ /// Represents a base notification item.
+ /// </summary>
+ public abstract class NotificationItem : ItemBase
+ {
+ public enum NotificationPriority
+ {
+ Low,
+ Normal,
+ High,
+ VeryHigh,
+ Critical,
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NotificationItem"/> class.
+ /// </summary>
+ public NotificationItem() : base()
+ {
+ CanClose = true;
+ Priority = NotificationPriority.Normal;
+ }
+
+ private bool _isExpanded;
+ /// <summary>
+ /// Gets or sets a value indicating whether the notification panel is expanded.
+ /// </summary>
+ public bool IsExpanded
+ {
+ get { return _isExpanded; }
+ set { _isExpanded = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _canClose;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can close.
+ /// </summary>
+ public bool CanClose
+ {
+ get { return _canClose; }
+ set { _canClose = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the notification priority.
+ /// </summary>
+ public NotificationPriority Priority { get; set; }
+
+ /// <summary>
+ /// Called when the item has been pressed.
+ /// </summary>
+ protected override void OnPreesed()
+ {
+ base.OnPreesed();
+
+ if (CanClose)
+ {
+ Close();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/TaskBarItem.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/TaskBarItem.cs
new file mode 100644
index 000000000..030e7a22a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/TaskBarItem.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Notifications
+{
+ public abstract class TaskBarItem : ItemBase
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..b67d40216
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/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.FSE.Common")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tango.FSE.Common")]
+[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
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>. For example, if you are using US english
+//in your source files, set the <UICulture> 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/FSE/Tango.FSE.Common/Properties/Resources.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..34aae5903
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.Common.Properties {
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // 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() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [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.FSE.Common.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [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/FSE/Tango.FSE.Common/Properties/Resources.resx b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..8a03234d1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.Common.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/FSE/Tango.FSE.Common/Properties/Settings.settings b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml
new file mode 100644
index 000000000..f58d24aa2
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml
@@ -0,0 +1,43 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.FSE.Common.Resources">
+
+ <!--COLORS-->
+ <Color x:Key="FSE_PrimaryBackgroundColor">#303030</Color>
+ <Color x:Key="FSE_PrimaryForegroundColor">#EEEEEE</Color>
+ <Color x:Key="FSE_SemiTransparentColor">#45000000</Color>
+ <Color x:Key="FSE_GrayColor">#07D10F</Color>
+
+ <Color x:Key="FSE_ErrorColor">#FF0000</Color>
+ <Color x:Key="FSE_WarningColor">#FF6200</Color>
+ <Color x:Key="FSE_SuccessColor">#07D10F</Color>
+ <Color x:Key="FSE_MessageBoxTitleHeaderBackgroundColor">#404040</Color>
+
+ <!--BRUSHES-->
+ <SolidColorBrush x:Key="FSE_PrimaryBackgroundBrush" Color="{StaticResource FSE_PrimaryBackgroundColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_PrimaryForegroundBrush" Color="{StaticResource FSE_PrimaryForegroundColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_SemiTransparentBrush" Color="{StaticResource FSE_SemiTransparentColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_GrayBrush" Color="{StaticResource FSE_GrayColor}"></SolidColorBrush>
+
+ <SolidColorBrush x:Key="FSE_ErrorBrush" Color="{StaticResource FSE_ErrorColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_WarningBrush" Color="{StaticResource FSE_WarningColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_SuccessBrush" Color="{StaticResource FSE_SuccessColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_InfoBrush" Color="{StaticResource FSE_PrimaryForegroundColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_MessageBoxTitleHeaderBackgroundBrush" Color="{StaticResource FSE_MessageBoxTitleHeaderBackgroundColor}"></SolidColorBrush>
+
+ <!--BRUSHES OVERRIDES-->
+ <SolidColorBrush x:Key="MaterialDesignPaper" Color="{StaticResource FSE_PrimaryBackgroundColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="MaterialDesignBody" Color="{StaticResource FSE_PrimaryForegroundColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="PrimaryHueMidForegroundBrush" Color="{StaticResource FSE_PrimaryForegroundColor}"/>
+
+ <!-- primary -->
+ <!--<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="#744CE0"/>-->
+ <!--<SolidColorBrush x:Key="PrimaryHueLightForegroundBrush" Color="#FFFFFF"/>-->
+ <!--<SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#6134D9"/>-->
+ <!--<SolidColorBrush x:Key="PrimaryHueDarkBrush" Color="#4D1DCF"/>-->
+ <!--<SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush" Color="#FFFFFF"/>-->
+ <!-- accent -->
+ <!--<SolidColorBrush x:Key="SecondaryAccentBrush" Color="#5C5B5E"/>-->
+ <!--<SolidColorBrush x:Key="SecondaryAccentForegroundBrush" Color="#FFFFFF"/>-->
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml
new file mode 100644
index 000000000..08e8dea6f
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml
@@ -0,0 +1,8 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:local="clr-namespace:Tango.FSE.Common.Resources">
+
+ <sys:Double x:Key="FSE_MessageBoxTitleFontSize">16</sys:Double>
+
+</ResourceDictionary> \ No newline at end of file
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
new file mode 100644
index 000000000..6fdd7acf2
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{BC37CCCB-7392-4F78-8D1C-E9629E6E046E}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <RootNamespace>Tango.FSE.Common</RootNamespace>
+ <AssemblyName>Tango.FSE.Common</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <Deterministic>true</Deterministic>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\Build\FSE\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\Build\FSE\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="ControlzEx, Version=3.0.2.4, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="MahApps.Metro, Version=1.6.5.1, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MahApps.Metro.1.6.5\lib\net46\MahApps.Metro.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignColors, Version=1.2.2.920, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MaterialDesignColors.1.2.2\lib\net45\MaterialDesignColors.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignThemes.Wpf, Version=3.0.1.920, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MaterialDesignThemes.3.0.1\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\ControlzEx.3.0.2.4\lib\net45\System.Windows.Interactivity.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Authentication\AuthenticationResult.cs" />
+ <Compile Include="Authentication\IAuthenticationProvider.cs" />
+ <Compile Include="FSEApplication\IFSEApplicationManager.cs" />
+ <Compile Include="FSEModuleAttribute.cs" />
+ <Compile Include="Gateway\GatewayClient.cs" />
+ <Compile Include="Gateway\IGatewayService.cs" />
+ <Compile Include="Modules\IFSEModuleLoader.cs" />
+ <Compile Include="Notifications\AppBarItem.cs" />
+ <Compile Include="Notifications\AppButton.cs" />
+ <Compile Include="Notifications\INotificationProvider.cs" />
+ <Compile Include="Notifications\ItemBase.cs" />
+ <Compile Include="Notifications\MessageBoxVM.cs" />
+ <Compile Include="Notifications\MessageType.cs" />
+ <Compile Include="Notifications\NotificationItem.cs" />
+ <Compile Include="Notifications\TaskBarItem.cs" />
+ <Compile Include="FSEModuleBase.cs" />
+ <Compile Include="Threading\IDispatcherProvider.cs" />
+ <Compile Include="Web\FSEWebClient.cs" />
+ <Compile Include="Web\FSEWebClientBase.cs" />
+ <Page Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Resources\Colors.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Resources\Fonts.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Themes\Generic.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="FSESettings.cs" />
+ <Compile Include="FSEViewModel.cs" />
+ <Compile Include="IFSEModule.cs" />
+ <Compile Include="IFSEView.cs" />
+ <Compile Include="Navigation\INavigationBlocker.cs" />
+ <Compile Include="Navigation\INavigationManager.cs" />
+ <Compile Include="Navigation\INavigationObjectReceiver.cs" />
+ <Compile Include="Navigation\INavigationResultProvider.cs" />
+ <Compile Include="Navigation\NavigationView.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.BL\Tango.BL.csproj">
+ <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
+ <Name>Tango.BL</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Settings\Tango.Settings.csproj">
+ <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
+ <Name>Tango.Settings</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74E700B0-1156-4126-BE40-EE450D3C3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Web\Tango.Web.csproj">
+ <Project>{5001990f-977b-48ff-b217-0236a5022ad8}</Project>
+ <Name>Tango.Web</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.FSE.Web\Tango.FSE.Web.csproj">
+ <Project>{d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f}</Project>
+ <Name>Tango.FSE.Web</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>nswag run "$(SolutionDir)Web\Tango.MachineService.Gateway\Nswag\GatewayClient.nswag" /variables:assembly="$(SolutionDir)Web\Tango.MachineService.Gateway\bin\Tango.MachineService.Gateway.dll",output="$(ProjectDir)Gateway\GatewayClient.cs"</PreBuildEvent>
+ </PropertyGroup>
+ <Import Project="..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>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}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets'))" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml
new file mode 100644
index 000000000..ec131133e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml
@@ -0,0 +1,44 @@
+<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.FSE.Common">
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Colors.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Fonts.xaml" />
+
+ <ResourceDictionary>
+ <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
+ <converters:BooleanInverseConverter x:Key="BooleanInverseConverter" />
+ <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" />
+ <converters:DateTimeUTCToShortDateConverter x:Key="DateTimeUTCToShortDateConverter" />
+ <converters:MathOperatorConverter x:Key="MathOperatorConverter" />
+ <converters:IsSegmentGradientConverter x:Key="IsSegmentGradientConverter" />
+ <converters:IsSegmentGradientToVisibilityConverter x:Key="IsSegmentGradientToVisibilityConverter" />
+ <converters:SegmentToBrushConverterMulti x:Key="SegmentToBrushConverterMulti" />
+ <converters:SegmentLengthToWidthConverter x:Key="SegmentLengthToWidthConverter" />
+ <converters:WidthHeightToRectConverter x:Key="WidthHeightToRectConverter" />
+ <converters:OneToPercentConverter x:Key="OneToPercentConverter" />
+ <converters:SmallerThanToBooleanConverter x:Key="SmallerThanToBooleanConverter" />
+ <converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter" />
+ <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" />
+ <converters:TimeSpanToTwoDigitsTimeConverter x:Key="TimeSpanToTwoDigitsTimeConverter" />
+ <converters:TimeSpanToLabelConverter x:Key="TimeSpanToLabelConverter" />
+ <converters:GreaterThanToBooleanConverter x:Key="GreaterThanToBooleanConverter" />
+ <converters:ByteArrayToFileSizeConverter x:Key="ByteArrayToFileSizeConverter" />
+ <converters:EnumToVisibilityConverter x:Key="EnumToVisibilityConverter" />
+ <converters:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
+ <converters:DateTimeUTCToStringConverter x:Key="DateTimeUTCToStringConverter" />
+ <converters:NullObjectToBooleanConverter x:Key="NullObjectToBooleanConverter" />
+ <converters:IsNullToVisibilityConverter x:Key="IsNullToVisibilityConverter" />
+ <converters:StringToLinesConverter x:Key="StringToLinesConverter" />
+ <converters:ColorToIntegerConverter x:Key="ColorToIntegerConverter" />
+ <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" />
+ <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" />
+ <converters:TimeSpanToMinutesConverter x:Key="TimeSpanToMinutesConverter" />
+ <converters:TimeSpanToSecondsConverter x:Key="TimeSpanToSecondsConverter" />
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+
+</ResourceDictionary>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Threading/IDispatcherProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Threading/IDispatcherProvider.cs
new file mode 100644
index 000000000..f6b03f694
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Threading/IDispatcherProvider.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Threading
+{
+ /// <summary>
+ /// Represents a mechanism for invoking actions on the main application thread.
+ /// </summary>
+ public interface IDispatcherProvider
+ {
+ /// <summary>
+ /// Invokes the specified action asynchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ void Invoke(Action action);
+
+ /// <summary>
+ /// Invokes the specified action synchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ void InvokeBlock(Action action);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClient.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClient.cs
new file mode 100644
index 000000000..4c15ff90f
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClient.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.DI;
+
+namespace Tango.FSE.Common.Web
+{
+ public class FSEWebClient : FSEWebClientBase
+ {
+ public FSEWebClient() : base(String.Empty)
+ {
+
+ }
+
+ public FSEWebClient(string address) : base(address)
+ {
+ }
+
+ public FSEWebClient(FSEWebClientBase cloned) : base(cloned)
+ {
+ }
+
+ public FSEWebClient(string address, string token) : base(address, token)
+ {
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClientBase.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClientBase.cs
new file mode 100644
index 000000000..d5fd41001
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Web/FSEWebClientBase.cs
@@ -0,0 +1,43 @@
+
+using System;
+using System.Threading.Tasks;
+using Tango.Web;
+
+namespace Tango.FSE.Common.Web
+{
+ /// <summary>
+ /// Represents a machine service FSE web client.
+ /// </summary>
+ /// <seealso cref="Tango.Web.TangoWebClient" />
+ public abstract class FSEWebClientBase : TangoWebClientV2<Tango.FSE.Web.Messages.LoginRequest, Tango.FSE.Web.Messages.LoginResponse>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FSEWebClientBase"/> class.
+ /// </summary>
+ /// <param name="address">The service address.</param>
+ /// <param name="token">Existing token.</param>
+ public FSEWebClientBase(String address, String token) : base(address, "FSE", token)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FSEWebClientBase"/> class.
+ /// </summary>
+ /// <param name="address">The service address.</param>
+ public FSEWebClientBase(String address) : this(address, null)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FSEWebClientBase"/> class.
+ /// </summary>
+ /// <param name="cloned">Other instance.</param>
+ public FSEWebClientBase(FSEWebClientBase cloned) : base(cloned)
+ {
+
+ }
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/packages.config b/Software/Visual_Studio/FSE/Tango.FSE.Common/packages.config
new file mode 100644
index 000000000..f8d27760e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/packages.config
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="ControlzEx" version="3.0.2.4" targetFramework="net461" />
+ <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
+ <package id="MahApps.Metro" version="1.6.5" targetFramework="net461" />
+ <package id="MaterialDesignColors" version="1.2.2" targetFramework="net461" />
+ <package id="MaterialDesignThemes" version="3.0.1" targetFramework="net461" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.config b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.config
new file mode 100644
index 000000000..22e3d6062
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.config
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <appSettings>
+ <add key="GatewayUrl" value="http://localhost:2222" />
+ </appSettings>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+ </startup>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.0.5.0" newVersion="5.0.5.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml
new file mode 100644
index 000000000..b2ba0b65d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml
@@ -0,0 +1,63 @@
+<Application x:Class="Tango.FSE.UI.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.UI"
+ StartupUri="MainWindow.xaml">
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <!--<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />-->
+
+ <!--<materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="LightBlue" SecondaryColor="Cyan" />
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />-->
+
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.lightblue.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/materialdesigncolor.yellow.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.CheckBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ListBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.RadioButton.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.TextBlock.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Label.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Slider.xaml">
+ </ResourceDictionary>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
+
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Themes/Generic.xaml" />
+
+ <!--<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.CheckBox.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ListBox.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.RadioButton.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.TextBlock.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Label.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Slider.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PackIcon.xaml" />-->
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs
new file mode 100644
index 000000000..9ccc9551e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.FSE.UI
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Authentication/DefaultAuthenticationProvider.cs
new file mode 100644
index 000000000..0dac693df
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Authentication/DefaultAuthenticationProvider.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Authentication;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.BL;
+using Tango.BL.Builders;
+using Tango.BL.Entities;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.FSE.Common;
+using Tango.FSE.Common.Authentication;
+using Tango.FSE.Common.FSEApplication;
+using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.Web;
+using Tango.FSE.Web.Messages;
+using Tango.MachineService.Gateway;
+using Tango.Settings;
+
+namespace Tango.FSE.UI.Authentication
+{
+ /// <summary>
+ /// Represents the default FSE authentication provider.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.FSE.Common.Authentication.IAuthenticationProvider" />
+ public class DefaultAuthenticationProvider : ExtendedObject, IAuthenticationProvider
+ {
+ private FSEWebClient _webClient;
+
+ [TangoInject(TangoInjectMode.WhenAvailable)]
+ private IFSEApplicationManager _appManager;
+
+ /// <summary>
+ /// Gets or sets the navigation manager.
+ /// </summary>
+ [TangoInject(TangoInjectMode.WhenAvailable)]
+ private INavigationManager _navigationManager;
+
+ /// <summary>
+ /// Occurs when the current logged-in user has changed.
+ /// </summary>
+ public event EventHandler<User> CurrentUserChanged;
+
+ private User _currentUser;
+ /// <summary>
+ /// Gets the current logged-in user.
+ /// </summary>
+ public User CurrentUser
+ {
+ get { return _currentUser; }
+ private set
+ {
+ _currentUser = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultAuthenticationProvider"/> class.
+ /// </summary>
+ /// <param name="webClient">The web client.</param>
+ public DefaultAuthenticationProvider(FSEWebClient webClient)
+ {
+ _webClient = webClient;
+ }
+
+ /// <summary>
+ /// Logins the specified email.
+ /// </summary>
+ /// <param name="email">The email.</param>
+ /// <param name="password">The password.</param>
+ /// <param name="environment">The environment.</param>
+ /// <returns></returns>
+ public Task<AuthenticationResult> Login(String email, String password, EnvironmentConfiguration environment)
+ {
+ return Task.Factory.StartNew<AuthenticationResult>(() =>
+ {
+ LogManager.Log($"Logging in user {email}...");
+
+ var settings = SettingsManager.Default.GetOrCreate<FSESettings>();
+
+ settings.LastEnvironmentId = environment.ID;
+
+ if (_appManager.StartupArgs.Contains("-webDebug"))
+ {
+ _webClient.Address = "http://localhost:1111";
+ }
+ else
+ {
+ _webClient.Address = environment.MachineServiceAddress;
+ }
+
+ var appVersion = _appManager.Version.ToString();
+
+ if (settings.ForceVersionUpdate)
+ {
+ appVersion = "1.0.0.0";
+ }
+
+ LoginResponse response = null;
+
+ try
+ {
+ response = _webClient.Login(new LoginRequest()
+ {
+
+ Email = email,
+ Password = password,
+ Version = appVersion,
+
+ }).Result;
+ }
+ catch (Exception ex)
+ {
+ throw new AggregateException(new AuthenticationException("Error logging in to machine service."), ex);
+ }
+
+ if (settings.Environment == FSESettings.WorkingEnvironment.Remote)
+ {
+ ObservablesContext.OverrideSettingsDataSource(response.DataSource);
+ }
+
+ if (response.PasswordChangeRequired)
+ {
+ return new AuthenticationResult() { Response = response };
+ }
+
+ using (var db = ObservablesContext.CreateDefault())
+ {
+ CurrentUser = new UserBuilder(db).Set(x => x.Email.ToLower() == email.ToLower())
+ .WithOrganization()
+ .WithRolesAndPermissions()
+ .Build();
+ }
+
+ if (CurrentUser != null)
+ {
+ LogManager.Log($"Current user is now: {CurrentUser.Contact.FullName}.");
+ }
+ else
+ {
+ throw new AuthenticationException("Login failed for some strange reason.");
+ }
+
+ settings.Save();
+
+ CurrentUserChanged?.Invoke(this, CurrentUser);
+
+ return new AuthenticationResult()
+ {
+ Response = response,
+ User = CurrentUser,
+ };
+ });
+ }
+
+ /// <summary>
+ /// Logs-out the current logged-in user.
+ /// </summary>
+ public void LogOut()
+ {
+ LogManager.Log("Logging out current user.");
+ CurrentUser = null;
+ CurrentUserChanged?.Invoke(this, CurrentUser);
+ _navigationManager.NavigateTo(NavigationView.LoginView);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs
new file mode 100644
index 000000000..2155699ef
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs
@@ -0,0 +1,370 @@
+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.Settings;
+using Tango.Core.DI;
+using Tango.FSE.Common;
+using System.Windows;
+using Tango.Core;
+using System.IO;
+using Tango.Core.Helpers;
+using Tango.FSE.Common.Modules;
+using System.Windows.Threading;
+using System.Data.SqlClient;
+using Tango.BL.Builders;
+using Tango.FSE.Common.Threading;
+using System.Diagnostics;
+using Tango.BL.Enumerations;
+using Tango.FSE.Common.Notifications;
+using Tango.Core.Threading;
+using Tango.Core.ExtensionMethods;
+using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.FSEApplication;
+
+namespace Tango.FSE.UI.FSEApplication
+{
+ /// <summary>
+ /// Represents the default FSE application manager.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.FSE.Common.Application.IFSEApplicationManager" />
+ public class DefaultFSEApplicationManager : ExtendedObject, IFSEApplicationManager
+ {
+ private List<FSEViewModel> _notifiedViewModels;
+ private IDispatcherProvider _dispatcher;
+ private IFSEModuleLoader _moduleLoader;
+ private INotificationProvider _notificationProvider;
+
+ /// <summary>
+ /// Occurs when the application has started.
+ /// </summary>
+ public event EventHandler ApplicationStarted;
+
+ /// <summary>
+ /// Occurs when all FSE modules are ready and initialized.
+ /// </summary>
+ public event EventHandler ModulesInitialized;
+
+ /// <summary>
+ /// Occurs when the application is ready and all modules are views are loaded.
+ /// </summary>
+ public event EventHandler ApplicationReady;
+
+ /// <summary>
+ /// Occurs when the main window content has been rendered.
+ /// </summary>
+ public event EventHandler ContentRendered;
+
+ /// <summary>
+ /// Occurs when the application has encountered an error when initializing.
+ /// </summary>
+ public event EventHandler<Exception> ApplicationInitializationError;
+
+ /// <summary>
+ /// Gets the application startup arguments.
+ /// </summary>
+ public List<String> StartupArgs { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether the application is shutting down.
+ /// </summary>
+ public bool IsShuttingDown { get; private set; }
+
+ /// <summary>
+ /// Gets the application version.
+ /// </summary>
+ public Version Version
+ {
+ get
+ {
+ return AssemblyHelper.GetCurrentAssemblyVersion();
+ }
+ }
+
+ /// <summary>
+ /// Gets the application build date.
+ /// </summary>
+ public String BuildDate
+ {
+ get
+ {
+ return AssemblyHelper.GetCurrentAssemblyBuildDate().ToShortDateString();
+ }
+ }
+
+ /// <summary>
+ /// Gets the application startup date.
+ /// </summary>
+ public DateTime StartUpDate { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether an update has occurred before the application started.
+ /// </summary>
+ public bool IsAfterUpdate { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the application folder.
+ /// </summary>
+ public String StartPath { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultFSEApplicationManager"/> class.
+ /// </summary>
+ public DefaultFSEApplicationManager(IDispatcherProvider dispatcherProvider, IFSEModuleLoader moduleLoader, INotificationProvider notificationProvider)
+ {
+ StartPath = AssemblyHelper.GetCurrentAssemblyFolder();
+ StartupArgs = Environment.GetCommandLineArgs().Skip(1).ToList();
+
+ _notificationProvider = notificationProvider;
+ _dispatcher = dispatcherProvider;
+ _moduleLoader = moduleLoader;
+
+ if (!DesignMode)
+ {
+ _notifiedViewModels = new List<FSEViewModel>();
+
+ MainWindow.Instance.ContentRendered += (_, __) =>
+ {
+ OnMainWindowContentRendered();
+ };
+ }
+ }
+
+ /// <summary>
+ /// Called when the main window content has been rendered
+ /// </summary>
+ private void OnMainWindowContentRendered()
+ {
+ LogManager.Log("Main window content rendered.");
+
+ ContentRendered?.Invoke(this, new EventArgs());
+
+ StartApplication();
+ }
+
+ private async void StartApplication()
+ {
+ FSESettings settings = null;
+
+ bool initialized = false;
+
+ StartUpDate = DateTime.Now;
+
+ await Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ initialized = true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Application Initialization Error!");
+ ApplicationInitializationError?.Invoke(this, ex);
+ return;
+ }
+ });
+
+
+ if (initialized)
+ {
+ try
+ {
+ PostDbInitialize();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Application Post Initialization Error!");
+ ApplicationInitializationError?.Invoke(this, ex);
+ return;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when the database has been initialized
+ /// </summary>
+ private void PostDbInitialize()
+ {
+ LogManager.Log($"Raising {nameof(ApplicationStarted)} event...");
+
+ ApplicationStarted?.Invoke(this, new EventArgs());
+
+ LogManager.Log("Invoking FSE view models OnApplicationStarted methods...");
+ foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<FSEViewModel>())
+ {
+ if (!_notifiedViewModels.Contains(vm))
+ {
+ LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationStarted...");
+ vm.OnApplicationStarted();
+ _notifiedViewModels.Add(vm);
+ }
+ }
+
+ var internalModules = this.GetType().Assembly.GetTypes().Where(xx => typeof(FSEModuleBase).IsAssignableFrom(xx)).ToList();
+
+ LogManager.Log("Waiting for IFSEModuleLoader instance injection...");
+ TangoIOC.Default.GetInstanceWhenAvailable<IFSEModuleLoader>((loader) =>
+ {
+ LogManager.Log("Module loader instance has been registered. Registering for the ModulesLoaded event...");
+
+ loader.ModulesLoaded += (x, y) =>
+ {
+ LogManager.Log("Loading modules views");
+ _dispatcher.InvokeBlock(() =>
+ {
+ foreach (var module in TangoIOC.Default.GetInstance<IFSEModuleLoader>().UserModules)
+ {
+ if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType))
+ {
+ try
+ {
+ LogManager.Log("Loading module view " + module.Name + "...");
+ FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
+ SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
+ Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error loading module view for module {module.Name}.");
+ }
+ }
+ }
+
+ //Adding internal modules.
+ LogManager.Log("Loading internal modules...");
+ foreach (var type in internalModules)
+ {
+ var module = Activator.CreateInstance(type) as IFSEModule;
+ LogManager.Log("Loading module view " + module.Name + "...");
+ FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
+ SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
+ Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
+ _moduleLoader.AllModules.Add(module);
+ _moduleLoader.UserModules.Add(module);
+ }
+ });
+
+ LogManager.Log($"{loader.UserModules.Count} modules loaded.");
+
+ LogManager.Log($"Invoking {nameof(ModulesInitialized)} event.");
+ ModulesInitialized?.Invoke(this, new EventArgs());
+
+ FinalizeModuleInitialization();
+ };
+ });
+ }
+
+ /// <summary>
+ /// Finalizes the module initialization.
+ /// </summary>
+ private void FinalizeModuleInitialization()
+ {
+ var settings = SettingsManager.Default.GetOrCreate<FSESettings>();
+
+ LogManager.Log("Finalizing application initialization...");
+
+ //LogManager.Log("Initializing Machine Provider...");
+ //_machineProvider.Init(_machine, _machineContext);
+
+ //LogManager.Log("Starting Machine Data Synchronizer...");
+ //_machineDataSynchronizer.IsEnabled = true;
+
+ LogManager.Log("Applications initialization completed!");
+
+ LogManager.Log("Checking for un-notified FSE view models...");
+ foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<FSEViewModel>())
+ {
+ if (!_notifiedViewModels.Contains(vm))
+ {
+ LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationStarted...");
+ vm.OnApplicationStarted();
+ _notifiedViewModels.Add(vm);
+ }
+ }
+
+ _dispatcher.Invoke(() =>
+ {
+ LogManager.Log($"Invoking {nameof(ApplicationReady)} event.");
+ ApplicationReady?.Invoke(this, new EventArgs());
+
+ LogManager.Log("Notifying view models about application ready...");
+ foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<FSEViewModel>())
+ {
+ LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationReady...");
+ vm.OnApplicationReady();
+ }
+ });
+ }
+
+ /// <summary>
+ /// Shutdown the application.
+ /// </summary>
+ public void ShutDown()
+ {
+ if (IsShuttingDown) return;
+
+ IsShuttingDown = true;
+
+ try
+ {
+ LogManager.Log("Shutting down application...");
+
+ foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<FSEViewModel>())
+ {
+ vm.OnApplicationShuttingDown();
+ }
+ }
+ catch { }
+
+ Environment.Exit(0);
+ }
+
+ /// <summary>
+ /// Restarts the application.
+ /// </summary>
+ public async void Restart()
+ {
+ if (IsShuttingDown) return;
+
+ IsShuttingDown = true;
+
+ try
+ {
+ _dispatcher.Invoke(() =>
+ {
+ var nav = TangoIOC.Default.GetInstance<INavigationManager>();
+ if (nav != null)
+ {
+ nav.NavigateTo(NavigationView.RestartingView);
+ }
+ });
+
+ LogManager.Log("Restarting the application...");
+
+ await Task.Delay(8000);
+
+ foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<FSEViewModel>())
+ {
+ vm.OnApplicationShuttingDown();
+ }
+ }
+ catch { }
+
+ //try
+ //{
+ // if (_machineProvider.MachineOperator.State == Transport.TransportComponentState.Connected)
+ // {
+ // _machineProvider.MachineOperator.Adapter.Disconnect().Wait();
+ // }
+ //}
+ //catch { }
+
+ Process.Start(Application.ResourceAssembly.Location);
+ Environment.Exit(0);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Gateway/DefaultGatewayService.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Gateway/DefaultGatewayService.cs
new file mode 100644
index 000000000..c003ce59c
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Gateway/DefaultGatewayService.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Configuration;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.FSE.Common.Gateway;
+using Tango.MachineService.Gateway;
+
+namespace Tango.FSE.UI.Gateway
+{
+ public class DefaultGatewayService : ExtendedObject, IGatewayService
+ {
+ private ReadOnlyObservableCollection<EnvironmentConfiguration> _environments;
+ public ReadOnlyObservableCollection<EnvironmentConfiguration> Environments
+ {
+ get { return _environments; }
+ set { _environments = value; RaisePropertyChangedAuto(); }
+ }
+
+
+ public async Task<List<EnvironmentConfiguration>> GetEnvironments()
+ {
+ using (HttpClient http = new HttpClient())
+ {
+ GatewayClient client = new GatewayClient(ConfigurationManager.AppSettings.Get("GatewayUrl"), http);
+ var list = (await client.GetEnvironmentsAsync(new EnvironmentsRequest())).Environments.ToList();
+ Environments = new ReadOnlyObservableCollection<EnvironmentConfiguration>(new ObservableCollection<EnvironmentConfiguration>(list));
+ return list;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
new file mode 100644
index 000000000..4802e7b57
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
@@ -0,0 +1,22 @@
+<mahapps:MetroWindow x:Class="Tango.FSE.UI.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:views="clr-namespace:Tango.FSE.UI.Views"
+ xmlns:local="clr-namespace:Tango.FSE.UI"
+ mc:Ignorable="d"
+ Title="Tango FSE" Height="720" Width="1280"
+ WindowStartupLocation="CenterScreen"
+ TextElement.Foreground="{StaticResource FSE_PrimaryForegroundBrush}"
+ Background="{StaticResource FSE_PrimaryBackgroundBrush}"
+ TextElement.FontWeight="Medium"
+ TextElement.FontSize="14"
+ TitleCharacterCasing="Normal" EnableDWMDropShadow="True" BorderThickness="1" BorderBrush="Gray">
+
+ <Grid>
+ <views:MainView/>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml.cs
new file mode 100644
index 000000000..28385d2dc
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml.cs
@@ -0,0 +1,32 @@
+using MahApps.Metro.Controls;
+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.UI
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : MetroWindow
+ {
+ public static MainWindow Instance { get; set; }
+
+ public MainWindow()
+ {
+ Instance = this;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Modules/DefaultFSEModuleLoader.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Modules/DefaultFSEModuleLoader.cs
new file mode 100644
index 000000000..7c5c6ce39
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Modules/DefaultFSEModuleLoader.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.BL.Entities;
+using Tango.Logging;
+using Tango.FSE.Common.Modules;
+using Tango.FSE.Common;
+using System.Windows.Data;
+using Tango.Core.DI;
+using Tango.FSE.Common.Authentication;
+
+namespace Tango.FSE.UI.Modules
+{
+ /// <summary>
+ /// Represents the default PPC <see cref="IPPCModuleLoader"></see>.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.PPC.Common.Modules.IPPCModuleLoader" />
+ public class DefaultFSEModuleLoader : ExtendedObject, IFSEModuleLoader
+ {
+ private static object _syncObject = new object();
+ private IAuthenticationProvider _authenticationProvider;
+ private bool _loaded;
+
+ /// <summary>
+ /// Occurs when the user has logged in and user modules are loaded.
+ /// </summary>
+ public event EventHandler ModulesLoaded;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultFSEModuleLoader"/> class.
+ /// </summary>
+ /// <param name="authenticationProvider">The authentication provider.</param>
+ public DefaultFSEModuleLoader(IAuthenticationProvider authenticationProvider)
+ {
+ _authenticationProvider = authenticationProvider;
+ AllModules = new ObservableCollection<IFSEModule>();
+ UserModules = new ObservableCollection<IFSEModule>();
+
+ BindingOperations.EnableCollectionSynchronization(UserModules, _syncObject);
+
+ _authenticationProvider.CurrentUserChanged += _authenticationProvider_CurrentUserChanged;
+ }
+
+ /// <summary>
+ /// Handles the authentication provider user changed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
+ private void _authenticationProvider_CurrentUserChanged(object sender, User e)
+ {
+ LoadModules();
+ }
+
+ private ObservableCollection<IFSEModule> _allModules;
+ /// <summary>
+ /// Gets all loaded modules.
+ /// </summary>
+ public ObservableCollection<IFSEModule> AllModules
+ {
+ get { return _allModules; }
+ private set { _allModules = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<IFSEModule> _userModules;
+ /// <summary>
+ /// Gets all the user permitted modules.
+ /// </summary>
+ public ObservableCollection<IFSEModule> UserModules
+ {
+ get { return _userModules; }
+ private set { _userModules = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Loads all available PPC modules.
+ /// </summary>
+ public void LoadModules()
+ {
+ if (!_loaded)
+ {
+ AllModules.Clear();
+ string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+
+ foreach (var file in Directory.GetFiles(assemblyFolder, "*.dll").Where(x => x.Contains("Tango.FSE")))
+ {
+ try
+ {
+ Assembly moduleAssembly = null;
+ moduleAssembly = Assembly.LoadFrom(file);
+
+ if (moduleAssembly != null)
+ {
+ foreach (var moduleType in moduleAssembly.GetLoadableTypes().Where(x => !x.IsInterface && typeof(IFSEModule).IsAssignableFrom(x) && !x.IsAbstract))
+ {
+ if (!AllModules.ToList().Exists(x => x.GetType() == moduleType))
+ {
+ try
+ {
+ LogManager.Log(String.Format("Loading module '{0}'...", moduleType.Name));
+ var module = Activator.CreateInstance(moduleType) as IFSEModule;
+ AllModules.Add(module);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Could not load module " + moduleType.Name);
+ }
+ }
+ }
+ }
+ }
+ catch { }
+ }
+
+ _loaded = true;
+ }
+
+ AllModules = AllModules.OrderBy(x => x.GetType().GetCustomAttribute<FSEModuleAttribute>().Index).ToObservableCollection();
+
+ UserModules.Clear();
+
+ if (_authenticationProvider.CurrentUser != null)
+ {
+ UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection();
+ }
+
+ ModulesLoaded?.Invoke(this, new EventArgs());
+ }
+
+ /// <summary>
+ /// Gets the PPC module of type T if loaded.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public T GetFSEModule<T>() where T : IFSEModule
+ {
+ return UserModules.OfType<T>().FirstOrDefault();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs
new file mode 100644
index 000000000..66d2bb40b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs
@@ -0,0 +1,539 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.FSE.Common;
+using Tango.FSE.Common.Modules;
+using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Threading;
+using Tango.FSE.UI.Views;
+using Tango.SharedUI.Controls;
+
+namespace Tango.FSE.UI.Navigation
+{
+ /// <summary>
+ /// Represents the default FSE navigation manager.
+ /// </summary>
+ /// <seealso cref="Tango.FSE.Common.Navigation.INavigationManager" />
+ public class DefaultNavigationManager : ExtendedObject, INavigationManager
+ {
+ //private event Action<Object, Object> NavigationCycleCompleted;
+ //private event Action<Object, Object> BeforeNavigationCycleCompleted;
+ private class AwaitingVMResult
+ {
+ public FSEViewModel FromVM { get; set; }
+ public FSEViewModel ToVM { get; set; }
+ public Action Action { get; set; }
+ }
+
+ private List<AwaitingVMResult> _awaitingVMResults;
+ private IDispatcherProvider _dispatcherProvider;
+ private IFSEModuleLoader _moduleLoader;
+ private INotificationProvider _notificationProvider;
+ private Object _currentVM;
+ private String _lastFullPath;
+ private bool _preventHistory;
+ private bool _navigating_back;
+
+ private Stack<String> _navigationHistory;
+
+ /// <summary>
+ /// Gets the current view model.
+ /// </summary>
+ public FSEViewModel CurrentVM
+ {
+ get { return _currentVM as FSEViewModel; }
+ }
+
+ private IFSEModule _currentModule;
+ /// <summary>
+ /// Gets or sets the current module.
+ /// </summary>
+ public IFSEModule CurrentModule
+ {
+ get { return _currentModule; }
+ private set { _currentModule = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Navigates to the previous view.
+ /// </summary>
+ public RelayCommand NavigateBackCommand { get; private set; }
+
+ /// <summary>
+ /// Navigates to the specified full path in command parameter.
+ /// </summary>
+ public RelayCommand<String> NavigateToCommand { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class.
+ /// </summary>
+ /// <param name="moduleLoader">The module loader.</param>
+ public DefaultNavigationManager(IFSEModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider)
+ {
+ IsBackEnabled = true;
+ _awaitingVMResults = new List<AwaitingVMResult>();
+ _navigationHistory = new Stack<String>();
+ _moduleLoader = moduleLoader;
+ _notificationProvider = notificationProvider;
+
+ NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x));
+ NavigateBackCommand = new RelayCommand(async () => await NavigateBack());
+
+ _dispatcherProvider = dispatcherProvider;
+ }
+
+ /// <summary>
+ /// Navigates to the specified FSE view.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ public Task<bool> NavigateTo(NavigationView view, bool pushToHistory = true)
+ {
+ if (view == NavigationView.Home)
+ {
+ _navigationHistory.Clear();
+ _lastFullPath = null;
+
+ var firstModule = _moduleLoader.UserModules.FirstOrDefault();
+
+ if (firstModule != null)
+ {
+ var moduleAtt = firstModule.GetType().GetCustomAttribute<FSEModuleAttribute>();
+
+ if (moduleAtt != null)
+ {
+ return NavigateTo(firstModule.GetType(), pushToHistory, moduleAtt.HomeViewName);
+ }
+ else
+ {
+ return NavigateTo(firstModule.GetType(), pushToHistory);
+ }
+ }
+ else
+ {
+ return NavigateTo(NavigationView.NoPermissionsView);
+ }
+ }
+ else
+ {
+
+ LogManager.Log($"Navigating to: {view.ToString()}...");
+
+ var fromView = MainView.Instance.NavigationControl.SelectedElement;
+ FrameworkElement toView = null;
+
+ toView = MainView.Instance.NavigationControl.NavigateTo(view.ToString(), () =>
+ {
+ _currentVM = toView.DataContext;
+ NotifyOnNavigated(fromView.DataContext, toView.DataContext);
+
+ });
+
+ NotifyOnBeforeNavigated(fromView.DataContext, toView.DataContext);
+
+ return Task.FromResult(true);
+ }
+ }
+
+ /// <summary>
+ /// Navigates to the specified FSE view with the specified receive object.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ /// <param name="obj"></param>
+ /// <param name="pushToHistory"></param>
+ /// <returns></returns>
+ public Task<bool> NavigateWithObject<TPass>(NavigationView view, TPass obj, bool pushToHistory = true)
+ {
+ LogManager.Log($"Navigating to: {view.ToString()}, with object {typeof(TPass).Name}...");
+ MainView.Instance.NavigationControl.NavigateTo(view.ToString());
+ INavigationObjectReceiver<TPass> receiver = MainView.Instance.NavigationControl.Elements.FirstOrDefault(x => (x.GetType().Name == view.ToString() || NavigationControl.GetNavigationName(x) == view.ToString()) && x.DataContext is INavigationObjectReceiver<TPass>).DataContext as INavigationObjectReceiver<TPass>;
+
+ if (receiver != null)
+ {
+ receiver.OnNavigatedToWithObject(obj);
+ }
+
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Navigates to the specified module.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public Task<bool> NavigateTo<T>(bool pushToHistory = true) where T : IFSEModule
+ {
+ return NavigateTo(typeof(T));
+ }
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView.JobsView).
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ public Task<bool> NavigateTo<T>(string viewPath, bool pushToHistory = true) where T : IFSEModule
+ {
+ return NavigateTo<T>(pushToHistory, viewPath.Split('.'));
+ }
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView,JobsView).
+ /// This method makes it easy to do stuff like NavigateTo(nameof(MainView),nameof(JobsView));
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ public Task<bool> NavigateTo<T>(bool pushToHistory = true, params String[] viewPath) where T : IFSEModule
+ {
+ return NavigateTo(typeof(T), pushToHistory, viewPath);
+ }
+
+ /// <summary>
+ /// Navigates to the specified module and view by full path (e.g Jobs.JobsView).
+ /// </summary>
+ /// <param name="fullPath">The full path.</param>
+ public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<FSEViewModel, FSEViewModel> onNavigating = null, Action<FSEViewModel, FSEViewModel> onNavigated = null)
+ {
+ try
+ {
+ String[] path = fullPath.Split('.');
+ var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]);
+
+ if (module == null)
+ {
+ await _notificationProvider.ShowError("The specified module was not loaded.");
+ return false;
+ }
+
+ if (path.Length == 1 && path[0] == CurrentModule.Name) return true;
+
+ LogManager.Log($"Navigating to: {fullPath}...");
+
+ var fromVM = _currentVM;
+
+ if (_currentVM != null && _currentVM is INavigationBlocker)
+ {
+ if (_navigating_back)
+ {
+ if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest())
+ {
+ return false;
+ }
+ }
+ }
+
+
+
+ if (pushToHistory && _lastFullPath != null && !_preventHistory)
+ {
+ _navigationHistory.Push(_lastFullPath);
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ }
+
+ _lastFullPath = fullPath;
+
+ MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString());
+ var navigationControl = LayoutView.Instance.NavigationControl;
+ CurrentModule = module;
+ var moduleView = navigationControl.NavigateTo(module.Name);
+
+ _currentVM = moduleView.DataContext;
+
+ if (path.Length > 1)
+ {
+ var moduleNavigation = moduleView.FindChildOffline<NavigationControl>();
+
+ if (moduleNavigation != null)
+ {
+ moduleNavigation.RegisterForLoadedOrNow(async (x, e) =>
+ {
+ var lastView = moduleNavigation.GetElement(path.Last());
+
+ if (lastView != null)
+ {
+ onNavigating?.Invoke(fromVM as FSEViewModel, lastView.DataContext as FSEViewModel);
+ }
+
+ foreach (var view in path.Skip(1))
+ {
+ await Task.Delay(100);
+
+ FrameworkElement v = null;
+
+ v = moduleNavigation.NavigateTo(view, () =>
+ {
+ if (v != null)
+ {
+ NotifyOnNavigated(fromVM, v.DataContext);
+ onNavigated?.Invoke(fromVM as FSEViewModel, v.DataContext as FSEViewModel);
+ NotifyAwaitingVMResults(fromVM as FSEViewModel, v.DataContext as FSEViewModel);
+ }
+ });
+
+ NotifyOnBeforeNavigated(fromVM, v.DataContext);
+
+ if (v != null)
+ {
+ _currentVM = v.DataContext;
+
+ if (view != path.Last())
+ {
+ moduleNavigation = v.FindChildOffline<NavigationControl>();
+ }
+ }
+ else
+ {
+ throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath));
+ }
+ }
+ });
+ }
+ else
+ {
+ onNavigating?.Invoke(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+
+ NotifyOnBeforeNavigated(fromVM, _currentVM);
+
+ await Task.Delay(navigationControl.TransitionDuration.TimeSpan);
+
+ NotifyOnNavigated(fromVM, _currentVM);
+
+ onNavigated?.Invoke(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+ NotifyAwaitingVMResults(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+ }
+ }
+ else
+ {
+ NotifyOnBeforeNavigated(fromVM, _currentVM);
+
+ onNavigating?.Invoke(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+
+ await Task.Delay(navigationControl.TransitionDuration.TimeSpan);
+
+ NotifyOnNavigated(fromVM, _currentVM);
+
+ onNavigated?.Invoke(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+ NotifyAwaitingVMResults(fromVM as FSEViewModel, _currentVM as FSEViewModel);
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ await _notificationProvider.ShowError($"Error navigating to '{fullPath}'.");
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Navigates for result.
+ /// </summary>
+ /// <typeparam name="TModule">The type of the module.</typeparam>
+ /// <typeparam name="TView">The type of the view.</typeparam>
+ /// <typeparam name="TResult">The type of the result.</typeparam>
+ /// <typeparam name="TObject">The type of the object.</typeparam>
+ /// <param name="obj">The object.</param>
+ /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
+ /// <returns></returns>
+ public async Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true)
+ where TModule : IFSEModule
+ {
+ TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>();
+
+ var fromVM = _currentVM;
+
+ await NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (from, to) =>
+ {
+ _awaitingVMResults.Add(new AwaitingVMResult()
+ {
+ FromVM = fromVM as FSEViewModel,
+ ToVM = to as FSEViewModel,
+ Action = () =>
+ {
+ if (to is INavigationResultProvider<TResult, TObject>)
+ {
+ source.SetResult((to as INavigationResultProvider<TResult, TObject>).GetNavigationResult());
+ }
+ }
+ });
+
+ if (to is INavigationResultProvider<TResult, TObject>)
+ {
+ (to as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj);
+ }
+ });
+
+ return await source.Task;
+ }
+
+ /// <summary>
+ /// Navigates to the specified module and view with the specified object.
+ /// </summary>
+ /// <typeparam name="TModule">The type of the module.</typeparam>
+ /// <typeparam name="TView">The type of the view.</typeparam>
+ /// <typeparam name="TPass">The type of the pass.</typeparam>
+ /// <param name="obj">The object.</param>
+ /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
+ /// <returns></returns>
+ public Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true) where TModule : IFSEModule
+ {
+ return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) =>
+ {
+ if (toVM is INavigationObjectReceiver<TPass>)
+ {
+ (toVM as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj);
+ }
+ });
+ }
+
+ private Task<bool> NavigateTo(Type moduleType, bool pushToHistory = true, params String[] viewPath)
+ {
+ if (viewPath != null && viewPath.Length > 0)
+ {
+ return NavigateTo(moduleType.Name + "." + String.Join(".", viewPath), pushToHistory);
+ }
+ else
+ {
+ return NavigateTo(moduleType.Name, pushToHistory);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the navigation system is able to navigate to the previous view.
+ /// </summary>
+ public bool CanNavigateBack
+ {
+ get { return _navigationHistory.Count > 0; }
+ }
+
+ private bool _isBackEnabled;
+ /// <summary>
+ /// Gets a value indicating whether the back should be enabled.
+ /// </summary>
+ public bool IsBackEnabled
+ {
+ get { return _isBackEnabled; }
+ set { _isBackEnabled = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Navigates to the previous view if <see cref="P:Tango.FSE.Common.Navigation.INavigationManager.CanNavigateBack" /> is true.
+ /// </summary>
+ public async Task<bool> NavigateBack()
+ {
+ LogManager.Log("Navigating back...");
+
+ _navigating_back = true;
+
+ if (_navigationHistory.Count > 0)
+ {
+ String first = _navigationHistory.Pop();
+ _preventHistory = true;
+
+ if (await NavigateTo(first))
+ {
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ _preventHistory = false;
+ _navigating_back = false;
+ return true;
+ }
+ else
+ {
+ _navigationHistory.Push(first);
+ _preventHistory = false;
+ _navigating_back = false;
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ return false;
+ }
+ }
+ else
+ {
+ await NavigateTo(NavigationView.Home);
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ _preventHistory = false;
+ _navigating_back = false;
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Clears the navigation back history.
+ /// </summary>
+ public void ClearHistory()
+ {
+ LogManager.Log("Navigation history cleared.");
+ _navigationHistory.Clear();
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ }
+
+ /// <summary>
+ /// Clears the navigation back history except the specified view type.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public void ClearHistoryExcept<T>()
+ {
+ LogManager.Log($"Navigation history cleared except for {typeof(T).Name}.");
+
+ var history_list = _navigationHistory.ToList();
+ history_list = history_list.Where(x => x.Contains(typeof(T).Name)).Distinct().ToList();
+ _navigationHistory.Clear();
+
+ foreach (var item in history_list)
+ {
+ _navigationHistory.Push(item);
+ }
+
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ }
+
+ private void NotifyOnBeforeNavigated(object fromVM, object toVM)
+ {
+ if (fromVM is FSEViewModel)
+ {
+ (fromVM as FSEViewModel)?.OnBeforeNavigatedFrom();
+ }
+
+ if (toVM is FSEViewModel)
+ {
+ (toVM as FSEViewModel)?.OnBeforeNavigatedTo();
+ }
+ }
+
+ private void NotifyOnNavigated(object fromVM, object toVM)
+ {
+ if (fromVM is FSEViewModel)
+ {
+ (fromVM as FSEViewModel)?.OnNavigatedFrom();
+ }
+
+ if (toVM is FSEViewModel)
+ {
+ (toVM as FSEViewModel)?.OnNavigatedTo();
+ (toVM as FSEViewModel)?.OnNavigatedTo(fromVM as FSEViewModel);
+ }
+ }
+
+ private void NotifyAwaitingVMResults(FSEViewModel fromVM, FSEViewModel toVM)
+ {
+ var awaiter = _awaitingVMResults.SingleOrDefault(x => x.FromVM == toVM && x.ToVM == fromVM);
+ if (awaiter != null)
+ {
+ _awaitingVMResults.Remove(awaiter);
+ awaiter.Action();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs
new file mode 100644
index 000000000..c3c541486
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs
@@ -0,0 +1,547 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+using Tango.FSE.Common.Notifications;
+using Tango.Core;
+using System.Collections.Concurrent;
+using System.Windows.Media.Imaging;
+using Tango.SharedUI.Helpers;
+using System.Timers;
+using Tango.Core.Commands;
+using Tango.SharedUI;
+using System.Reflection;
+using Tango.Core.DI;
+using System.ComponentModel;
+using System.Windows.Data;
+using MaterialDesignThemes.Wpf;
+
+namespace Tango.FSE.UI.Notifications
+{
+ /// <summary>
+ /// Represents the default FSE notification provider.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.FSE.Common.Notifications.INotificationProvider" />
+ public class DefaultNotificationProvider : ExtendedObject, INotificationProvider
+ {
+ private ConcurrentQueue<PendingNotification<MessageBoxVM, bool>> _pendingMessageBoxes;
+ private ConcurrentQueue<PendingNotification<DialogAndView, DialogViewVM>> _pendingDialogs;
+ private List<AppButton> _appButtons;
+
+ private bool _notificationsVisible;
+ /// <summary>
+ /// Gets or sets a value indicating whether to allow notifications visibility.
+ /// </summary>
+ public bool NotificationsVisible
+ {
+ get { return _notificationsVisible; }
+ set { _notificationsVisible = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets the collection of notification items.
+ /// </summary>
+ public ObservableCollection<NotificationItem> NotificationItems { get; private set; }
+
+ /// <summary>
+ /// Gets the notification items view.
+ /// </summary>
+ public ICollectionView NotificationItemsView { get; private set; }
+
+ /// <summary>
+ /// Gets the collection of taskbar items.
+ /// </summary>
+ public ObservableCollection<TaskBarItem> TaskBarItems { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultNotificationProvider"/> class.
+ /// </summary>
+ public DefaultNotificationProvider()
+ {
+ NotificationsVisible = true;
+ NotificationItems = new ObservableCollection<NotificationItem>();
+ TaskBarItems = new ObservableCollection<TaskBarItem>();
+ _pendingMessageBoxes = new ConcurrentQueue<PendingNotification<MessageBoxVM, bool>>();
+ _pendingDialogs = new ConcurrentQueue<PendingNotification<DialogAndView, DialogViewVM>>();
+ _appButtons = new List<AppButton>();
+
+ PopNotificationCommand = new RelayCommand<NotificationItem>((x) => PopNotification(x));
+
+ NotificationItems.EnableCrossThreadOperations();
+
+ NotificationItemsView = CollectionViewSource.GetDefaultView(NotificationItems);
+ NotificationItemsView.SortDescriptions.Add(new SortDescription(nameof(NotificationItem.Priority), ListSortDirection.Descending));
+ }
+
+ private MessageBoxVM _currentMessageBox;
+ /// <summary>
+ /// Gets the current message box if any.
+ /// </summary>
+ public MessageBoxVM CurrentMessageBox
+ {
+ get { return _currentMessageBox; }
+ private set
+ {
+ _currentMessageBox = value;
+ RaisePropertyChangedAuto();
+ RaisePropertyChanged(nameof(HasMessageBox));
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether a message box is available.
+ /// </summary>
+ public bool HasMessageBox
+ {
+ get
+ {
+ return CurrentMessageBox != null;
+ }
+ }
+
+ private FrameworkElement _currentDialog;
+ /// <summary>
+ /// Gets the current dialog if any.
+ /// </summary>
+ public FrameworkElement CurrentDialog
+ {
+ get { return _currentDialog; }
+ private set
+ {
+ _currentDialog = value;
+ RaisePropertyChangedAuto();
+ RaisePropertyChanged(nameof(HasDialog));
+ }
+ }
+
+ private AppButton _currentAppButton;
+ /// <summary>
+ /// Gets the current app button.
+ /// </summary>
+ public AppButton CurrentAppButton
+ {
+ get { return _currentAppButton; }
+ private set { _currentAppButton = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether a dialog is available.
+ /// </summary>
+ public bool HasDialog
+ {
+ get
+ {
+ return CurrentDialog != null;
+ }
+ }
+
+ /// <summary>
+ /// Shows an error message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public Task ShowError(string message)
+ {
+ return ShowMessageBox(new MessageBoxVM()
+ {
+ Message = message,
+ Title = "Error",
+ Type = MessageType.Error,
+ });
+ }
+ /// <summary>
+ /// Shows an information message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public Task ShowInfo(string message)
+ {
+ return ShowMessageBox(new MessageBoxVM()
+ {
+ Message = message,
+ Title = "Information",
+ Type = MessageType.Info,
+ });
+ }
+
+ /// <summary>
+ /// Shows warning message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public Task ShowWarning(string message)
+ {
+ return ShowMessageBox(new MessageBoxVM()
+ {
+ Message = message,
+ Title = "Warning",
+ Type = MessageType.Warning,
+ });
+ }
+
+ /// <summary>
+ /// Shows a question message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public Task<bool> ShowQuestion(string message)
+ {
+ return ShowMessageBox(new MessageBoxVM()
+ {
+ Message = message,
+ Title = "Confirm",
+ HasCancel = true,
+ Type = MessageType.Info,
+ });
+ }
+
+ /// <summary>
+ /// Shows a success message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public Task ShowSuccess(string message)
+ {
+ return ShowMessageBox(new MessageBoxVM()
+ {
+ Message = message,
+ Title = "Success",
+ Type = MessageType.Success,
+ });
+ }
+
+ /// <summary>
+ /// Shows the message box.
+ /// </summary>
+ /// <param name="vm">The view model.</param>
+ /// <returns></returns>
+ private Task<bool> ShowMessageBox(MessageBoxVM vm)
+ {
+ ReleaseGlobalBusyMessage();
+
+ LogManager.Log($"Displaying MessagBox '{vm.Message}'.");
+
+ TaskCompletionSource<bool> source = new TaskCompletionSource<bool>();
+
+ vm.Accepted += () => { OnMessageBoxClosed(); source.SetResult(true); };
+ vm.Canceled += () => { OnMessageBoxClosed(); source.SetResult(false); };
+
+ if (CurrentMessageBox == null)
+ {
+ CurrentMessageBox = vm;
+ }
+ else
+ {
+ _pendingMessageBoxes.Enqueue(new PendingNotification<MessageBoxVM, bool>(vm, source));
+ }
+
+ return source.Task;
+ }
+
+ /// <summary>
+ /// Called when the message box has been closed.
+ /// </summary>
+ private void OnMessageBoxClosed()
+ {
+ LogManager.Log("MessageBox closed.");
+
+ CurrentMessageBox = null;
+
+ if (_pendingMessageBoxes.Count > 0)
+ {
+ PendingNotification<MessageBoxVM, bool> p = null;
+ if (_pendingMessageBoxes.TryDequeue(out p))
+ {
+ CurrentMessageBox = p.Item;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Inserts the notification item to the bottom of the notifications collection.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns></returns>
+ public NotificationItem PushNotification(NotificationItem item)
+ {
+ LogManager.Log($"Pushing NotificationItem '{item.GetType().Name}'.");
+ item.RemoveAction = () => { PopNotification(item); };
+ NotificationItems.Insert(0, item);
+ RaisePropertyChanged(nameof(HasNotificationItems));
+ return item;
+ }
+
+ /// <summary>
+ /// Pushes the notification.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public NotificationItem PushNotification<T>() where T : NotificationItem
+ {
+ return PushNotification(Activator.CreateInstance<T>());
+ }
+
+ /// <summary>
+ /// Removed the specified notification item.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ public void PopNotification(NotificationItem item)
+ {
+ LogManager.Log($"Popping out NotificationItem '{item.GetType().Name}'.");
+ NotificationItems.Remove(item);
+ RaisePropertyChanged(nameof(HasNotificationItems));
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has notification items.
+ /// </summary>
+ public bool HasNotificationItems
+ {
+ get
+ {
+ return NotificationItems.Count > 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the pop notification command.
+ /// </summary>
+ public RelayCommand<NotificationItem> PopNotificationCommand { get; private set; }
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="datacontext">The data context.</param>
+ /// <param name="view">The view.</param>
+ /// <returns></returns>
+ public async Task<T> ShowDialog<T>(T datacontext, FrameworkElement view) where T : DialogViewVM
+ {
+ view.DataContext = datacontext;
+
+ TangoIOC.Default.Inject(datacontext);
+
+ view.Loaded += (_, __) =>
+ {
+ view.DataContext = datacontext;
+ datacontext.OnShow();
+ };
+
+ TaskCompletionSource<DialogViewVM> source = new TaskCompletionSource<DialogViewVM>();
+
+ datacontext.Accepted += () => { OnDialogClosed(); source.SetResult(datacontext); };
+ datacontext.Canceled += () => { OnDialogClosed(); source.SetResult(datacontext); };
+
+ if (CurrentDialog == null)
+ {
+ CurrentDialog = view;
+ }
+ else
+ {
+ _pendingDialogs.Enqueue(new PendingNotification<DialogAndView, DialogViewVM>(new DialogAndView(datacontext, view), source));
+ }
+
+ var result = await source.Task;
+ return result as T;
+ }
+
+ /// <summary>
+ /// Called when [dialog closed].
+ /// </summary>
+ private void OnDialogClosed()
+ {
+ CurrentDialog = null;
+
+ if (_pendingDialogs.Count > 0)
+ {
+ PendingNotification<DialogAndView, DialogViewVM> p = null;
+ if (_pendingDialogs.TryDequeue(out p))
+ {
+ CurrentDialog = p.Item.View;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// The notification provider will try to locate the view automatically using conventions.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="datacontext">The data context.</param>
+ /// <returns></returns>
+ public Task<T> ShowDialog<T>(T datacontext) where T : DialogViewVM
+ {
+ var callingAssembly = datacontext.GetType().Assembly;
+ String viewName = datacontext.GetType().FullName.Replace("VM", "");
+ var viewType = callingAssembly.GetType(viewName);
+
+ if (viewType == null)
+ {
+ throw new NullReferenceException("View type for " + datacontext.GetType().Name + " could not be found!");
+ }
+
+ var view = Activator.CreateInstance(viewType) as FrameworkElement;
+
+ if (view == null)
+ {
+ throw new NullReferenceException("The view " + viewType.ToString() + " is not of type framework element.");
+ }
+
+ return ShowDialog<T>(datacontext, view);
+ }
+
+ /// <summary>
+ /// Displays the specified dialog in a modal design.
+ /// The data context instance will be automatically created.
+ /// The notification provider will try to locate the view automatically using conventions.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public Task<T> ShowDialog<T>() where T : DialogViewVM
+ {
+ return ShowDialog<T>(Activator.CreateInstance<T>());
+ }
+
+ /// <summary>
+ /// Sets the global busy message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ public void SetGlobalBusyMessage(string message)
+ {
+ GlobalBusyMessage = message;
+ IsInGlobalBusyState = true;
+
+ RaisePropertyChanged(nameof(IsInGlobalBusyState));
+ RaisePropertyChanged(nameof(GlobalBusyMessage));
+ }
+
+ /// <summary>
+ /// Releases the global busy message.
+ /// </summary>
+ public void ReleaseGlobalBusyMessage()
+ {
+ GlobalBusyMessage = null;
+ IsInGlobalBusyState = false;
+
+ RaisePropertyChanged(nameof(IsInGlobalBusyState));
+ RaisePropertyChanged(nameof(GlobalBusyMessage));
+ }
+
+ /// <summary>
+ /// Gets the current global busy message.
+ /// </summary>
+ public string GlobalBusyMessage { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance is in global busy state.
+ /// </summary>
+ public bool IsInGlobalBusyState { get; private set; }
+
+ private AppBarItem _currentAppBarItem;
+ /// <summary>
+ /// Gets the current application bar item.
+ /// </summary>
+ public AppBarItem CurrentAppBarItem
+ {
+ get { return _currentAppBarItem; }
+ set { _currentAppBarItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasAppBarItem)); }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance has application bar item.
+ /// </summary>
+ public bool HasAppBarItem
+ {
+ get { return CurrentAppBarItem != null; }
+ }
+
+ /// <summary>
+ /// Pushes the application bar item.
+ /// </summary>
+ /// <param name="appBarItem">The application bar item.</param>
+ /// <returns></returns>
+ public AppBarItem PushAppBarItem(AppBarItem appBarItem)
+ {
+ LogManager.Log($"Pushing AppBarItem '{appBarItem.GetType().Name}'.");
+ CurrentAppBarItem = appBarItem;
+ appBarItem.RemoveAction = () => PopAppBarItem(appBarItem);
+ return appBarItem;
+ }
+
+ /// <summary>
+ /// Pushes the application bar item.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public AppBarItem PushAppBarItem<T>() where T : AppBarItem
+ {
+ return PushAppBarItem(Activator.CreateInstance<T>());
+ }
+
+ /// <summary>
+ /// Pops the application bar item.
+ /// </summary>
+ /// <param name="appBarItem">The application bar item.</param>
+ public void PopAppBarItem(AppBarItem appBarItem)
+ {
+ LogManager.Log($"Popping out AppBarItem '{appBarItem.GetType().Name}'.");
+ CurrentAppBarItem = null;
+ }
+
+ /// <summary>
+ /// Pushes the task bar item.
+ /// </summary>
+ /// <param name="taskBarItem">The task bar item.</param>
+ /// <returns></returns>
+ public TaskBarItem PushTaskBarItem(TaskBarItem taskBarItem)
+ {
+ TaskBarItems.Add(taskBarItem);
+ return taskBarItem;
+ }
+
+ /// <summary>
+ /// Handles the Push Task Bar Item event.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public TaskBarItem PushTaskBarItem<T>() where T : TaskBarItem
+ {
+ return PushTaskBarItem(Activator.CreateInstance<T>());
+ }
+
+ /// <summary>
+ /// Pops the task bar item.
+ /// </summary>
+ /// <param name="taskBarItem"></param>
+ public void PopTaskBarItem(TaskBarItem taskBarItem)
+ {
+ TaskBarItems.Remove(taskBarItem);
+ }
+
+ /// <summary>
+ /// Pushes the app button.
+ /// </summary>
+ /// <param name="appButton">The app button.</param>
+ public void PushAppButton(AppButton appButton)
+ {
+ _appButtons.Insert(0, appButton);
+ CurrentAppButton = appButton;
+ }
+
+ /// <summary>
+ /// Pops the app button.
+ /// </summary>
+ /// <param name="appButton">The app button.</param>
+ public void PopAppButton(AppButton appButton)
+ {
+ _appButtons.RemoveAll(x => x == appButton);
+
+ CurrentAppButton = _appButtons.FirstOrDefault();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DialogAndView.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DialogAndView.cs
new file mode 100644
index 000000000..47d8ba762
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DialogAndView.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.SharedUI;
+
+namespace Tango.FSE.UI.Notifications
+{
+ /// <summary>
+ /// Represents a dialog and view couple.
+ /// </summary>
+ public class DialogAndView
+ {
+ /// <summary>
+ /// Gets or sets the vm.
+ /// </summary>
+ public DialogViewVM VM { get; set; }
+
+ /// <summary>
+ /// Gets or sets the view.
+ /// </summary>
+ public FrameworkElement View { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DialogAndView"/> class.
+ /// </summary>
+ public DialogAndView()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DialogAndView"/> class.
+ /// </summary>
+ /// <param name="vm">The vm.</param>
+ /// <param name="view">The view.</param>
+ public DialogAndView(DialogViewVM vm, FrameworkElement view) : this()
+ {
+ VM = vm;
+ View = view;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/PendingNotification.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/PendingNotification.cs
new file mode 100644
index 000000000..8eedcd362
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/PendingNotification.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.UI.Notifications
+{
+ /// <summary>
+ /// Represents a pending notification item.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <typeparam name="TResult">The type of the result.</typeparam>
+ public class PendingNotification<T, TResult>
+ {
+ /// <summary>
+ /// Gets or sets the item.
+ /// </summary>
+ public T Item { get; set; }
+
+ /// <summary>
+ /// Gets or sets the completion source.
+ /// </summary>
+ public TaskCompletionSource<TResult> CompletionSource { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PendingNotification{T, TResult}"/> class.
+ /// </summary>
+ public PendingNotification()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PendingNotification{T, TResult}"/> class.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="completionSource">The completion source.</param>
+ public PendingNotification(T item, TaskCompletionSource<TResult> completionSource) : this()
+ {
+ Item = item;
+ CompletionSource = completionSource;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..1f3a92752
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/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.FSE.UI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tango.FSE.UI")]
+[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
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>. For example, if you are using US english
+//in your source files, set the <UICulture> 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/FSE/Tango.FSE.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..b9a160c5e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.UI.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // 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()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [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.FSE.UI.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [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/FSE/Tango.FSE.UI/Properties/Resources.resx b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..dd9284a2e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// 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.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.FSE.UI.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/FSE/Tango.FSE.UI/Properties/Settings.settings b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
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
new file mode 100644
index 000000000..820d20e5d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{26C54A4F-315D-4B79-B163-EDDDE8F93A86}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.FSE.UI</RootNamespace>
+ <AssemblyName>Tango.FSE.UI</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ <Deterministic>true</Deterministic>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\Build\FSE\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\Build\FSE\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="ControlzEx, Version=3.0.2.4, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="MahApps.Metro, Version=1.6.5.1, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MahApps.Metro.1.6.5\lib\net46\MahApps.Metro.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignColors, Version=1.2.2.920, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MaterialDesignColors.1.2.2\lib\net45\MaterialDesignColors.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignThemes.Wpf, Version=3.0.1.920, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\MaterialDesignThemes.3.0.1\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\ControlzEx.3.0.2.4\lib\net45\System.Windows.Interactivity.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Compile Include="Authentication\DefaultAuthenticationProvider.cs" />
+ <Compile Include="Gateway\DefaultGatewayService.cs" />
+ <Compile Include="Modules\DefaultFSEModuleLoader.cs" />
+ <Compile Include="Navigation\DefaultNavigationManager.cs" />
+ <Compile Include="FSEApplication\DefaultFSEApplicationManager.cs" />
+ <Compile Include="Notifications\DefaultNotificationProvider.cs" />
+ <Compile Include="Notifications\DialogAndView.cs" />
+ <Compile Include="Notifications\PendingNotification.cs" />
+ <Compile Include="Threading\DefaultDispatcherProvider.cs" />
+ <Compile Include="ViewModelLocator.cs" />
+ <Compile Include="ViewModels\LayoutViewVM.cs" />
+ <Compile Include="ViewModels\LoadingViewVM.cs" />
+ <Compile Include="ViewModels\LoginViewVM.cs" />
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="Views\LayoutView.xaml.cs">
+ <DependentUpon>LayoutView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\LoadingView.xaml.cs">
+ <DependentUpon>LoadingView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\LoginView.xaml.cs">
+ <DependentUpon>LoginView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ </Compile>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="MainWindow.xaml.cs">
+ <DependentUpon>MainWindow.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Page Include="Views\LayoutView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\LoadingView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\LoginView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.BL\Tango.BL.csproj">
+ <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
+ <Name>Tango.BL</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Settings\Tango.Settings.csproj">
+ <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
+ <Name>Tango.Settings</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Web\Tango.Web.csproj">
+ <Project>{5001990f-977b-48ff-b217-0236a5022ad8}</Project>
+ <Name>Tango.Web</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Modules\Tango.FSE.Diagnostics\Tango.FSE.Diagnostics.csproj">
+ <Project>{8cffa4fc-f46f-475d-a270-dafbfb532bc8}</Project>
+ <Name>Tango.FSE.Diagnostics</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.FSE.Common\Tango.FSE.Common.csproj">
+ <Project>{bc37cccb-7392-4f78-8d1c-e9629e6e046e}</Project>
+ <Name>Tango.FSE.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.FSE.Web\Tango.FSE.Web.csproj">
+ <Project>{d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f}</Project>
+ <Name>Tango.FSE.Web</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>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}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets'))" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Threading/DefaultDispatcherProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Threading/DefaultDispatcherProvider.cs
new file mode 100644
index 000000000..c83041fd5
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Threading/DefaultDispatcherProvider.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Threading;
+using Tango.FSE.Common.Threading;
+
+namespace Tango.FSE.UI.Threading
+{
+ /// <summary>
+ /// Represents the default PPC <see cref="IDispatcherProvider"/> which will invoke action on the current application dispatcher.
+ /// </summary>
+ /// <seealso cref="Tango.PPC.Common.Threading.IDispatcherProvider" />
+ public class DefaultDispatcherProvider : IDispatcherProvider
+ {
+ private Dispatcher _dispatcher;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultDispatcherProvider"/> class.
+ /// </summary>
+ /// <param name="dispatcher">The dispatcher.</param>
+ public DefaultDispatcherProvider(Dispatcher dispatcher)
+ {
+ _dispatcher = dispatcher;
+ }
+
+ /// <summary>
+ /// Invokes the specified action asynchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ public void Invoke(Action action)
+ {
+ _dispatcher.BeginInvoke(action);
+ }
+
+ /// <summary>
+ /// Invokes the specified action synchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ public void InvokeBlock(Action action)
+ {
+ _dispatcher.Invoke(action);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
new file mode 100644
index 000000000..c1168253d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core.DI;
+using Tango.FSE.Common.Authentication;
+using Tango.FSE.Common.FSEApplication;
+using Tango.FSE.Common.Gateway;
+using Tango.FSE.Common.Modules;
+using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Threading;
+using Tango.FSE.Common.Web;
+using Tango.FSE.UI.Authentication;
+using Tango.FSE.UI.FSEApplication;
+using Tango.FSE.UI.Gateway;
+using Tango.FSE.UI.Modules;
+using Tango.FSE.UI.Navigation;
+using Tango.FSE.UI.Notifications;
+using Tango.FSE.UI.Threading;
+using Tango.FSE.UI.ViewModels;
+
+namespace Tango.FSE.UI
+{
+ public static class ViewModelLocator
+ {
+ static ViewModelLocator()
+ {
+ TangoIOC.Default.Unregister<IGatewayService>();
+ TangoIOC.Default.Unregister<FSEWebClient>();
+ TangoIOC.Default.Unregister<IDispatcherProvider>();
+ TangoIOC.Default.Unregister<INotificationProvider>();
+ TangoIOC.Default.Unregister<IAuthenticationProvider>();
+ TangoIOC.Default.Unregister<IFSEModuleLoader>();
+ TangoIOC.Default.Unregister<INavigationManager>();
+ //TangoIOC.Default.Unregister<IMachineProvider>();
+ TangoIOC.Default.Unregister<IFSEApplicationManager>();
+ //TangoIOC.Default.Unregister<ExternalBridgeScanner>();
+ //TangoIOC.Default.Unregister<IDiagnosticsFrameProvider>();
+ //TangoIOC.Default.Unregister<IEventLogger>();
+ //TangoIOC.Default.Unregister<ITeamFoundationServiceClient>();
+ //TangoIOC.Default.Unregister<IFSEExternalBridgeService>();
+ //TangoIOC.Default.Unregister<IStorageProvider>();
+
+ TangoIOC.Default.Register<IGatewayService, DefaultGatewayService>();
+ TangoIOC.Default.Register<FSEWebClient, FSEWebClient>(new FSEWebClient());
+ TangoIOC.Default.Register<IDispatcherProvider, DefaultDispatcherProvider>(new DefaultDispatcherProvider(Application.Current.Dispatcher));
+ TangoIOC.Default.Register<INotificationProvider, DefaultNotificationProvider>();
+ TangoIOC.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>();
+ TangoIOC.Default.Register<IFSEModuleLoader, DefaultFSEModuleLoader>();
+ TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>();
+ //TangoIOC.Default.Register<IMachineProvider, DefaultMachineProvider>();
+ TangoIOC.Default.Register<IFSEApplicationManager, DefaultFSEApplicationManager>();
+
+ TangoIOC.Default.Register<MainViewVM>();
+ TangoIOC.Default.Register<LoadingViewVM>();
+ TangoIOC.Default.Register<LayoutViewVM>();
+ TangoIOC.Default.Register<LoginViewVM>();
+ }
+
+ public static MainViewVM MainViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<MainViewVM>();
+ }
+ }
+
+ public static LoadingViewVM LoadingViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<LoadingViewVM>();
+ }
+ }
+
+ public static LayoutViewVM LayoutViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<LayoutViewVM>();
+ }
+ }
+
+ public static LoginViewVM LoginViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<LoginViewVM>();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs
new file mode 100644
index 000000000..13d2baff0
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LayoutViewVM.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FSE.Common;
+
+namespace Tango.FSE.UI.ViewModels
+{
+ public class LayoutViewVM : FSEViewModel
+ {
+ public override void OnApplicationStarted()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs
new file mode 100644
index 000000000..ec6042046
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FSE.Common;
+using Tango.FSE.Common.Gateway;
+using Tango.FSE.Common.Navigation;
+using Tango.MachineService.Gateway;
+
+namespace Tango.FSE.UI.ViewModels
+{
+ public class LoadingViewVM : FSEViewModel
+ {
+ public LoadingViewVM()
+ {
+
+ }
+
+ public async override void OnApplicationStarted()
+ {
+ await GatewayService.GetEnvironments();
+ await NavigationManager.NavigateTo(NavigationView.LoginView);
+ }
+
+ public override void OnApplicationReady()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs
new file mode 100644
index 000000000..77b15adc4
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.FSE.Common;
+using Tango.FSE.Common.Navigation;
+using Tango.MachineService.Gateway;
+
+namespace Tango.FSE.UI.ViewModels
+{
+ public class LoginViewVM : FSEViewModel
+ {
+ private String _email;
+ public String Email
+ {
+ get { return _email; }
+ set { _email = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ private String _password;
+ public String Password
+ {
+ get { return _password; }
+ set { _password = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ private EnvironmentConfiguration _selectedEnvironment;
+ public EnvironmentConfiguration SelectedEnvironment
+ {
+ get { return _selectedEnvironment; }
+ set { _selectedEnvironment = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ public RelayCommand LoginCommand { get; set; }
+
+ public LoginViewVM()
+ {
+ LoginCommand = new RelayCommand(Login,() => Email.IsNotNullOrEmpty() && Password.IsNotNullOrEmpty() && SelectedEnvironment != null);
+ }
+
+ public override void OnApplicationStarted()
+ {
+ Email = "roy@twine-s.com";
+ Password = "1Creativity";
+ }
+
+ public override void OnNavigatedTo()
+ {
+ base.OnNavigatedTo();
+ SelectedEnvironment = GatewayService.Environments.FirstOrDefault();
+ }
+
+ private async void Login()
+ {
+ try
+ {
+ var result = await AuthenticationProvider.Login(Email, Password, SelectedEnvironment);
+
+ if (!result.Response.PasswordChangeRequired)
+ {
+ await NavigationManager.NavigateTo(NavigationView.Home);
+ }
+ }
+ catch (Exception ex)
+ {
+ await NotificationProvider.ShowError(ex.Message);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..4d88a8967
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/MainViewVM.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FSE.Common;
+
+namespace Tango.FSE.UI.ViewModels
+{
+ public class MainViewVM : FSEViewModel
+ {
+ public String Text { get; set; } = "This is a simple text binding";
+
+ public override void OnApplicationStarted()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml
new file mode 100644
index 000000000..a08123e1b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml
@@ -0,0 +1,17 @@
+<UserControl x:Class="Tango.FSE.UI.Views.LayoutView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:global="clr-namespace:Tango.FSE.UI"
+ xmlns:vm="clr-namespace:Tango.FSE.UI.ViewModels"
+ xmlns:local="clr-namespace:Tango.FSE.UI.Views"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LayoutViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LayoutViewVM}">
+ <Grid>
+ <controls:NavigationControl x:Name="NavigationControl">
+
+ </controls:NavigationControl>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml.cs
new file mode 100644
index 000000000..610bcc867
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml.cs
@@ -0,0 +1,31 @@
+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.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for LayoutView.xaml
+ /// </summary>
+ public partial class LayoutView : UserControl
+ {
+ public static LayoutView Instance { get; set; }
+
+ public LayoutView()
+ {
+ Instance = this;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml
new file mode 100644
index 000000000..167f78f8a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml
@@ -0,0 +1,14 @@
+<UserControl x:Class="Tango.FSE.UI.Views.LoadingView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:global="clr-namespace:Tango.FSE.UI"
+ xmlns:vm="clr-namespace:Tango.FSE.UI.ViewModels"
+ xmlns:local="clr-namespace:Tango.FSE.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingViewVM}">
+ <Grid>
+ <TextBlock FontSize="60" HorizontalAlignment="Center" VerticalAlignment="Center">Loading View</TextBlock>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.xaml.cs
new file mode 100644
index 000000000..3dfc6e573
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoadingView.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.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for LoadingView.xaml
+ /// </summary>
+ public partial class LoadingView : UserControl
+ {
+ public LoadingView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml
new file mode 100644
index 000000000..769b28021
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml
@@ -0,0 +1,23 @@
+<UserControl x:Class="Tango.FSE.UI.Views.LoginView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:global="clr-namespace:Tango.FSE.UI"
+ xmlns:vm="clr-namespace:Tango.FSE.UI.ViewModels"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LoginViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoginViewVM}">
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
+ <TextBox Text="{Binding Email,UpdateSourceTrigger=PropertyChanged}" material:HintAssist.Hint="Email" material:HintAssist.IsFloating="True"></TextBox>
+ <PasswordBox Margin="0 20 0 0" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" material:HintAssist.Hint="Password" material:HintAssist.IsFloating="True"></PasswordBox>
+
+ <ComboBox Margin="0 20 0 0" ItemsSource="{Binding GatewayService.Environments}" SelectedItem="{Binding SelectedEnvironment}" DisplayMemberPath="Description" material:ComboBoxAssist.ShowSelectedItem="True"></ComboBox>
+
+ <Button Margin="0 20 0 0" Height="40" Command="{Binding LoginCommand}">LOGIN</Button>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml.cs
new file mode 100644
index 000000000..7948ee473
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.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.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for LoginView.xaml
+ /// </summary>
+ public partial class LoginView : UserControl
+ {
+ public LoginView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml
new file mode 100644
index 000000000..ac5cbfcf6
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml
@@ -0,0 +1,94 @@
+<UserControl x:Class="Tango.FSE.UI.Views.MainView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:global="clr-namespace:Tango.FSE.UI"
+ xmlns:vm="clr-namespace:Tango.FSE.UI.ViewModels"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.FSE.UI.Views"
+ mc:Ignorable="d"
+ Background="{StaticResource FSE_PrimaryBackgroundBrush}"
+ Foreground="{StaticResource FSE_PrimaryForegroundBrush}"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}"
+ DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
+ <Grid>
+ <controls:NavigationControl x:Name="NavigationControl">
+ <local:LoadingView/>
+ <local:LoginView/>
+ <local:LayoutView/>
+ </controls:NavigationControl>
+
+ <!--DIALOGS-->
+ <Grid Background="{StaticResource FSE_SemiTransparentBrush}" Visibility="{Binding NotificationProvider.HasMessageBox,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Grid Height="400" Margin="20" RenderTransformOrigin="0.5,0.5">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="0" ScaleY="0" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding NotificationProvider.HasMessageBox}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="1" Duration="00:00:0.2" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="1" Duration="00:00:0.2" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="0" Duration="00:00:0.2" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="1" To="0" Duration="00:00:0.2" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+
+ <Border DataContext="{Binding NotificationProvider.CurrentMessageBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" CornerRadius="5" Margin="10">
+ <Border.Effect>
+ <DropShadowEffect BlurRadius="10" />
+ </Border.Effect>
+ <Grid ClipToBounds="True">
+ <DockPanel>
+ <Grid DockPanel.Dock="Top">
+ <Border CornerRadius="5 5 0 0" BorderBrush="{StaticResource FSE_GrayBrush}" BorderThickness="0 0 0 1" Padding="30" Background="{StaticResource FSE_MessageBoxTitleHeaderBackgroundBrush}">
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
+ <material:PackIcon Width="24" Height="24" Margin="0 0 20 0">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="Foreground" Value="{StaticResource FSE_InfoBrush}"></Setter>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ <TextBlock Text="{Binding Title}" FontSize="{StaticResource FSE_MessageBoxTitleFontSize}" FontWeight="Normal"></TextBlock>
+ </StackPanel>
+ </Border>
+ <Button Background="Transparent" Style="{StaticResource MaterialDesignToolForegroundButton}" Command="{Binding CloseCommand}" CommandParameter="{Binding}" HorizontalAlignment="Right" MaxHeight="90" Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Opacity="0.5" />
+ </Grid>
+
+ <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Height="50" Margin="0 0 0 40">
+ <Button x:Name="btnCancel" Style="{StaticResource MaterialDesignToolForegroundButton}" FontWeight="Normal" Width="220" Margin="0 0 30 0" Command="{Binding CloseCommand}" Visibility="{Binding HasCancel,Converter={StaticResource BooleanToVisibilityConverter}}">CANCEL</Button>
+ <Button x:Name="btnOK" Style="{StaticResource MaterialDesignToolForegroundButton}" FontWeight="Normal" Width="220" Margin="30 0 0 0" Command="{Binding OKCommand}">OK</Button>
+ </StackPanel>
+
+ <TextBlock Text="{Binding Message}" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"></TextBlock>
+
+ </DockPanel>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
+ <!--DIALOGS-->
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs
new file mode 100644
index 000000000..c410a4fa3
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs
@@ -0,0 +1,31 @@
+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.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public static MainView Instance { get; set; }
+
+ public MainView()
+ {
+ Instance = this;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config
new file mode 100644
index 000000000..f8d27760e
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="ControlzEx" version="3.0.2.4" targetFramework="net461" />
+ <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
+ <package id="MahApps.Metro" version="1.6.5" targetFramework="net461" />
+ <package id="MaterialDesignColors" version="1.2.2" targetFramework="net461" />
+ <package id="MaterialDesignThemes" version="3.0.1" targetFramework="net461" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginRequest.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginRequest.cs
new file mode 100644
index 000000000..6898364ae
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginRequest.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport.Web;
+
+namespace Tango.FSE.Web.Messages
+{
+ public class LoginRequest : WebRequestMessage
+ {
+ public String Version { get; set; }
+ public String Email { get; set; }
+ public String Password { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginResponse.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginResponse.cs
new file mode 100644
index 000000000..83fd59439
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LoginResponse.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Web.Security;
+
+namespace Tango.FSE.Web.Messages
+{
+ public class LoginResponse : WebTokenResponse
+ {
+ public DataSource DataSource { get; set; }
+ public bool VersionChangeRequired { get; set; }
+ public String RequiredVersion { get; set; }
+ public bool PasswordChangeRequired { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..4a8bdfddc
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 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.FSE.Web")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tango.FSE.Web")]
+[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)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f")]
+
+// 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/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj
new file mode 100644
index 000000000..166162caf
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.FSE.Web</RootNamespace>
+ <AssemblyName>Tango.FSE.Web</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\Build\FSE\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\Build\FSE\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Messages\LoginRequest.cs" />
+ <Compile Include="Messages\LoginResponse.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{A34EE0F0-649D-41C8-8489-B6F1CC6924EE}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74E700B0-1156-4126-BE40-EE450D3C3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Web\Tango.Web.csproj">
+ <Project>{5001990F-977B-48FF-B217-0236A5022AD8}</Project>
+ <Name>Tango.Web</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Installers/Nswag/NSwagStudio.msi b/Software/Visual_Studio/Installers/Nswag/NSwagStudio.msi
new file mode 100644
index 000000000..3cab2e601
--- /dev/null
+++ b/Software/Visual_Studio/Installers/Nswag/NSwagStudio.msi
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index 2df984c7c..d07f75dbd 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -430,4 +430,8 @@
<UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Notes/Tango.Notes/Nswag/Pre-Build Example.txt b/Software/Visual_Studio/Notes/Tango.Notes/Nswag/Pre-Build Example.txt
new file mode 100644
index 000000000..eb9849fba
--- /dev/null
+++ b/Software/Visual_Studio/Notes/Tango.Notes/Nswag/Pre-Build Example.txt
@@ -0,0 +1 @@
+nswag run "$(SolutionDir)Web\Tango.MachineService.Gateway\Nswag\GatewayClient.nswag" /variables:assembly="$(SolutionDir)Web\Tango.MachineService.Gateway\bin\Tango.MachineService.Gateway.dll",output="$(ProjectDir)Gateway\GatewayClient.cs" \ No newline at end of file
diff --git a/Software/Visual_Studio/Notes/Tango.Notes/Tango.Notes.csproj b/Software/Visual_Studio/Notes/Tango.Notes/Tango.Notes.csproj
index e95fe1069..023a4bc69 100644
--- a/Software/Visual_Studio/Notes/Tango.Notes/Tango.Notes.csproj
+++ b/Software/Visual_Studio/Notes/Tango.Notes/Tango.Notes.csproj
@@ -49,6 +49,7 @@
<Content Include="Azure\SQL Database.txt" />
<Content Include="DB\DB Schema Change Log.txt" />
<Content Include="DB\SQL Dependency.txt" />
+ <Content Include="Nswag\Pre-Build Example.txt" />
<Content Include="PPC\Remote Debugging.txt" />
<Content Include="PPC\Virtual Flash Drive.txt" />
<Content Include="PPC\Windows 10 LTSB.txt" />
@@ -60,7 +61,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs
index 375b648d0..375b648d0 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
index 467b68d8b..f06109584 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
@@ -162,7 +162,7 @@
<Compile Include="Dialogs\FirmwareUpgradeFromFileViewVM.cs" />
<Compile Include="Dialogs\UpdateFromFileViewVM.cs" />
<Compile Include="InternalModule.cs" />
- <Compile Include="Modules\DefaultStudioModuleLoader.cs" />
+ <Compile Include="Modules\DefaultPPCModuleLoader.cs" />
<Compile Include="Navigation\DefaultNavigationManager.cs" />
<Compile Include="Notifications\DefaultNotificationProvider.cs" />
<Compile Include="Notifications\DialogAndView.cs" />
@@ -693,7 +693,7 @@ if $(ConfigurationName) == Debug copy /Y "$(TargetDir)Packages" "$(TargetDir)"</
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
+ <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj b/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
index 4c2793367..41413f4bd 100644
--- a/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
+++ b/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
@@ -90,6 +90,7 @@
<Compile Include="ObservablesAdapterFile.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Property.cs" />
+ <Compile Include="TangoWebClientv2CodeFile.cs" />
<Compile Include="TangoWebClientCodeFile.cs" />
</ItemGroup>
<ItemGroup>
@@ -125,11 +126,12 @@
<EmbeddedResource Include="Templates\TangoWebClientCodeFile.cshtml" />
<EmbeddedResource Include="Templates\EntityDTOCodeFile.cshtml" />
<EmbeddedResource Include="Templates\EntityInheritedDTOCodeFile.cshtml" />
+ <EmbeddedResource Include="Templates\TangoWebClientv2CodeFile.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/TangoWebClientv2CodeFile.cs b/Software/Visual_Studio/Tango.CodeGeneration/TangoWebClientv2CodeFile.cs
new file mode 100644
index 000000000..421655d07
--- /dev/null
+++ b/Software/Visual_Studio/Tango.CodeGeneration/TangoWebClientv2CodeFile.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.CodeGeneration
+{
+ public class TangoWebClientv2CodeFile : Class
+ {
+ public class ControllerAction
+ {
+ public String Name { get; set; }
+ public String Request { get; set; }
+ public String Response { get; set; }
+ }
+
+ public String Namespace { get; set; }
+ public String ControllerName { get; set; }
+ public String LoginRequest { get; set; }
+ public String LoginResponse { get; set; }
+
+ public List<ControllerAction> Actions { get; set; }
+
+ public TangoWebClientv2CodeFile()
+ {
+ Actions = new List<ControllerAction>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/Templates/TangoWebClientv2CodeFile.cshtml b/Software/Visual_Studio/Tango.CodeGeneration/Templates/TangoWebClientv2CodeFile.cshtml
new file mode 100644
index 000000000..cfcc89716
--- /dev/null
+++ b/Software/Visual_Studio/Tango.CodeGeneration/Templates/TangoWebClientv2CodeFile.cshtml
@@ -0,0 +1,59 @@
+@{
+ Tango.CodeGeneration.TangoWebClientv2CodeFile model = Model as Tango.CodeGeneration.TangoWebClientv2CodeFile;
+}
+using System;
+using System.Threading.Tasks;
+using Tango.Web;
+
+namespace @(model.Namespace)
+{
+ /// <summary>
+ /// Represents a machine service @(model.ControllerName) web client.
+ /// </summary>
+ /// <seealso cref="Tango.Web.TangoWebClient" />
+ public abstract class @(model.Name) : TangoWebClientV2<@(model.LoginRequest), @(model.LoginResponse)>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="@(model.Name)"/> class.
+ /// </summary>
+ /// <param name="address">The service address.</param>
+ /// <param name="token">Existing token.</param>
+ public @(model.Name)(String address, String token) : base(address, "@(model.ControllerName)", token)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="@(model.Name)"/> class.
+ /// </summary>
+ /// <param name="address">The service address.</param>
+ public @(model.Name)(String address) : this(address, null)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="@(model.Name)"/> class.
+ /// </summary>
+ /// <param name="cloned">Other instance.</param>
+ public @(model.Name)(@(model.Name) cloned) : base(cloned)
+ {
+
+ }
+
+ @foreach (var action in model.Actions)
+ {
+ <div>
+ /// <summary>
+ /// Executes the @(action.Name) action and returns @(action.Response).
+ /// </summary>
+ /// <returns></returns>
+ public Task<@(action.Response)> @(action.Name)(@(action.Request) request)
+ {
+ return Post<@(action.Request), @(action.Response)>("@(action.Name)", request);
+ }
+
+ </div>
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
index 78bb693f6..4984c84db 100644
--- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
@@ -234,6 +234,11 @@ public static class StringExtensions
return String.IsNullOrEmpty(str) ? null : str;
}
+ public static bool IsNotNullOrEmpty(this String str)
+ {
+ return !String.IsNullOrWhiteSpace(str);
+ }
+
public static List<T> ToEnumValues<T>(this String str, char splitChar) where T : struct
{
if (!String.IsNullOrWhiteSpace(str))
diff --git a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
index 426aa87ed..ce62ac4b4 100644
--- a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
+++ b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
@@ -263,6 +263,7 @@
<Compile Include="Storage\BlobStorageManager.cs" />
<Compile Include="Storage\TableStorageManager.cs" />
<Compile Include="TangoWebApplication.cs" />
+ <Compile Include="TangoWebClientV2.cs" />
<Compile Include="TangoWebClient.cs" />
<Compile Include="WebConfig.cs" />
<Compile Include="Controllers\TangoController.cs" />
diff --git a/Software/Visual_Studio/Tango.Web/TangoWebClientv2.cs b/Software/Visual_Studio/Tango.Web/TangoWebClientv2.cs
new file mode 100644
index 000000000..3a4ff7756
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/TangoWebClientv2.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Authentication;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport.Web;
+using Tango.Web.Security;
+
+namespace Tango.Web
+{
+ public abstract class TangoWebClientV2<TLoginRequest, TLoginResponse> : IDisposable where TLoginRequest : WebRequestMessage where TLoginResponse : WebTokenResponse
+ {
+ private WebTransportClient _client;
+ private bool _disposed;
+ private TLoginRequest _lastLoginRequest;
+
+ public String Address { get; set; }
+ public String Controller { get; private set; }
+ public String Token { get; private set; }
+ public WebToken WebToken { get; private set; }
+ public bool IsAuthenticated { get; private set; }
+
+ public TimeSpan RequestTimeout
+ {
+ get { return _client.RequestTimeout; }
+ set { _client.RequestTimeout = value; }
+ }
+
+ public TangoWebClientV2(String address, String controller)
+ {
+ _client = new WebTransportClient();
+ Controller = controller;
+ Address = address;
+ }
+
+ public TangoWebClientV2(String address, String controller, String token) : this(address, controller)
+ {
+ Token = token;
+ }
+
+ public TangoWebClientV2(TangoWebClientV2<TLoginRequest, TLoginResponse> cloned)
+ {
+ _client = new WebTransportClient();
+ Address = cloned.Address;
+ Controller = cloned.Controller;
+ IsAuthenticated = cloned.IsAuthenticated;
+ RequestTimeout = cloned.RequestTimeout;
+ WebToken = cloned.WebToken;
+ _lastLoginRequest = cloned._lastLoginRequest;
+ Token = cloned.Token;
+ }
+
+ public T Clone<T>() where T : TangoWebClientV2<TLoginRequest, TLoginResponse>
+ {
+ return Activator.CreateInstance(typeof(T), new object[] { this }) as T;
+ }
+
+ public async Task<TLoginResponse> Login(TLoginRequest request)
+ {
+ var response = await _client.PostJson<TLoginRequest, TLoginResponse>(GetActionAddress("Login"), request);
+ Token = response.AccessToken;
+ _client.AuthenticationToken = Token;
+
+ WebToken = WebToken.FromToken(Token);
+
+ _lastLoginRequest = request;
+ IsAuthenticated = true;
+ return response;
+ }
+
+ protected virtual async Task<TResponse> Post<TRequest, TResponse>(String action, TRequest request) where TRequest : class, IWebRequestMessage where TResponse : class, IWebResponseMessage
+ {
+ if (IsAuthenticated)
+ {
+ if (DateTime.UtcNow >= WebToken.Expiration)
+ {
+ await Login(_lastLoginRequest);
+ }
+ }
+
+ try
+ {
+ var response = await _client.PostJson<TRequest, TResponse>(GetActionAddress(action), request);
+ return response;
+ }
+ catch (TokenExpiredException ex)
+ {
+ try
+ {
+ await Login(_lastLoginRequest);
+ var response = await _client.PostJson<TRequest, TResponse>(GetActionAddress(action), request);
+ return response;
+ }
+ catch
+ {
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw;
+ }
+ }
+
+ private String GetActionAddress(String action)
+ {
+ return GetServiceAddress() + action;
+ }
+
+ protected virtual String GetServiceAddress()
+ {
+ return Address + $"/api/{Controller}/";
+ }
+
+ public virtual void Dispose()
+ {
+ if (!_disposed)
+ {
+ _disposed = true;
+ _client.Dispose();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln
index bb8c26b93..a471c9e98 100644
--- a/Software/Visual_Studio/Tango.sln
+++ b/Software/Visual_Studio/Tango.sln
@@ -341,6 +341,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.AzureUtils.UI", "Azur
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MachineService.Gateway", "Web\Tango.MachineService.Gateway\Tango.MachineService.Gateway.csproj", "{0F5F28AD-81B9-43A0-9BA7-CFB74F37202C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FSE", "FSE", "{004337EB-0761-4D30-B9F5-AE6E1CFC6013}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{4EE6DBA1-71BC-49E2-8DC7-266487E61050}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.UI", "FSE\Tango.FSE.UI\Tango.FSE.UI.csproj", "{26C54A4F-315D-4B79-B163-EDDDE8F93A86}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Common", "FSE\Tango.FSE.Common\Tango.FSE.Common.csproj", "{BC37CCCB-7392-4F78-8D1C-E9629E6E046E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Diagnostics", "FSE\Modules\Tango.FSE.Diagnostics\Tango.FSE.Diagnostics.csproj", "{8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Web", "FSE\Tango.FSE.Web\Tango.FSE.Web.csproj", "{D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AppVeyor|Any CPU = AppVeyor|Any CPU
@@ -6073,6 +6085,166 @@ Global
{0F5F28AD-81B9-43A0-9BA7-CFB74F37202C}.Release|x64.Build.0 = Release|Any CPU
{0F5F28AD-81B9-43A0-9BA7-CFB74F37202C}.Release|x86.ActiveCfg = Release|Any CPU
{0F5F28AD-81B9-43A0-9BA7-CFB74F37202C}.Release|x86.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|Any CPU.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|ARM.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|ARM.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|ARM64.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|x64.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|x64.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|x86.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.AppVeyor|x86.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|ARM.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|x64.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Debug|x86.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|ARM.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|x64.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.DefaultBuild|x86.Build.0 = Debug|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|Any CPU.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|ARM.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|ARM.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|ARM64.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|x64.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|x64.Build.0 = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|x86.ActiveCfg = Release|Any CPU
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86}.Release|x86.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|Any CPU.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|ARM.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|ARM.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|ARM64.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|x64.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|x64.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|x86.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.AppVeyor|x86.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|ARM.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|x64.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Debug|x86.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|ARM.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|x64.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.DefaultBuild|x86.Build.0 = Debug|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|ARM.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|ARM.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|ARM64.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|x64.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|x64.Build.0 = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|x86.ActiveCfg = Release|Any CPU
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E}.Release|x86.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|Any CPU.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|ARM.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|ARM.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|ARM64.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|x64.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|x64.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|x86.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.AppVeyor|x86.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|ARM.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|x64.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Debug|x86.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|ARM.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|x64.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.DefaultBuild|x86.Build.0 = Debug|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|ARM.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|ARM.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|ARM64.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|x64.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|x64.Build.0 = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|x86.ActiveCfg = Release|Any CPU
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8}.Release|x86.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|Any CPU.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|ARM.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|ARM.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|ARM64.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|x64.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|x64.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|x86.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.AppVeyor|x86.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|ARM.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|x64.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Debug|x86.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|ARM.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|x64.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.DefaultBuild|x86.Build.0 = Debug|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|ARM.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|ARM.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|ARM64.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|x64.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|x64.Build.0 = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|x86.ActiveCfg = Release|Any CPU
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -6187,6 +6359,11 @@ Global
{4A6B97E5-5EBA-4702-A016-6F4004F14B08} = {7E56E37C-85E4-433B-B5F7-ECD0FEBAFB67}
{DF378E50-F0F8-46BF-A410-36DB02F2A742} = {7E56E37C-85E4-433B-B5F7-ECD0FEBAFB67}
{0F5F28AD-81B9-43A0-9BA7-CFB74F37202C} = {59B2E8DA-2D5D-48FA-9A96-F53BDB7EF7A9}
+ {4EE6DBA1-71BC-49E2-8DC7-266487E61050} = {004337EB-0761-4D30-B9F5-AE6E1CFC6013}
+ {26C54A4F-315D-4B79-B163-EDDDE8F93A86} = {004337EB-0761-4D30-B9F5-AE6E1CFC6013}
+ {BC37CCCB-7392-4F78-8D1C-E9629E6E046E} = {004337EB-0761-4D30-B9F5-AE6E1CFC6013}
+ {8CFFA4FC-F46F-475D-A270-DAFBFB532BC8} = {4EE6DBA1-71BC-49E2-8DC7-266487E61050}
+ {D6F7D31D-7F8C-45E2-AE0A-FBBD1F5F9D5F} = {004337EB-0761-4D30-B9F5-AE6E1CFC6013}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6}
diff --git a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
index 6bbcd1884..b05e6e311 100644
--- a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
+++ b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
@@ -21,6 +21,9 @@ namespace Tango.WebClientGenerator
//Generate Machine Studio client.
GenerateWebClient<MachineStudio.Common.Web.LoginRequest, MachineStudio.Common.Web.LoginResponse, MachineService.Controllers.MachineStudioController>("Tango.MachineStudio.Common.Web", "MachineStudioWebClientBase", PathHelper.GetSolutionFolder() + @"\MachineStudio\Tango.MachineStudio.Common\Web");
+
+ //Generate FSE client.
+ GenerateWebClientV2<FSE.Web.Messages.LoginRequest, FSE.Web.Messages.LoginResponse, MachineService.Controllers.FSEController>("Tango.FSE.Common.Web", "FSEWebClientBase", PathHelper.GetSolutionFolder() + @"\FSE\Tango.FSE.Common\Web");
}
private static void GenerateWebClient<TLoginRequest, TLoginResponse, TController>(String nameSpace, String name, String path) where TLoginRequest : WebRequestMessage where TLoginResponse : WebTokenResponse where TController : TangoController
@@ -45,5 +48,28 @@ namespace Tango.WebClientGenerator
String code = model.GenerateCode();
File.WriteAllText(Path.Combine(path, name + ".cs"), code);
}
+
+ private static void GenerateWebClientV2<TLoginRequest, TLoginResponse, TController>(String nameSpace, String name, String path) where TLoginRequest : WebRequestMessage where TLoginResponse : WebTokenResponse where TController : TangoController
+ {
+ TangoWebClientv2CodeFile model = new TangoWebClientv2CodeFile();
+ model.Namespace = nameSpace;
+ model.ControllerName = typeof(TController).Name.Replace("Controller", "");
+ model.Name = name;
+ model.LoginRequest = typeof(TLoginRequest).FullName;
+ model.LoginResponse = typeof(TLoginResponse).FullName;
+
+ foreach (var action in typeof(TController).GetMethods().Where(x => typeof(WebResponseMessage).IsAssignableFrom(x.ReturnType) && x.Name != "Login"))
+ {
+ model.Actions.Add(new TangoWebClientv2CodeFile.ControllerAction()
+ {
+ Name = action.Name,
+ Request = action.GetParameters()[0].ParameterType.FullName,
+ Response = action.ReturnType.FullName,
+ });
+ }
+
+ String code = model.GenerateCode();
+ File.WriteAllText(Path.Combine(path, name + ".cs"), code);
+ }
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Tango.WebClientGenerator.csproj b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Tango.WebClientGenerator.csproj
index da8738617..e589db6be 100644
--- a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Tango.WebClientGenerator.csproj
+++ b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Tango.WebClientGenerator.csproj
@@ -53,6 +53,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\FSE\Tango.FSE.Web\Tango.FSE.Web.csproj">
+ <Project>{d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f}</Project>
+ <Name>Tango.FSE.Web</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\MachineStudio\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
<Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
<Name>Tango.MachineStudio.Common</Name>
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Controllers/GatewayController.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Controllers/GatewayController.cs
index 52036e46b..e3391cd5d 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Controllers/GatewayController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Controllers/GatewayController.cs
@@ -4,15 +4,37 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
+using Tango.MachineService.Gateway.DB;
+using Tango.MachineService.Gateway.DTO;
+using Tango.MachineService.Gateway.Messages;
+using Tango.Web.Controllers;
namespace Tango.MachineService.Gateway.Controllers
{
- public class GatewayController : ApiController
+ public class GatewayController : TangoController
{
[HttpPost]
- public String GetUrl()
+ public EnvironmentsResponse GetEnvironments(EnvironmentsRequest request)
{
- return "URL";
+ EnvironmentsResponse response = new EnvironmentsResponse();
+
+ using (GatewayDbContext db = GatewayDbContext.CreateDefault())
+ {
+ var envs = db.Environments.ToList();
+
+ foreach (var env in envs)
+ {
+ response.Environments.Add(new EnvironmentConfiguration()
+ {
+ ID = env.ID.ToString(),
+ Name = env.Name,
+ Description = env.Description,
+ MachineServiceAddress = env.MachineServiceAddress
+ });
+ }
+ }
+
+ return response;
}
}
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/ENVIRONMENT.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/ENVIRONMENT.cs
new file mode 100644
index 000000000..66cd2ff0c
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/ENVIRONMENT.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Web;
+
+namespace Tango.MachineService.Gateway.DB
+{
+ [Table("ENVIRONMENTS")]
+ public class Environment
+ {
+ [Column("ID")]
+ public int ID { get; set; }
+
+ [Column("NAME")]
+ public String Name { get; set; }
+
+ [Column("DESCRIPTION")]
+ public String Description { get; set; }
+
+ [Column("MACHINE_SERVICE_ADDRESS")]
+ public String MachineServiceAddress { get; set; }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/GatewayDbContext.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/GatewayDbContext.cs
new file mode 100644
index 000000000..9f4a9f0f9
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DB/GatewayDbContext.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Linq;
+using System.Web;
+using Tango.Core;
+
+namespace Tango.MachineService.Gateway.DB
+{
+ public class GatewayDbContext : DbContext
+ {
+ public GatewayDbContext(DataSource dataSource) : base(dataSource.ToConnection(), true)
+ {
+
+ }
+
+ public static GatewayDbContext CreateDefault()
+ {
+ return new GatewayDbContext(new DataSource()
+ {
+ Address = GatewayConfig.DB_ADDRESS,
+ IntegratedSecurity = false,
+ Catalog = GatewayConfig.DB_CATALOG,
+ Type = DataSourceType.SQLServer,
+ UserName = GatewayConfig.DB_USER_NAME,
+ Password = GatewayConfig.DB_PASSWORD
+ });
+ }
+
+ /// <summary>
+ /// Gets or sets the environments.
+ /// </summary>
+ public DbSet<Environment> Environments
+ {
+ get; set;
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DTO/EnvironmentConfiguration.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DTO/EnvironmentConfiguration.cs
new file mode 100644
index 000000000..0da9de5e5
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/DTO/EnvironmentConfiguration.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace Tango.MachineService.Gateway.DTO
+{
+ public class EnvironmentConfiguration
+ {
+ public String ID { get; set; }
+ public String Name { get; set; }
+ public String Description { get; set; }
+ public String MachineServiceAddress { get; set; }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/GatewayConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/GatewayConfig.cs
index e7ad241ed..dbbb10709 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/GatewayConfig.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/GatewayConfig.cs
@@ -9,6 +9,11 @@ namespace Tango.MachineService.Gateway
{
public class GatewayConfig
{
+ public static String DB_ADDRESS => ConfigurationManager.AppSettings[nameof(DB_ADDRESS)].ToString();
+ public static String DB_USER_NAME => ConfigurationManager.AppSettings[nameof(DB_USER_NAME)].ToString();
+ public static String DB_PASSWORD => ConfigurationManager.AppSettings[nameof(DB_PASSWORD)].ToString();
+ public static String DB_CATALOG => ConfigurationManager.AppSettings[nameof(DB_CATALOG)].ToString();
+
public static String JWT_TOKEN_SECRET => ConfigurationManager.AppSettings[nameof(JWT_TOKEN_SECRET)].ToString();
public static String AZURE_UTILS_GROUP => ConfigurationManager.AppSettings[nameof(AZURE_UTILS_GROUP)].ToString();
public static String TENANT_ID => ConfigurationManager.AppSettings[nameof(TENANT_ID)].ToString();
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsRequest.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsRequest.cs
new file mode 100644
index 000000000..6d2ab0f8d
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace Tango.MachineService.Gateway.Messages
+{
+ public class EnvironmentsRequest
+ {
+ public String AppSecret { get; set; }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsResponse.cs b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsResponse.cs
new file mode 100644
index 000000000..2063d5e59
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Messages/EnvironmentsResponse.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using Tango.MachineService.Gateway.DTO;
+
+namespace Tango.MachineService.Gateway.Messages
+{
+ public class EnvironmentsResponse
+ {
+ public List<EnvironmentConfiguration> Environments { get; set; }
+
+ public EnvironmentsResponse()
+ {
+ Environments = new List<EnvironmentConfiguration>();
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Nswag/GatewayClient.nswag b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Nswag/GatewayClient.nswag
new file mode 100644
index 000000000..d3db33524
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Nswag/GatewayClient.nswag
@@ -0,0 +1,140 @@
+{
+ "runtime": "Default",
+ "defaultVariables": "",
+ "documentGenerator": {
+ "webApiToOpenApi": {
+ "controllerNames": [
+ "Tango.MachineService.Gateway.Controllers.GatewayController"
+ ],
+ "isAspNetCore": false,
+ "resolveJsonOptions": false,
+ "defaultUrlTemplate": "api/{controller}/{action}",
+ "addMissingPathParameters": false,
+ "includedVersions": null,
+ "defaultPropertyNameHandling": "Default",
+ "defaultReferenceTypeNullHandling": "Null",
+ "defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
+ "defaultResponseReferenceTypeNullHandling": "NotNull",
+ "defaultEnumHandling": "Integer",
+ "flattenInheritanceHierarchy": false,
+ "generateKnownTypes": true,
+ "generateEnumMappingDescription": false,
+ "generateXmlObjects": false,
+ "generateAbstractProperties": false,
+ "generateAbstractSchemas": true,
+ "ignoreObsoleteProperties": false,
+ "allowReferencesWithProperties": false,
+ "excludedTypeNames": [],
+ "serviceHost": null,
+ "serviceBasePath": null,
+ "serviceSchemes": [],
+ "infoTitle": "My Title",
+ "infoDescription": null,
+ "infoVersion": "1.0.0",
+ "documentTemplate": null,
+ "documentProcessorTypes": [],
+ "operationProcessorTypes": [],
+ "typeNameGeneratorType": null,
+ "schemaNameGeneratorType": null,
+ "contractResolverType": null,
+ "serializerSettingsType": null,
+ "useDocumentProvider": true,
+ "documentName": "v1",
+ "aspNetCoreEnvironment": null,
+ "createWebHostBuilderMethod": null,
+ "startupType": null,
+ "allowNullableBodyParameters": true,
+ "output": null,
+ "outputType": "Swagger2",
+ "assemblyPaths": [
+ "$(assembly)"
+ ],
+ "assemblyConfig": null,
+ "referencePaths": [],
+ "useNuGetCache": false
+ }
+ },
+ "codeGenerators": {
+ "openApiToCSharpClient": {
+ "clientBaseClass": null,
+ "configurationClass": null,
+ "generateClientClasses": true,
+ "generateClientInterfaces": false,
+ "injectHttpClient": true,
+ "disposeHttpClient": true,
+ "protectedMethods": [],
+ "generateExceptionClasses": true,
+ "exceptionClass": "ApiException",
+ "wrapDtoExceptions": true,
+ "useHttpClientCreationMethod": false,
+ "httpClientType": "System.Net.Http.HttpClient",
+ "useHttpRequestMessageCreationMethod": false,
+ "useBaseUrl": true,
+ "generateBaseUrlProperty": true,
+ "generateSyncMethods": true,
+ "exposeJsonSerializerSettings": false,
+ "clientClassAccessModifier": "public",
+ "typeAccessModifier": "public",
+ "generateContractsOutput": false,
+ "contractsNamespace": null,
+ "contractsOutputFilePath": null,
+ "parameterDateTimeFormat": "s",
+ "parameterDateFormat": "yyyy-MM-dd",
+ "generateUpdateJsonSerializerSettingsMethod": true,
+ "useRequestAndResponseSerializationSettings": false,
+ "serializeTypeInformation": false,
+ "queryNullValue": "",
+ "className": "GatewayClient",
+ "operationGenerationMode": "MultipleClientsFromOperationId",
+ "additionalNamespaceUsages": [],
+ "additionalContractNamespaceUsages": [],
+ "generateOptionalParameters": false,
+ "generateJsonMethods": false,
+ "enforceFlagEnums": false,
+ "parameterArrayType": "System.Collections.Generic.IEnumerable",
+ "parameterDictionaryType": "System.Collections.Generic.IDictionary",
+ "responseArrayType": "System.Collections.Generic.ICollection",
+ "responseDictionaryType": "System.Collections.Generic.IDictionary",
+ "wrapResponses": false,
+ "wrapResponseMethods": [],
+ "generateResponseClasses": true,
+ "responseClass": "SwaggerResponse",
+ "namespace": "Tango.MachineService.Gateway",
+ "requiredPropertiesMustBeDefined": true,
+ "dateType": "System.DateTimeOffset",
+ "jsonConverters": null,
+ "anyType": "object",
+ "dateTimeType": "System.DateTimeOffset",
+ "timeType": "System.TimeSpan",
+ "timeSpanType": "System.TimeSpan",
+ "arrayType": "System.Collections.Generic.ICollection",
+ "arrayInstanceType": "System.Collections.ObjectModel.Collection",
+ "dictionaryType": "System.Collections.Generic.IDictionary",
+ "dictionaryInstanceType": "System.Collections.Generic.Dictionary",
+ "arrayBaseType": "System.Collections.ObjectModel.Collection",
+ "dictionaryBaseType": "System.Collections.Generic.Dictionary",
+ "classStyle": "Poco",
+ "generateDefaultValues": true,
+ "generateDataAnnotations": true,
+ "excludedTypeNames": [],
+ "excludedParameterNames": [],
+ "handleReferences": false,
+ "generateImmutableArrayProperties": false,
+ "generateImmutableDictionaryProperties": false,
+ "jsonSerializerSettingsTransformationMethod": null,
+ "inlineNamedArrays": false,
+ "inlineNamedDictionaries": false,
+ "inlineNamedTuples": true,
+ "inlineNamedAny": false,
+ "generateDtoTypes": true,
+ "generateOptionalPropertiesAsNullable": false,
+ "templateDirectory": null,
+ "typeNameGeneratorType": null,
+ "propertyNameGeneratorType": null,
+ "enumNameGeneratorType": null,
+ "serviceHost": null,
+ "serviceSchemes": null,
+ "output": "$(output)"
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Tango.MachineService.Gateway.csproj b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Tango.MachineService.Gateway.csproj
index c1f3b59bd..f749f7f57 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Tango.MachineService.Gateway.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Tango.MachineService.Gateway.csproj
@@ -45,6 +45,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
<Reference Include="JWT, Version=5.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\JWT.5.0.0\lib\net46\JWT.dll</HintPath>
<Private>True</Private>
@@ -161,6 +167,7 @@
<Reference Include="System.IdentityModel" />
<Reference Include="System.Net" />
<Reference Include="System.Runtime" />
+ <Reference Include="System.Security" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
@@ -244,18 +251,25 @@
<Compile Include="Controllers\GatewayController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\ValuesController.cs" />
+ <Compile Include="DB\Environment.cs" />
+ <Compile Include="DB\GatewayDbContext.cs" />
+ <Compile Include="DTO\EnvironmentConfiguration.cs" />
<Compile Include="Filters\JwtTokenFilter.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="GatewayConfig.cs" />
+ <Compile Include="Messages\EnvironmentsRequest.cs" />
+ <Compile Include="Messages\EnvironmentsResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TangoController.cs" />
<Compile Include="WebToken.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
- <Content Include="Web.config" />
+ <Content Include="Web.config">
+ <SubType>Designer</SubType>
+ </Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
@@ -270,7 +284,10 @@
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
- <None Include="packages.config" />
+ <Content Include="Nswag\GatewayClient.nswag" />
+ <None Include="packages.config">
+ <SubType>Designer</SubType>
+ </None>
<None Include="Properties\PublishProfiles\machineservice-gateway - Web Deploy.pubxml" />
</ItemGroup>
<ItemGroup>
@@ -287,6 +304,9 @@
<Name>Tango.Logging</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Web.config b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Web.config
index f53e9c92e..6dd29d57d 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Web.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/Web.config
@@ -4,30 +4,28 @@
https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
-
<add key="DB_ADDRESS" value="twine.database.windows.net" />
<add key="DB_USER_NAME" value="Roy" />
<add key="DB_PASSWORD" value="Aa123456" />
- <add key="DB_CATALOG" value="Tango_Gateway" />
-
+ <add key="DB_CATALOG" value="Gateway" />
<add key="TENANT_ID" value="2ebd63a5-bc2f-41dc-9066-4409ed5e5dd4" />
<add key="CLIENT_ID" value="be33437c-5052-449f-ab9d-a88d008eae24" />
<add key="CLIENT_SECRET" value="bf67fb6f-4d06-4893-988c-6b347aff23d6" />
<add key="SUBSCRIPTION_ID" value="10c8aa60-3b15-4e0d-b412-6aeef90e5e91" />
-
<add key="AZURE_UTILS_GROUP" value="Azure Utils" />
-
<add key="STORAGE_ACCOUNT" value="DefaultEndpointsProtocol=https;AccountName=tangostorage;AccountKey=S4z/D+Yg6mwMis+bs/VpcDLA9yE1iZaYq23shQlRIi2KmM9E7JY8zdZjeAPOPdG3gONHoNDEpsgH6D4cqQ/bsA==;EndpointSuffix=core.windows.net" />
<add key="TANGO_VERSIONS_CONTAINER" value="tango-versions-dev" />
<add key="MACHINE_STUDIO_VERSIONS_CONTAINER" value="machine-studio-versions-dev" />
-
<add key="JWT_TOKEN_SECRET" value="GQDstcKsx0NHjLOuXOYg5MbeJ1yT0u1iwDVTwine" />
-
<add key="CDN_ENDPOINT" value="https://tango.azureedge.net" />
</appSettings>
<system.web>
@@ -104,4 +102,13 @@
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
-</configuration>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+ <connectionStrings>
+ <add name="GatewayDbContext" connectionString="metadata=res://*/DB.GatewayDatabaseModel.csdl|res://*/DB.GatewayDatabaseModel.ssdl|res://*/DB.GatewayDatabaseModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost\SQLEXPRESS;initial catalog=Gateway;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
+ </connectionStrings>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/packages.config b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/packages.config
index 8f284e11d..72f15dbf6 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService.Gateway/packages.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService.Gateway/packages.config
@@ -2,6 +2,7 @@
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net461" />
<package id="bootstrap" version="3.3.7" targetFramework="net461" />
+ <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
<package id="jQuery" version="3.3.1" targetFramework="net461" />
<package id="JWT" version="5.0.0" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="5.2.4" targetFramework="net461" />
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs
new file mode 100644
index 000000000..abcd1c41f
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Authentication;
+using System.Web.Http;
+using Tango.BL.Builders;
+using Tango.BL.Entities;
+using Tango.Core;
+using Tango.Core.Cryptography;
+using Tango.FSE.Web.Messages;
+using Tango.Web.Controllers;
+using Tango.Web.Helpers;
+using Tango.Web.Security;
+using Tango.Web.SQLServer;
+
+namespace Tango.MachineService.Controllers
+{
+ public class FSEController : TangoController
+ {
+ public class TokenObject
+ {
+ public String UserGuid { get; set; }
+ }
+
+ /// <summary>
+ /// Login to the service.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns></returns>
+ /// <exception cref="AuthenticationException"></exception>
+ [HttpPost]
+ public LoginResponse Login(LoginRequest request)
+ {
+ User user = null;
+ DataSource dataSource = null;
+ IHashGenerator hash = new BasicHashGenerator();
+
+ Version client_version;
+
+ if (!Version.TryParse(request.Version, out client_version))
+ {
+ client_version = new Version("1.0.0.0");
+ }
+
+ bool versionChangeRequired = false;
+ String requiredVersion = null;
+
+ var password = hash.Encrypt(request.Password);
+
+ using (var db = ObservablesContextHelper.CreateContext())
+ {
+ user = new UserBuilder(db).Set(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == password).WithRolesAndPermissions().WithDeleted().Build();
+
+ if (user == null)
+ {
+ throw new AuthenticationException("Invalid email or password.");
+ }
+
+ if (user.Deleted)
+ {
+ throw new AuthenticationException("Your account has been disabled. Please contact your administrator.");
+ }
+
+ user.LastLogin = DateTime.UtcNow;
+ db.SaveChanges();
+ }
+
+ SQLServerManager sqlServer = new SQLServerManager();
+ var accessToken = sqlServer.GetAccessToken();
+
+ dataSource = new DataSource()
+ {
+ Address = MachineServiceConfig.DB_ADDRESS,
+ Catalog = MachineServiceConfig.DB_CATALOG,
+ Type = DataSourceType.AccessToken,
+ IntegratedSecurity = false,
+ AccessToken = accessToken.AccessToken,
+ AccessTokenExpiration = accessToken.ExpiresOn.UtcDateTime
+ };
+
+
+ //Enforce Machine Studio Version ?
+ //if (MachineServiceConfig.ENFORCE_MACHINE_STUDIO_VERSION)
+ //{
+ // using (var db = ObservablesContextHelper.CreateContext())
+ // {
+ // var latest_version = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
+
+ // if (latest_version != null && Version.Parse(latest_version.Version) != client_version)
+ // {
+ // versionChangeRequired = true;
+ // requiredVersion = latest_version.Version;
+ // }
+ // }
+ //}
+
+ //Return data source
+ return new LoginResponse()
+ {
+ DataSource = dataSource,
+ AccessToken = WebToken<TokenObject>.CreateNew(MachineServiceConfig.JWT_TOKEN_SECRET, new TokenObject()
+ {
+ UserGuid = user.Guid,
+ }, DateTime.UtcNow.AddDays(1)).AccessToken,
+ VersionChangeRequired = versionChangeRequired,
+ RequiredVersion = requiredVersion,
+ PasswordChangeRequired = user.PasswordChangeRequired
+ };
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
index 1be2a5de8..f508fea15 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
@@ -89,7 +89,7 @@ namespace Tango.MachineService.Controllers
String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments));
- if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion)
+ if (latestVersion != null && Version.Parse(latestVersion.Version) != currentVersion)
{
var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER);
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
index 6ac2e3657..b132a4c48 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
@@ -317,7 +317,7 @@ namespace Tango.MachineService.Controllers
var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
- if (Version.Parse(latest_machine_version.Version) > Version.Parse(request.Version))
+ if (Version.Parse(latest_machine_version.Version) != Version.Parse(request.Version))
{
response.IsUpdateAvailable = true;
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
index e916f01e6..a05fee42f 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
@@ -306,6 +306,7 @@
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="Controllers\DownloadsController.cs" />
<Compile Include="Controllers\AccountController.cs" />
+ <Compile Include="Controllers\FSEController.cs" />
<Compile Include="Filters\JwtTokenFilter.cs" />
<Compile Include="Hubs\ExternalBridgeHub.cs" />
<Compile Include="MachineServiceConfig.cs" />
@@ -372,6 +373,10 @@
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\FSE\Tango.FSE.Web\Tango.FSE.Web.csproj">
+ <Project>{d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f}</Project>
+ <Name>Tango.FSE.Web</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\MachineStudio\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
<Project>{CB0B0AA2-BB24-4BCA-A720-45E397684E12}</Project>
<Name>Tango.MachineStudio.Common</Name>
@@ -456,7 +461,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
- <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
+ <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">