diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2020-01-27 09:19:11 +0200 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2020-01-27 09:19:11 +0200 |
| commit | ddda6089bff56e80703c8d2dce297919edc58bf1 (patch) | |
| tree | 7702c5cf169124d522eacc7f1a9e0878373baedd /Software/Visual_Studio/MachineStudio/Modules | |
| parent | 1d4d327571d4c0c9f4e17411551bd4dae1e2aed0 (diff) | |
| parent | bf2f3245339b9fd9148a2ad25b5ba3320e970cc1 (diff) | |
| download | Tango-ddda6089bff56e80703c8d2dce297919edc58bf1.tar.gz Tango-ddda6089bff56e80703c8d2dce297919edc58bf1.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules')
89 files changed, 5067 insertions, 436 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs new file mode 100644 index 000000000..3a9dcdfaa --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs @@ -0,0 +1,62 @@ +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; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.ActionLogs.Views; +using Tango.SharedUI.Helpers; + +namespace Tango.MachineStudio.ActionLogs +{ + [StudioModule(21)] + public class ActionLogsModule : StudioModuleBase + { + public override string Name + { + get + { + return "Action Logs"; + } + } + + public override string Description + { + get + { + return "Monitor and track changes made to Twine's global datasets."; + } + } + + public override BitmapSource Image + { + get + { + return ResourceHelper.GetImageFromResources("Images/action_logs.jpg"); + } + } + + public override Type MainViewType + { + get + { + return typeof(MainView); + } + } + + public override Permissions Permission + { + get + { + return Permissions.RunMachineStudio; + } + } + + public override void Dispose() + { + + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml new file mode 100644 index 000000000..3ab646c7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml @@ -0,0 +1,12 @@ +<Application x:Class="Tango.MachineStudio.ActionLogs.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.MachineStudio.Common;component/Resources/MaterialDesign.xaml" /> + <ResourceDictionary Source="pack://application:,,,/Tango.MachineStudio.Common;component/Themes/LightThemeColors.xaml" /> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> + </Application.Resources> +</Application>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg Binary files differnew file mode 100644 index 000000000..75f39c09c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..072265a74 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +[assembly: AssemblyTitle("Tango - Machine Studio Action Logs Module")] +[assembly: AssemblyVersion("1.0.0.1737")] + +[assembly: ComVisible(false)] + +[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) +)] diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs new file mode 100644 index 000000000..796a67686 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/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.MachineStudio.ActionLogs.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.MachineStudio.ActionLogs.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/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/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/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs new file mode 100644 index 000000000..507ac539d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/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.MachineStudio.ActionLogs.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/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/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/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj new file mode 100644 index 000000000..0d6fa213c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj @@ -0,0 +1,158 @@ +<?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>{447ECB9F-F730-47D6-8DF8-D232BF4A0315}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>Tango.MachineStudio.ActionLogs</RootNamespace> + <AssemblyName>Tango.MachineStudio.ActionLogs</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\Machine Studio\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\Machine Studio\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="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> + <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath> + </Reference> + <Reference Include="MaterialDesignColors, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll</HintPath> + </Reference> + <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MaterialDesignThemes.2.3.1.953\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.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\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="..\..\..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="ViewModelLocator.cs" /> + <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="Views\MainView.xaml.cs"> + <DependentUpon>MainView.xaml</DependentUpon> + </Compile> + <Compile Include="ActionLogsModule.cs" /> + <Page Include="App.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </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="app.config" /> + <None Include="packages.config" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <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.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</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.MachineStudio.Common\Tango.MachineStudio.Common.csproj"> + <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> + <Name>Tango.MachineStudio.Common</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\action_logs.jpg" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs new file mode 100644 index 000000000..29540fa86 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.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; +using Tango.MachineStudio.ActionLogs.ViewModels; + +namespace Tango.MachineStudio.ActionLogs +{ + public static class ViewModelLocator + { + /// <summary> + /// Initializes a new instance of the ViewModelLocator class. + /// </summary> + static ViewModelLocator() + { + TangoIOC.Default.Register<MainViewVM>(); + } + + public static MainViewVM MainViewVM + { + get + { + return TangoIOC.Default.GetInstance<MainViewVM>(); + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs new file mode 100644 index 000000000..fb6568df8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs @@ -0,0 +1,164 @@ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.Entity; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; +using Tango.Core.Commands; +using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common; +using Tango.SharedUI.Components; + +namespace Tango.MachineStudio.ActionLogs.ViewModels +{ + public class MainViewVM : StudioViewModel + { + #region Properties + + private DateTime _startSelectedDate; + public DateTime StartSelectedDate + { + get { return _startSelectedDate; } + set { _startSelectedDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _endSelectedDate; + public DateTime EndSelectedDate + { + get { return _endSelectedDate; } + set { _endSelectedDate = value; RaisePropertyChangedAuto(); } + } + + private string _searchFilter; + public string SearchFilter + { + get { return _searchFilter; } + set { _searchFilter = value; RaisePropertyChangedAuto(); } + } + + private ObservableCollection<ActionLog> _actionLogs; + public ObservableCollection<ActionLog> ActionLogs + { + get { return _actionLogs; } + set { _actionLogs = value; RaisePropertyChanged(nameof(ActionLogs)); } + } + + private SelectedObjectCollection<ActionLogType> _selectedActionLogTypes; + public SelectedObjectCollection<ActionLogType> SelectedActionLogTypes + { + get { return _selectedActionLogTypes; } + set { _selectedActionLogTypes = value; + RaisePropertyChanged(nameof(SelectedActionLogTypes)); } + } + + private ActionLog _selectedActionLog = null; + public ActionLog SelectedActionLog + { + get { return _selectedActionLog; } + set { _selectedActionLog = value; + SelectedItemChanged(); + RaisePropertyChangedAuto(); + InvalidateRelayCommands(); + } + } + + private ActionLogDifference _differenceObject; + public ActionLogDifference DifferenceObject + { + get { return _differenceObject; } + set { _differenceObject = value; RaisePropertyChangedAuto(); } + } + + + private bool _isRunning; + public bool IsRunning + { + get { return _isRunning; } + set { _isRunning = value; } + } + + #endregion + + public RelayCommand SearchCommand { get; set; } + public RelayCommand CopyToClipBoardCommand { get; set; } + public RelayCommand CopyRelateObjectIDCommand { get; set; } + + public MainViewVM() + { + ActionLogs = new ObservableCollection<ActionLog>(); + SearchCommand = new RelayCommand(GetActionLogs, ()=> !IsRunning); + CopyRelateObjectIDCommand = new RelayCommand(CopyRelateObjectID); + CopyToClipBoardCommand = new RelayCommand(CopyToClipBoard, () => SelectedActionLog != null && SelectedActionLog.DifferenceObject != null); + DateTime now = DateTime.Now; + StartSelectedDate = now.AddMonths(-1); + EndSelectedDate = now; + _isRunning = false; + var source = Enum.GetValues(typeof(ActionLogType)).Cast<ActionLogType>().ToObservableCollection(); + var syncedSource = Enum.GetValues(typeof(ActionLogType)).Cast<ActionLogType>().ToObservableCollection(); + + SelectedActionLogTypes = new SelectedObjectCollection<ActionLogType>(source, syncedSource); + } + + public override void OnApplicationReady() + { + + } + + private void CopyToClipBoard() + { + DataObject data = new DataObject(SelectedActionLog.DifferenceObject.ToJsonString()); + System.Windows.Clipboard.SetDataObject(data); + + } + private void CopyRelateObjectID() + { + DataObject data = new DataObject(SelectedActionLog.RelatedObjectGuid); + System.Windows.Clipboard.SetDataObject(data); + } + + /// <summary> + /// New Database Query with search parameters. Initialization ActionLogs property. + /// </summary> + private async void GetActionLogs() + { + string filter = SearchFilter?.ToLower(); + + if (String.IsNullOrWhiteSpace(filter)) filter = null; + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + DateTime startUtc = StartSelectedDate.ToUniversalTime(); + TimeSpan offsetTime = (EndSelectedDate.Date == DateTime.Now.Date)? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); + DateTime endUtc = EndSelectedDate.ToUniversalTime()+ offsetTime; + IsRunning = true; + ActionLogs = await new ActionLogsCollectionBuilder(db).Set(x => x.LastUpdated <= DbFunctions.TruncateTime(endUtc) && x.LastUpdated >= DbFunctions.TruncateTime(startUtc.Date)) + .WithUsers() + .WithActionType(SelectedActionLogTypes.SynchedSource.ToArray()) + .Query(y => y.Where + (x => filter == null || + (x.ID.ToString().ToLower().StartsWith(filter) + || (x.RelatedObjectName != null && x.RelatedObjectName.ToLower().StartsWith(filter)) + || (x.RelatedObjectGuid != null && x.RelatedObjectGuid.ToLower().StartsWith(filter)) + || (x.User != null && x.User.Contact != null && x.User.Contact.FullName.ToLower().StartsWith(filter))))) + .BuildAsync(); + IsRunning = false; + } + } + + private void SelectedItemChanged() + { + if (SelectedActionLog == null || SelectedActionLog.DifferenceObject== null) + return; + DifferenceObject = SelectedActionLog.DifferenceObject; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml new file mode 100644 index 000000000..80cc12a69 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml @@ -0,0 +1,312 @@ +<UserControl x:Class="Tango.MachineStudio.ActionLogs.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:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:local="clr-namespace:Tango.MachineStudio.ActionLogs.Views" + xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:vm="clr-namespace:Tango.MachineStudio.ActionLogs.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.ActionLogs" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf" + xmlns:diff="clr-namespace:Tango.BL.ValueObjects;assembly=Tango.BL" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + <UserControl.Resources> + <sharedConverters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> + <sharedConverters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" /> + <sharedConverters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter"/> + </UserControl.Resources> + <Grid IsEnabled="{Binding IsFree}"> + <Grid.RowDefinitions> + <RowDefinition Height="200"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + <TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="70"></TextBlock> + <Grid Grid.Row="1" Margin="40 0 40 40"> + <Grid.RowDefinitions> + <RowDefinition Height="70"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width ="7*"/> + <ColumnDefinition Width ="3*"/> + </Grid.ColumnDefinitions > + + <Grid x:Name ="searchButtons" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Stretch"> + <Border Padding="14 14 12 14" BorderBrush="DimGray" BorderThickness="0" Background="{StaticResource Logging.Background}" HorizontalAlignment="Stretch" CornerRadius="2" > + <Border.Effect> + <DropShadowEffect ShadowDepth="4" BlurRadius="10" Opacity="0.5"/> + </Border.Effect> + <DockPanel> + <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal"> + <StackPanel > + <TextBlock FontSize="10">Start Date:</TextBlock> + <DatePicker x:Name="startdatePicker" SelectedDate="{Binding StartSelectedDate}" materialDesign:HintAssist.Hint="Pick start date" Width="160" VerticalAlignment="Center" FontSize="16" /> + </StackPanel> + <StackPanel Margin="50 0 0 0"> + <TextBlock FontSize="10">End Date:</TextBlock> + <DatePicker x:Name="endDatePicker" SelectedDate="{Binding EndSelectedDate}" materialDesign:HintAssist.Hint="Pick end date" Width="160" VerticalAlignment="Center" FontSize="16" /> + </StackPanel> + <DockPanel Margin="50 0 0 0" > + <TextBlock DockPanel.Dock="Top" Text="Action Log Type:" VerticalAlignment="Center" FontSize="10"></TextBlock> + <ToggleButton Width="200" Margin="0 5 0 0" x:Name="selectActionsButton"> + <ToggleButton.Template> + <ControlTemplate> + <Grid> + <Border CornerRadius="3" BorderBrush="{StaticResource borderBrush}" BorderThickness="1" TextElement.Foreground="Black" > + <DockPanel> + <Button Width="18" Padding="0" Height="16" DockPanel.Dock="Right" BorderBrush="{x:Null}" HorizontalAlignment="Left" Click="Button_Click" Style="{StaticResource MaterialDesignFlatButton}" Foreground="{StaticResource MainWindow.Foreground}"> + <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> + </Button> + <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}"> + <Run Text=" Select Actions"></Run> + <Run>(</Run><Run Text="{Binding SelectedActionLogTypes.SynchedSource.Count,Mode=OneWay}"></Run><Run>)</Run> + </TextBlock> + </DockPanel> + </Border> + <Popup StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }" > + <Border Padding="5" Background="{DynamicResource ComboBox.Floating.Background}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> + <ScrollViewer MaxHeight="600" Background="{DynamicResource ComboBox.Floating.Background}"> + <ItemsControl ItemsSource="{Binding SelectedActionLogTypes}" Foreground="{StaticResource MainWindow.Foreground}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <DockPanel Margin="2"> + <CheckBox VerticalAlignment="Center" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data,Converter={StaticResource EnumToDescriptionConverter}}"></TextBlock> + </DockPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </ScrollViewer> + </Border> + </Popup> + </Grid> + </ControlTemplate> + </ToggleButton.Template> + </ToggleButton> + + </DockPanel> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="50 10 0 0"> + <materialDesign:PackIcon Kind="Magnify" Width="26" Height="26"/> + <TextBox Width="Auto" materialDesign:HintAssist.Hint="Search by ID, user, related object name" Text="{Binding SearchFilter,UpdateSourceTrigger=PropertyChanged}" /> + </StackPanel> + </StackPanel> + <Button DockPanel.Dock="Right" Width="120" HorizontalAlignment="Right" Command="{Binding SearchCommand}" Margin="10 0 10 0" VerticalAlignment="Center">Search</Button> + </DockPanel> + </Border> + </Grid> + + <Grid IsEnabled="{Binding IsFree}" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > + <DataGrid Margin="0 0 0 10" SelectionMode="Single" SelectionUnit="FullRow" RowHeight="40" BorderBrush="{StaticResource borderBrush}" IsReadOnly="True" BorderThickness="1" + Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserReorderColumns="True" + CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding ActionLogs}" + SelectedItem="{Binding SelectedActionLog}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" FontSize="11"> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + </Style.Triggers> + </Style> + </DataGrid.CellStyle> + <DataGrid.RowStyle> + <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + <Setter Property="Cursor" Value="Hand"></Setter> + </Trigger> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </DataGrid.RowStyle> + + <DataGrid.Columns> + <DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="40" /> + <DataGridTextColumn Header="TIME" Binding="{Binding LastUpdated, Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" /> + <DataGridTextColumn Header="ACTION" Binding="{Binding ActionType, Converter={StaticResource EnumToDescriptionConverter}}" Width="Auto"/> + <DataGridTextColumn Header="USER" Binding="{Binding User.Contact.FullName}" Width="Auto"/> + <DataGridTextColumn Header="RELATED OBJECT NAME" Binding="{Binding RelatedObjectName}" Width="Auto" /> + <DataGridTextColumn Header="RELATED OBJECT ID" Binding="{Binding RelatedObjectGuid}" Width="Auto" > + <DataGridTextColumn.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}" > + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext}"/> + <Setter Property="ContextMenu"> + <Setter.Value> + <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" Padding="0" Margin="0" > + <MenuItem Header="Copy (Ctrl+C)" Command="{Binding CopyRelateObjectIDCommand}" FontSize="12" Background="{StaticResource MainWindow.Background}"> + <MenuItem.Icon> + <materialDesign:PackIcon Width="16" Height="16" Kind="ContentCopy" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}"/> + </MenuItem.Icon> + <MenuItem.ItemContainerStyle> + <Style TargetType="MenuItem" BasedOn="{StaticResource MaterialDesignMenuItem}"> + <Setter Property="Background" Value="Transparent"></Setter> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </MenuItem.ItemContainerStyle> + </MenuItem> + <ContextMenu.Style> + <Style TargetType="{x:Type ContextMenu}" BasedOn="{StaticResource MaterialDesignMenu}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate > + <AdornerDecorator CacheMode="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:ShadowAssist.CacheMode)}"> + <Border Background="{StaticResource MainWindow.Background}" Effect="{DynamicResource MaterialDesignShadowDepth1}" Margin="3" CornerRadius="2"> + <Grid RenderOptions.ClearTypeHint="Enabled" Margin="0"> + <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/> + </Grid> + </Border> + </AdornerDecorator> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </ContextMenu.Style> + </ContextMenu> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + </Style.Triggers> + </Style> + </DataGridTextColumn.CellStyle> + </DataGridTextColumn> + <DataGridTextColumn Header="MESSAGE" Binding="{Binding Message}" Width="1*" /> + </DataGrid.Columns> + </DataGrid> + </Grid> + <Grid Grid.Row="1" Grid.Column="0" Visibility="{Binding IsRunning,Converter={StaticResource BooleanToVisibilityConverter}}"> + <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"> + <mahapps:ProgressRing Margin="20 60 20 40" Width="80" Height="80" IsActive="{Binding IsRunning}"></mahapps:ProgressRing> + <TextBlock Text="Loading..." HorizontalAlignment="Center" FontSize="20" FontStyle="Italic" VerticalAlignment="Center" Margin="0 20 0 0"></TextBlock> + </StackPanel> + </Grid> + + <Grid Grid.Row="0" Grid.Column="1" Margin="40 0 10 0"> + <Border Padding="14 14 12 14" BorderBrush="DimGray" BorderThickness="0" Background="{StaticResource Logging.Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="2"> + <Border.Effect> + <DropShadowEffect ShadowDepth="4" BlurRadius="10" Opacity="0.5"/> + </Border.Effect> + <DockPanel> + <TextBlock DockPanel.Dock="Left" Margin="10 0 0 0" Foreground="{StaticResource DimGrayBrush}" FontSize="16" VerticalAlignment="Center" Width="150">Object Changes</TextBlock> + <Button Width="Auto" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Right" DockPanel.Dock="Right" Command="{Binding CopyToClipBoardCommand}" > + <StackPanel Orientation="Horizontal" > + <materialDesign:PackIcon Width="16" Height="16" Kind="ContentCopy" VerticalAlignment="Center" Margin="-5 0 10 0"/> + <TextBlock Text="Copy to Clipboard" VerticalAlignment="Center"></TextBlock> + </StackPanel> + </Button> + </DockPanel> + </Border> + </Grid> + <Border Grid.Row="1" Grid.Column="1" Margin="40 0 10 10" IsEnabled="{Binding IsFree}" BorderThickness="1 0 1 1 " BorderBrush="{StaticResource LightGrayBrush100}" > + <DockPanel > + <TextBlock DockPanel.Dock="Top" Height="40" Text="{Binding DifferenceObject.Name, Mode=OneWay}" VerticalAlignment="Center" Padding="5" FontSize="18" HorizontalAlignment="Center"></TextBlock> + <TreeView x:Name="treeView" ItemsSource="{Binding DifferenceObject.Children, Mode=OneWay}" Background="{StaticResource TransparentBackgroundBrush}" > + <TreeView.ItemContainerStyle> + <Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type TreeViewItem}"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition MinWidth="19" Width="Auto"/> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + <RowDefinition/> + </Grid.RowDefinitions> + <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" + Style="{StaticResource MaterialDesignExpandCollapseToggleStyle}" + Foreground="{TemplateBinding Foreground}" + Margin="8 0 8 0" + VerticalAlignment="Center" + /> + <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> + <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> + </Border> + <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/> + </Grid> + <ControlTemplate.Triggers> + <Trigger Property="IsExpanded" Value="false"> + <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/> + </Trigger> + <Trigger Property="HasItems" Value="false"> + <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/> + </Trigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsSelected" Value="true"/> + <Condition Property="IsSelectionActive" Value="false"/> + </MultiTrigger.Conditions> + <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/> + </MultiTrigger> + <Trigger Property="IsEnabled" Value="false"> + <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + <Setter Property="IsExpanded" Value="True" /> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </TreeView.ItemContainerStyle> + <TreeView.Resources> + <HierarchicalDataTemplate DataType="{x:Type diff:ActionLogDifference}" ItemsSource="{Binding Children}"> + <TextBlock Text="{Binding Name}" Margin="5 0 0 0" Foreground ="{StaticResource MainWindow.Foreground}"/> + </HierarchicalDataTemplate> + + <DataTemplate DataType="{x:Type diff:ActionLogDifferenceValue}"> + <TextBlock Margin="5 0 0 0" Foreground ="{StaticResource MainWindow.Foreground}"> + <Run Text="{Binding Name}"/> + <Run>: </Run> + <Run Text="{Binding Before,Mode=OneWay}" Foreground="{StaticResource DimGrayBrush}"/> + <Run> | </Run> + <Run Text="{Binding After,Mode=OneWay}" Foreground="{StaticResource RedBrush100}"/> + </TextBlock> + </DataTemplate> + </TreeView.Resources> + </TreeView> + + </DockPanel> + </Border> + + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs new file mode 100644 index 000000000..67641e3fc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs @@ -0,0 +1,34 @@ +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.MachineStudio.ActionLogs.Views +{ + /// <summary> + /// Interaction logic for MainView.xaml + /// </summary> + public partial class MainView : UserControl + { + public MainView() + { + InitializeComponent(); + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + selectActionsButton.IsChecked = true; + e.Handled = true; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config new file mode 100644 index 000000000..7b82e5f7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/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.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="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.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.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="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="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/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config new file mode 100644 index 000000000..e57143046 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="EntityFramework" version="6.2.0" targetFramework="net461" /> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net461" /> + <package id="MahApps.Metro" version="1.5.0" targetFramework="net461" /> + <package id="MaterialDesignColors" version="1.1.2" targetFramework="net461" /> + <package id="MaterialDesignThemes" version="2.3.1.953" 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/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs index 652ad3093..406622ee1 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs @@ -17,6 +17,10 @@ using Microsoft.Win32; using Tango.Core.Helpers; using System.IO; using Tango.MachineStudio.Catalogs.Excel; +using Tango.BL.ActionLogs; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.Enumerations; +using Tango.BL.DTO; namespace Tango.MachineStudio.Catalogs.ViewModels { @@ -25,6 +29,9 @@ namespace Tango.MachineStudio.Catalogs.ViewModels private ObservablesContext _catalogsContext; private ObservablesContext _activeCatalogContext; private INotificationProvider _notification; + private IActionLogManager _actionLogManager; + private IAuthenticationProvider _authentication; + private ColorCatalogDTO _catalogBeforeSave; #region Properties @@ -151,9 +158,11 @@ namespace Tango.MachineStudio.Catalogs.ViewModels /// Initializes a new instance of the <see cref="MainViewVM"/> class. /// </summary> /// <param name="notificationProvider">The notification provider.</param> - public MainViewVM(INotificationProvider notificationProvider) : this() + public MainViewVM(INotificationProvider notificationProvider, IActionLogManager actionLogManager, IAuthenticationProvider authenticationProvider) : this() { + _actionLogManager = actionLogManager; _notification = notificationProvider; + _authentication = authenticationProvider; } #endregion @@ -197,7 +206,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels _activeCatalogContext = ObservablesContext.CreateDefault(); - ActiveCatalog = await new ColorCatalogBuilder(_activeCatalogContext).Set(SelectedCatalog.Guid).WithGroups().WithItems().WithRecipes().BuildAsync(); + ActiveCatalog = await new CatalogBuilder(_activeCatalogContext).Set(SelectedCatalog.Guid).WithGroups().WithItems().WithRecipes().BuildAsync(); SelectedGroup = ActiveCatalog.ColorCatalogsGroups.FirstOrDefault(); RMLS = await _activeCatalogContext.Rmls.ToListAsync(); @@ -206,6 +215,8 @@ namespace Tango.MachineStudio.Catalogs.ViewModels SelectedItem = SelectedGroup.ColorCatalogsItems.FirstOrDefault(); } + _catalogBeforeSave = ColorCatalogDTO.FromObservable(ActiveCatalog); + View.NavigateTo(CatalogsNavigationView.CatalogView); } catch (Exception ex) @@ -233,6 +244,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels { IsFree = false; await SelectedCatalog.DeleteCascadeAsync(_catalogsContext); + _actionLogManager.InsertLog(ActionLogType.CatalogDeleted, _authentication.CurrentUser, SelectedCatalog.Name, SelectedCatalog, "Catalog deleted using Machine Studio.", false); SelectedCatalog = null; } catch (Exception ex) @@ -265,6 +277,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels newCatalog.Company = "Twine"; _catalogsContext.ColorCatalogs.Add(newCatalog); await _catalogsContext.SaveChangesAsync(); + _actionLogManager.InsertLog(ActionLogType.CatalogCreated, _authentication.CurrentUser, newCatalog.Name, newCatalog, "Catalog created using Machine Studio."); SelectedCatalog = newCatalog; EditSelectedCatalog(); } @@ -305,8 +318,15 @@ namespace Tango.MachineStudio.Catalogs.ViewModels try { IsFree = false; + ActiveCatalog.LastUpdated = DateTime.UtcNow; await _activeCatalogContext.SaveChangesAsync(); + + var activeCatalogDTO = ColorCatalogDTO.FromObservable(ActiveCatalog); + _actionLogManager.InsertLog(ActionLogType.CatalogSaved, _authentication.CurrentUser, _catalogBeforeSave.Name, _catalogBeforeSave, activeCatalogDTO, "Catalog saved using Machine Studio."); + _catalogBeforeSave = activeCatalogDTO; + await LoadCatalogs(); + _notification.ShowInfo("Catalog updated successfully."); } catch (Exception ex) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj index 8f37a9c2d..4e6feceb5 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj @@ -18,7 +18,7 @@ <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> - <OutputPath>..\..\..\Build\Machine Studio\Debug\</OutputPath> + <OutputPath>bin\Debug\</OutputPath> <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> @@ -26,7 +26,7 @@ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> - <OutputPath>..\..\..\Build\Machine Studio\Release\</OutputPath> + <OutputPath>bin\Release\</OutputPath> <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 4ab3bb1bb..a641c87b6 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -50,6 +50,9 @@ using Tango.Core.ExtensionMethods; using Tango.ColorConversion; using Tango.PMR.Exports; using Microsoft.WindowsAPICodePack.Dialogs; +using Tango.BL.Enumerations; +using Tango.BL.DTO; +using Tango.BL.ActionLogs; namespace Tango.MachineStudio.Developer.ViewModels { @@ -84,6 +87,10 @@ namespace Tango.MachineStudio.Developer.ViewModels private bool _rml_has_no_cct; private TaskItem _preparingTaskItem; private IColorConverter _converter; + private string _current_job_string; + private JobDTO _beforeSaveJobDTO; + private IActionLogManager _actionLogManager; + private RmlDTO _selectedRMLBeforeLiquidFactorsSaves; #region Properties @@ -746,7 +753,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// </summary> /// <param name="applicationManager">The application manager.</param> /// <param name="notificationProvider">The notification provider.</param> - public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech) + public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech, IActionLogManager actionLogManager) { _converter = new DefaultColorConverter(); @@ -755,6 +762,7 @@ namespace Tango.MachineStudio.Developer.ViewModels AuthenticationProvider = authentication; + _actionLogManager = actionLogManager; _notification = notificationProvider; _speech = speech; _navigation = navigation; @@ -872,7 +880,7 @@ namespace Tango.MachineStudio.Developer.ViewModels foreach (var stop in stops) { - if (stop.ColorSpace.Code == BL.Enumerations.ColorSpaces.Volume.ToInt32() && !stop.IsLiquidVolumesOutOfRange) + if (stop.ColorSpace.Code == BL.Enumerations.ColorSpaces.Volume.ToInt32()) { try { @@ -1033,6 +1041,11 @@ namespace Tango.MachineStudio.Developer.ViewModels { var percent = (e.Progress / e.Total * 100d); + if (_preparingTaskItem != null) + { + _preparingTaskItem.Message = $"Preparing job for printing {(e.Progress / e.Total * 100d).ToString("0.0")}%..."; + } + if (_preparingTaskItem == null && percent == 0) { _preparingTaskItem = _notification.PushTaskItem("Preparing job for printing..."); @@ -1042,13 +1055,6 @@ namespace Tango.MachineStudio.Developer.ViewModels _preparingTaskItem.Pop(); _preparingTaskItem = null; } - else - { - if (_preparingTaskItem != null) - { - _preparingTaskItem.Message = $"Preparing job for printing {(e.Progress / e.Total * 100d).ToString("0.0")}%..."; - } - } } private void MachineOperator_ResumingJob(object sender, ResumingJobEventArgs e) @@ -1593,8 +1599,12 @@ namespace Tango.MachineStudio.Developer.ViewModels { LogManager.Log(String.Format("Saving liquid factors for RML {0}...", SelectedRML.Name)); await SelectedRML.SaveAsync(_activeJobDbContext); + var rmlAfterChange = RmlDTO.FromObservable(SelectedRML); + _actionLogManager.InsertLog(ActionLogType.RmlSaved, AuthenticationProvider.CurrentUser, SelectedRML.Name, _selectedRMLBeforeLiquidFactorsSaves, rmlAfterChange, "RML liquid factors changed from Machine Studio Research module."); + _selectedRMLBeforeLiquidFactorsSaves = rmlAfterChange; LiquidTypesRmls = ActiveJob.Machine.Configuration.GetSupportedIdsPacks(SelectedRML).Select(x => x.LiquidType).SelectMany(x => x.LiquidTypesRmls).Where(x => x.Rml.Guid == SelectedRML.Guid).ToList(); + foreach (var segment in ActiveJob.Segments) { SetSegmentBrushStopsLiquidVolumes(segment); @@ -1624,6 +1634,8 @@ namespace Tango.MachineStudio.Developer.ViewModels _selectedRML = new RmlBuilder(_activeJobDbContext).Set(SelectedRML.Guid).WithAllParametersGroup().WithCAT(SelectedMachine.Guid).WithCCT().WithLiquidFactors().Build(); + _selectedRMLBeforeLiquidFactorsSaves = RmlDTO.FromObservable(_selectedRML); + if (_selectedRML.Cct == null) { InvokeUI(() => @@ -1714,6 +1726,8 @@ namespace Tango.MachineStudio.Developer.ViewModels using (_notification.PushTaskItem("Saving Parameters Group...")) { + var processGroupBefore = ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()); + using (var db = ObservablesContext.CreateDefault()) { var active_groups = db.ProcessParametersTablesGroups.Where(x => x.RmlGuid == SelectedRML.Guid && x.Active).ToList(); @@ -1755,6 +1769,8 @@ namespace Tango.MachineStudio.Developer.ViewModels SelectedRML.ProcessParametersTablesGroups.Add(group); await SelectedRML.SaveAsync(_activeJobDbContext); + _actionLogManager.InsertLog(ActionLogType.RmlActiveProcessParametersChanged, AuthenticationProvider.CurrentUser, SelectedRML.Name, processGroupBefore, ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()), "RML Active process parameters changed from Machine Studio Research module."); + InvalidateLiquidFactorsAndProcessTables(); } @@ -1799,92 +1815,110 @@ namespace Tango.MachineStudio.Developer.ViewModels using (_notification.PushTaskItem("Loading job details...")) { - await Task.Factory.StartNew(() => + try { - _disable_gamut_check = true; + await Task.Factory.StartNew(() => + { + _disable_gamut_check = true; - LogManager.Log(String.Format("Loading job {0}...", SelectedMachineJob.Name)); - SelectedSegments = new ObservableCollection<Segment>(); - SelectedBrushStops = new ObservableCollection<BrushStop>(); - SelectedRML = null; - SelectedSegment = null; - SelectedGroupHistory = null; - SelectedBrushStop = null; - SelectedProcessParametersTable = null; - RmlProcessParametersTableGroup = null; + LogManager.Log(String.Format("Loading job {0}...", SelectedMachineJob.Name)); + SelectedSegments = new ObservableCollection<Segment>(); + SelectedBrushStops = new ObservableCollection<BrushStop>(); + SelectedRML = null; + SelectedSegment = null; + SelectedGroupHistory = null; + SelectedBrushStop = null; + SelectedProcessParametersTable = null; + RmlProcessParametersTableGroup = null; - _blockInvalidateCommands = false; + _blockInvalidateCommands = false; - LogManager.Log("Creating active job DB context..."); - _activeJobDbContext = ObservablesContext.CreateDefault(); + LogManager.Log("Creating active job DB context..."); + _activeJobDbContext = ObservablesContext.CreateDefault(); - LogManager.Log("Initializing available color spaces, RMLs & Winding methods..."); + LogManager.Log("Initializing available color spaces, RMLs & Winding methods..."); - //var processParamsGroups = _activeJobDbContext.ProcessParametersTablesGroups.ToList(); - //var processParams = _activeJobDbContext.ProcessParametersTables.ToList(); + //var processParamsGroups = _activeJobDbContext.ProcessParametersTablesGroups.ToList(); + //var processParams = _activeJobDbContext.ProcessParametersTables.ToList(); - ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection(); - Rmls = _activeJobDbContext.Rmls.ToObservableCollection(); - WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection(); - SpoolTypes = _activeJobDbContext.SpoolTypes.ToObservableCollection(); + ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection(); + Rmls = _activeJobDbContext.Rmls.ToObservableCollection(); + WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection(); + SpoolTypes = _activeJobDbContext.SpoolTypes.ToObservableCollection(); - LogManager.Log("Loading machine spools..."); - _activeJobDbContext.Spools.Where(x => x.MachineGuid == SelectedMachine.Guid).Load(); + LogManager.Log("Loading machine spools..."); + _activeJobDbContext.Spools.Where(x => x.MachineGuid == SelectedMachine.Guid).Load(); - LogManager.Log("Setting active job..."); - ActiveJob = new JobBuilder(_activeJobDbContext).Set(SelectedMachineJob.Guid).WithUser().WithSegments().WithBrushStops().WithConfiguration().WithRML().Build(); + LogManager.Log("Setting active job..."); + ActiveJob = new JobBuilder(_activeJobDbContext).Set(SelectedMachineJob.Guid).WithUser().WithSegments().WithBrushStops().WithConfiguration().WithRML().Build(); - //_activeJobDbContext.Ccts.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); - //_activeJobDbContext.Cats.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); - //_activeJobDbContext.Machines.SingleOrDefault(x => x.Guid == ActiveJob.MachineGuid); - //_activeJobDbContext.Configurations.SingleOrDefault(x => x.Guid == ActiveJob.Machine.ConfigurationGuid); + //_activeJobDbContext.Ccts.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); + //_activeJobDbContext.Cats.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); + //_activeJobDbContext.Machines.SingleOrDefault(x => x.Guid == ActiveJob.MachineGuid); + //_activeJobDbContext.Configurations.SingleOrDefault(x => x.Guid == ActiveJob.Machine.ConfigurationGuid); - //_activeJobDbContext.LiquidTypesRmls.ToList(); + //_activeJobDbContext.LiquidTypesRmls.ToList(); - //_activeJobDbContext.IdsPackFormulas.ToList(); - //_activeJobDbContext.LiquidTypes.ToList(); - //_activeJobDbContext.MidTankTypes.ToList(); - //_activeJobDbContext.DispenserTypes.ToList(); + //_activeJobDbContext.IdsPackFormulas.ToList(); + //_activeJobDbContext.LiquidTypes.ToList(); + //_activeJobDbContext.MidTankTypes.ToList(); + //_activeJobDbContext.DispenserTypes.ToList(); - //_activeJobDbContext.IdsPacks.Where(x => x.ConfigurationGuid == ActiveJob.Machine.ConfigurationGuid).ToList(); + //_activeJobDbContext.IdsPacks.Where(x => x.ConfigurationGuid == ActiveJob.Machine.ConfigurationGuid).ToList(); + _beforeSaveJobDTO = JobDTO.FromObservable(ActiveJob); - LogManager.Log("Setting selected segment..."); - _selectedSegment = ActiveJob.OrderedSegments.FirstOrDefault(); + LogManager.Log("Setting selected segment..."); + _selectedSegment = ActiveJob.OrderedSegments.FirstOrDefault(); - ActiveJob.LengthChanged -= ActiveJob_LengthChanged; - ActiveJob.LengthChanged += ActiveJob_LengthChanged; + ActiveJob.LengthChanged -= ActiveJob_LengthChanged; + ActiveJob.LengthChanged += ActiveJob_LengthChanged; - _selectedRML = ActiveJob.Rml; - InvalidateLiquidFactorsAndProcessTables(); - RaisePropertyChanged(nameof(SelectedRML)); + _selectedRML = ActiveJob.Rml; + InvalidateLiquidFactorsAndProcessTables(); + RaisePropertyChanged(nameof(SelectedRML)); - UpdateEstimatedDuration(); + UpdateEstimatedDuration(); - _blockInvalidateCommands = false; - InvalidateRelayCommands(); + _blockInvalidateCommands = false; + InvalidateRelayCommands(); - _disable_gamut_check = false; + _disable_gamut_check = false; - _settings.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null; - _settings.LastSelectedJobGuid = SelectedMachineJob != null ? SelectedMachineJob.Guid : null; + _settings.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null; + _settings.LastSelectedJobGuid = SelectedMachineJob != null ? SelectedMachineJob.Guid : null; - _settings.Save(); - }); + _settings.Save(); + }); - SegmentsCollectionView = CollectionViewSource.GetDefaultView(ActiveJob.Segments); - SegmentsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Segment.SegmentIndex), ListSortDirection.Ascending)); + SegmentsCollectionView = CollectionViewSource.GetDefaultView(ActiveJob.Segments); + SegmentsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Segment.SegmentIndex), ListSortDirection.Ascending)); - foreach (var segment in ActiveJob.Segments) - { - SetSegmentBrushStopsLiquidVolumes(segment); - } + foreach (var segment in ActiveJob.Segments) + { + SetSegmentBrushStopsLiquidVolumes(segment); + } - SelectedSegment = _selectedSegment; + SelectedSegment = _selectedSegment; - UIHelper.DoEvents(); - _navigation.NavigateTo(DeveloperNavigationView.JobView); + if (ActiveJob != null) + { + _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); + } + + UIHelper.DoEvents(); + _navigation.NavigateTo(DeveloperNavigationView.JobView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job."); + _notification.ShowError($"An error occurred while trying to load the selected job.\n{ex.FlattenMessage()}"); + } + finally + { + CanWork = true; + } } CanWork = true; @@ -1902,46 +1936,65 @@ namespace Tango.MachineStudio.Developer.ViewModels { CanWork = false; - using (_notification.PushTaskItem("Saving job details...")) + try { - await Task.Factory.StartNew(() => + using (_notification.PushTaskItem("Saving job details...")) { - LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name)); - ActiveJob.LastUpdated = DateTime.UtcNow; - ActiveJob.Rml = SelectedRML; - ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; - _activeJobDbContext.SaveChanges(); - - _machineDbContext.Entry(SelectedMachineJob).Reload(); + await Task.Factory.StartNew(() => + { + LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name)); + ActiveJob.LastUpdated = DateTime.UtcNow; + ActiveJob.IsSynchronized = false; + ActiveJob.Rml = SelectedRML; + ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; + ActiveJob.MarkModified(_activeJobDbContext); + _activeJobDbContext.SaveChanges(); + var afterJobDTO = JobDTO.FromObservable(ActiveJob); + _actionLogManager.InsertLog(ActionLogType.JobSaved, AuthenticationProvider.CurrentUser, _beforeSaveJobDTO.Name, _beforeSaveJobDTO, afterJobDTO, "Job saved from research module in Machine Studio."); + _beforeSaveJobDTO = afterJobDTO; - _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); + _machineDbContext.Entry(SelectedMachineJob).Reload(); - foreach (var segment in SelectedMachineJob.Segments.ToList()) - { - _machineDbContext.Entry(segment).Collection(x => x.BrushStops).Load(); + _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); - foreach (var brushStop in segment.BrushStops.ToList()) + foreach (var segment in SelectedMachineJob.Segments.ToList()) { - _machineDbContext.Entry(brushStop).Reload(); - } + _machineDbContext.Entry(segment).Collection(x => x.BrushStops).Load(); - _machineDbContext.Entry(segment).Reload(); - } + foreach (var brushStop in segment.BrushStops.ToList()) + { + _machineDbContext.Entry(brushStop).Reload(); + } - InvokeUI(() => - { - SelectedMachineJob.Segments = SelectedMachineJob.Segments; - }); + _machineDbContext.Entry(segment).Reload(); + } - var settings = SettingsManager.Default.GetOrCreate<DeveloperModuleSettings>(); - settings.DefaultJobRmlGuid = ActiveJob.RmlGuid; - settings.Save(); + InvokeUI(() => + { + SelectedMachineJob.Segments = SelectedMachineJob.Segments; + }); - }); - } + var settings = SettingsManager.Default.GetOrCreate<DeveloperModuleSettings>(); + settings.DefaultJobRmlGuid = ActiveJob.RmlGuid; + settings.Save(); - CanWork = true; + if (ActiveJob != null) + { + _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); + } + }); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving active job."); + _notification.ShowError($"An error occurred while trying to save the current job.\n{ex.FlattenMessage()}"); + } + finally + { + CanWork = true; + } } } @@ -1950,7 +2003,7 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("User request for 'back to jobs'..."); LogManager.Log("Comparing active job with selected job..."); - bool jobModified = !ActiveJob.CompareUsingJson(SelectedMachineJob); + bool jobModified = ActiveJob.ToJobFileWhenLoaded().ToString() != _current_job_string; if (jobModified) { @@ -2161,6 +2214,8 @@ namespace Tango.MachineStudio.Developer.ViewModels { if (_notification.ShowQuestion("Are you sure you want to delete the selected jobs?")) { + var jobsToReport = SelectedJobs.Select(x => JobDTO.FromObservable(x)).ToList(); + LogManager.Log(String.Format("Removing {0} jobs...", SelectedJobs.Count)); SelectedJobs.ToList().ForEach(x => { @@ -2172,6 +2227,11 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); } + + foreach (var job in jobsToReport) + { + _actionLogManager.InsertLog(ActionLogType.JobDeleted, AuthenticationProvider.CurrentUser, job.Name, job, "Job deleted using Machine Studio.", true); + } } } } @@ -2192,6 +2252,8 @@ namespace Tango.MachineStudio.Developer.ViewModels var settings = SettingsManager.Default.GetOrCreate<DeveloperModuleSettings>(); Job newJob = new Job(); + newJob.LastUpdated = DateTime.UtcNow; + newJob.JobSource = JobSource.Remote; newJob.Name = jobName; newJob.CreationDate = DateTime.UtcNow; newJob.UserGuid = AuthenticationProvider.CurrentUser.Guid; @@ -2226,6 +2288,7 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); + _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, newJob.Name, newJob, "Job created using Machine Studio."); SelectedMachineJob = newJob; LoadSelectedJob(); } @@ -2251,6 +2314,7 @@ namespace Tango.MachineStudio.Developer.ViewModels return; } SelectedSegment.BrushStops.Remove(x); + _activeJobDbContext.BrushStops.Remove(x); }); ArrangeBrushStopsIndices(); @@ -2355,6 +2419,11 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); + foreach (var job in SelectedJobs) + { + _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, job.Name, job, "Job cloned using Machine Studio."); + } + CanWork = true; } } @@ -2578,17 +2647,26 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log($"Importing job files..."); + List<Job> jobsToReport = new List<Job>(); + foreach (var file in dlg.FileNames) { var bytes = File.ReadAllBytes(file); var jobFile = JobFile.Parser.ParseFrom(bytes); var job = await Job.FromJobFile(jobFile, SelectedMachine.Guid, AuthenticationProvider.CurrentUser.Guid); + job.JobSource = JobSource.Remote; _machineDbContext.Jobs.Add(job); + jobsToReport.Add(job); } await _machineDbContext.SaveChangesAsync(); + foreach (var job in jobsToReport) + { + _actionLogManager.InsertLog(ActionLogType.JobImported, AuthenticationProvider.CurrentUser, job.Name, job, "Job imported using Machine Studio."); + } + IsFree = true; _notification.ShowInfo($"Jobs imported successfully."); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml index f0e9dc29c..c0cb963e7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml @@ -5,8 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:vm="clr-namespace:Tango.MachineStudio.Developer.ViewModels" xmlns:local="clr-namespace:Tango.MachineStudio.Developer.Views" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" - Height="450" Width="800" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}"> + Height="590" Width="800" d:DataContext="{d:DesignInstance Type=vm:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource Dialog.Foreground}" + Background="{StaticResource Dialog.Background}"> <Grid Margin="10"> <DockPanel> <StackPanel DockPanel.Dock="Top"> @@ -23,28 +25,60 @@ <Button HorizontalAlignment="Right" DockPanel.Dock="Bottom" Height="40" Width="140" Command="{Binding CloseCommand}" Margin="10 0 0 0">CLOSE</Button> </Grid> - <Border Margin="0 40 0 0" BorderThickness="1" BorderBrush="{StaticResource BorderBrushGainsboro}" CornerRadius="3"> - <ItemsControl ItemsSource="{Binding Exception.IdsPackLevels}"> + <Border Margin="0 20 0 0" Padding="10" BorderThickness="1" BorderBrush="{StaticResource BorderBrushGainsboro}" CornerRadius="3"> + <ItemsControl ItemsSource="{Binding Exception.IdsPackLevels}" VerticalAlignment="Top"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> - <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> + <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Vertical" IsItemsHost="True"></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <StackPanel Margin="15 0"> - <TextBlock HorizontalAlignment="Center" Text="{Binding IdsPack.LiquidType.Name}"></TextBlock> - <Border Margin="0 5 0 0" Height="150" Width="50" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource BorderBrushGainsboro}"> + <Grid Margin="0 0 0 4"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="40" /> + <ColumnDefinition Width="160" /> + <ColumnDefinition Width="1*" /> + </Grid.ColumnDefinitions> + <material:PackIcon VerticalAlignment="Center" Width="24" Height="24"> + <material:PackIcon.Style> + <Style TargetType="material:PackIcon"> + <Setter Property="Kind" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource GreenBrush100}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsValid}" Value="False"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource OrangeBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOverMax}" Value="True"> + <Setter Property="Kind" Value="AlertOctagon"></Setter> + <Setter Property="Foreground" Value="{StaticResource RedBrush100}"></Setter> + </DataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsValid}" Value="True" /> + <Condition Binding="{Binding IsOverMax}" Value="False" /> + </MultiDataTrigger.Conditions> + <Setter Property="Kind" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource GreenBrush100}"></Setter> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </material:PackIcon.Style> + </material:PackIcon> + <!--<material:PackIcon Kind="AlertOctagon" VerticalAlignment="Center" Width="24" Height="24" Visibility="{Binding IsValid,Converter={StaticResource BoolToVisConverter}}" />--> + + <Border Grid.Column="1" Margin="5 0 0 0" Height="45" Width="150" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource BorderBrushGainsboro}"> <Grid> - <Border CornerRadius="3" VerticalAlignment="Bottom" Loaded="IdsPackLoaded" MinHeight="5"> + <Border VerticalAlignment="Center" CornerRadius="3" Loaded="IdsPackLoaded" MinHeight="45" HorizontalAlignment="Left" MinWidth="5"> <Border.Background> - <LinearGradientBrush> - <GradientStop Offset="0" Color="#4DFFFFFF" /> + <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Offset="0.5" Color="{Binding IdsPack.LiquidType.LiquidTypeColor}" /> + <GradientStop Offset="1" Color="#4EFFFFFF" /> </LinearGradientBrush> </Border.Background> </Border> - <Rectangle Loaded="Limit_Loaded" Stroke="Red" StrokeThickness="2" VerticalAlignment="Bottom"> + <Rectangle Loaded="Limit_Loaded" Stroke="Red" StrokeThickness="2" HorizontalAlignment="Left"> <Rectangle.Style> <Style TargetType="Rectangle"> <Style.Triggers> @@ -69,9 +103,18 @@ </Style> </Rectangle.Style> </Rectangle> + + + <TextBlock Foreground="#3B3B3B" HorizontalAlignment="Center" Text="{Binding IdsPack.LiquidType.Name}" VerticalAlignment="Center"> + <TextBlock.Effect> + <DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="White" /> + </TextBlock.Effect> + </TextBlock> + </Grid> </Border> - </StackPanel> + <TextBlock Grid.Column="2" HorizontalAlignment="Left" Text="{Binding Message}" VerticalAlignment="Center" Margin="20,0,0,0" TextWrapping="Wrap" Foreground="{StaticResource RedBrush100}"></TextBlock> + </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs index 171cb754e..51cfb1e73 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs @@ -33,7 +33,7 @@ namespace Tango.MachineStudio.Developer.Views Grid parent = border.Parent as Grid; IDSPackLevel packLevel = border.DataContext as IDSPackLevel; - border.Height = ((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; + border.Width = ((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth; } private void Limit_Loaded(object sender, RoutedEventArgs e) @@ -42,8 +42,8 @@ namespace Tango.MachineStudio.Developer.Views Grid parent = rect.Parent as Grid; IDSPackLevel packLevel = rect.DataContext as IDSPackLevel; - var top = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; - rect.Margin = new Thickness(0, 0, 0, top); + var left = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth; + rect.Margin = new Thickness(left, 0, 0, 0); if (packLevel.IsValid) { diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml index 3bda86036..47cb41522 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml @@ -241,91 +241,93 @@ </Style> <DataTemplate x:Key="Volume_Template"> - <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> - <StackPanel VerticalAlignment="Center"> - <ItemsControl VerticalAlignment="Center"> - <ItemsControl.Style> - <Style TargetType="ItemsControl"> - <Setter Property="ItemsSource" Value="{Binding LiquidVolumes}"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.Settings.UsePreferredLiquidVolumeIndex}" Value="True"> - <Setter Property="ItemsSource" Value="{Binding LiquidVolumesOrdered}"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </ItemsControl.Style> - <ItemsControl.ItemsPanel> - <ItemsPanelTemplate> - <StackPanel VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> - </ItemsPanelTemplate> - </ItemsControl.ItemsPanel> - <ItemsControl.ItemTemplate> - <DataTemplate> - <Border> - <Border.Style> - <Style TargetType="Border"> - <Setter Property="Visibility" Value="Visible"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding IdsPack.IdsPackFormula.Name}" Value="Lubricant"> - <Setter Property="Visibility" Value="Collapsed"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Border.Style> - <ContentControl Focusable="False" Style="{StaticResource numberBorder}" Margin="10 0 0 0" Width="60" Height="60"> - <ContentControl.Foreground> - <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> - </ContentControl.Foreground> - <mahapps:NumericUpDown ValueChanged="OnBrushStopFieldValueChanged" FontSize="{StaticResource NumbersFontSize}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> - <mahapps:NumericUpDown.Resources> - <StaticResource ResourceKey="SelectAllTextBoxResource"></StaticResource> - </mahapps:NumericUpDown.Resources> - </mahapps:NumericUpDown> - </ContentControl> - </Border> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - - <StackPanel Orientation="Horizontal" Margin="30 10 0 0" Height="16" Visibility="{Binding IsLiquidVolumesOutOfRange,Converter={StaticResource BooleanToVisibilityConverter}}"> - <materialDesign:PackIcon Kind="Alert" Foreground="{StaticResource OrangeBrush}" /> - <TextBlock Margin="5 0 0 0" Foreground="{StaticResource OrangeBrush}">Liquid volumes exceeds the maximum range for color conversion!</TextBlock> + <StackPanel> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> + <StackPanel VerticalAlignment="Center"> + <ItemsControl VerticalAlignment="Center"> + <ItemsControl.Style> + <Style TargetType="ItemsControl"> + <Setter Property="ItemsSource" Value="{Binding LiquidVolumes}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.Settings.UsePreferredLiquidVolumeIndex}" Value="True"> + <Setter Property="ItemsSource" Value="{Binding LiquidVolumesOrdered}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ItemsControl.Style> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Border> + <Border.Style> + <Style TargetType="Border"> + <Setter Property="Visibility" Value="Visible"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IdsPack.IdsPackFormula.Name}" Value="Lubricant"> + <Setter Property="Visibility" Value="Collapsed"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Border.Style> + <ContentControl Focusable="False" Style="{StaticResource numberBorder}" Margin="10 0 0 0" Width="60" Height="60"> + <ContentControl.Foreground> + <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> + </ContentControl.Foreground> + <mahapps:NumericUpDown ValueChanged="OnBrushStopFieldValueChanged" FontSize="{StaticResource NumbersFontSize}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <StaticResource ResourceKey="SelectAllTextBoxResource"></StaticResource> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </ContentControl> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> </StackPanel> - </StackPanel> - <materialDesign:PackIcon Kind="ChevronDoubleLeft" Margin="40 2 0 0" VerticalAlignment="Center" Foreground="Gray" /> + <materialDesign:PackIcon Kind="ChevronDoubleLeft" Margin="40 2 0 0" VerticalAlignment="Center" Foreground="Gray" /> - <TextBlock VerticalAlignment="Center" FontSize="16" Margin="5 0 0 0" FontStyle="Italic" Foreground="Gray"> + <TextBlock VerticalAlignment="Center" FontSize="16" Margin="5 0 0 0" FontStyle="Italic" Foreground="Gray"> <Run>Total:</Run> <Run Text="{Binding TotalLiquidVolume,Mode=OneWay,StringFormat=0}"></Run><Run>%</Run> <Run>(</Run> <Run FontSize="10" Text="{Binding TotalLiquidNanoliterPerCentimeter,Mode=OneWay,StringFormat=0.00}"></Run> <Run FontSize="12">nl</Run> <Run>)</Run> - </TextBlock> + </TextBlock> - <Border Margin="60 0 0 0" DataContext="{Binding LiquidVolumes,Converter={StaticResource LiquidVolumesToLubricantLiquidVolume}}" BorderBrush="{StaticResource WhiteBrush100}" BorderThickness="1 0 0 0"> - <Border.Style> - <Style TargetType="Border"> - <Setter Property="Visibility" Value="Collapsed"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding Converter={StaticResource NullObjectToBooleanConverter}}" Value="True"> - <Setter Property="Visibility" Value="Visible"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Border.Style> - <ContentControl Focusable="False" Style="{StaticResource numberBorder}" Margin="10 0 0 0" Width="55" Height="55"> - <ContentControl.Foreground> - <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> - </ContentControl.Foreground> - <mahapps:NumericUpDown Foreground="{StaticResource GrayBrush250}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontSize="20" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> - <mahapps:NumericUpDown.Resources> - <StaticResource ResourceKey="SelectAllTextBoxResource"></StaticResource> - </mahapps:NumericUpDown.Resources> - </mahapps:NumericUpDown> - </ContentControl> - </Border> + <Border Margin="60 0 0 0" DataContext="{Binding LiquidVolumes,Converter={StaticResource LiquidVolumesToLubricantLiquidVolume}}" BorderBrush="{StaticResource WhiteBrush100}" BorderThickness="1 0 0 0"> + <Border.Style> + <Style TargetType="Border"> + <Setter Property="Visibility" Value="Collapsed"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Converter={StaticResource NullObjectToBooleanConverter}}" Value="True"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Border.Style> + <ContentControl Focusable="False" Style="{StaticResource numberBorder}" Margin="10 0 0 0" Width="55" Height="55"> + <ContentControl.Foreground> + <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> + </ContentControl.Foreground> + <mahapps:NumericUpDown Foreground="{StaticResource GrayBrush250}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontSize="20" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <StaticResource ResourceKey="SelectAllTextBoxResource"></StaticResource> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </ContentControl> + </Border> + </StackPanel> + + <StackPanel Orientation="Horizontal" Margin="30 10 0 0" Height="16" Visibility="{Binding IsLiquidVolumesOutOfRange,Converter={StaticResource BooleanToVisibilityConverter}}"> + <materialDesign:PackIcon Kind="Alert" Foreground="{StaticResource OrangeBrush}" /> + <TextBlock Margin="5 0 0 0" Foreground="{StaticResource OrangeBrush}">Liquid volumes exceeds the maximum range for color conversion!</TextBlock> + </StackPanel> </StackPanel> </DataTemplate> @@ -789,9 +791,9 @@ </StackPanel> - <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 40 180 0"> + <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="60 40 180 0"> <materialDesign:PackIcon Kind="ChevronLeft" Width="24" Height="24" /> - <TextBlock Margin="0 -2 0 0" VerticalAlignment="Center"><Run>SUPPORTED MEDIA LIQUID</Run> <Run FontSize="10" Foreground="{StaticResource DimGrayBrush}">( Max Nanolitter/CM )</Run></TextBlock> + <TextBlock Margin="0 -2 0 0" VerticalAlignment="Center"><Run>MEDIA LIQUIDS</Run> <Run FontSize="10" Foreground="{StaticResource DimGrayBrush}">( Max Nanolitter/CM )</Run></TextBlock> <materialDesign:PackIcon Kind="ChevronRight" Width="24" Height="24" /> </StackPanel> @@ -1187,6 +1189,41 @@ <Setter Property="Content"> <Setter.Value> <TextBlock> + <Run Text="{Binding PulsePerSecondFull,Mode=OneWay,StringFormat='0.0'}"></Run> + <Run Text="(pulse)" FontSize="9" Foreground="{StaticResource GrayBrush250}"></Run> + </TextBlock> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding DispenserStepDivision}" Value="{x:Static dispensing:DispenserStepDivisions.Auto}"> + <Setter Property="Content" Value="Auto"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding DispenserStepDivision,Converter={StaticResource IsNotConverter},ConverterParameter={x:Static dispensing:DispenserStepDivisions.Auto}}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <TextBlock> + <Run Text="{Binding PulsePerSecondFull,Mode=OneWay,StringFormat='0.0'}"></Run> + <Run Text="(pulse)" FontSize="9" Foreground="{StaticResource GrayBrush250}"></Run> + </TextBlock> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Label.Style> + </Label> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="PULSE / SEC (full step)"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Label VerticalAlignment="Center"> + <Label.Style> + <Style TargetType="Label"> + <Setter Property="Content"> + <Setter.Value> + <TextBlock> <Run Text="{Binding PulsePerSecond,Mode=OneWay,StringFormat='0.0'}"></Run> <Run Text="(pulse)" FontSize="9" Foreground="{StaticResource GrayBrush250}"></Run> </TextBlock> @@ -1366,7 +1403,7 @@ <Grid Background="{StaticResource TransparentBackgroundBrush100}"> <Grid.Style> <Style TargetType="Grid"> - <Setter Property="Width" Value="520"></Setter> + <Setter Property="Width" Value="640"></Setter> <Setter Property="LayoutTransform"> <Setter.Value> <ScaleTransform ScaleY="1" ScaleX="0"></ScaleTransform> @@ -1504,7 +1541,7 @@ </WrapPanel.Resources> - <editors:ParameterizedEditor ParameterizedObject="{Binding}" GeneratingItems="ParameterizedEditor_GeneratingItems"> + <editors:ParameterizedEditor ParameterizedObject="{Binding}"> <editors:ParameterizedEditor.ItemsPanel> <ItemsPanelTemplate> <WrapPanel IsItemsHost="True" Orientation="Horizontal" /> @@ -1512,11 +1549,11 @@ </editors:ParameterizedEditor.ItemsPanel> <editors:ParameterizedEditor.DoubleTemplate> <DataTemplate> - <Grid Background="Transparent" Style="{StaticResource draggableDroppableGrid}" dragAndDrop:DragAndDropService.Drop="OnProcessParameterDropped" dragAndDrop:DragAndDropService.DraggingSurface="{Binding RelativeSource={RelativeSource AncestorType=editors:ParameterizedEditor},Path=DraggingSurface}"> + <Grid Background="Transparent"> <ContentControl> <StackPanel> <TextBlock IsHitTestVisible="False" Margin="0 5 0 5" Text="{Binding Name}" FontSize="11" Foreground="{StaticResource MainWindow.Foreground}"></TextBlock> - <mahapps:NumericUpDown FontSize="20" Minimum="0" Margin="0 0 5 0" HideUpDownButtons="True" HorizontalContentAlignment="Center" Maximum="10000" StringFormat="0.0" InterceptArrowKeys="True" Background="Transparent" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" Value="{Binding Value,Mode=TwoWay}" Foreground="{StaticResource MainWindow.Foreground}"></mahapps:NumericUpDown> + <mahapps:NumericUpDown FontSize="20" Minimum="0" Margin="0 0 5 0" HideUpDownButtons="True" HorizontalContentAlignment="Center" Maximum="10000" StringFormat="{Binding StringFormat}" InterceptArrowKeys="True" Background="Transparent" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" Value="{Binding Value,Mode=TwoWay}" Foreground="{StaticResource MainWindow.Foreground}"></mahapps:NumericUpDown> </StackPanel> </ContentControl> </Grid> @@ -1572,16 +1609,17 @@ <StackPanel Orientation="Horizontal"> <ToggleButton IsChecked="{Binding AutoProcessSelection}" /> - <TextBlock Margin="5 0 0 0">Use Recommended Process Parameters (auto)</TextBlock> + <TextBlock Margin="5 3 0 0">Use Recommended Process Parameters (auto)</TextBlock> </StackPanel> - <StackPanel Margin="0 40 0 0" Orientation="Horizontal" HorizontalAlignment="Right"> - <Button Height="40" Width="105" Command="{Binding ResetProcessParametersCommand}" Background="Transparent" BorderBrush="{StaticResource DarkGrayBrush200}" Foreground="{StaticResource DarkGrayBrush200}" Margin="0 2 10 0" ToolTip="Resets the current process parameters in the embedded device"> + <Grid Margin="0 40 0 0" > + <Button HorizontalAlignment="Left" Height="40" Width="105" Command="{Binding ResetProcessParametersCommand}" Background="Transparent" BorderBrush="{StaticResource DarkGrayBrush200}" Foreground="{StaticResource DarkGrayBrush200}" Margin="0 2 10 0" ToolTip="Resets the current process parameters in the embedded device"> <TextBlock TextWrapping="Wrap" TextAlignment="Center"> TEMP OFF </TextBlock> </Button> - <Button Height="40" Command="{Binding SaveProcessParametersCommand}" HorizontalAlignment="Left" IsEnabled="{Binding AuthenticationProvider.CurrentUser,Converter={StaticResource UserRoleToBooleanConverter},ConverterParameter='Researcher'}"> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> + <Button Height="40" Command="{Binding SaveProcessParametersCommand}" HorizontalAlignment="Left" IsEnabled="{Binding AuthenticationProvider.CurrentUser,Converter={StaticResource UserRoleToBooleanConverter},ConverterParameter='Researcher'}"> <StackPanel Orientation="Horizontal"> <materialDesign:PackIcon VerticalAlignment="Center" Kind="ContentSave"></materialDesign:PackIcon> <TextBlock Margin="10 0 0 0">SAVE PARAMETERS</TextBlock> @@ -1594,6 +1632,7 @@ </StackPanel> </Button> </StackPanel> + </Grid> </StackPanel> </StackPanel> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml.cs index 28e488aae..a4a8fdcf4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml.cs @@ -159,46 +159,6 @@ namespace Tango.MachineStudio.Developer.Views e.Handled = true; } - private void ParameterizedEditor_GeneratingItems(object sender, SharedUI.Editors.ParameterizedEditor.GeneratingItemsEventArgs e) - { - var settings = SettingsManager.Default.GetOrCreate<DeveloperModuleSettings>(); - - List<ParameterItem> items = e.Result.ToList(); - - if (settings.ProcessParametersIndices.Count > 0) - { - items.Clear(); - - foreach (var item in settings.ProcessParametersIndices.OrderBy(x => x.Index)) - { - var p = e.Source.SingleOrDefault(x => x.Name == item.Name); - - if (p != null) - { - items.Add(p); - } - } - } - else - { - ProcessParametersTable p = new ProcessParametersTable(); - var pp = p.CreateParametersCollection(Core.ParameterItemMode.Binding); - - foreach (var item in pp) - { - settings.ProcessParametersIndices.Add(new ParameterIndex() - { - Index = pp.IndexOf(item), - Name = item.Name - }); - } - - settings.Save(); - } - - e.Result = items; - } - private void OnProcessParameterDropped(object sender, DropEventArgs e) { ParameterItem draggedItem = e.Draggable.DataContext as ParameterItem; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index f8a10e7c4..bf626f462 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -64,7 +64,7 @@ <Grid DockPanel.Dock="Top"> <StackPanel> <StackPanel Orientation="Horizontal"> - <Image Source="../Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant" Width="50"></Image> + <Image Source="{StaticResource MachineSmall}" RenderOptions.BitmapScalingMode="Fant" Width="50"></Image> <TextBlock VerticalAlignment="Center" FontWeight="SemiBold" Margin="30 0 0 0" FontSize="30" FontStyle="Italic">MACHINE JOBS</TextBlock> </StackPanel> <Rectangle HorizontalAlignment="Stretch" Margin="0 10 0 0" VerticalAlignment="Bottom" StrokeThickness="1" Height="3"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml index 08ba5b699..d0caa2447 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml @@ -330,31 +330,36 @@ <Rectangle Height="30" Margin="0 10 0 0" VerticalAlignment="Center" Fill="{Binding SegmentBrush}"> </Rectangle> - <Canvas Height="30" HorizontalAlignment="Center" Width="80"> - <Label Padding="0" Margin="0"> - <Label.Style> - <Style TargetType="Label"> - <Setter Property="Content" Value="{x:Null}"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding Started}" Value="True"> - <Setter Property="Content"> - <Setter.Value> - <TextBlock Text="{Binding RemainingTime,StringFormat=hh\\:mm\\:ss}" Foreground="{StaticResource RedBrush300}" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Margin="10" FontSize="20"></TextBlock> - </Setter.Value> - </Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Completed}" Value="True"> - <Setter Property="Content"> - <Setter.Value> - <materialDesign:PackIcon Margin="30 10 0 0" HorizontalAlignment="Center" Width="24" Height="24" Kind="Check" Foreground="#47FF00" /> - </Setter.Value> - </Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Label.Style> - </Label> - </Canvas> + + <Grid Height="30"> + <TextBlock Visibility="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.RunningJobStatus.IsFinalizing, Converter={StaticResource BooleanToVisibilityConverter}}" VerticalAlignment="Center" Background="Transparent" FontSize="12" Foreground="{StaticResource RedBrush100}">Finalizing...</TextBlock> + <Canvas Height="30" HorizontalAlignment="Center" Width="80"> + <Label Padding="0" Margin="0"> + <Label.Style> + <Style TargetType="Label"> + <Setter Property="Content" Value="{x:Null}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Started}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <TextBlock Text="{Binding RemainingTime,StringFormat=hh\\:mm\\:ss}" Foreground="{StaticResource RedBrush300}" FontFamily="{StaticResource digital-7}" HorizontalAlignment="Center" Margin="10" FontSize="20"></TextBlock> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Completed}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <materialDesign:PackIcon Margin="30 10 0 0" HorizontalAlignment="Center" Width="24" Height="24" Kind="Check" Foreground="#47FF00" /> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Label.Style> + </Label> + </Canvas> + </Grid> + </StackPanel> <Rectangle HorizontalAlignment="Right" Stroke="White" Margin="0 35 0 25" ></Rectangle> @@ -408,8 +413,7 @@ </Grid> </DockPanel> - <TextBlock Visibility="{Binding RunningJobStatus.IsFinalizing,Converter={StaticResource BooleanToVisibilityConverter}}" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="-170 0 0 0" Background="{StaticResource DarkGrayBrush}" FontSize="14" Height="30" Foreground="{StaticResource RedBrush100}">Finalizing...</TextBlock> - </Grid> + </Grid> </Border> <ProgressBar IsIndeterminate="True" VerticalAlignment="Bottom" Height="3" Visibility="{Binding IsJobRunning,Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar> @@ -555,15 +559,15 @@ <Border BorderBrush="{StaticResource GrayBrush280}" BorderThickness="0 1 0 1" Padding="5"> <DockPanel> - <StackPanel Orientation="Horizontal" DockPanel.Dock="Left"> - <materialDesign:PackIcon Kind="Alert" Width="32" Height="32" VerticalAlignment="Center" /> - <TextBlock VerticalAlignment="Center" FontSize="16" FontWeight="SemiBold" Margin="10 0 0 0" FontStyle="Italic">Job Aborted By User</TextBlock> + <StackPanel Orientation="Horizontal" DockPanel.Dock="Left" > + <materialDesign:PackIcon Kind="Alert" Width="32" Height="32" VerticalAlignment="Center" Foreground="#FF494949"/> + <TextBlock VerticalAlignment="Center" Foreground="#FF494949" FontSize="16" FontWeight="SemiBold" Margin="10 0 0 0" FontStyle="Italic">Job Aborted By User</TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" DockPanel.Dock="Right" Margin="0 0 10 0"> <Button Padding="0" Height="20" Command="{Binding CloseJobCompletionStatusCommand}" Style="{StaticResource MaterialDesignFlatButton}"> <StackPanel Orientation="Horizontal"> - <materialDesign:PackIcon Foreground="{StaticResource DarkGrayBrush}" VerticalAlignment="Center" Width="20" Height="20" Kind="Close" /> + <materialDesign:PackIcon Foreground="#FF494949" VerticalAlignment="Center" Width="20" Height="20" Kind="Close" /> </StackPanel> </Button> </StackPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Tango.MachineStudio.HardwareDesigner_ijdp5tm3_wpftmp.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Tango.MachineStudio.HardwareDesigner_ijdp5tm3_wpftmp.csproj new file mode 100644 index 000000000..0ef643858 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Tango.MachineStudio.HardwareDesigner_ijdp5tm3_wpftmp.csproj @@ -0,0 +1,184 @@ +<?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>{69DB0564-268C-4B3C-B5D6-A3CDC7D14EAE}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>Tango.MachineStudio.HardwareDesigner</RootNamespace> + <AssemblyName>Tango.MachineStudio.HardwareDesigner</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\..\..\Build\Machine Studio\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\Machine Studio\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="Comparison\HardwareCompareResult.cs" /> + <Compile Include="Comparison\HardwareComponentCollectionCompareResult.cs" /> + <Compile Include="Comparison\HardwareComponentCompareResult.cs" /> + <Compile Include="Comparison\HardwareComponentPropertyResult.cs" /> + <Compile Include="Comparison\IHasDifference.cs" /> + <Compile Include="Report\ReportModel.cs" /> + <Compile Include="ViewModelLocator.cs" /> + <Compile Include="ViewModels\ComparisonWizardViewVM.cs" /> + <Compile Include="Views\ComparisonWizardView.xaml.cs"> + <DependentUpon>ComparisonWizardView.xaml</DependentUpon> + </Compile> + <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="Views\MainView.xaml.cs"> + <DependentUpon>MainView.xaml</DependentUpon> + </Compile> + <Compile Include="HardwareDesignerModule.cs" /> + </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.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.DragAndDrop\Tango.DragAndDrop.csproj"> + <Project>{b112d89a-a106-41ae-a0c1-4abc84c477f5}</Project> + <Name>Tango.DragAndDrop</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</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.MachineStudio.Common\Tango.MachineStudio.Common.csproj"> + <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> + <Name>Tango.MachineStudio.Common</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup /> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <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" /> + </VisualStudio> + </ProjectExtensions> + <ItemGroup> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Microsoft.CSharp.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.DataAnnotations.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xaml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.BL.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Core.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.CSV.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.DragAndDrop.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Integration.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Logging.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Machine Studio\Debug\Tango.MachineStudio.Common.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Settings.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.SharedUI.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll" /> + </ItemGroup> + <ItemGroup> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.HardwareDesigner\obj\Debug\App.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.HardwareDesigner\obj\Debug\Views\ComparisonWizardView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.HardwareDesigner\obj\Debug\Views\MainView.g.cs" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/ComparisonWizardViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/ComparisonWizardViewVM.cs index 47a40ade4..a58d69a93 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/ComparisonWizardViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/ComparisonWizardViewVM.cs @@ -281,6 +281,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -303,6 +304,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -325,6 +327,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -347,6 +350,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -369,6 +373,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -391,6 +396,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -413,6 +419,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels collection.Components.Add(componentResult); } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.ComponentName).ToSynchronizedObservableCollection(); return collection; } @@ -432,7 +439,6 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels result.Properties.Add(hProp); } - return result; } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs index 918eb02d4..0a8780346 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs @@ -14,6 +14,11 @@ using System.Runtime.CompilerServices; using Tango.MachineStudio.Common; using Tango.Core.ExtensionMethods; using Tango.MachineStudio.HardwareDesigner.Views; +using Microsoft.Win32; +using System.IO; +using Tango.BL.ActionLogs; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.DTO; namespace Tango.MachineStudio.HardwareDesigner.ViewModels { @@ -22,6 +27,9 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels private INotificationProvider _notification; private bool _isNew; private ObservablesContext _db; + private IActionLogManager _actionLogManager; + private IAuthenticationProvider _authentication; + private HardwareVersionDTO _hwBeforeSave; private HardwareVersion _selectedVersion; public HardwareVersion SelectedVersion @@ -43,6 +51,8 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels get { return _selectedHardwareObject; } set { + _selectedHardwareObject = null; + RaisePropertyChangedAuto(); _selectedHardwareObject = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(SelectedHardwareObjectTypeName)); @@ -87,7 +97,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels return name; } } - + private ObservableCollection<HardwareVersion> _hardwareVersions; public ObservableCollection<HardwareVersion> HardwareVersions { @@ -107,9 +117,15 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels public RelayCommand OpenComparisonWizardCommand { get; set; } - public MainViewVM(INotificationProvider notification) + public RelayCommand ExportHardwareVersionCommand { get; set; } + + public RelayCommand ImportHardwareVersionCommand { get; set; } + + public MainViewVM(INotificationProvider notification, IActionLogManager actionLogManager, IAuthenticationProvider authentication) { _notification = notification; + _actionLogManager = actionLogManager; + _authentication = authentication; CurrentVersion = new HardwareVersion(); @@ -122,7 +138,88 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels CopyParametersCommand = new RelayCommand(CopyParameters, (x) => SelectedVersion != null && IsFree); CloneCommand = new RelayCommand(CloneCurrentVersion, () => SelectedVersion != null && IsFree); - OpenComparisonWizardCommand = new RelayCommand(OpenComparisonWizard); + OpenComparisonWizardCommand = new RelayCommand(OpenComparisonWizard, () => IsFree); + ExportHardwareVersionCommand = new RelayCommand(ExportHardwareVersion, () => IsFree && SelectedVersion != null && CurrentVersion != null); + ImportHardwareVersionCommand = new RelayCommand(ImportHardwareVersion, () => IsFree); + } + + private async void ExportHardwareVersion() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Export hardware version"; + dlg.DefaultExt = ".hv"; + dlg.Filter = "Hardware Version Files|*.hv"; + + if (dlg.ShowDialog().Value) + { + try + { + var json = await CurrentVersion.ToHardwareVersionFile(); + File.WriteAllText(dlg.FileName, json); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting hardware version."); + _notification.ShowError($"An error occurred while trying to export the selected hardware version.\n{ex.FlattenMessage()}"); + } + } + } + + private async void ImportHardwareVersion() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Title = "Import hardware version"; + dlg.DefaultExt = ".hv"; + dlg.Filter = "Hardware Version Files|*.hv"; + + if (dlg.ShowDialog().Value) + { + try + { + var hv = await HardwareVersion.FromHardwareVersionFile(File.ReadAllText(dlg.FileName)); + + String name = _notification.ShowTextInput("Enter hardware version name", "Name", hv.Name); + if (!String.IsNullOrWhiteSpace(name)) + { + using (_notification.PushTaskItem("Importing hardware version...")) + { + try + { + IsFree = false; + + hv.Name = name; + hv.Version = HardwareVersions.Max(x => x.Version) + 1; + + _db.HardwareVersions.Add(hv); + await _db.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionImported, _authentication.CurrentUser, CurrentVersion.Name, CurrentVersion, "New hardware version imported using Machine Studio."); + + RefreshVersions(); + + InvokeUI(() => + { + SelectedVersion = HardwareVersions.SingleOrDefault(x => x.Guid == hv.Guid); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error importing hardware version."); + _notification.ShowError($"An error occurred while trying to import the selected hardware version.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error importing hardware version."); + _notification.ShowError($"An error occurred while trying to load the selected hardware version file.\n{ex.FlattenMessage()}"); + } + } } public override void OnApplicationReady() @@ -136,7 +233,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels private void CopyParameters(object obj) { - obj.MapPrimitivesTo(SelectedHardwareObject, + obj.MapPropertiesTo(SelectedHardwareObject, MappingFlags.PrimitivesOnly, (prop) => !prop.PropertyType.IsEnum && @@ -151,13 +248,13 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels _db = ObservablesContext.CreateDefault(); - CurrentVersion.HardwareMotors = _db.HardwareMotorTypes.ToList().Select(x => new HardwareMotor() { HardwareMotorType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwareDancers = _db.HardwareDancerTypes.ToList().Select(x => new HardwareDancer() { HardwareDancerType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwarePidControls = _db.HardwarePidControlTypes.ToList().Select(x => new HardwarePidControl() { HardwarePidControlType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwareWinders = _db.HardwareWinderTypes.ToList().Select(x => new HardwareWinder() { HardwareWinderType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwareSpeedSensors = _db.HardwareSpeedSensorTypes.ToList().Select(x => new HardwareSpeedSensor() { HardwareSpeedSensorType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwareBlowers = _db.HardwareBlowerTypes.ToList().Select(x => new HardwareBlower() { HardwareBlowerType = x }).ToSynchronizedObservableCollection(); - CurrentVersion.HardwareBreakSensors = _db.HardwareBreakSensorTypes.ToList().Select(x => new HardwareBreakSensor() { HardwareBreakSensorType = x }).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareMotors = _db.HardwareMotorTypes.ToList().Select(x => new HardwareMotor() { HardwareMotorType = x }).OrderByAlphaNumeric(x => x.HardwareMotorType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareDancers = _db.HardwareDancerTypes.ToList().Select(x => new HardwareDancer() { HardwareDancerType = x }).OrderByAlphaNumeric(x => x.HardwareDancerType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwarePidControls = _db.HardwarePidControlTypes.ToList().Select(x => new HardwarePidControl() { HardwarePidControlType = x }).OrderByAlphaNumeric(x => x.HardwarePidControlType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareWinders = _db.HardwareWinderTypes.ToList().Select(x => new HardwareWinder() { HardwareWinderType = x }).OrderByAlphaNumeric(x => x.HardwareWinderType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareSpeedSensors = _db.HardwareSpeedSensorTypes.ToList().Select(x => new HardwareSpeedSensor() { HardwareSpeedSensorType = x }).OrderByAlphaNumeric(x => x.HardwareSpeedSensorType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareBlowers = _db.HardwareBlowerTypes.ToList().Select(x => new HardwareBlower() { HardwareBlowerType = x }).OrderByAlphaNumeric(x => x.HardwareBlowerType.Description).ToSynchronizedObservableCollection(); + CurrentVersion.HardwareBreakSensors = _db.HardwareBreakSensorTypes.ToList().Select(x => new HardwareBreakSensor() { HardwareBreakSensorType = x }).OrderByAlphaNumeric(x => x.HardwareBreakSensorType.Description).ToSynchronizedObservableCollection(); } private void RefreshVersions() @@ -252,6 +349,8 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels }); CurrentVersion.HardwareBreakSensors = CurrentVersion.HardwareBreakSensors.OrderBy(x => x.HardwareBreakSensorType.Code).ToSynchronizedObservableCollection(); + + _hwBeforeSave = HardwareVersionDTO.FromObservable(CurrentVersion); }); } @@ -306,6 +405,8 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels _db.HardwareVersions.Add(CurrentVersion); _db.SaveChanges(); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, CurrentVersion.Name, CurrentVersion, "New hardware version created using Machine Studio."); + RefreshVersions(); InvokeUI(() => @@ -333,7 +434,13 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels await Task.Factory.StartNew(() => { + CurrentVersion.LastUpdated = DateTime.UtcNow; _db.SaveChanges(); + + var dtoAfter = HardwareVersionDTO.FromObservable(CurrentVersion); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionSaved, _authentication.CurrentUser, _hwBeforeSave.Name, _hwBeforeSave, dtoAfter, "Hardware Version saved using Machine Studio."); + _hwBeforeSave = dtoAfter; + RefreshVersions(); InvokeUI(() => @@ -375,6 +482,9 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels cloned.Version = HardwareVersions.Max(x => x.Version) + 1; _db.HardwareVersions.Add(cloned); _db.SaveChanges(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, cloned.Name, cloned, "New hardware version cloned using Machine Studio."); + RefreshVersions(); InvokeUI(() => @@ -410,6 +520,8 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels await CurrentVersion.DeleteCascadeAsync(_db); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionDeleted, _authentication.CurrentUser, CurrentVersion.Name, _hwBeforeSave, "Hardware version deleted using Machine Studio.", true); + await Task.Factory.StartNew(() => { SelectedVersion = null; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml index 86cc089e5..1c00397aa 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml @@ -66,12 +66,26 @@ </ComboBox> </StackPanel> - <Button Margin="100,10,0,0" Cursor="Hand" Height="40" FontSize="12" ToolTip="Open Comparison Wizard" Command="{Binding OpenComparisonWizardCommand}"> + <Button Margin="100 10 0 0" Cursor="Hand" Height="40" FontSize="12" ToolTip="Open Comparison Wizard" Command="{Binding OpenComparisonWizardCommand}"> <StackPanel Orientation="Horizontal"> <materialDesign:PackIcon Width="24" Height="24" Kind="Compare"/> <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" FontSize="16">Comparison Wizard</TextBlock> </StackPanel> </Button> + + <Button Margin="10 10 0 0" Cursor="Hand" MinWidth="150" Height="40" FontSize="12" ToolTip="Import hardware version to file" Command="{Binding ImportHardwareVersionCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Width="24" Height="24" Kind="FileImport"/> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" FontSize="16">IMPORT</TextBlock> + </StackPanel> + </Button> + + <Button Margin="10 10 0 0" Cursor="Hand" MinWidth="150" Height="40" FontSize="12" ToolTip="Export hardware version to file" Command="{Binding ExportHardwareVersionCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Width="24" Height="24" Kind="FileExport"/> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" FontSize="16">EXPORT</TextBlock> + </StackPanel> + </Button> </StackPanel> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventsViewVM.cs index c813e9752..2c3886ea4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventsViewVM.cs @@ -135,31 +135,39 @@ namespace Tango.MachineStudio.Logging.ViewModels { using (_notification.PushTaskItem("Loading machine events...")) { - await Task.Factory.StartNew(() => + try { - _db = ObservablesContext.CreateDefault(); + await Task.Factory.StartNew(() => + { + _db = ObservablesContext.CreateDefault(); - _db.EventTypes.Load(); + _db.EventTypes.Load(); - DateTime now = DateTime.UtcNow.AddMonths(-1); + DateTime now = DateTime.UtcNow.AddMonths(-1); - _history_events = _db.MachinesEvents.Where(x => x.MachineGuid == SelectedMachine.Guid && x.DateTime > now).Include(x => x.User).Include(x => x.User.Contact).Include(x => x.Machine).ToList(); + _history_events = _db.MachinesEvents.Where(x => x.MachineGuid == SelectedMachine.Guid && x.DateTime > now).Include(x => x.User).Include(x => x.User.Contact).Include(x => x.Machine).ToList(); - Dates = new ObservableCollection<DateTime>(); + Dates = new ObservableCollection<DateTime>(); - foreach (var day in _history_events.GroupBy(x => x.DateTime.DayOfYear).Select(x => x.First().DateTime).OrderByDescending(x => x)) - { - Dates.Add(day); - } + foreach (var day in _history_events.GroupBy(x => x.DateTime.DayOfYear).Select(x => x.First().DateTime).OrderByDescending(x => x)) + { + Dates.Add(day); + } - if (Dates.Count > 0) - { - MinDate = Dates.Min(); - MaxDate = Dates.Max(); - } + if (Dates.Count > 0) + { + MinDate = Dates.Min(); + MaxDate = Dates.Max(); + } - SelectedDate = Dates.FirstOrDefault(); - }); + SelectedDate = Dates.FirstOrDefault(); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading machine events."); + _notification.ShowError($"An error occurred while trying to load the selected machine events.\n{ex.FlattenMessage()}"); + } } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj index d80060831..69cc75461 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj @@ -89,14 +89,20 @@ <Compile Include="ViewModels\ColorCalibrationViewVM.cs" /> <Compile Include="ViewModels\HardwareConfigurationViewVM.cs" /> <Compile Include="ViewModels\MachineCreationDialogVM.cs" /> + <Compile Include="ViewModels\MachineUpdateDetailsDialogVM.cs" /> + <Compile Include="ViewModels\MachineUpdatesViewVM.cs" /> <Compile Include="ViewModels\MachineVersionDialogVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="ViewModels\TupViewVM.cs" /> <Compile Include="Views\ColorCalibrationView.xaml.cs"> <DependentUpon>ColorCalibrationView.xaml</DependentUpon> </Compile> <Compile Include="Views\HardwareConfigurationView.xaml.cs"> <DependentUpon>HardwareConfigurationView.xaml</DependentUpon> </Compile> + <Compile Include="Views\MachineUpdateDetailsDialog.xaml.cs"> + <DependentUpon>MachineUpdateDetailsDialog.xaml</DependentUpon> + </Compile> <Compile Include="Views\MachineCreationDialog.xaml.cs"> <DependentUpon>MachineCreationDialog.xaml</DependentUpon> </Compile> @@ -122,6 +128,12 @@ <Compile Include="Views\MainView.xaml.cs"> <DependentUpon>MainView.xaml</DependentUpon> </Compile> + <Compile Include="Views\MachineUpdatesView.xaml.cs"> + <DependentUpon>MachineUpdatesView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\TupView.xaml.cs"> + <DependentUpon>TupView.xaml</DependentUpon> + </Compile> <Compile Include="Views\SpoolsView.xaml.cs"> <DependentUpon>SpoolsView.xaml</DependentUpon> </Compile> @@ -137,6 +149,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\MachineUpdateDetailsDialog.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Views\MachineCreationDialog.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -169,6 +185,14 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\MachineUpdatesView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="Views\TupView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Views\SpoolsView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -308,7 +332,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <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/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs index f7ae88f68..e29ba3b6f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs @@ -92,16 +92,19 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { HardwareVersion hardwareVersion = configuration.HardwareVersion; - _hwConfig = configuration.GetHardwareConfiguration(); + if (hardwareVersion != null) + { + _hwConfig = configuration.GetHardwareConfiguration(); - Collections.Clear(); - Collections.Add(CreateMotorsCollection(hardwareVersion)); - Collections.Add(CreateDancerCollection(hardwareVersion)); - Collections.Add(CreatePidCollection(hardwareVersion)); - Collections.Add(CreateWindersCollection(hardwareVersion)); - Collections.Add(CreateSpeedSensorsCollection(hardwareVersion)); - Collections.Add(CreateBlowersCollection(hardwareVersion)); - Collections.Add(CreateBreakSensorCollection(hardwareVersion)); + Collections.Clear(); + Collections.Add(CreateMotorsCollection(hardwareVersion)); + Collections.Add(CreateDancerCollection(hardwareVersion)); + Collections.Add(CreatePidCollection(hardwareVersion)); + Collections.Add(CreateWindersCollection(hardwareVersion)); + Collections.Add(CreateSpeedSensorsCollection(hardwareVersion)); + Collections.Add(CreateBlowersCollection(hardwareVersion)); + Collections.Add(CreateBreakSensorCollection(hardwareVersion)); + } } private HardwareCollection CreateMotorsCollection(HardwareVersion hardwareVersion) @@ -124,6 +127,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreateDancerCollection(HardwareVersion hardwareVersion) @@ -146,6 +150,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreatePidCollection(HardwareVersion hardwareVersion) @@ -168,6 +173,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreateWindersCollection(HardwareVersion hardwareVersion) @@ -190,6 +196,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreateSpeedSensorsCollection(HardwareVersion hardwareVersion) @@ -212,6 +219,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreateBlowersCollection(HardwareVersion hardwareVersion) @@ -234,6 +242,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components= collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareCollection CreateBreakSensorCollection(HardwareVersion hardwareVersion) @@ -256,6 +265,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels collection.Components.Add(componentResult); } } + collection.Components = collection.Components.OrderByAlphaNumeric(x => x.Description).ToSynchronizedObservableCollection(); return collection; } private HardwareComponent CreateComponent(String name, String description, List<PropertyInfo> properties, Object component) @@ -265,7 +275,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels Description = description, ComponentName = name }; - + foreach (var prop in properties) { var hProp = new HardwareParameter(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineCreationDialogVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineCreationDialogVM.cs index 0f6ab3314..4584d3508 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineCreationDialogVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineCreationDialogVM.cs @@ -13,5 +13,50 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels public List<MachineVersion> MachineVersions { get; set; } public MachineVersion SelectedMachineVersion { get; set; } + + private bool _isNewMachine; + public bool IsNewMachine + { + get { return _isNewMachine; } + set { _isNewMachine = value; RaisePropertyChangedAuto(); } + } + + private String _serialNumber; + public String SerialNumber + { + get { return _serialNumber; } + set { _serialNumber = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _name; + public String Name + { + get { return _name; } + set { _name = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _generateDispensers; + public bool GenerateDispensers + { + get { return _generateDispensers; } + set { _generateDispensers = value; RaisePropertyChangedAuto(); } + } + + private double _dispenserFactor; + public double DispenserFactor + { + get { return _dispenserFactor; } + set { _dispenserFactor = value; RaisePropertyChangedAuto(); } + } + + public MachineCreationDialogVM() : base() + { + DispenserFactor = 2.34; + } + + protected override bool CanOK() + { + return base.CanOK() && !String.IsNullOrWhiteSpace(SerialNumber) && !String.IsNullOrWhiteSpace(Name); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs new file mode 100644 index 000000000..49d410cdf --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class MachineUpdateDetailsDialogVM : DialogViewVM + { + private TangoUpdate _update; + public TangoUpdate Update + { + get { return _update; } + set { _update = value; RaisePropertyChangedAuto(); } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs new file mode 100644 index 000000000..616ad0a47 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.MachineDesigner.Views; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class MachineUpdatesViewVM : ViewModel + { + private INotificationProvider _notification; + private ObservablesContext _context; + private const int MAX_UPDATE_ITEMS = 100; + + #region Properties + + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + private List<TangoUpdate> _updates; + public List<TangoUpdate> Updates + { + get { return _updates; } + set { _updates = value; RaisePropertyChangedAuto(); } + } + + private ICollectionView _updatesView; + public ICollectionView UpdatesView + { + get { return _updatesView; } + set { _updatesView = value; RaisePropertyChangedAuto(); } + } + + + private TangoUpdate _selectedUpdate; + public TangoUpdate SelectedUpdate + { + get { return _selectedUpdate; } + set { _selectedUpdate = value; RaisePropertyChangedAuto(); OnSelectedUpdateChanged(); } + } + + private bool _displayMachineSetups; + public bool DisplayMachineSetups + { + get { return _displayMachineSetups; } + set { _displayMachineSetups = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayApplicationUpdates; + public bool DisplayApplicationUpdates + { + get { return _displayApplicationUpdates; } + set { _displayApplicationUpdates = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayDatabaseUpdates; + public bool DisplayDatabaseUpdates + { + get { return _displayDatabaseUpdates; } + set { _displayDatabaseUpdates = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displaySynchronizations; + public bool DisplaySynchronizations + { + get { return _displaySynchronizations; } + set { _displaySynchronizations = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayOfflineUpdates; + public bool DisplayOfflineUpdates + { + get { return _displayOfflineUpdates; } + set { _displayOfflineUpdates = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayFirmwareUpgrades; + public bool DisplayFirmwareUpgrades + { + get { return _displayFirmwareUpgrades; } + set { _displayFirmwareUpgrades = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + #endregion + + #region Commands + + public RelayCommand RefreshCommand { get; set; } + + #endregion + + #region Constructors + + public MachineUpdatesViewVM() + { + DisplayApplicationUpdates = true; + DisplayMachineSetups = true; + DisplayDatabaseUpdates = true; + DisplaySynchronizations = true; + DisplayOfflineUpdates = true; + DisplayFirmwareUpgrades = true; + + RefreshCommand = new RelayCommand(Refresh, () => IsFree); + } + + public MachineUpdatesViewVM(INotificationProvider notificationProvider) : this() + { + _notification = notificationProvider; + } + + #endregion + + #region Public Methods + + public async Task Init(Machine machine, ObservablesContext context) + { + try + { + _context = context; + Machine = machine; + Updates = (await new TangoUpdatesCollectionBuilder(context).Set(x => x.MachineGuid == machine.Guid).Query(x => x.OrderByDescending(y => y.StartDate).Take(MAX_UPDATE_ITEMS)).BuildAsync()).ToList(); + UpdatesView = CollectionViewSource.GetDefaultView(Updates); + UpdatesView.Filter = UpdatesFilter; + OnFilterChanged(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading machine updates."); + _notification.ShowError($"An error occurred while loading the history of machine updates.\n{ex.FlattenMessage()}"); + } + } + + #endregion + + #region Private Methods + + private async void Refresh() + { + IsFree = false; + using (_notification.PushTaskItem("Refreshing machine updates...")) + { + await Init(Machine, _context); + } + IsFree = true; + } + + private void OnFilterChanged() + { + if (UpdatesView != null) + { + UpdatesView.Refresh(); + } + } + + private bool UpdatesFilter(object obj) + { + TangoUpdate update = obj as TangoUpdate; + if (update != null) + { + if (!DisplayMachineSetups && update.IsSetup) return false; + if (!DisplayApplicationUpdates && update.IsUpdate) return false; + if (!DisplayDatabaseUpdates && update.IsDataBase) return false; + if (!DisplaySynchronizations && update.IsSynchronization) return false; + if (!DisplayOfflineUpdates && update.IsOfflineUpdate) return false; + if (!DisplayFirmwareUpgrades && update.IsOfflineFirmwareUpgrade) return false; + return true; + } + else + { + return false; + } + } + + private void OnSelectedUpdateChanged() + { + if (SelectedUpdate != null && SelectedUpdate.ApplicationVersion != "Fake") + { + _notification.ShowModalDialog<MachineUpdateDetailsDialogVM, MachineUpdateDetailsDialog>(new MachineUpdateDetailsDialogVM() { Update = SelectedUpdate }, (vm) => { }, () => { }); + SelectedUpdate = new TangoUpdate() { ApplicationVersion = "Fake"}; + } + } + + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 5f2dcd00d..e0d99d0f0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -25,17 +25,30 @@ using Tango.Core.Threading; using Tango.MachineStudio.RML.ViewModels; using Tango.Settings; using Tango.MachineStudio.RML.Models; +using Tango.BL.ActionLogs; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.DTO; namespace Tango.MachineStudio.MachineDesigner.ViewModels { public class MainViewVM : StudioViewModel<IMainView> { private INotificationProvider _notification; + private IActionLogManager _actionLogManager; + private IAuthenticationProvider _authentication; private ActionTimer _machines_action_timer; private ActionTimer _dispensers_action_timer; + private MachineDTO _machineBeforeSave; #region Properties + private bool _isNewMachine; + public bool IsNewMachine + { + get { return _isNewMachine; } + set { _isNewMachine = value; RaisePropertyChangedAuto(); } + } + private ObservablesStaticCollections _machinesAdapter; public ObservablesStaticCollections MachinesAdapter { @@ -115,6 +128,21 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } + private Site _selectedSite; + public Site SelectedSite + { + get { return _selectedSite; } + set { _selectedSite = value; RaisePropertyChangedAuto(); } + } + + private List<Site> _sites; + public List<Site> Sites + { + get { return _sites; } + set { _sites = value; RaisePropertyChangedAuto(); } + } + + private ColorCalibrationViewVM _colorCalibrationViewVM; public ColorCalibrationViewVM ColorCalibrationViewVM { @@ -123,7 +151,6 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } private HardwareConfigurationViewVM _hardwareConfigurationViewVM; - public HardwareConfigurationViewVM HardwareConfigurationViewVM { get { return _hardwareConfigurationViewVM; } @@ -134,6 +161,19 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + private MachineUpdatesViewVM _machineUpdatesViewVM; + public MachineUpdatesViewVM MachineUpdatesViewVM + { + get { return _machineUpdatesViewVM; } + set { _machineUpdatesViewVM = value; RaisePropertyChangedAuto(); } + } + + private TupViewVM _tupViewVM; + public TupViewVM TupViewVM + { + get { return _tupViewVM; } + set { _tupViewVM = value; RaisePropertyChangedAuto(); } + } #endregion @@ -188,6 +228,17 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels /// Gets or sets the clone machine command. /// </summary> public RelayCommand CloneMachineCommand { get; set; } + + /// <summary> + /// Gets or sets the reset device registration command. + /// </summary> + public RelayCommand ResetDeviceRegistrationCommand { get; set; } + + /// <summary> + /// Gets or sets the make prototype command. + /// </summary> + public RelayCommand MakePrototypeCommand { get; set; } + #endregion #region Constructors @@ -200,10 +251,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels /// <summary> /// Initializes a new instance of the <see cref="MainViewVM"/> class. /// </summary> - public MainViewVM(INotificationProvider notification) + public MainViewVM(INotificationProvider notification, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { MachinesAdapter = new ObservablesStaticCollections(ObservablesContext.CreateDefault()); _notification = notification; + _authentication = authentication; + _actionLogManager = actionLogManager; _machines_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); _dispensers_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); @@ -218,7 +271,13 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels AddSpoolCommand = new RelayCommand(AddNewSpool); RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); CloneMachineCommand = new RelayCommand(CloneMachine, () => SelectedMachine != null); + ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); + MakePrototypeCommand = new RelayCommand(MakePrototype); + + MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification); + TupViewVM = new TupViewVM(_notification); } + #endregion #region Application Ready @@ -239,7 +298,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { Task.Factory.StartNew(() => { - ActiveMachineAdapter.Dispensers = ActiveMachineAdapter.Context.Dispensers.Where(x => x.SerialNumber.ToLower().StartsWith(DispensersFilter.ToLower())).ToSynchronizedObservableCollection(); + ActiveMachineAdapter.Dispensers = ActiveMachineAdapter.Context.Dispensers.Where(x => x.SerialNumber.ToLower().StartsWith(DispensersFilter.ToLower())).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); }); }); } @@ -388,8 +447,10 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels InvalidateRelayCommands(); } - private async void LoadSelectedMachine(bool newMachine = false, bool clone = false, MachineVersion selectedVersion = null) + private async void LoadSelectedMachine(bool newMachine = false, bool clone = false, MachineCreationDialogVM machineCreationDialogVM = null) { + IsNewMachine = false; + using (_notification.PushTaskItem("Loading machine details...")) { try @@ -421,33 +482,140 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachineAdapter.MachineVersions = (await ActiveMachineAdapter.Context.MachineVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.Organizations = (await ActiveMachineAdapter.Context.Organizations.ToListAsync()).ToObservableCollection(); + bool initHwConfig = true; + + Configuration machineConfigBeforeClone = null; + if (!newMachine) { ActiveMachine = (await new MachineBuilder(ActiveMachineAdapter.Context).Set(SelectedMachine.Guid).WithOrganization().WithConfiguration().WithSpools().BuildAsync()); + _machineBeforeSave = MachineDTO.FromObservable(ActiveMachine); + if (clone) { + machineConfigBeforeClone = ActiveMachine.Configuration; + + IsNewMachine = true; ActiveMachine = ActiveMachine.Clone(); - ActiveMachine.Name = ""; - ActiveMachine.SerialNumber = ""; + ActiveMachine.Name = machineCreationDialogVM.Name; + ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; + ActiveMachine.IsDeviceRegistered = false; + ActiveMachine.DeviceId = null; + ActiveMachine.DeviceName = null; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); } } else { - if (selectedVersion == null) + IsNewMachine = true; + + if (machineCreationDialogVM.SelectedMachineVersion == null) { ActiveMachine = new Machine(); ActiveMachine.Configuration = new Configuration(); + ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; + ActiveMachine.Name = machineCreationDialogVM.Name; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); } else { - ActiveMachine = selectedVersion.CreatePrototypeMachine(ActiveMachineAdapter.Context); - ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); + try + { + initHwConfig = false; + ActiveMachine = machineCreationDialogVM.SelectedMachineVersion.CreatePrototypeMachine(ActiveMachineAdapter.Context); + ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; + ActiveMachine.Name = machineCreationDialogVM.Name; + ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); + + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + var version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(ActiveMachine.Configuration.HardwareVersionGuid).WithHardwareComponents().BuildAsync(); + HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + } + catch (Exception ex) + { + _notification.ShowError($"Invalid machine version prototype.\n{ex.FlattenMessage()}"); + View.NavigateTo(MachineDesignerNavigationView.MachinesView); + return; + } } } + if ((newMachine || clone) && machineCreationDialogVM.GenerateDispensers) + { + for (int i = 0; i < 8; i++) + { + var serial = machineCreationDialogVM.SerialNumber + "-" + (i + 1); + + var existingDispenser = await ActiveMachineAdapter.Context.Dispensers.Include(x => x.IdsPacks).SingleAsync(x => x.SerialNumber == serial); + + if (existingDispenser != null) + { + if (existingDispenser.IsInstalled) + { + _notification.ShowError($"Dispenser '{serial}' already exists. Cannot create machine."); + return; + } + else + { + if (!_notification.ShowErrorQuestion($"Dispenser '{serial}' already exists and is not installed. Do you wish to assign the existing dispenser to this machine?")) + { + return; + } + } + } + + Dispenser dispenser = new Dispenser(); + + if (existingDispenser == null) + { + dispenser.SerialNumber = serial; + + if (newMachine) + { + dispenser.NlPerPulse = machineCreationDialogVM.DispenserFactor; + dispenser.DispenserTypeGuid = ActiveMachineAdapter.DispenserTypes.First().Guid; + } + else + { + var packBefore = machineConfigBeforeClone.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); + + if (packBefore != null) + { + dispenser.NlPerPulse = packBefore.Dispenser.NlPerPulse; + dispenser.DispenserTypeGuid = packBefore.Dispenser.DispenserType.Guid; + } + else + { + continue; + } + } + + dispenser.ProductionDate = DateTime.UtcNow; + + ActiveMachineAdapter.Context.Dispensers.Add(dispenser); + } + else + { + dispenser = existingDispenser; + } + + var idsPack = ActiveMachine.Configuration.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); + + if (idsPack != null) + { + idsPack.Dispenser = dispenser; + idsPack.DispenserGuid = dispenser.Guid; + } + } + } + + var sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); + sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + + Sites = sites; + SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); + ColorCalibrationViewVM = new ColorCalibrationViewVM(_notification, ActiveMachine, _activeMachineAdapter.Context) { Rmls = ActiveMachineAdapter.Rmls, @@ -455,8 +623,17 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels SelectedRML = ActiveMachineAdapter.Rmls.FirstOrDefault(), }; - HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); - HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + if (initHwConfig) + { + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + } + + if (!IsNewMachine) + { + await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); + TupViewVM.Init(ActiveMachine); + } ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; @@ -485,6 +662,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { try { + if (HardwareConfigurationViewVM == null) + { + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + } + version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(version.Guid).WithHardwareComponents().BuildAsync(); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } @@ -620,15 +802,25 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachine.ConfigurationGuid = ActiveMachine.Configuration.Guid; ActiveMachine.LastUpdated = DateTime.UtcNow; - ActiveMachine.ProductionDate = DateTime.UtcNow; + ActiveMachine.SiteGuid = SelectedSite == null ? null : (SelectedSite.ID == -1 ? null : SelectedSite.Guid); ColorCalibrationViewVM.Save(); var hwConfig = HardwareConfigurationViewVM.GetResultingHardwareConfiguration(); ActiveMachine.Configuration.SetHardwareConfiguration(hwConfig); - await ActiveMachineAdapter.Context.SaveChangesAsync(); + if (IsNewMachine) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineCreated, _authentication.CurrentUser, ActiveMachine.Name, ActiveMachine, "New machine created using Machine Studio."); + } + else + { + var machineAfterDTO = MachineDTO.FromObservable(ActiveMachine); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineSaved, _authentication.CurrentUser, _machineBeforeSave.Name, _machineBeforeSave, machineAfterDTO, "Machine saved using Machine Studio."); + _machineBeforeSave = machineAfterDTO; + } + if (SelectedMachine != null) { await SelectedMachine.Reload(MachinesAdapter.Context); @@ -652,16 +844,23 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels private void AddNewMachine() { MachineCreationDialogVM vm = new MachineCreationDialogVM(); + vm.IsNewMachine = true; vm.MachineVersions = MachinesAdapter.MachineVersions.ToList(); _notification.ShowModalDialog<MachineCreationDialogVM, Views.MachineCreationDialog>(vm, (x) => { + if (MachinesAdapter.Context.Machines.Any(y => y.SerialNumber == vm.SerialNumber || y.Name.ToLower() == vm.Name.ToLower())) + { + _notification.ShowError("Machine serial number or name already exists."); + return; + } + if (vm.SelectedMachineVersion != null && String.IsNullOrWhiteSpace(vm.SelectedMachineVersion.PrototypeMachineData)) { _notification.ShowError("The selected version does not contain any prototype machine data."); return; } - LoadSelectedMachine(true, false, vm.SelectedMachineVersion); + LoadSelectedMachine(true, false, vm); }, () => { }); } @@ -675,7 +874,9 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { IsFree = false; await SelectedMachine.DeleteCascadeAsync(MachinesAdapter.Context); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineDeleted, _authentication.CurrentUser, SelectedMachine.Name, SelectedMachine, "Machine deleted using Machine Studio."); MachinesAdapter.Context.Machines.Remove(SelectedMachine); + MachinesAdapter.Machines.Remove(SelectedMachine); } catch (Exception ex) { @@ -690,11 +891,68 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + private void ResetDeviceRegistration() + { + if (_notification.ShowQuestion("Are you sure you wish to reset this machine device registration?")) + { + ActiveMachine.IsDeviceRegistered = false; + ActiveMachine.DeviceId = null; + ActiveMachine.DeviceName = null; + } + } + + private async void MakePrototype() + { + if (ActiveMachine.MachineVersion == null) + { + _notification.ShowError("Machine version must be selected in order to make a prototype."); + return; + } + + if (_notification.ShowQuestion($"Are you sure you wish to make this machine configuration as a prototype for version '{ActiveMachine.MachineVersion.Name}' ?")) + { + using (_notification.PushTaskItem($"Making prototype machine for '{ActiveMachine.MachineVersion.Name}'...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + var machineVersion = await db.MachineVersions.SingleOrDefaultAsync(x => x.Guid == ActiveMachine.MachineVersionGuid); + await machineVersion.ApplyPrototypeMachine(ActiveMachine, db); + await db.SaveChangesAsync(); + } + } + catch (Exception ex) + { + _notification.ShowError($"Error making machine version prototype\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } + } + #endregion private void CloneMachine() { - LoadSelectedMachine(false, true); + MachineCreationDialogVM vm = new MachineCreationDialogVM(); + vm.IsNewMachine = false; + vm.MachineVersions = MachinesAdapter.MachineVersions.ToList(); + _notification.ShowModalDialog<MachineCreationDialogVM, Views.MachineCreationDialog>(vm, (x) => + { + if (MachinesAdapter.Context.Machines.Any(y => y.SerialNumber == vm.SerialNumber || y.Name.ToLower() == vm.Name.ToLower())) + { + _notification.ShowError("Machine serial number or name already exists."); + return; + } + + LoadSelectedMachine(false, true, vm); + }, () => { }); } private void AddNewSpool() @@ -725,7 +983,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels try { IsFree = false; - MachinesAdapter.Machines = MachinesAdapter.Context.Machines.Where(x => x.SerialNumber.StartsWith(Filter)).Include(x => x.Organization).Include(x => x.MachineVersion).ToSynchronizedObservableCollection(); + MachinesAdapter.Machines = MachinesAdapter.Context.Machines.Where(x => x.SerialNumber.StartsWith(Filter)).Include(x => x.Organization).Include(x => x.MachineVersion).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); } catch { diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs new file mode 100644 index 000000000..5d1703dc3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs @@ -0,0 +1,129 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.Tup; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class TupViewVM : ViewModel + { + private INotificationProvider _notification; + + private String _latestVersion; + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + private String _filePath; + public String FilePath + { + get { return _filePath; } + set { _filePath = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private TupFileBuilderProgressEventArgs _progress; + public TupFileBuilderProgressEventArgs Progress + { + get { return _progress; } + set { _progress = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand CreateTupFileCommand { get; set; } + + public RelayCommand SelectFileCommand { get; set; } + + public TupViewVM() + { + + } + + public TupViewVM(INotificationProvider notification) : this() + { + _notification = notification; + CreateTupFileCommand = new RelayCommand(CreateTupFile, () => FilePath != null && IsFree); + SelectFileCommand = new RelayCommand(SelectFile); + } + + public void Init(Machine machine) + { + Machine = machine; + DisplayLatestPPCVersion(); + } + + private async void DisplayLatestPPCVersion() + { + TupFileBuilder builder = new TupFileBuilder(); + + try + { + LatestVersion = await builder.GetLatestPPCVersion(Machine.SerialNumber); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error retrieving latest PPC version."); + await Task.Delay(5000); + DisplayLatestPPCVersion(); + } + } + + private void SelectFile() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Select package location"; + dlg.Filter = "Tango Update Package Files|*.tup"; + dlg.DefaultExt = ".tup"; + dlg.FileName = LatestVersion == null ? $"{Machine.SerialNumber}_Update_{DateTime.Now.Date.ToFileName()}.tup" : $"{Machine.SerialNumber}_Update_{DateTime.Now.Date.ToFileName()}_v{LatestVersion}.tup"; + + if (dlg.ShowDialog().Value) + { + FilePath = dlg.FileName; + } + } + + private async void CreateTupFile() + { + try + { + LogManager.Log($"Generating TUP file to '{FilePath}'..."); + + IsFree = false; + TupFileBuilder builder = new TupFileBuilder(); + builder.Progress += Builder_Progress; + await builder.Build(Machine.SerialNumber, FilePath); + + LogManager.Log("TUP file generated successfully."); + _notification.ShowInfo("Tango update package created successfuly."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating tup file."); + _notification.ShowError($"An error occurred while generating the .tup file.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void Builder_Progress(object sender, TupFileBuilderProgressEventArgs e) + { + Progress = e; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml index e3ba1bff4..417dfbc0b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml @@ -6,9 +6,15 @@ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" mc:Ignorable="d" - d:DesignHeight="400" d:DesignWidth="700" Height="400" Width="700" Background="White" d:DataContext="{d:DesignInstance Type=vm:MachineCreationDialogVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="400" d:DesignWidth="700" Height="460" Width="750" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:MachineCreationDialogVM, IsDesignTimeCreatable=False}"> + + <UserControl.Resources> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></converters:BooleanToVisibilityConverter> + </UserControl.Resources> + <Grid Margin="10"> <DockPanel> <Grid DockPanel.Dock="Top"> @@ -17,7 +23,18 @@ <Image Source="../Images/machine-full-fx.png" Width="120" RenderOptions.BitmapScalingMode="Fant"></Image> <materialDesign:PackIcon HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 -10 -10" Kind="PlusCircle" Foreground="#15C315" Width="42" Height="42" /> </Grid> - <TextBlock Margin="30 0 0 0" VerticalAlignment="Bottom" FontSize="22">NEW MACHINE</TextBlock> + <TextBlock Margin="30 0 0 0" VerticalAlignment="Bottom" FontSize="22"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="CLONE MACHINE"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsNewMachine}" Value="True"> + <Setter Property="Text" Value="NEW MACHINE"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> </StackPanel> </Grid> @@ -33,12 +50,30 @@ </Grid> <Grid> - <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="400"> - <TextBlock TextWrapping="Wrap" TextAlignment="Center"> - <Run>Please specify the machine version in order to prototype the new machine with default machine settings and configuartion.</Run> + <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20 20 0 0" Width="400"> + <TextBlock TextWrapping="Wrap" Visibility="{Binding IsNewMachine,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Run>Please specify the machine version in order to prototype the new machine with default machine settings and configuration.</Run> </TextBlock> - <ComboBox ItemsSource="{Binding MachineVersions}" SelectedItem="{Binding SelectedMachineVersion}" DisplayMemberPath="Name" Margin="0 10 0 0" FontSize="16" materialDesign:HintAssist.Hint="NONE"></ComboBox> + <ComboBox Visibility="{Binding IsNewMachine,Converter={StaticResource BooleanToVisibilityConverter}}" ItemsSource="{Binding MachineVersions}" SelectedItem="{Binding SelectedMachineVersion}" DisplayMemberPath="Name" Margin="0 10 0 0" FontSize="16" materialDesign:HintAssist.Hint="NONE"></ComboBox> + + <TextBlock Margin="0 20 0 0" FontSize="10">Serial Number</TextBlock> + <TextBox Margin="0 2 0 0" Text="{Binding SerialNumber,UpdateSourceTrigger=PropertyChanged}"></TextBox> + + <TextBlock Margin="0 20 0 0" FontSize="10">Name</TextBlock> + <TextBox Margin="0 2 0 0" Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}"></TextBox> + + <CheckBox Margin="0 30 0 0" IsChecked="{Binding GenerateDispensers}"> + <TextBlock> + <Run>Automatically generate 8 dispensers for this machine</Run> + <Run>(</Run><Run Foreground="{StaticResource GrayBrush}" FontSize="10" Text="{Binding SerialNumber}"></Run><Run Foreground="{StaticResource GrayBrush}" FontSize="10">-1-8</Run><Run>)</Run> + </TextBlock> + </CheckBox> + + <StackPanel Margin="20 10 0 0" Visibility="{Binding IsNewMachine,Converter={StaticResource BooleanToVisibilityConverter}}"> + <TextBlock FontSize="10">Dispenser max nl/cm</TextBlock> + <mahapps:NumericUpDown Minimum="0" StringFormat="0.00" Maximum="10" InterceptMouseWheel="True" Value="{Binding DispenserFactor,Mode=TwoWay}" HorizontalContentAlignment="Left" Width="95" HorizontalAlignment="Left" BorderThickness="0 0 0 1" Margin="0 2 0 0" HideUpDownButtons="True" HasDecimals="True"></mahapps:NumericUpDown> + </StackPanel> </StackPanel> </Grid> </DockPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml index 1f748fe9f..b2b770698 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml @@ -5,11 +5,17 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" xmlns:global="clr-namespace:Tango.MachineStudio.MachineDesigner" - xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + <UserControl.Resources> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" /> + </UserControl.Resources> + <Grid Margin="20"> <DockPanel> <Grid DockPanel.Dock="Top"> @@ -23,7 +29,7 @@ </StackPanel> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 0 20 0"> - <Button Width="170" Height="45" VerticalAlignment="Center" Command="{Binding SaveCommand}"> + <Button Width="170" Height="45" VerticalAlignment="Center" Command="{Binding SaveCommand}"> <StackPanel Orientation="Horizontal"> <materialDesign:PackIcon Kind="ContentSaveAll" Width="24" Height="24" /> <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">SAVE</TextBlock> @@ -61,6 +67,12 @@ <TabItem Header="HW CONFIGURATION"> <local:HardwareConfigurationView/> </TabItem> + <TabItem Header="UPDATES" Visibility="{Binding IsNewMachine,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <local:MachineUpdatesView/> + </TabItem> + <TabItem Header="TUP" Visibility="{Binding IsNewMachine,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <local:TupView/> + </TabItem> </TabControl> </Grid> </DockPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml index 62c38a1e6..499d6dc89 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml @@ -27,81 +27,103 @@ <local:MachineView DataContext="{Binding ActiveMachine}" IsHitTestVisible="False" /> - <Border Grid.Column="1" Margin="100 70" CornerRadius="5" Background="{StaticResource TransparentBackgroundBrush600}" Padding="10" BorderBrush="{StaticResource borderBrush}" BorderThickness="1"> - <Grid TextElement.Foreground="{StaticResource GrayBrush280}"> - <Grid.ColumnDefinitions> - <ColumnDefinition/> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition/> - </Grid.ColumnDefinitions> - <controls:TableGrid RowHeight="50" Margin="10"> - <TextBlock FontWeight="SemiBold">Serial Number</TextBlock> - <TextBox Text="{Binding ActiveMachine.SerialNumber}"></TextBox> + <StackPanel Grid.Column="1" Margin="100 30"> + <Border CornerRadius="5" Background="{StaticResource TransparentBackgroundBrush600}" Padding="10" BorderBrush="{StaticResource borderBrush}" BorderThickness="1"> + <Grid TextElement.Foreground="{StaticResource GrayBrush280}"> + <Grid.ColumnDefinitions> + <ColumnDefinition/> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition/> + </Grid.ColumnDefinitions> - <TextBlock FontWeight="SemiBold">Name</TextBlock> - <TextBox Text="{Binding ActiveMachine.Name}"></TextBox> + <StackPanel> + <controls:TableGrid RowHeight="50" Margin="10"> + <TextBlock FontWeight="SemiBold">Serial Number</TextBlock> + <TextBox Text="{Binding ActiveMachine.SerialNumber}"></TextBox> - <TextBlock FontWeight="SemiBold">Machine Version</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.MachineVersions}" SelectedItem="{Binding ActiveMachine.MachineVersion}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <TextBlock FontWeight="SemiBold">Name</TextBlock> + <TextBox Text="{Binding ActiveMachine.Name}"></TextBox> - <TextBlock FontWeight="SemiBold">Organization</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.Organizations}" SelectedItem="{Binding ActiveMachine.Organization}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <TextBlock FontWeight="SemiBold">Machine Version</TextBlock> + <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.MachineVersions}" SelectedItem="{Binding ActiveMachine.MachineVersion}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> - <TextBlock FontWeight="SemiBold">Default RML</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.Rmls}" SelectedItem="{Binding ActiveMachine.DefaultRml}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <TextBlock FontWeight="SemiBold">Organization</TextBlock> + <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.Organizations}" SelectedItem="{Binding ActiveMachine.Organization}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> - <TextBlock FontWeight="SemiBold">Loaded RML</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.Rmls}" SelectedValue="{Binding ActiveMachine.LoadedRmlGuid}" SelectedValuePath="Guid" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <TextBlock FontWeight="SemiBold">Site</TextBlock> + <ComboBox Background="Transparent" ItemsSource="{Binding Sites}" SelectedItem="{Binding SelectedSite}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> - <TextBlock FontWeight="SemiBold">Default Color Space</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.ColorSpaces}" SelectedItem="{Binding ActiveMachine.DefaultColorSpace}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <TextBlock FontWeight="SemiBold">OS Key</TextBlock> + <TextBox Text="{Binding ActiveMachine.OsKey}"></TextBox> - <TextBlock FontWeight="SemiBold">Default Segment Length</TextBlock> - <mahapps:NumericUpDown HideUpDownButtons="True" BorderThickness="0 0 0 1" Background="Transparent" Minimum="0" Maximum="1000" Value="{Binding ActiveMachine.DefaultSegmentLength}" HasDecimals="False"></mahapps:NumericUpDown> + <TextBlock FontWeight="SemiBold">Device COM Port</TextBlock> + <TextBox Text="{Binding ActiveMachine.DeviceComPort}"></TextBox> + </controls:TableGrid> - <TextBlock FontWeight="SemiBold">Default Spool Type</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.SpoolTypes}" SelectedItem="{Binding ActiveMachine.DefaultSpoolType}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <Button Margin="0 20 0 0" Background="{StaticResource RedBrush300}" ToolTip="Make this machine configuration as a prototype for the selected machine version" BorderBrush="{StaticResource RedBrush300}" Width="200" Height="45" VerticalAlignment="Bottom" Command="{Binding MakePrototypeCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Copyright" Width="24" Height="24" /> + <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">MAKE PROTOTYPE</TextBlock> + </StackPanel> + </Button> + </StackPanel> - <TextBlock FontWeight="SemiBold">OS Key</TextBlock> - <TextBox Text="{Binding ActiveMachine.OsKey}"></TextBox> + <Rectangle Grid.Column="1" StrokeThickness="1" Stroke="{StaticResource borderBrush}" HorizontalAlignment="Center" Margin="50 50" /> + <controls:TableGrid RowHeight="50" Margin="10" Grid.Column="2"> + <TextBlock FontWeight="SemiBold">Auto Login</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.AutoLogin}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Device COM Port</TextBlock> - <TextBox Text="{Binding ActiveMachine.DeviceComPort}"></TextBox> - </controls:TableGrid> - <Rectangle Grid.Column="1" StrokeThickness="1" Stroke="{StaticResource borderBrush}" HorizontalAlignment="Center" Margin="50 50" /> - <controls:TableGrid RowHeight="50" Margin="10" Grid.Column="2"> - <TextBlock FontWeight="SemiBold">Auto Login</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.AutoLogin}"></ToggleButton> + <!--<TextBlock FontWeight="SemiBold">Auto Check For Updates</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.AutoCheckForUpdates}"></ToggleButton>--> - <TextBlock FontWeight="SemiBold">Auto Check For Updates</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.AutoCheckForUpdates}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Setup Activation</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupActivation}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Setup Activation</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupActivation}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Setup Remote Assistance</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupRemoteAssistance}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Setup Remote Assistance</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupRemoteAssistance}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Setup UWF</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupUwf}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Setup UWF</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupUwf}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Setup Firmware</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupFirmware}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Setup Firmware</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupFirmware}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Setup FPGA</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupFpga}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Setup FPGA</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SetupFpga}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Is Demo Machine</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.IsDemo}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Is Demo Machine</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.IsDemo}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Suspend Version Update</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SuspendVersionUpdate}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Suspend Version Update</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.SuspendVersionUpdate}"></ToggleButton> + <TextBlock FontWeight="SemiBold">Force Version Update</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.ForceVersionUpdate}"></ToggleButton> - <TextBlock FontWeight="SemiBold">Update Schema on Update</TextBlock> - <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.PerformSchemaUpdateOnDataUpdate}"></ToggleButton> - </controls:TableGrid> - </Grid> - </Border> + <TextBlock FontWeight="SemiBold">Update Schema on Update</TextBlock> + <ToggleButton HorizontalAlignment="Left" IsChecked="{Binding ActiveMachine.PerformSchemaUpdateOnDataUpdate}"></ToggleButton> + </controls:TableGrid> + </Grid> + </Border> + + <Border Visibility="{Binding ActiveMachine.IsDeviceRegistered,Converter={StaticResource BoolToVisConverter}}" Margin="0 10 0 0" CornerRadius="5" Background="{StaticResource TransparentBackgroundBrush600}" Padding="20" BorderBrush="{StaticResource borderBrush}" BorderThickness="1"> + <DockPanel> + <StackPanel DockPanel.Dock="Left"> + <TextBlock FontSize="16" FontWeight="SemiBold">Device Registration</TextBlock> + <TextBlock Margin="0 10 0 0"> + <Run FontWeight="SemiBold">Device ID:</Run> + <Run Text="{Binding ActiveMachine.DeviceId}"></Run> + </TextBlock> + <TextBlock Margin="0 5 0 0"> + <Run FontWeight="SemiBold">Device Name:</Run> + <Run Text="{Binding ActiveMachine.DeviceName}"></Run> + </TextBlock> + </StackPanel> + + <Button Command="{Binding ResetDeviceRegistrationCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource RedBrush300}" BorderBrush="{StaticResource RedBrush300}" Padding="10" Height="45" Width="240">RESET DEVICE REGISTRATION</Button> + </DockPanel> + </Border> + </StackPanel> </Grid> </DockPanel> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml new file mode 100644 index 000000000..0e793dc6a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml @@ -0,0 +1,94 @@ +<UserControl x:Class="Tango.MachineStudio.MachineDesigner.Views.MachineUpdateDetailsDialog" + 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:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels" + xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" + mc:Ignorable="d" + d:DesignHeight="400" d:DesignWidth="700" Height="700" Width="1280" Background="White" d:DataContext="{d:DesignInstance Type=vm:MachineUpdateDetailsDialogVM, IsDesignTimeCreatable=False}"> + <UserControl.Resources> + <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" /> + <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" /> + <converters:StringToOneLineConverter x:Key="StringToOneLineConverter" /> + </UserControl.Resources> + + <Grid> + <Grid Grid.RowSpan="2"> + <Grid.RowDefinitions> + <RowDefinition Height="60"/> + <RowDefinition Height="31*"/> + <RowDefinition Height="50"/> + </Grid.RowDefinitions> + + <StackPanel Orientation="Horizontal" DataContext="{Binding Update}"> + <materialDesign:PackIcon Width="42" Height="42" VerticalAlignment="Center"> + <materialDesign:PackIcon.Style> + <Style TargetType="materialDesign:PackIcon"> + <Setter Property="Kind" Value="Information"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsSetup}" Value="True"> + <Setter Property="Kind" Value="Settings"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsUpdate}" Value="True"> + <Setter Property="Kind" Value="CloudDownload"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsDataBase}" Value="True"> + <Setter Property="Kind" Value="Database"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsSynchronization}" Value="True"> + <Setter Property="Kind" Value="Sync"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOfflineUpdate}" Value="True"> + <Setter Property="Kind" Value="Sd"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOfflineFirmwareUpgrade}" Value="True"> + <Setter Property="Kind" Value="Chip"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsStarted}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource OrangeBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsCompleted}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource GreenBrush }"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsFailed}" Value="True"> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </materialDesign:PackIcon.Style> + </materialDesign:PackIcon> + <TextBlock VerticalAlignment="Center" Text="{Binding UpdateStatus,Converter={StaticResource EnumToDescriptionConverter}}" TextWrapping="NoWrap" Height="22" TextTrimming="CharacterEllipsis" Width="500" Margin="10 0 0 0" FontSize="16"></TextBlock> + </StackPanel> + + <Grid Grid.Row="1"> + <DockPanel> + <Grid DockPanel.Dock="Top"> + <controls:TableGrid RowHeight="30"> + <TextBlock Text="Started On:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Update.StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}"></TextBlock> + <TextBlock Text="Application:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Update.ApplicationVersion}"></TextBlock> + <TextBlock Text="Firmware:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Update.FirmwareVersion}"></TextBlock> + <TextBlock Text="Ended:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Update.EndDate,TargetNullValue='Never',FallbackValue='Never',Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}"></TextBlock> + </controls:TableGrid> + </Grid> + + <Border Padding="5" BorderThickness="1" BorderBrush="{StaticResource BorderBrushGainsboro}"> + <TextBox BorderThickness="0" Text="{Binding Update.FailedLog,TargetNullValue='No further Information available.'}" Style="{x:Null}" TextWrapping="NoWrap" IsReadOnly="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="Transparent" /> + </Border> + </DockPanel> + </Grid> + + <Grid Grid.Row="2"> + <Button HorizontalAlignment="Right" Width="140" Command="{Binding CloseCommand}">CLOSE</Button> + </Grid> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs new file mode 100644 index 000000000..8bb051c51 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.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.MachineStudio.MachineDesigner.Views +{ + /// <summary> + /// Interaction logic for MachineCreationDialog.xaml + /// </summary> + public partial class MachineUpdateDetailsDialog : UserControl + { + public MachineUpdateDetailsDialog() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml new file mode 100644 index 000000000..bd272718d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml @@ -0,0 +1,114 @@ +<UserControl x:Class="Tango.MachineStudio.MachineDesigner.Views.MachineUpdatesView" + 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.MachineStudio.MachineDesigner.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.MachineDesigner" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" + mc:Ignorable="d" + d:DesignHeight="720" d:DesignWidth="1500" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + <UserControl.Resources> + <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" /> + <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" /> + <converters:StringToOneLineConverter x:Key="StringToOneLineConverter" /> + </UserControl.Resources> + + <Grid Margin="20" DataContext="{Binding MachineUpdatesViewVM}"> + <DockPanel IsEnabled="{Binding IsFree}"> + <Grid DockPanel.Dock="Bottom"> + + </Grid> + + <Grid Margin="0 20"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="38*"/> + <ColumnDefinition Width="117*"/> + </Grid.ColumnDefinitions> + + <local:MachineView Margin="30 80 0 0" DataContext="{Binding Machine}" IsHitTestVisible="False" VerticalAlignment="Top" Height="241" /> + + <DockPanel Grid.Column="1" Margin="50 100 50 50"> + <Grid DockPanel.Dock="Bottom" Height="50"> + <StackPanel Orientation="Horizontal"> + <CheckBox IsChecked="{Binding DisplayMachineSetups}">Machine Setups</CheckBox> + <CheckBox IsChecked="{Binding DisplayApplicationUpdates}" Margin="30 0">Software Updates</CheckBox> + <CheckBox IsChecked="{Binding DisplayDatabaseUpdates}">Database Updates</CheckBox> + <CheckBox IsChecked="{Binding DisplaySynchronizations}" Margin="30 0 0 0">Synchronizations</CheckBox> + <CheckBox IsChecked="{Binding DisplayOfflineUpdates}" Margin="30 0 0 0">Offline Updates</CheckBox> + <CheckBox IsChecked="{Binding DisplayFirmwareUpgrades}" Margin="30 0 0 0">Offline Firmware Upgrades</CheckBox> + </StackPanel> + + <Button Command="{Binding RefreshCommand}" HorizontalAlignment="Right" Width="150" Style="{StaticResource MaterialDesignFlatButton}">REFRESH</Button> + </Grid> + <Grid> + <DataGrid Margin="0 0 0 10" SelectionUnit="FullRow" BorderBrush="{StaticResource borderBrush }" BorderThickness="1" Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True" ItemsSource="{Binding Updates}" SelectedItem="{Binding SelectedUpdate}"> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + </Style> + </DataGrid.CellStyle> + <DataGrid.Columns> + <DataGridTemplateColumn Header=""> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <materialDesign:PackIcon Width="16" Height="16"> + <materialDesign:PackIcon.Style> + <Style TargetType="materialDesign:PackIcon"> + <Setter Property="Kind" Value="Information"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsSetup}" Value="True"> + <Setter Property="Kind" Value="Settings"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsUpdate}" Value="True"> + <Setter Property="Kind" Value="CloudDownload"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsDataBase}" Value="True"> + <Setter Property="Kind" Value="Database"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsSynchronization}" Value="True"> + <Setter Property="Kind" Value="Sync"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOfflineUpdate}" Value="True"> + <Setter Property="Kind" Value="Sd"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOfflineFirmwareUpgrade}" Value="True"> + <Setter Property="Kind" Value="Chip"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsStarted}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource OrangeBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsCompleted}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource GreenBrush }"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsFailed}" Value="True"> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </materialDesign:PackIcon.Style> + </materialDesign:PackIcon> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="STARTED" Binding="{Binding StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" /> + <DataGridTextColumn Header="APPLICATION" Binding="{Binding ApplicationVersion}" Width="Auto" /> + <DataGridTextColumn Header="FIRMWARE" Binding="{Binding FirmwareVersion}" Width="Auto" /> + <DataGridTextColumn Header="ENDED" Binding="{Binding EndDate,TargetNullValue='Never',FallbackValue='Never',Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" /> + <DataGridTextColumn Header="STATUS" Binding="{Binding UpdateStatus,Converter={StaticResource EnumToDescriptionConverter}}" Width="Auto" /> + <DataGridTextColumn Header="REASON" Binding="{Binding FailedReason,Converter={StaticResource StringToOneLineConverter},ConverterParameter='80'}" Width="*" /> + </DataGrid.Columns> + </DataGrid> + </Grid> + </DockPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs new file mode 100644 index 000000000..d13ef2d0e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.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.MachineStudio.MachineDesigner.Views +{ + /// <summary> + /// Interaction logic for SpoolsView.xaml + /// </summary> + public partial class MachineUpdatesView : UserControl + { + public MachineUpdatesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml index 35b578b6a..a231e92a3 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml @@ -15,6 +15,7 @@ d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> <UserControl.Resources> <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" /> + <converters:BooleanToYesNoConverter x:Key="BooleanToYesNoConverter" /> </UserControl.Resources> <Grid> @@ -73,7 +74,8 @@ <DataGridTextColumn Header="NAME" Binding="{Binding Name}" Width="Auto" /> <DataGridTextColumn Header="ORGANIZATION" Binding="{Binding Organization.Name}" Width="Auto" /> <DataGridTextColumn Header="VERSION" Binding="{Binding MachineVersion.Name}" Width="Auto" /> - <DataGridTextColumn Header="DEMO MACHINE" Binding="{Binding IsDemo}" Width="Auto" /> + <DataGridTextColumn Header="REGISTERED" Binding="{Binding IsDeviceRegistered,Converter={StaticResource BooleanToYesNoConverter}}" Width="Auto" /> + <DataGridTextColumn Header="DEMO MACHINE" Binding="{Binding IsDemo,Converter={StaticResource BooleanToYesNoConverter}}" Width="Auto" /> <DataGridTextColumn Header="LAST UPDATED" Binding="{Binding LastUpdated,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="1*" /> </DataGrid.Columns> </controls:DoubleClickDataGrid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml index bc9b038dc..833086bf0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml @@ -9,7 +9,7 @@ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - <Grid> + <Grid IsEnabled="{Binding IsFree}"> <controls:NavigationControl x:Name="navigationControl" TransitionType="Slide"> <local:MachinesView /> <local:MachineDetailsView/> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml new file mode 100644 index 000000000..895a26ca0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml @@ -0,0 +1,60 @@ +<UserControl x:Class="Tango.MachineStudio.MachineDesigner.Views.TupView" + 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.MachineStudio.MachineDesigner.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.MachineDesigner" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" + mc:Ignorable="d" + d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}" Background="Transparent"> + + <Grid Margin="20" DataContext="{Binding TupViewVM}"> + <DockPanel IsEnabled="{Binding IsFree}"> + <Grid DockPanel.Dock="Bottom"> + + </Grid> + + <Grid Margin="0 20"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="38*"/> + <ColumnDefinition Width="117*"/> + </Grid.ColumnDefinitions> + + <local:MachineView Margin="30 80 0 0" DataContext="{Binding Machine}" IsHitTestVisible="False" VerticalAlignment="Top" Height="241" /> + + <DockPanel Grid.Column="1" Margin="50 100 300 100"> + <TextBlock DockPanel.Dock="Top"> + <Run>Create a complete update package (.tup) in order to update this machine offline using a removable storage device.</Run> + <LineBreak/> + <Run>The latest PPC version is </Run> + <Run Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" Text="{Binding LatestVersion,FallbackValue='loading...',TargetNullValue='loading...'}"></Run> + </TextBlock> + <Grid Margin="0 20 0 0"> + <Border Background="{StaticResource Transparent200}" CornerRadius="5" Padding="60" BorderThickness="1" BorderBrush="Silver"> + <DockPanel> + <DockPanel DockPanel.Dock="Top" Height="40"> + <Button Command="{Binding SelectFileCommand}" DockPanel.Dock="Right" BorderBrush="Silver" BorderThickness="1" Padding="0" Height="Auto" Width="40" Margin="5 0 0 0" Style="{StaticResource MaterialDesignFlatButton}"> + <material:PackIcon Kind="Folder" /> + </Button> + <TextBox materialDesign:HintAssist.Hint="Select package location" BorderBrush="Silver" BorderThickness="1" Text="{Binding FilePath}" IsReadOnly="True" VerticalContentAlignment="Center" Padding="10 0 0 0"></TextBox> + </DockPanel> + <StackPanel DockPanel.Dock="Bottom"> + <TextBlock HorizontalAlignment="Center" Text="{Binding Progress.Message,FallbackValue='Ready',TargetNullValue='Ready'}"></TextBlock> + <ProgressBar Margin="0 10 0 0" Height="15" IsIndeterminate="{Binding Progress.IsIntermediate}" Value="{Binding Progress.Progress}" Maximum="{Binding Progress.Total}"></ProgressBar> + </StackPanel> + <Grid> + <Button Command="{Binding CreateTupFileCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="20 10" Height="60" Width="300">GENERATE UPDATE PACKAGE</Button> + </Grid> + </DockPanel> + </Border> + </Grid> + </DockPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs new file mode 100644 index 000000000..fe01296d8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.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.MachineStudio.MachineDesigner.Views +{ + /// <summary> + /// Interaction logic for SpoolsView.xaml + /// </summary> + public partial class TupView : UserControl + { + public TupView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs index b68239b4b..f583fa15e 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs @@ -309,6 +309,19 @@ namespace Tango.MachineStudio.RML.ViewModels } } + private double GetTotalMaximumLiquidVolumeLimit() + { + try + { + var tables = RML.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); + return (tables[1].MaxInkUptake / tables[0].MaxInkUptake) * 100; + } + catch + { + return BrushStop.MAX_TOTAL_LIQUID_VOLUME; + } + } + private void OnLiquidVolumeChanged() { try @@ -316,7 +329,7 @@ namespace Tango.MachineStudio.RML.ViewModels if (LiquidsCalibrationData == null || _prevent_inverse_conversion) return; //TODO: This is temporary because of out of range volumes. - if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.Volume) > 200) + if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.Volume) > GetTotalMaximumLiquidVolumeLimit()) { IsVolumesOutOfRange = true; return; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs index ee21b9ac3..5c55892ba 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs @@ -21,12 +21,18 @@ using Tango.MachineStudio.RML.Views; using Tango.PMR.ColorLab; using System.Data.Entity; using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; namespace Tango.MachineStudio.RML.ViewModels { public class MainViewVM : StudioViewModel<IMainView> { private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private RmlDTO _rmlBeforeSave; private ObservablesContext _rmls_context; private ObservablesContext _active_context; @@ -185,9 +191,11 @@ namespace Tango.MachineStudio.RML.ViewModels public RelayCommand ImportRMLFileCommand { get; set; } - public MainViewVM(INotificationProvider notificationProvider) + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null); RemoveRmlCommand = new RelayCommand(RemoveSelectedRml, () => SelectedRML != null); CloneRmlCommand = new RelayCommand(CloneSelectedRml, () => SelectedRML != null); @@ -334,6 +342,8 @@ namespace Tango.MachineStudio.RML.ViewModels LiquidTypesRmls = LiquidTypesRmls, }; + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); + View.NavigateTo(RmlNavigationView.RmlView); InvalidateRelayCommands(); @@ -423,6 +433,9 @@ namespace Tango.MachineStudio.RML.ViewModels _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); _active_context.Rmls.Add(rml); await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, rml.Name, rml, "Rml created using Machine Studio."); + LoadActiveRML(rml.Guid); IsFree = true; @@ -432,7 +445,7 @@ namespace Tango.MachineStudio.RML.ViewModels private async void RemoveSelectedRml() { - if (_notification.ShowQuestion("Removing the selected RML will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) + if (_notification.ShowQuestion("Removing the selected thread will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) { IsFree = false; @@ -440,7 +453,18 @@ namespace Tango.MachineStudio.RML.ViewModels { try { + var rml_jobs = await _rmls_context.Jobs.Where(x => x.RmlGuid == SelectedRML.Guid).Include(x => x.Machine).OrderBy(x => x.Machine.SerialNumber).ToListAsync(); + + if (rml_jobs.Count > 0) + { + _notification.ShowError($"The following jobs must be removed or change thread type before the selected thread can be deleted:\n{String.Join("\n",rml_jobs.Select(x => $"{x.Machine.SerialNumber} => {x.Name}"))}"); + return; + } + await SelectedRML.DeleteCascadeAsync(_rmls_context); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlDeleted, _authentication.CurrentUser, SelectedRML.Name, SelectedRML, "RML deleted from Machine Studio."); + LoadRmls(); } catch (Exception ex) @@ -471,7 +495,7 @@ namespace Tango.MachineStudio.RML.ViewModels var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().BuildAsync(); Rml cloned = new Rml(); - rml.MapPrimitivesWithStrings(cloned); + rml.MapPropertiesTo(cloned, MappingFlags.NoReferenceTypes); cloned.Code = Rmls.Max(x => x.Code) + 1; cloned.Guid = Guid.NewGuid().ToString(); @@ -504,6 +528,8 @@ namespace Tango.MachineStudio.RML.ViewModels context.Rmls.Add(cloned); await context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, cloned.Name, cloned, "RML cloned from Machine Studio."); } LoadRmls(); @@ -665,7 +691,13 @@ namespace Tango.MachineStudio.RML.ViewModels } } + var rmlAfter = RmlDTO.FromObservable(ActiveRML); + await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlSaved, _authentication.CurrentUser, _rmlBeforeSave.Name, _rmlBeforeSave, rmlAfter, "RML saved using Machine Studio."); + + _rmlBeforeSave = rmlAfter; } } catch (Exception ex) @@ -804,6 +836,8 @@ namespace Tango.MachineStudio.RML.ViewModels var rmlFile = await Rml.FromRmlFile(db, json); db.Rmls.Add(rmlFile); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlImported, _authentication.CurrentUser, rmlFile.Name, rmlFile, "RML imported from Machine Studio."); } await db.SaveChangesAsync(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml index b85fd2c12..cae614aeb 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml @@ -70,7 +70,7 @@ <DataTemplate> <DockPanel> <TextBlock IsHitTestVisible="False" Margin="0 5 0 5" Text="{Binding Name}" FontSize="11"></TextBlock> - <mahapps:NumericUpDown HorizontalAlignment="Right" Minimum="0" Margin="0 0 5 0" HideUpDownButtons="True" HorizontalContentAlignment="Right" Maximum="10000" StringFormat="0.0" InterceptArrowKeys="True" Background="Transparent" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" Value="{Binding Value,Mode=TwoWay}"></mahapps:NumericUpDown> + <mahapps:NumericUpDown HorizontalAlignment="Right" Minimum="0" Margin="0 0 5 0" HideUpDownButtons="True" HorizontalContentAlignment="Right" Maximum="10000" StringFormat="{Binding StringFormat}" InterceptArrowKeys="True" Background="Transparent" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" Value="{Binding Value,Mode=TwoWay}"></mahapps:NumericUpDown> </DockPanel> </DataTemplate> </editors:ParameterizedEditor.DoubleTemplate> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml index 50f6a6297..e34854046 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml @@ -191,7 +191,7 @@ </UniformGrid> <TextBlock Margin="0 40 0 0" Text="Color Conversion Version:" HorizontalAlignment="Center"></TextBlock> - <mahapps:NumericUpDown Minimum="1" Maximum="2" Value="{Binding ActiveRML.ColorConversionVersion}" HorizontalContentAlignment="Center" Background="Transparent" BorderBrush="{StaticResource DimGrayBrush}" HasDecimals="False" Margin="0 5 0 0" /> + <mahapps:NumericUpDown Minimum="1" Maximum="3" Value="{Binding ActiveRML.ColorConversionVersion}" HorizontalContentAlignment="Center" Background="Transparent" BorderBrush="{StaticResource DimGrayBrush}" HasDecimals="False" Margin="0 5 0 0" /> </StackPanel> </StackPanel> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml new file mode 100644 index 000000000..01a064b05 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml @@ -0,0 +1,12 @@ +<Application x:Class="Tango.MachineStudio.Sites.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.MachineStudio.Common;component/Resources/MaterialDesign.xaml" /> + <ResourceDictionary Source="pack://application:,,,/Tango.MachineStudio.Common;component/Themes/LightThemeColors.xaml" /> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> + </Application.Resources> +</Application> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs new file mode 100644 index 000000000..67f57b28c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.SharedUI; + +namespace Tango.MachineStudio.Sites.Contracts +{ + public enum SitesNavigationView + { + SitesView, + SiteDetailsView, + } + + public interface IMainView : IView + { + void NavigateTo(SitesNavigationView view); + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png Binary files differnew file mode 100644 index 000000000..9b22e53b0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/site.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/site.png Binary files differnew file mode 100644 index 000000000..2fee5fafa --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/site.png diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs new file mode 100644 index 000000000..007f8a3ad --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.SharedUI.Components; + +namespace Tango.MachineStudio.Sites.Models +{ + public class SiteModel : Site + { + public String Organization { get; set; } + public int MachineCount { get; set; } + public int CatalogCount { get; set; } + public int ThreadCount { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a6eebb5a8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +[assembly: AssemblyTitle("Tango - Machine Studio Sites Module")] +[assembly: AssemblyVersion("1.0.0.1737")] + +[assembly: ComVisible(false)] + +[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) +)] diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.Designer.cs new file mode 100644 index 000000000..ecefa25e7 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/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.MachineStudio.Sites.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.MachineStudio.Sites.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/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.resx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/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/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.Designer.cs new file mode 100644 index 000000000..5fa894ceb --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/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.MachineStudio.Sites.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/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.settings b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/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/MachineStudio/Modules/Tango.MachineStudio.Sites/SitesModule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/SitesModule.cs new file mode 100644 index 000000000..96d3aed49 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/SitesModule.cs @@ -0,0 +1,62 @@ +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; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Sites.Views; +using Tango.SharedUI.Helpers; + +namespace Tango.MachineStudio.Sites +{ + [StudioModule(20)] + public class SitesModule : StudioModuleBase + { + public override string Name + { + get + { + return "Sites"; + } + } + + public override string Description + { + get + { + return "Manage organizations sites and their common machine properties."; + } + } + + public override BitmapSource Image + { + get + { + return ResourceHelper.GetImageFromResources("Images/site.png"); + } + } + + public override Type MainViewType + { + get + { + return typeof(MainView); + } + } + + public override Permissions Permission + { + get + { + return Permissions.RunRMLModule; + } + } + + public override void Dispose() + { + + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj new file mode 100644 index 000000000..ea9162ce2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj @@ -0,0 +1,177 @@ +<?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>{18A27902-9881-4556-8163-F6DF2236A14D}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>Tango.MachineStudio.Sites</RootNamespace> + <AssemblyName>Tango.MachineStudio.Sites</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\Machine Studio\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\Machine Studio\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="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> + <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath> + </Reference> + <Reference Include="MaterialDesignColors, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll</HintPath> + </Reference> + <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MaterialDesignThemes.2.3.1.953\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.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\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="Contracts\IMainView.cs" /> + <Compile Include="Models\SiteModel.cs" /> + <Compile Include="ViewModelLocator.cs" /> + <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="ViewModels\SiteDetailsViewVM.cs" /> + <Compile Include="Views\MainView.xaml.cs"> + <DependentUpon>MainView.xaml</DependentUpon> + </Compile> + <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="SitesModule.cs" /> + <Compile Include="Views\SiteDetailsView.xaml.cs"> + <DependentUpon>SiteDetailsView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\SitesView.xaml.cs"> + <DependentUpon>SitesView.xaml</DependentUpon> + </Compile> + <Page Include="App.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="Views\MainView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Views\SiteDetailsView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Views\SitesView.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="app.config" /> + <None Include="packages.config" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\machine_site.png" /> + </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.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</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.MachineStudio.Common\Tango.MachineStudio.Common.csproj"> + <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> + <Name>Tango.MachineStudio.Common</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\site.png" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModelLocator.cs new file mode 100644 index 000000000..c06ae05e7 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModelLocator.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; +using Tango.MachineStudio.Sites.ViewModels; + +namespace Tango.MachineStudio.Sites +{ + public static class ViewModelLocator + { + /// <summary> + /// Initializes a new instance of the ViewModelLocator class. + /// </summary> + static ViewModelLocator() + { + TangoIOC.Default.Register<MainViewVM>(); + } + + public static MainViewVM MainViewVM + { + get + { + return TangoIOC.Default.GetInstance<MainViewVM>(); + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs new file mode 100644 index 000000000..5db5e004d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs @@ -0,0 +1,220 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.ActionLogs; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.Core.Threading; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Authentication; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Sites.Contracts; +using Tango.MachineStudio.Sites.Models; + +namespace Tango.MachineStudio.Sites.ViewModels +{ + public class MainViewVM : StudioViewModel<IMainView> + { + private ObservablesContext _db; + private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private ActionTimer _filter_timer; + + private List<SiteModel> _sites; + public List<SiteModel> Sites + { + get { return _sites; } + set { _sites = value; RaisePropertyChangedAuto(); } + } + + private SiteModel _selectedSite; + public SiteModel SelectedSite + { + get { return _selectedSite; } + set { _selectedSite = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _filter; + public String Filter + { + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private SiteDetailsViewVM _siteDetailsViewVM; + public SiteDetailsViewVM SiteDetailsViewVM + { + get { return _siteDetailsViewVM; } + set { _siteDetailsViewVM = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand AddSiteCommand { get; set; } + + public RelayCommand RemoveSiteCommand { get; set; } + + public RelayCommand ManageSiteCommand { get; set; } + + public RelayCommand BackToSitesCommand { get; set; } + + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) + { + _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; + _filter_timer = new ActionTimer(TimeSpan.FromMilliseconds(500)); + + ManageSiteCommand = new RelayCommand(() => LoadSelectedSite(), () => SelectedSite != null); + BackToSitesCommand = new RelayCommand(() => { View.NavigateTo(SitesNavigationView.SitesView); }); + AddSiteCommand = new RelayCommand(AddNewSite); + RemoveSiteCommand = new RelayCommand(RemoveSelectedSite, () => SelectedSite != null); + } + + private async void RemoveSelectedSite() + { + if (!_notification.ShowQuestion("Are you sure you wish to remove the selected site?")) return; + + try + { + using (_notification.PushTaskItem("Removing site...")) + { + IsFree = false; + await Task.Factory.StartNew(() => + { + var site = _db.Sites.SingleOrDefault(x => x.Guid == SelectedSite.Guid); + site.Delete(_db); + _db.SaveChanges(); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteDeleted, _authentication.CurrentUser, site.Name, site, "Site deleted using Machine Studio."); + Sites.Remove(SelectedSite); + LoadSites(); + }); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error removing site."); + _notification.ShowError($"Error removing site.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private async void AddNewSite() + { + try + { + String name = _notification.ShowTextInput("Enter site name", "name"); + if (String.IsNullOrWhiteSpace(name)) return; + + using (_notification.PushTaskItem("Creating site...")) + { + IsFree = false; + SiteDetailsViewVM = new SiteDetailsViewVM(); + SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; + await SiteDetailsViewVM.Init(SelectedSite?.Guid, _notification, _authentication, _actionLogManager, true, name); + View.NavigateTo(SitesNavigationView.SiteDetailsView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error creating site."); + _notification.ShowError($"Error creating site.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private async void LoadSelectedSite() + { + try + { + using (_notification.PushTaskItem("Loading site details...")) + { + IsFree = false; + SiteDetailsViewVM = new SiteDetailsViewVM(); + SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; + await SiteDetailsViewVM.Init(SelectedSite.Guid, _notification, _authentication, _actionLogManager, false); + View.NavigateTo(SitesNavigationView.SiteDetailsView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading site details."); + _notification.ShowError($"Error loading site details.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void SiteDetailsViewVM_Saved(object sender, EventArgs e) + { + OnFilterChanged(); + View.NavigateTo(SitesNavigationView.SitesView); + } + + private void OnFilterChanged() + { + if (Filter != null) + { + _filter_timer.ResetReplace(() => + { + try + { + LoadSites(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading sites list."); + } + }); + } + } + + private void LoadSites() + { + using (_notification.PushTaskItem("Loading sites...")) + { + Sites = (from site in _db.Sites + join organization in _db.Organizations on site.OrganizationGuid equals organization.Guid + join sites_rmls in _db.SitesRmls on site.Guid equals sites_rmls.SiteGuid into rmls + join sites_catalogs in _db.SitesCatalogs on site.Guid equals sites_catalogs.SiteGuid into catalogs + join sites_machines in _db.Machines on site.Guid equals sites_machines.SiteGuid into machines + where Filter == null || Filter == "" || site.Name.ToLower().StartsWith(Filter.ToLower()) || organization.Name.ToLower().StartsWith(Filter.ToLower()) + select new + { + Site = site, + OrganizationName = organization.Name, + ThreadCount = rmls.Count(x => x.SiteGuid == site.Guid), + CatalogCount = catalogs.Count(x => x.SiteGuid == site.Guid), + MachineCount = machines.Count(x => x.SiteGuid == site.Guid) + }).Distinct().ToList().DistinctBy(x => x.Site.Guid).Select(x => new SiteModel() + { + Guid = x.Site.Guid, + ID = x.Site.ID, + Name = x.Site.Name, + Description = x.Site.Description, + ThreadCount = x.ThreadCount, + CatalogCount = x.CatalogCount, + MachineCount = x.MachineCount, + Organization = x.OrganizationName, + }).ToList(); + } + } + + public override void OnApplicationReady() + { + _db = ObservablesContext.CreateDefault(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs new file mode 100644 index 000000000..92dd8273d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs @@ -0,0 +1,169 @@ +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.Core.Commands; +using Tango.SharedUI; +using Tango.SharedUI.Components; +using System.Data.Entity; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; +using Tango.BL.Builders; + +namespace Tango.MachineStudio.Sites.ViewModels +{ + public class SiteDetailsViewVM : ViewModel + { + private ObservablesContext _db; + private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private bool _isNew; + private SiteDTO _siteBeforeSave; + + public event EventHandler Saved; + + private Site _site; + public Site Site + { + get { return _site; } + set { _site = value; RaisePropertyChangedAuto(); } + } + + private List<Organization> _organizations; + public List<Organization> Organizations + { + get { return _organizations; } + set { _organizations = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection<Rml> _rmls; + public SelectedObjectCollection<Rml> Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection<ColorCatalog> _catalogs; + public SelectedObjectCollection<ColorCatalog> Catalogs + { + get { return _catalogs; } + set { _catalogs = value; RaisePropertyChangedAuto(); } + } + + private List<Machine> _machines; + public List<Machine> Machines + { + get { return _machines; } + set { _machines = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand SaveCommand { get; set; } + + public SiteDetailsViewVM() + { + SaveCommand = new RelayCommand(Save, () => IsFree); + } + + public async Task Init(String siteGuid, INotificationProvider notification, IAuthenticationProvider authentication, IActionLogManager actionLogManager, bool isNew, string newSiteName = null) + { + _notification = notification; + _authentication = authentication; + _actionLogManager = actionLogManager; + + _db = ObservablesContext.CreateDefault(); + Organizations = await _db.Organizations.ToListAsync(); + + if (isNew) + { + Site = new Site(); + Site.Name = newSiteName; + Site.Description = "My site description"; + _db.Sites.Add(Site); + + _isNew = true; + } + else + { + _isNew = false; + Site = await new SiteBuilder(_db).Set(siteGuid) + .WithSiteCatalogs() + .WithCatalogs() + .WithSiteRmls() + .WithRmls() + .WithOrganization() + .BuildAsync(); + } + + Machines = await _db.Machines.Where(x => x.SiteGuid == Site.Guid).Include(x => x.Organization).ToListAsync(); + + var rmls = await _db.Rmls.OrderBy(x => x.Name).ToListAsync(); + var catalogs = await _db.ColorCatalogs.OrderBy(x => x.Name).ToListAsync(); + + Rmls = new SelectedObjectCollection<Rml>(rmls.ToObservableCollection(), Site.SitesRmls.Select(x => x.Rml).ToObservableCollection()); + Catalogs = new SelectedObjectCollection<ColorCatalog>(catalogs.ToObservableCollection(), Site.SitesCatalogs.Select(x => x.ColorCatalog).ToObservableCollection()); + + _siteBeforeSave = SiteDTO.FromObservable(Site); + } + + private async void Save() + { + try + { + if (!Site.Validate(_db)) + { + _notification.ShowError(String.Join("\n", Site.ValidationErrors)); + return; + } + + IsFree = false; + + using (_notification.PushTaskItem("Saving site details...")) + { + //Remove site rmls. + Site.SitesRmls.ToList().Where(x => !Rmls.SynchedSource.ToList().Exists(y => y.Guid == x.RmlGuid)).ToList().ForEach(x => _db.SitesRmls.Remove(x)); + Site.SitesCatalogs.ToList().Where(x => !Catalogs.SynchedSource.ToList().Exists(y => y.Guid == x.ColorCatalogGuid)).ToList().ForEach(x => _db.SitesCatalogs.Remove(x)); + + foreach (var selectedRml in Rmls.SynchedSource.Where(x => !Site.SitesRmls.ToList().Exists(y => y.RmlGuid == x.Guid))) + { + _db.SitesRmls.Add(new SitesRml() { SiteGuid = Site.Guid, RmlGuid = selectedRml.Guid }); + } + + foreach (var selectedCatalog in Catalogs.SynchedSource.Where(x => !Site.SitesCatalogs.ToList().Exists(y => y.ColorCatalogGuid == x.Guid))) + { + _db.SitesCatalogs.Add(new SitesCatalog() { SiteGuid = Site.Guid, ColorCatalogGuid = selectedCatalog.Guid }); + } + + await _db.SaveChangesAsync(); + + if (_isNew) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteCreated, _authentication.CurrentUser, Site.Name, Site, "Site created using Machine Studio."); + } + else + { + SiteDTO siteAfter = SiteDTO.FromObservable(Site); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteSaved, _authentication.CurrentUser, _siteBeforeSave.Name, _siteBeforeSave, siteAfter, "Site saved using Machine Studio."); + _siteBeforeSave = siteAfter; + } + } + _db.Dispose(); + Saved?.Invoke(this, new EventArgs()); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving site details."); + _notification.ShowError($"Error saving site details.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml new file mode 100644 index 000000000..4ca82c4f7 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml @@ -0,0 +1,19 @@ +<UserControl x:Class="Tango.MachineStudio.Sites.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:local="clr-namespace:Tango.MachineStudio.Sites.Views" + xmlns:vm="clr-namespace:Tango.MachineStudio.Sites.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.Sites" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + <Grid IsEnabled="{Binding IsFree}"> + <controls:NavigationControl x:Name="navigationControl" TransitionType="Slide"> + <local:SitesView /> + <local:SiteDetailsView/> + </controls:NavigationControl> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs new file mode 100644 index 000000000..c4f9995ce --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs @@ -0,0 +1,36 @@ +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; +using Tango.Core.DI; +using Tango.MachineStudio.Sites.Contracts; + +namespace Tango.MachineStudio.Sites.Views +{ + /// <summary> + /// Interaction logic for MainView.xaml + /// </summary> + public partial class MainView : UserControl, IMainView + { + public MainView() + { + InitializeComponent(); + TangoIOC.Default.Register<IMainView>(this); + } + + public void NavigateTo(SitesNavigationView view) + { + navigationControl.NavigateTo(view.ToString()); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml new file mode 100644 index 000000000..182f05be0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml @@ -0,0 +1,170 @@ +<UserControl x:Class="Tango.MachineStudio.Sites.Views.SiteDetailsView" + 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:local="clr-namespace:Tango.MachineStudio.Sites.Views" + xmlns:vm="clr-namespace:Tango.MachineStudio.Sites.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.Sites" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + <UserControl.Resources> + <Style x:Key="GridStyle" TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}"> + <Setter Property="AutoGenerateColumns" Value="False"></Setter> + <Setter Property="SelectionMode" Value="Single"></Setter> + <Setter Property="SelectionUnit" Value="FullRow"></Setter> + <Setter Property="IsReadOnly" Value="True"></Setter> + </Style> + + <Style x:Key="CellStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type DataGridCell}"> + <Grid Background="{TemplateBinding Background}"> + <ContentPresenter VerticalAlignment="Center" Margin="8" /> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="BorderBrush" Value="Cyan"/> + </Trigger> + </Style.Triggers> + </Style> + </UserControl.Resources> + + <Grid Margin="20" DataContext="{Binding SiteDetailsViewVM}" d:DataContext="{d:DesignInstance Type=vm:SiteDetailsViewVM, IsDesignTimeCreatable=False}"> + <DockPanel> + <Grid DockPanel.Dock="Top"> + <StackPanel Orientation="Horizontal"> + <Button Style="{StaticResource MaterialDesignFlatButton}" Height="Auto" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.BackToSitesCommand}"> + <materialDesign:PackIcon Kind="ArrowLeft" Width="50" Height="50" Foreground="#202020" ToolTip="Back to RML list" /> + </Button> + <TextBlock Text="{Binding Site.Name,NotifyOnValidationError=False,ValidatesOnNotifyDataErrors=False}" VerticalAlignment="Center" Margin="10 0 0 0" FontSize="34"></TextBlock> + </StackPanel> + + <StackPanel HorizontalAlignment="Right" Orientation="Horizontal"> + <Button Margin="10 0 0 0" Width="170" Height="45" VerticalAlignment="Center" Command="{Binding SaveCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="ContentSaveAll" Width="24" Height="24" /> + <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">SAVE</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + + <Grid Margin="0 20"> + <Grid.RowDefinitions> + <RowDefinition Height="113*"/> + <RowDefinition Height="358*"/> + </Grid.RowDefinitions> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="302*"/> + <ColumnDefinition Width="399*"/> + <ColumnDefinition Width="1179*"/> + </Grid.ColumnDefinitions> + + <Grid Margin="10"> + <materialDesign:Card Background="{DynamicResource MaterialDesignBackground}" VerticalAlignment="Stretch"> + <Border Padding="20"> + <DockPanel> + <TextBlock DockPanel.Dock="Top" FontSize="16">PROPERTIES</TextBlock> + <controls:TableGrid RowHeight="35"> + <TextBlock Text="Name:" ></TextBlock> + <TextBox Text="{Binding Site.Name,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + + <TextBlock Text="Organization:" ></TextBlock> + <ComboBox ItemsSource="{Binding Organizations}" SelectedItem="{Binding Site.Organization}" DisplayMemberPath="Name"></ComboBox> + + <TextBlock Text="Description:" ></TextBlock> + <TextBox Text="{Binding Site.Description,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + </controls:TableGrid> + </DockPanel> + </Border> + </materialDesign:Card> + </Grid> + + <Grid Grid.Column="1" Margin="10"> + + </Grid> + + <Grid Grid.ColumnSpan="3"> + + </Grid> + </Grid> + + <Grid Grid.Row="1" Margin="0 20 0 0"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + + <DockPanel Margin="10"> + <TextBlock DockPanel.Dock="Top" FontSize="16">SITE RML</TextBlock> + + <materialDesign:Card Margin="0 5 0 0" Background="{DynamicResource MaterialDesignBackground}" VerticalAlignment="Stretch"> + <DataGrid ItemsSource="{Binding Rmls}" Style="{StaticResource GridStyle}" CellStyle="{StaticResource CellStyle}"> + <DataGrid.Columns> + <DataGridTemplateColumn Header="" Width="Auto"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="NAME" IsReadOnly="True" Binding="{Binding Data.Name}" Width="1*" /> + </DataGrid.Columns> + </DataGrid> + </materialDesign:Card> + </DockPanel> + + + <DockPanel Margin="10" Grid.Column="1"> + <TextBlock DockPanel.Dock="Top" FontSize="16" Text="SITE CATALOGS"/> + <materialDesign:Card Margin="0 5 0 0" Background="{DynamicResource MaterialDesignBackground}" VerticalAlignment="Stretch"> + <DataGrid ItemsSource="{Binding Catalogs}" Style="{StaticResource GridStyle}" CellStyle="{StaticResource CellStyle}"> + <DataGrid.Columns> + <DataGridTemplateColumn Header="" Width="Auto"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="NAME" Binding="{Binding Data.Name}" Width="1*" /> + </DataGrid.Columns> + </DataGrid> + </materialDesign:Card> + </DockPanel> + + <DockPanel Margin="10" Grid.Column="2"> + <TextBlock DockPanel.Dock="Top" FontSize="16" Text="SITE MACHINES"/> + <materialDesign:Card Margin="0 5 0 0" Background="{DynamicResource MaterialDesignBackground}" VerticalAlignment="Stretch"> + <DataGrid ItemsSource="{Binding Machines}" Style="{StaticResource GridStyle}" CellStyle="{StaticResource CellStyle}"> + <DataGrid.Columns> + <DataGridTextColumn Header="ORGANIZATION" Binding="{Binding Organization.Name}" Width="Auto" /> + <DataGridTextColumn Header="SERIAL NUMBER" Binding="{Binding SerialNumber}" Width="Auto" /> + <DataGridTextColumn Header="NAME" Binding="{Binding Name}" Width="1*" /> + </DataGrid.Columns> + </DataGrid> + </materialDesign:Card> + </DockPanel> + </Grid> + </Grid> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs new file mode 100644 index 000000000..03e9a2f75 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.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.MachineStudio.Sites.Views +{ + /// <summary> + /// Interaction logic for SiteDetailsView.xaml + /// </summary> + public partial class SiteDetailsView : UserControl + { + public SiteDetailsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml new file mode 100644 index 000000000..437003a8a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml @@ -0,0 +1,76 @@ +<UserControl x:Class="Tango.MachineStudio.Sites.Views.SitesView" + 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:local="clr-namespace:Tango.MachineStudio.Sites.Views" + xmlns:vm="clr-namespace:Tango.MachineStudio.Sites.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.Sites" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + <UserControl.Resources> + <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" /> + </UserControl.Resources> + + <Grid> + <DockPanel Margin="100" MaxWidth="1200"> + <Grid DockPanel.Dock="Top"> + <StackPanel Orientation="Horizontal"> + <Image Source="../Images/machine_site.png" Width="350" RenderOptions.BitmapScalingMode="Fant" Margin="10" /> + + <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Margin="0 0 0 10"> + <materialDesign:PackIcon VerticalAlignment="Center" Kind="Magnify" Width="32" Height="32" /> + <TextBox Width="400" FontSize="20" Margin="10 0 0 0" materialDesign:HintAssist.Hint="Name, Organization" Text="{Binding Filter,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox> + </StackPanel> + </StackPanel> + </Grid> + <Grid DockPanel.Dock="Bottom" IsEnabled="{Binding IsFree}"> + <StackPanel VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0 0 0 0"> + <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="{StaticResource RedBrush300}" BorderBrush="{StaticResource RedBrush300}" Command="{Binding RemoveSiteCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Delete" Width="20" Height="20" /> + <TextBlock Margin="5 0 0 0" FontSize="16">DELETE</TextBlock> + </StackPanel> + </Button> + <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="{StaticResource GreenBrush300}" BorderBrush="{StaticResource GreenBrush300}" Command="{Binding AddSiteCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Plus" Width="20" Height="20" /> + <TextBlock Margin="5 0 0 0" FontSize="16">NEW SITE</TextBlock> + </StackPanel> + </Button> + </StackPanel> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> + <Button Margin="50 0 0 0" MinWidth="200" Height="60" Command="{Binding ManageSiteCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Pencil" Width="24" Height="24" /> + <TextBlock Margin="10 0 0 0" FontSize="18">EDIT</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + <Grid IsEnabled="{Binding IsFree}"> + <controls:DoubleClickDataGrid Style="{StaticResource {x:Type DataGrid}}" DoubleClickCommand="{Binding ManageSiteCommand}" Margin="0 0 0 10" BorderBrush="{StaticResource borderBrush}" IsReadOnly="True" BorderThickness="1" Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding Sites}" SelectedItem="{Binding SelectedSite}"> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + </Style> + </DataGrid.CellStyle> + <DataGrid.Columns> + <DataGridTextColumn Header="NAME" Binding="{Binding Name}" Width="Auto" /> + <DataGridTextColumn Header="DESCRIPTION" Binding="{Binding Description}" Width="Auto" /> + <DataGridTextColumn Header="ORGANIZATION" Binding="{Binding Organization}" Width="Auto" /> + <DataGridTextColumn Header="MACHINES" Binding="{Binding MachineCount}" Width="Auto" /> + <DataGridTextColumn Header="THREADS" Binding="{Binding ThreadCount}" Width="Auto" /> + <DataGridTextColumn Header="CATALOGS" Binding="{Binding CatalogCount}" Width="Auto" /> + <DataGridTextColumn Header="LAST UPDATED" Binding="{Binding LastUpdated,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="1*" /> + </DataGrid.Columns> + </controls:DoubleClickDataGrid> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs new file mode 100644 index 000000000..e6a4a6fe6 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.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.MachineStudio.Sites.Views +{ + /// <summary> + /// Interaction logic for SitesView.xaml + /// </summary> + public partial class SitesView : UserControl + { + public SitesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config new file mode 100644 index 000000000..7b82e5f7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/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.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="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.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.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="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="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/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config new file mode 100644 index 000000000..e57143046 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="EntityFramework" version="6.2.0" targetFramework="net461" /> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net461" /> + <package id="MahApps.Metro" version="1.5.0" targetFramework="net461" /> + <package id="MaterialDesignColors" version="1.1.2" targetFramework="net461" /> + <package id="MaterialDesignThemes" version="2.3.1.953" 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/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs new file mode 100644 index 000000000..8e5642e3d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs @@ -0,0 +1,45 @@ + +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.Core.ExtensionMethods; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class JobRunModel : JobRun + { + private static Dictionary<String, Machine> _machines = new Dictionary<string, Machine>(); + + public JobRunModel() + { + + } + + public JobRunModel(JobRun run) + { + run.MapPropertiesTo(this, MappingFlags.NoReferenceTypes); + } + + public Task LoadMachine(ObservablesContext context) + { + return Task.Factory.StartNew(() => + { + if (!_machines.ContainsKey(MachineGuid)) + { + Machine = context.Machines.SingleOrDefault(x => x.Guid == MachineGuid); + _machines.Add(MachineGuid, Machine); + } + else + { + Machine = _machines[MachineGuid]; + } + }); + } + + public Machine Machine { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index 243663c5a..36c371165 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -73,6 +73,7 @@ <Reference Include="PresentationFramework" /> </ItemGroup> <ItemGroup> + <Compile Include="Models\JobRunModel.cs" /> <Compile Include="Models\LabeledSeriesCollection.cs" /> <Compile Include="Tooltips\PieChartTooltipControl.xaml.cs"> <DependentUpon>PieChartTooltipControl.xaml</DependentUpon> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs index ef9561d0b..dfbfe2648 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs @@ -7,20 +7,20 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Media; using Tango.BL; -using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Helpers; using Tango.MachineStudio.Common; using Tango.MachineStudio.Statistics.Models; using System.Data.Entity; using Tango.MachineStudio.Common.Notifications; +using Tango.BL.Entities; namespace Tango.MachineStudio.Statistics.ViewModels { public class MainViewVM : StudioViewModel { private ObservablesContext _context; - private List<JobRun> _job_runs; + private List<JobRunModel> _job_runs; private bool rendered; private INotificationProvider _notification; private bool _loaded; @@ -74,7 +74,6 @@ namespace Tango.MachineStudio.Statistics.ViewModels set { _maxDate = value; RaisePropertyChangedAuto(); } } - public MainViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; @@ -88,12 +87,12 @@ namespace Tango.MachineStudio.Statistics.ViewModels } - private List<JobRun> GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) + private List<JobRunModel> GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) { return _job_runs.Where(x => x.StartDate.ToLocalTime() >= startDate && x.StartDate.ToLocalTime() <= endTime && (status == null || x.JobRunStatus == status)).ToList(); } - private List<JobRun> GetJobRunsByDate(DateTime date, JobRunStatus? status = null) + private List<JobRunModel> GetJobRunsByDate(DateTime date, JobRunStatus? status = null) { return _job_runs.Where(x => x.StartDate.ToLocalTime().Date == date.Date && (status == null || x.JobRunStatus == status)).ToList(); } @@ -106,8 +105,6 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } - - public override async void OnNavigatedTo() { base.OnNavigatedTo(); @@ -124,7 +121,11 @@ namespace Tango.MachineStudio.Statistics.ViewModels await Task.Factory.StartNew(() => { _context = ObservablesContext.CreateDefault(); - _job_runs = _context.JobRuns.Include(x => x.Job).Include(x => x.Job.Machine).OrderBy(x => x.StartDate).ToList(); + _job_runs = _context.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunModel(x)).ToList(); + foreach (var run in _job_runs) + { + run.LoadMachine(_context).GetAwaiter().GetResult(); + } }); if (_job_runs.Count > 0) @@ -282,12 +283,12 @@ namespace Tango.MachineStudio.Statistics.ViewModels private void GeneratePrintPerWeekChart() { - List<JobRun> range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); + List<JobRunModel> range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); Dictionary<Machine, List<double>> weeks_print_avg = new Dictionary<Machine, List<double>>(); //Init machines weeks averages dictionary. - foreach (var machine in range_job_runs.Select(x => x.Job.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) + foreach (var machine in range_job_runs.Select(x => x.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) { weeks_print_avg[machine] = new List<double>(); } @@ -305,7 +306,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels { var week_job_runs = range_job_runs.Where(x => x.EndPosition > 10 && x.StartDate >= current_sunday && x.StartDate <= current_sunday.AddDays(7)).ToList(); - foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Job.Machine)) + foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Machine)) { weeks_print_avg[machine_job_runs.Key].Add(machine_job_runs.Select(x => x.EndPosition).Average()); } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj new file mode 100644 index 000000000..698c6fe82 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj @@ -0,0 +1,154 @@ +<?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>{5991F6B5-EA4E-41E9-A4F6-7D3A50010FD6}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>Tango.MachineStudio.Storage</RootNamespace> + <AssemblyName>Tango.MachineStudio.Storage</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\Machine Studio\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\Machine Studio\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="Converters\StorageItemToImageConverter.cs" /> + <Compile Include="Helpers\FileIconHelper.cs" /> + <Compile Include="Models\StorageFileHandlerModel.cs" /> + <Compile Include="Models\StorageFileHandlerType.cs" /> + <Compile Include="StorageModule.cs" /> + <Compile Include="ViewModelLocator.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.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</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="..\..\..\Utilities\Tango.FirmwarePackageGenerator\Tango.FirmwarePackageGenerator.csproj"> + <Project>{43135fb9-41db-4f87-9771-cf2c762027c0}</Project> + <Name>Tango.FirmwarePackageGenerator</Name> + </ProjectReference> + <ProjectReference Include="..\..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj"> + <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> + <Name>Tango.MachineStudio.Common</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup /> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Utilities\Debug\fpgen.exe" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Microsoft.CSharp.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.DataAnnotations.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xaml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.BL.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Core.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Integration.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Logging.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Machine Studio\Debug\Tango.MachineStudio.Common.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.SharedUI.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Transport.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll" /> + </ItemGroup> + <ItemGroup> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.Storage\obj\Debug\App.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.Storage\obj\Debug\Views\MainView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\MachineStudio\Modules\Tango.MachineStudio.Storage\obj\Debug\GeneratedInternalTypeHelper.g.cs" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs index f6b8a35df..ac54a714a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs @@ -79,6 +79,9 @@ namespace Tango.MachineStudio.Technician.ViewModels private DateTime _last_time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0); private Machine _machine; private List<PackColor> _packsColors; + private int _diagnostics_index = 0; + private DateTime _diagnosticsStartTime; + private DateTime _diagnosticsNowTime; #region Properties @@ -411,7 +414,7 @@ namespace Tango.MachineStudio.Technician.ViewModels PackColor pc = new PackColor(); pc.Index = pack.PackIndex; pc.Name = pack.LiquidType.Name; - + if (pack.LiquidType.LiquidTypeColor == Colors.Black) { pc.Color = Colors.Gray; @@ -456,13 +459,30 @@ namespace Tango.MachineStudio.Technician.ViewModels /// <param name="data">The data.</param> private void PopulateDiagnosticsData(StartDiagnosticsResponse data) { - if (data.Monitors == null) return; + if (data.Monitors == null || _machineOperator == null || _machineOperator.DeviceInformation == null) return; + + _diagnostics_index++; + uint interval = _machineOperator.DeviceInformation.DiagnosticsInterval; TimeSpan delta_base = DateTime.Now - _start_time; TimeSpan delta = (DateTime.Now - _last_time); - double delta_mili = delta.TotalMilliseconds; _last_time = DateTime.Now; + if (data.ElapsedMilli > 0) + { + _diagnosticsNowTime = DateTime.ParseExact(data.DateTime, "MM/dd/yyyy HH:mm:ss.fff", null); //_diagnosticsNowTime.Add(TimeSpan.FromMilliseconds(data.ElapsedMilli)); + //var now = _diagnosticsStartTime.Add(TimeSpan.FromMilliseconds(interval * _diagnostics_index)); + //Debug.WriteLine("DeltaBase Before: " + delta_base); + delta_base = _diagnosticsNowTime - _start_time; + //Debug.WriteLine("DeltaBase After: " + delta_base); + + //Debug.WriteLine("Delta Before: " + delta); + delta = TimeSpan.FromMilliseconds(data.ElapsedMilli); + //Debug.WriteLine("Delta After: " + delta); + } + + double delta_mili = delta.TotalMilliseconds; + if (DateTime.Now > _lastDiagnosticsResponseUpdate.AddMilliseconds(MIN_DIAGNOSTICS_UPDATE_MILI)) { CurrentDiagnosticsResponse = data; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png Binary files differnew file mode 100644 index 000000000..9f7d0b9ba --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj index 82376b751..035cb2b9d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj @@ -49,6 +49,9 @@ <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="SimpleValidator, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> @@ -80,6 +83,7 @@ <Compile Include="UsersAndRolesModule.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="ViewModels\UserCreationDialogVM.cs" /> <Compile Include="Views\AddressView.xaml.cs"> <DependentUpon>AddressView.xaml</DependentUpon> </Compile> @@ -95,6 +99,9 @@ <Compile Include="Views\OrganizationSelectionView.xaml.cs"> <DependentUpon>OrganizationSelectionView.xaml</DependentUpon> </Compile> + <Compile Include="Views\UserCreationDialog.xaml.cs"> + <DependentUpon>UserCreationDialog.xaml</DependentUpon> + </Compile> <Compile Include="Views\UserManagementView.xaml.cs"> <DependentUpon>UserManagementView.xaml</DependentUpon> </Compile> @@ -120,7 +127,9 @@ <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> - <None Include="app.config" /> + <None Include="app.config"> + <SubType>Designer</SubType> + </None> <None Include="packages.config" /> <None Include="Properties\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> @@ -186,6 +195,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\UserCreationDialog.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\UserManagementView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -210,11 +223,13 @@ <ItemGroup> <Resource Include="Images\roles.png" /> </ItemGroup> - <ItemGroup /> + <ItemGroup> + <Resource Include="Images\login.png" /> + </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> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs index a46d5f456..81ef04dd4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs @@ -15,6 +15,10 @@ using Tango.MachineStudio.UsersAndRoles.Providers; using Tango.SharedUI; using System.Data.Entity; using Tango.BL.Builders; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; +using Tango.BL.Enumerations; +using Tango.MachineStudio.Common.Authentication; namespace Tango.MachineStudio.UsersAndRoles.ViewModels { @@ -25,6 +29,10 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels private ObservablesContext _userContext; private UsersAndRolesNavigationManager _navigation; private INotificationProvider _notification; + private IActionLogManager _actionLogManager; + private OrganizationDTO _organizationBeforeSave; + private IAuthenticationProvider _authenticationProvider; + private UserDTO _userBeforeSave; private ObservableCollection<Organization> _organizations; public ObservableCollection<Organization> Organizations @@ -105,6 +113,21 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels } } + private bool _showDeleted; + public bool ShowDeleted + { + get { return _showDeleted; } + set + { + _showDeleted = value; + if (_showDeleted) + { + //ShowDeletedUsers(); + } + } + } + + public RelayCommand ManageOrganizationCommand { get; set; } public RelayCommand BackToOrganizationsCommand { get; set; } @@ -123,14 +146,18 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels public RelayCommand SaveManagedUserCommand { get; set; } + public RelayCommand RestoreAndSaveManagedUserCommand { get; set; } + public RelayCommand AddUserCommand { get; set; } public RelayCommand RemoveUserCommand { get; set; } - public MainViewVM(UsersAndRolesNavigationManager navigation, INotificationProvider notification) + public MainViewVM(UsersAndRolesNavigationManager navigation, INotificationProvider notification, IActionLogManager actionLogManager, IAuthenticationProvider authenticationProvider) { _navigation = navigation; _notification = notification; + _actionLogManager = actionLogManager; + _authenticationProvider = authenticationProvider; ManageOrganizationCommand = new RelayCommand(LoadSelectedOrganization, () => SelectedOrganization != null); BackToOrganizationsCommand = new RelayCommand(BackToOrganizations); @@ -141,8 +168,10 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels BackToManagedOrganizationCommand = new RelayCommand(BackToManagedOrganization); RemoveRoleCommand = new RelayCommand<Role>(RemoveUserRole); SaveManagedUserCommand = new RelayCommand(SaveManagedUser); + RestoreAndSaveManagedUserCommand = new RelayCommand(RestoreAndSaveManagedUser); AddUserCommand = new RelayCommand(AddNewUser); RemoveUserCommand = new RelayCommand(RemoveSelectedUser, () => SelectedUser != null); + _showDeleted = false; } public override void OnApplicationReady() @@ -164,6 +193,7 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels org.Contact = new Contact(); _organizationsContext.Organizations.Add(org); await org.SaveAsync(_organizationsContext); + _actionLogManager.InsertLog(ActionLogType.OrganizationCreated, _authenticationProvider.CurrentUser, org.Name, org, "Organization created using Machine Studio."); Organizations = _organizationsContext.Organizations.ToObservableCollection(); SelectedOrganization = org; LoadSelectedOrganization(); @@ -178,6 +208,7 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels using (_notification.PushTaskItem("Removing organization...")) { await SelectedOrganization.DeleteCascadeAsync(_organizationsContext); + _actionLogManager.InsertLog(ActionLogType.OrganizationDeleted, _authenticationProvider.CurrentUser, SelectedOrganization.Name, SelectedOrganization, "Organization deleted using Machine Studio."); await LoadOrganizations(); } } @@ -187,7 +218,13 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels { using (_notification.PushTaskItem("Saving organization address and contact...")) { + var organizationAfter = OrganizationDTO.FromObservable(ManagedOrganization); + await ManagedOrganization.SaveAsync(_manageContext); + _actionLogManager.InsertLog(ActionLogType.OrganizationSaved, _authenticationProvider.CurrentUser, ManagedOrganization.Name, _organizationBeforeSave, organizationAfter, "Organization saved using Machine Studio."); + + _organizationBeforeSave = organizationAfter; + await LoadOrganizations(); SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == ManagedOrganization.Guid); } @@ -202,8 +239,10 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels _userContext = ObservablesContext.CreateDefault(); Roles = new RolesCollectionBuilder(_userContext).SetAll().WithPermission().Build(); - ManagedUser = new UserBuilder(_userContext).Set(SelectedUser.Guid).WithRolesAndPermissions().Build(); + ManagedUser = new UserBuilder(_userContext).WithDeleted().Set(SelectedUser.Guid).WithRolesAndPermissions().Build(); ManagedUserRoles = ManagedUser.Roles.ToObservableCollection(); + + _userBeforeSave = UserDTO.FromObservable(ManagedUser); }); _navigation.NavigateTo(UsersAndRolesNavigationView.UserManagementView); @@ -244,11 +283,40 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels using (_notification.PushTaskItem("Saving user details...")) { + var userAfter = UserDTO.FromObservable(ManagedUser); await ManagedUser.SaveAsync(_userContext); + _actionLogManager.InsertLog(ActionLogType.UserSaved, _authenticationProvider.CurrentUser, ManagedUser.Email, _userBeforeSave, userAfter, "User saved using Machine Studio."); + _userBeforeSave = userAfter; LoadSelectedOrganization(); } } + private async void RestoreAndSaveManagedUser() + { + try + { + ManagedUser.Validate(_userContext); + } + catch (Exception ex) + { + _notification.ShowError(ex.Message); + return; + } + if (_notification.ShowQuestion("Are you sure you wish to re-activate this account?")) + { + using (_notification.PushTaskItem("Saving user details...")) + { + ManagedUser.Deleted = false; + + var userAfter = UserDTO.FromObservable(ManagedUser); + await ManagedUser.SaveAsync(_userContext); + _actionLogManager.InsertLog(ActionLogType.UserRestored, _authenticationProvider.CurrentUser, ManagedUser.Email, _userBeforeSave, userAfter, "User restored using Machine Studio."); + _userBeforeSave = userAfter; + LoadSelectedOrganization(); + } + } + } + private async void LoadSelectedOrganization() { using (_notification.PushTaskItem("Loading organization...")) @@ -257,7 +325,9 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels { _manageContext = ObservablesContext.CreateDefault(); - ManagedOrganization = new OrganizationBuilder(_manageContext).Set(SelectedOrganization.Guid).WithUsers().Build(); + ManagedOrganization = new OrganizationBuilder(_manageContext).Set(SelectedOrganization.Guid).WithUsers(true).Build(); + + _organizationBeforeSave = OrganizationDTO.FromObservable(ManagedOrganization); }); _navigation.NavigateTo(UsersAndRolesNavigationView.OrganizationManagementView); @@ -294,25 +364,25 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels using (_notification.PushTaskItem("Removing user...")) { await SelectedUser.DeleteCascadeAsync(_manageContext); + _actionLogManager.InsertLog(ActionLogType.UserDeleted, _authenticationProvider.CurrentUser, SelectedUser.Email, SelectedUser, "User deleted using Machine Studio."); LoadSelectedOrganization(); } } } - private async void AddNewUser() + private void AddNewUser() { - String email = _notification.ShowTextInput("Enter user email", "email"); - - if (!String.IsNullOrWhiteSpace(email)) + _notification.ShowModalDialog<UserCreationDialogVM>(async (vm) => { User user = new User(); - user.Email = email; - user.Password = "1111"; + user.Email = vm.Email; + user.Password = User.GetPasswordHash(vm.Password); + user.PasswordChangeRequired = true; user.Contact = new Contact() { - FirstName = "Twine", - LastName = "User", - Email = email, + FirstName = vm.FirstName, + LastName = vm.LastName, + Email = vm.Email, }; user.Address = new Address(); @@ -323,6 +393,18 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.User) }); + user.UsersRoles.Add(new UsersRole() + { + User = user, + Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.MachineStudioUser) + }); + + user.UsersRoles.Add(new UsersRole() + { + User = user, + Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.PPCUser) + }); + try { user.Validate(_manageContext); @@ -338,10 +420,11 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels using (_notification.PushTaskItem("Adding new user...")) { await ManagedOrganization.SaveAsync(_manageContext); + _actionLogManager.InsertLog(ActionLogType.UserCreated, _authenticationProvider.CurrentUser, user.Email, user, "User created using Machine Studio."); await LoadOrganizations(); SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == ManagedOrganization.Guid); } - } + }); } private void SetUserPlace(Place place) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs new file mode 100644 index 000000000..08762ac96 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SimpleValidator.Extensions; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UsersAndRoles.ViewModels +{ + public class UserCreationDialogVM : DialogViewVM + { + private static Random rnd = new Random(); + + private String _email; + [Required(ErrorMessage = "Email is required")] + [EmailAddress(ErrorMessage = "Please provide a valid 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(); } + } + + private String _firstName; + [Required(ErrorMessage = "First name is required")] + public String FirstName + { + get { return _firstName; } + set { _firstName = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _lastName; + [Required(ErrorMessage = "Last name is required")] + public String LastName + { + get { return _lastName; } + set { _lastName = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + protected override void Accept() + { + if (Validate()) + { + base.Accept(); + } + } + + public override void OnShow() + { + base.OnShow(); + Password = GetRandomPassword(4); + } + + private String GetRandomPassword(int count) + { + String pass = String.Empty; + + for (int i = 0; i < count; i++) + { + pass += rnd.Next(0, 9).ToString(); + } + + return pass; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/OrganizationManagementView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/OrganizationManagementView.xaml index d5a5d41d7..1572923a6 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/OrganizationManagementView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/OrganizationManagementView.xaml @@ -82,6 +82,10 @@ </Button> </StackPanel> </Grid> + <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" VerticalAlignment="Center" Margin="0 10 0 5" HorizontalAlignment="Left"> + <CheckBox Name="cbShowDeleted" IsChecked="{Binding ShowDeleted}" VerticalAlignment="Center"></CheckBox> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" Text="Show deleted" FontSize="16" FontWeight="Normal"></TextBlock> + </StackPanel> <Grid DockPanel.Dock="Bottom"> <StackPanel VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0 0 0 0"> <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="{StaticResource RedBrush300}" BorderBrush="{StaticResource RedBrush300}" Command="{Binding RemoveUserCommand}"> @@ -113,6 +117,28 @@ <Setter Property="BorderThickness" Value="0"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Setter Property="Visibility" Value="Visible" /> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding ElementName=cbShowDeleted, Path=IsChecked}" Value="False"/> + <Condition Binding="{Binding Deleted}" Value="True"/> + </MultiDataTrigger.Conditions> + <MultiDataTrigger.Setters> + <Setter Property="Visibility" Value="Collapsed" /> + </MultiDataTrigger.Setters> + </MultiDataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding ElementName=cbShowDeleted, Path=IsChecked}" Value="true"/> + <Condition Binding="{Binding Deleted}" Value="True"/> + </MultiDataTrigger.Conditions> + <MultiDataTrigger.Setters> + <Setter Property="Visibility" Value="Visible" /> + <Setter Property="Foreground" Value="{StaticResource RedBrush100}" /> + </MultiDataTrigger.Setters> + </MultiDataTrigger> + </Style.Triggers> </Style> </DataGrid.CellStyle> <DataGrid.Columns> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml new file mode 100644 index 000000000..7433d3768 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml @@ -0,0 +1,53 @@ +<UserControl x:Class="Tango.MachineStudio.UsersAndRoles.Views.UserCreationDialog" + 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:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:global="clr-namespace:Tango.MachineStudio.UsersAndRoles" + xmlns:vm="clr-namespace:Tango.MachineStudio.UsersAndRoles.ViewModels" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.MachineStudio.UsersAndRoles.Views" + mc:Ignorable="d" + d:DesignHeight="400" d:DesignWidth="700" Height="400" Width="700" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:UserCreationDialogVM, IsDesignTimeCreatable=False}"> + <Grid Margin="10"> + <DockPanel> + <Grid DockPanel.Dock="Top"> + <StackPanel Orientation="Horizontal"> + <Grid> + <Image Source="../Images/login.png" Width="80" RenderOptions.BitmapScalingMode="Fant"></Image> + <materialDesign:PackIcon HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 -14 -10" Kind="PlusCircle" Foreground="#15C315" Width="42" Height="42" /> + </Grid> + <TextBlock Margin="30 0 0 0" VerticalAlignment="Bottom" FontSize="22">NEW USER</TextBlock> + </StackPanel> + </Grid> + + <Grid DockPanel.Dock="Bottom"> + <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" DockPanel.Dock="Bottom"> + <Button Command="{Binding CloseCommand}" Width="140" Height="40" Margin="0 0 10 0"> + CANCEL + </Button> + <Button Command="{Binding OKCommand}" IsDefault="True" Width="140" Height="40"> + CREATE + </Button> + </StackPanel> + </Grid> + + <Grid> + <StackPanel Width="400" HorizontalAlignment="Center" Margin="20"> + <controls:TableGrid RowHeight="40"> + <TextBlock>EMAIL</TextBlock> + <TextBox Text="{Binding Email,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + <TextBlock>FIRST NAME</TextBlock> + <TextBox Text="{Binding FirstName,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + <TextBlock>LAST NAME</TextBlock> + <TextBox Text="{Binding LastName,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox> + </controls:TableGrid> + + <TextBox Margin="0 -15 0 0" Style="{x:Null}" BorderThickness="0" FontSize="30" HorizontalAlignment="Center" Text="{Binding Password}" IsReadOnly="True"></TextBox> + <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource GrayBrush}">Provide this password to the user</TextBlock> + </StackPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs new file mode 100644 index 000000000..cfa389ed1 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.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.MachineStudio.UsersAndRoles.Views +{ + /// <summary> + /// Interaction logic for UserCreationDialog.xaml + /// </summary> + public partial class UserCreationDialog : UserControl + { + public UserCreationDialog() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml index bb003f525..3964abfc8 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml @@ -19,6 +19,8 @@ <UserControl.Resources> <providers:PlacesProvider x:Key="PlacesProvider" /> + <converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"></converters:BooleanToVisibilityConverter> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"></converters:BooleanToVisibilityInverseConverter> </UserControl.Resources> <Grid> @@ -48,7 +50,7 @@ <StackPanel> <TextBlock FontSize="16" FontWeight="SemiBold">LOGIN</TextBlock> <Border Width="300" BorderThickness="1" BorderBrush="Gray" Margin="0 5 0 0" Padding="15 5" Height="150" Background="{StaticResource TransparentBackgroundBrush500}"> - <local:UserView FontSize="10" DataContext="{Binding ManagedUser}" /> + <local:UserView VerticalAlignment="Top" Margin="0 15 0 0" FontSize="10" DataContext="{Binding ManagedUser}" /> </Border> </StackPanel> <StackPanel Margin="10 0 0 0"> @@ -74,12 +76,18 @@ </Grid> </Grid> <Grid DockPanel.Dock="Bottom"> - <Button Margin="0 10 0 0" MinWidth="200" Height="60" Command="{Binding SaveManagedUserCommand}" HorizontalAlignment="Right"> + <Button Margin="0 10 0 0" MinWidth="200" Height="60" Command="{Binding SaveManagedUserCommand}" HorizontalAlignment="Right" Visibility="{Binding Path=ManagedUser.Deleted, Converter={StaticResource BooleanToVisibilityInverseConverter}}"> <StackPanel Orientation="Horizontal"> <TextBlock FontSize="18" VerticalAlignment="Center">SAVE</TextBlock> <materialDesign:PackIcon Margin="5 0 0 0" Kind="ContentSave" Width="30" Height="30" /> </StackPanel> </Button> + <Button Margin="0 10 0 0" MinWidth="200" Height="60" Background="{StaticResource OrangeBrush300}" BorderBrush="{StaticResource OrangeBrush300}" Command="{Binding RestoreAndSaveManagedUserCommand}" HorizontalAlignment="Right" Visibility="{Binding Path=ManagedUser.Deleted, Converter={StaticResource BoolToVisibilityConverter}}"> + <StackPanel Orientation="Horizontal"> + <TextBlock FontSize="18" VerticalAlignment="Center" Text="RESTORE & SAVE"/> + <materialDesign:PackIcon Margin="5 0 0 0" Kind="ContentSave" Width="30" Height="30" /> + </StackPanel> + </Button> </Grid> <Grid> <DockPanel Margin="0 20 0 0"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml index 0858d7e08..37f649a7a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml @@ -16,8 +16,6 @@ <controls:TableGrid> <TextBlock Text="EMAIL"></TextBlock> <TextBox Text="{Binding Email}"></TextBox> - <TextBlock Text="PASSWORD"></TextBlock> - <PasswordBox MaxLength="30" pass:PasswordHelper.Attach="True" pass:PasswordHelper.Password="{Binding PasswordGateWay,Mode=TwoWay}"></PasswordBox> </controls:TableGrid> </Grid> </UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config index fe4f26e87..8696cb880 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config @@ -7,4 +7,5 @@ <package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" /> <package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" /> <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> + <package id="SimpleValidator" version="0.6.1.0" targetFramework="net461" /> </packages>
\ No newline at end of file |
