diff options
Diffstat (limited to 'Software/Visual_Studio')
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 Binary files differnew file mode 100644 index 000000000..3cab2e601 --- /dev/null +++ b/Software/Visual_Studio/Installers/Nswag/NSwagStudio.msi 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=\"Web\" /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="data source=localhost\SQLEXPRESS;initial catalog=Gateway;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" 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"> |
