aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2018-04-25 18:30:00 +0300
committerRoy Ben-Shabat <Roy@Twine-s.com>2018-04-25 18:30:00 +0300
commit2c60f9390e0553dd5a608a7e5b30d69d54d4c763 (patch)
treec251afbab85f1276424826e4595319c19241893f /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
parenta89077bae848d010ae70da6be572dee3b824a895 (diff)
downloadTango-2c60f9390e0553dd5a608a7e5b30d69d54d4c763.tar.gz
Tango-2c60f9390e0553dd5a608a7e5b30d69d54d4c763.zip
Issue reporting.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.pngbin0 -> 6496 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml16
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs95
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs10
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs68
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs61
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml34
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml110
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml82
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs28
13 files changed, 465 insertions, 52 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png
new file mode 100644
index 000000000..e49f62923
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
index eb9ef8012..e5e8b2d67 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
@@ -15,5 +15,7 @@ namespace Tango.MachineStudio.UI.TFS
public String HostName { get; set; }
public Machine Machine { get; set; }
public String ConfigurationString { get; set; }
+ public String HardwareString { get; set; }
+ public String LoadedProcessParametersString { get; set; }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
index 7b0c4a896..698932d46 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
@@ -62,9 +62,23 @@
<div style="font-size:20pt;text-decoration:underline;margin-top:10px">Configuration</div>
<div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.ConfigurationString</div>
+
+ <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Hardware Version</div>
+ <div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.HardwareString</div>
+
+ <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Process Parameters</div>
+
+ if (vm.LoadedProcessParametersString != null)
+ {
+ <div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.LoadedProcessParametersString</div>
+ }
+ else
+ {
+ <div style="color:Red;margin-top:10px">NOT SET</div>
+ }
}
else
{
- <div style="color:Red;margin-top:10px">Not Connected</div>
+ <div style="color:Red;margin-top:10px">NOT CONNECTED</div>
}
</div> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
index 27b257e61..0a8cbd60d 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Tango.BL.Entities;
@@ -21,6 +23,13 @@ namespace Tango.MachineStudio.UI.TFS
{
public Project Project { get; private set; }
+ private ObservableCollection<WorkItem> _resolvedWorkItems;
+ public ObservableCollection<WorkItem> ResolvedWorkItems
+ {
+ get { return _resolvedWorkItems; }
+ set { _resolvedWorkItems = value; RaisePropertyChangedAuto(); }
+ }
+
private bool _isInitialized;
public bool IsInitialized
{
@@ -30,7 +39,20 @@ namespace Tango.MachineStudio.UI.TFS
public TeamFoundationServiceExtendedClient(string collectionURL, string userName, string personalToken) : base(collectionURL, userName, personalToken)
{
+ ResolvedWorkItems = new ObservableCollection<WorkItem>();
+ TangoIOC.Default.GetInstance<IAuthenticationProvider>().CurrentUserChanged += TeamFoundationServiceExtendedClient_CurrentUserChanged;
+ }
+ private void TeamFoundationServiceExtendedClient_CurrentUserChanged(object sender, User user)
+ {
+ if (user != null)
+ {
+ Task.Factory.StartNew(async () =>
+ {
+ Thread.Sleep(5000);
+ await UpdateCurrentUserResolvedWorkItems();
+ });
+ }
}
public Task<WorkItem> UploadWorkItem(WorkItem workItem)
@@ -38,14 +60,52 @@ namespace Tango.MachineStudio.UI.TFS
return UploadWorkItem(Project, workItem);
}
+ public async Task UpdateCurrentUserResolvedWorkItems()
+ {
+ try
+ {
+ IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();
+ var items = await GetWorkItemsCreatedBy(Project, GetUserTeamMember());
+ items.Where(x => x.StepsToReproduce != null).ToList().ForEach(x => x.StepsToReproduce = x.StepsToReproduce.Replace("<div style=\"white-space:pre;\">", "").Replace("</div>", ""));
+ ResolvedWorkItems = items.Where(x => x.State == State.Resolved && x.IsBuildVersionValid && x.FoundInBuildVersion < Version.Parse(app.Version)).ToObservableCollection();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error getting the current user resolved work items.");
+ }
+ }
+
+ public async Task<WorkItem> CloseWorkItem(WorkItem workItem)
+ {
+ await SetWorkItemState(Project, workItem, State.Closed);
+ var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been verified and closed by " + GetUserTeamMember().DisplayName + " (via Tango Software).");
+ ResolvedWorkItems.Remove(workItem);
+ return updated;
+ }
+
+ public async Task<WorkItem> ReactivateWorkItem(WorkItem workItem)
+ {
+ await SetWorkItemState(Project, workItem, State.New);
+ var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been reactivated by " + GetUserTeamMember().DisplayName + " (via Tango Software).");
+ ResolvedWorkItems.Remove(workItem);
+ return updated;
+ }
+
public void Initialize()
{
Task.Factory.StartNew(() =>
{
if (!IsInitialized)
{
- Project = GetProject("Tango").Result;
- IsInitialized = true;
+ try
+ {
+ Project = GetProject("Tango").Result;
+ IsInitialized = true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error initializing the Team Foundation Service client.");
+ }
}
});
}
@@ -60,7 +120,7 @@ namespace Tango.MachineStudio.UI.TFS
item.Area = Project.Areas.FirstOrDefault();
item.Iteration = Project.Iterations.FirstOrDefault();
- TeamMember currentUser = Project.Members.SingleOrDefault(x => x.UniqueName.ToLower().Contains(auth.CurrentUser.Email.ToLower()));
+ TeamMember currentUser = GetUserTeamMember();
item.CreatedBy = currentUser;
item.ChangedBy = currentUser;
item.AuthorizedAs = currentUser;
@@ -82,6 +142,14 @@ namespace Tango.MachineStudio.UI.TFS
Name = "Screen Capture.jpg",
});
+ return item;
+ }
+
+ public void FinalizeBug(WorkItem item)
+ {
+ IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
+ IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();
+
FileLogger appFileLogger = LogManager.Default.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
FileLogger embeddedFileLogger = MachineOperator.EmbeddedLogManager.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
@@ -126,13 +194,13 @@ namespace Tango.MachineStudio.UI.TFS
MachineDesigner.Views.MainView machineView = new MachineDesigner.Views.MainView();
machineView.Width = 1280;
machineView.Height = 1100;
- machineView.PanelColumnDefinition.Width = new System.Windows.GridLength(0);
+ machineView.PanelColumnDefinition.Width = new GridLength(0);
machineView.stackHeader.Visibility = Visibility.Collapsed;
machineView.Background = System.Windows.Media.Brushes.White;
machineView.DataContext = new MachineDesigner.ViewModels.MainViewVM() { SelectedMachine = machine, Configuration = machine.Configuration };
String configImageFile = PathHelper.GetTempFilePath();
- machineView.RenderToFile(configImageFile, System.Drawing.Imaging.ImageFormat.Jpeg, new System.Windows.Size(machineView.Width, machineView.Height), 100);
+ machineView.RenderToFile(configImageFile, System.Drawing.Imaging.ImageFormat.Jpeg, new Size(machineView.Width, machineView.Height), 100);
item.Attachments.Add(new Attachment()
{
@@ -141,7 +209,13 @@ namespace Tango.MachineStudio.UI.TFS
Name = "Machine Configuration.jpg"
});
- sysModel.ConfigurationString = machine.Configuration.CloneConfiguration().ToJsonString();
+ sysModel.ConfigurationString = machine.Configuration.CloneConfiguration().ToJsonString(nameof(Configuration.MachinesConfigurations), nameof(Configuration.MachineVersions));
+ sysModel.HardwareString = machine.Configuration.HardwareVersion.ToJsonString(nameof(HardwareVersion.Configurations));
+
+ if (app.ConnectedMachine.CurrentProcessParameters != null)
+ {
+ sysModel.LoadedProcessParametersString = app.ConnectedMachine.CurrentProcessParameters.ToJsonString(nameof(ProcessParametersTable.ProcessParametersTablesGroup));
+ }
}
String html = String.Empty;
@@ -154,7 +228,14 @@ namespace Tango.MachineStudio.UI.TFS
item.SystemInformation = CodeGeneration.Helper.Parse(html, sysModel);
- return item;
+ item.StepsToReproduce = String.Format("<div style=\"white-space:pre\">{0}</div>", item.StepsToReproduce);
+ }
+
+ private TeamMember GetUserTeamMember()
+ {
+ IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
+ TeamMember currentUser = Project.Members.SingleOrDefault(x => x.UniqueName.ToLower().Contains(auth.CurrentUser.Email.ToLower()));
+ return currentUser;
}
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
index 1418d0576..3e85f91b4 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
@@ -16,13 +16,19 @@ namespace Tango.MachineStudio.UI.TFS
if (String.IsNullOrWhiteSpace(item.Title))
{
- ErrorMessage = "Title is empty";
+ ErrorMessage = "Title is required.";
return false;
}
if (item.AssignedTo == null)
{
- ErrorMessage = "Assigned To is empty";
+ ErrorMessage = "Assigned To field is required.";
+ return false;
+ }
+
+ if (String.IsNullOrWhiteSpace(item.StepsToReproduce))
+ {
+ ErrorMessage = "Please enter steps to reproduce.";
return false;
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
index 8ab6bb188..c6afdca4b 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
@@ -161,6 +161,7 @@
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\ModuleWindowVM.cs" />
<Compile Include="ViewModels\ReportIssueViewVM.cs" />
+ <Compile Include="ViewModels\ResolvedIssuesViewVM.cs" />
<Compile Include="ViewModels\ShutdownViewVM.cs" />
<Compile Include="ViewModels\UpdateViewVM.cs" />
<Compile Include="Views\ConnectedMachineView.xaml.cs">
@@ -190,6 +191,9 @@
<Compile Include="Views\ReportIssueView.xaml.cs">
<DependentUpon>ReportIssueView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\ResolvedIssuesView.xaml.cs">
+ <DependentUpon>ResolvedIssuesView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\ShutdownView.xaml.cs">
<DependentUpon>ShutdownView.xaml</DependentUpon>
</Compile>
@@ -270,6 +274,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\ResolvedIssuesView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\ShutdownView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -460,6 +468,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Html\HTML Templates\Thread Break.html" />
+ <Resource Include="Images\bug-resolved.png" />
<EmbeddedResource Include="TFS\SystemInformationTemplate.cshtml" />
<Resource Include="Images\bug.png" />
</ItemGroup>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
index 8e6f11452..8d3a2c6bf 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
@@ -64,7 +64,6 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Unregister<IHtmlPresenter>();
TangoIOC.Default.Unregister<ITeamFoundationServiceClient>();
- TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com/DefaultCollection", "Roy", "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa"));
TangoIOC.Default.Register<INotificationProvider, DefaultNotificationProvider>();
TangoIOC.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>();
TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>();
@@ -76,6 +75,7 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Register<IEventLogger, DefaultEventLogger>();
TangoIOC.Default.Register<ISpeechProvider, DefaultSpeechProvider>();
TangoIOC.Default.Register<IHtmlPresenter, DefaultHtmlPresenter>();
+ TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com/DefaultCollection", "Roy", "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa"));
TangoIOC.Default.Register<MainViewVM>();
TangoIOC.Default.Register<LoadingViewVM>();
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
index 0882267e8..4c41c7860 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
@@ -148,6 +148,11 @@ namespace Tango.MachineStudio.UI.ViewModels
/// </summary>
public RelayCommand ReportIssueCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the open resolved bugs.
+ /// </summary>
+ public RelayCommand OpenResolvedBugsCommand { get; set; }
+
private IAuthenticationProvider _authenticationProvider;
/// <summary>
/// Gets or sets the authentication provider.
@@ -302,6 +307,7 @@ namespace Tango.MachineStudio.UI.ViewModels
ResolveMachineEventCommand = new RelayCommand<MachinesEvent>(ResolveMachineEvent);
ReportIssueCommand = new RelayCommand(ReportIssue);
+ OpenResolvedBugsCommand = new RelayCommand(OpenResolvedBugs);
}
private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable<MachinesEvent> e)
@@ -649,10 +655,70 @@ namespace Tango.MachineStudio.UI.ViewModels
{
using (_notificationProvider.PushTaskItem("Uploading bug report..."))
{
- await TFSClient.UploadWorkItem(vm.WorkItem);
+ try
+ {
+ TFSClient.FinalizeBug(vm.WorkItem);
+ await TFSClient.UploadWorkItem(vm.WorkItem);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to create the issue." + Environment.NewLine + ex.Message);
+ }
}
}, null);
}
+
+ private void OpenResolvedBugs()
+ {
+ ResolvedIssuesViewVM vm = null;
+
+ vm = new ResolvedIssuesViewVM(TFSClient, async (item) =>
+ {
+ //Approve
+ using (_notificationProvider.PushTaskItem("Approving issue..."))
+ {
+ vm.IsAvailable = false;
+ try
+ {
+ await TFSClient.CloseWorkItem(item);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to update the issue." + Environment.NewLine + ex.Message);
+ }
+ vm.IsAvailable = true;
+
+ if (TFSClient.ResolvedWorkItems.Count == 0)
+ {
+ vm.Close();
+ }
+ }
+ }, async (item) =>
+ {
+ //Decline
+ using (_notificationProvider.PushTaskItem("Reactivating issue..."))
+ {
+ vm.IsAvailable = false;
+ try
+ {
+ await TFSClient.ReactivateWorkItem(item);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to update the issue." + Environment.NewLine + ex.Message);
+ }
+
+ vm.IsAvailable = true;
+
+ if (TFSClient.ResolvedWorkItems.Count == 0)
+ {
+ vm.Close();
+ }
+ }
+ });
+
+ _notificationProvider.ShowModalDialog<ResolvedIssuesViewVM, ResolvedIssuesView>(vm, (_) => { }, null);
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs
new file mode 100644
index 000000000..552880792
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.UI.TFS;
+using Tango.TFS;
+
+namespace Tango.MachineStudio.UI.ViewModels
+{
+ public class ResolvedIssuesViewVM : DialogViewVM
+ {
+ private Action<WorkItem> _onApprove;
+ private Action<WorkItem> _onDecline;
+
+ public TeamFoundationServiceExtendedClient TFSClient { get; set; }
+
+ public RelayCommand<WorkItem> ApproveCommand { get; set; }
+
+ public RelayCommand<WorkItem> DeclineCommand { get; set; }
+
+ private bool _isAvailable;
+
+ public bool IsAvailable
+ {
+ get { return _isAvailable; }
+ set { _isAvailable = value; RaisePropertyChangedAuto(); }
+ }
+
+ public ResolvedIssuesViewVM() : base()
+ {
+ IsAvailable = true;
+ ApproveCommand = new RelayCommand<WorkItem>(ApproveIssue);
+ DeclineCommand = new RelayCommand<WorkItem>(DeclineIssue);
+ }
+
+ public ResolvedIssuesViewVM(TeamFoundationServiceExtendedClient tfsClient, Action<WorkItem> onApprove, Action<WorkItem> onDecline) : this()
+ {
+ TFSClient = tfsClient;
+ _onApprove = onApprove;
+ _onDecline = onDecline;
+ }
+
+ private void DeclineIssue(WorkItem workItem)
+ {
+ _onDecline(workItem);
+ }
+
+ private void ApproveIssue(WorkItem workItem)
+ {
+ _onApprove(workItem);
+ }
+
+ public void Close()
+ {
+ Accept();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
index 86723479b..bb46814b5 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
@@ -320,7 +320,7 @@
<Button Cursor="Hand" Command="{Binding ReportIssueCommand}" IsEnabled="{Binding TFSClient.IsInitialized}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource emptyButton}">
- <Setter Property="ToolTip" Value="Report and issue"></Setter>
+ <Setter Property="ToolTip" Value="Report issue"></Setter>
<Setter Property="Opacity" Value="1"></Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
@@ -332,6 +332,38 @@
</Button.Style>
<Image Margin="10 0 0 0" Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant" />
</Button>
+ <Button Cursor="Hand" Command="{Binding OpenResolvedBugsCommand}">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource emptyButton}">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="Loaded">
+ <EventTrigger.Actions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Duration="00:00:01" RepeatBehavior="Forever">
+ <DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1" />
+ <DiscreteDoubleKeyFrame KeyTime="00:00:0.5" Value="0" />
+ </DoubleAnimationUsingKeyFrames>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ <DataTrigger Binding="{Binding TFSClient.ResolvedWorkItems.Count}" Value="0">
+ <Setter Property="Visibility" Value="Collapsed"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ <Button.ToolTip>
+ <TextBlock>
+ <Run>There are</Run>
+ <Run Text="{Binding TFSClient.ResolvedWorkItems.Count,Mode=OneWay}"></Run>
+ <Run>issues waiting for your approval</Run>
+ </TextBlock>
+ </Button.ToolTip>
+ <Image Margin="10 0 0 0" Source="/Images/bug-resolved.png" Width="24" RenderOptions.BitmapScalingMode="Fant" />
+ </Button>
</StackPanel>
</Grid>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
index f2e3038b9..25d2f2996 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
@@ -12,7 +12,7 @@
xmlns:tfs="clr-namespace:Tango.TFS;assembly=Tango.TFS"
xmlns:tfss="clr-namespace:Tango.MachineStudio.UI.TFS"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
- mc:Ignorable="d" Width="530" Height="650" Background="White" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}">
+ mc:Ignorable="d" Width="530" Height="680" Background="White" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter" />
@@ -36,53 +36,85 @@
</Grid>
<Grid Grid.Row="1">
- <StackPanel>
- <TextBox materialDesign:HintAssist.Hint="Title" materialDesign:HintAssist.IsFloating="True" FontSize="16" Text="{Binding WorkItem.Title}"></TextBox>
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Top">
+ <DockPanel>
+ <materialDesign:PackIcon Kind="Pencil" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBox materialDesign:HintAssist.Hint="Title" materialDesign:HintAssist.IsFloating="True" FontSize="16" Text="{Binding WorkItem.Title}"></TextBox>
+ </DockPanel>
- <autoComplete:AutoCompleteTextBox Provider="{StaticResource TeamMembersProvider}" SelectedItem="{Binding WorkItem.AssignedTo,Mode=TwoWay}" DisplayMember="DisplayName" Margin="0 10 0 0" materialDesign:HintAssist.Hint="Assigned To" materialDesign:HintAssist.IsFloating="True"></autoComplete:AutoCompleteTextBox>
- <ComboBox Margin="0 10 0 0" materialDesign:HintAssist.Hint="Area" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Project.Areas}" SelectedItem="{Binding WorkItem.Area}" DisplayMemberPath="Name"></ComboBox>
- <ComboBox Margin="0 10 0 0" materialDesign:HintAssist.Hint="Severity" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Source={x:Type tfs:Severity},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding WorkItem.Severity}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="Account" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <autoComplete:AutoCompleteTextBox Provider="{StaticResource TeamMembersProvider}" SelectedItem="{Binding WorkItem.AssignedTo,Mode=TwoWay}" DisplayMember="DisplayName" materialDesign:HintAssist.Hint="Assigned To" materialDesign:HintAssist.IsFloating="True"></autoComplete:AutoCompleteTextBox>
+ </DockPanel>
- <TextBlock Margin="0 10 0 0">Tags</TextBlock>
- <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Height="120">
- <ItemsControl ItemsSource="{Binding SelectedTags}">
- <ItemsControl.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
- </ItemsPanelTemplate>
- </ItemsControl.ItemsPanel>
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <ToggleButton Style="{StaticResource emptyToggleButton}" IsChecked="{Binding IsSelected}" Cursor="Hand">
- <Border CornerRadius="5" Margin="0 5 5 5" Padding="5" BorderThickness="1" BorderBrush="DimGray">
- <Border.Style>
- <Style TargetType="Border">
- <Setter Property="Background" Value="Silver"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding IsSelected}" Value="True">
- <Setter Property="Background" Value="{StaticResource AccentColorBrush}"></Setter>
- <Setter Property="TextElement.Foreground" Value="White"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Border.Style>
- <TextBlock Text="{Binding Data.Name}" FontSize="11"></TextBlock>
- </Border>
- </ToggleButton>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
- </ScrollViewer>
- </StackPanel>
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="Star" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <ComboBox materialDesign:HintAssist.Hint="Area" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Project.Areas}" SelectedItem="{Binding WorkItem.Area}" DisplayMemberPath="Name"></ComboBox>
+ </DockPanel>
+
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="CommentAlertOutline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <ComboBox materialDesign:HintAssist.Hint="Severity" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Source={x:Type tfs:Severity},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding WorkItem.Severity}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ </DockPanel>
+
+ <DockPanel Margin="0 20 0 0">
+ <materialDesign:PackIcon Kind="Tag" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center"><Run>Tags</Run> <Run FontSize="10" Foreground="Gray">(highlight selected tags)</Run></TextBlock>
+ </DockPanel>
+ <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Height="120">
+ <ItemsControl ItemsSource="{Binding SelectedTags}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <ToggleButton Style="{StaticResource emptyToggleButton}" IsChecked="{Binding IsSelected}" Cursor="Hand">
+ <Border CornerRadius="5" Margin="0 5 5 5" Padding="5" BorderThickness="1" BorderBrush="DimGray">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="Background" Value="Silver"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsSelected}" Value="True">
+ <Setter Property="Background" Value="{StaticResource AccentColorBrush}"></Setter>
+ <Setter Property="TextElement.Foreground" Value="White"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <TextBlock Text="{Binding Data.Name}" FontSize="11"></TextBlock>
+ </Border>
+ </ToggleButton>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </StackPanel>
+
+ <Grid>
+ <DockPanel>
+ <DockPanel Margin="0 10 0 0" DockPanel.Dock="Top">
+ <materialDesign:PackIcon Kind="ChartTimeline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Steps To Reproduce</TextBlock>
+ </DockPanel>
+
+ <Grid>
+ <TextBox Margin="0 5 0 0" Style="{x:Null}" BorderBrush="Silver" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Text="{Binding WorkItem.StepsToReproduce}"></TextBox>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </DockPanel>
</Grid>
<Grid Grid.Row="2">
- <Button HorizontalAlignment="Right" Width="140" Command="{Binding OKCommand}">SUBMIT</Button>
+ <Button HorizontalAlignment="Right" Height="40" Width="140" Command="{Binding OKCommand}" Background="#FF6262" BorderBrush="#FF6262" IsDefault="True">SUBMIT</Button>
<ItemsControl ItemsSource="{Binding ValidationErrors}" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" Visibility="Visible">
<ItemsControl.ItemTemplate>
<DataTemplate>
- <TextBlock Foreground="#FF4C4C" Margin="0 2 0 0"><Run>*</Run> <Run Text="{Binding}"></Run></TextBlock>
+ <TextBlock Foreground="#FF4C4C" Margin="0 2 0 0"><Run>*</Run> <Run Text="{Binding Path=*,Mode=OneWay}"></Run></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
new file mode 100644
index 000000000..d70e57786
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
@@ -0,0 +1,82 @@
+<UserControl x:Class="Tango.MachineStudio.UI.Views.ResolvedIssuesView"
+ 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:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete"
+ xmlns:integration="clr-namespace:Tango.Integration.Services;assembly=Tango.Integration"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.UI.ViewModels"
+ xmlns:tfs="clr-namespace:Tango.TFS;assembly=Tango.TFS"
+ xmlns:tfss="clr-namespace:Tango.MachineStudio.UI.TFS"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
+ mc:Ignorable="d" Width="530" Height="580" Background="White" d:DataContext="{d:DesignInstance Type=vm:ResolvedIssuesViewVM, IsDesignTimeCreatable=False}">
+ <Grid>
+ <Grid IsEnabled="{Binding IsAvailable}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="90"/>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="200"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/bug-resolved.png" Width="48" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 0 0" FontSize="20">Resolved Issues</TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <ListBox x:Name="list" ItemsSource="{Binding TFSClient.ResolvedWorkItems}" HorizontalContentAlignment="Stretch">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Border BorderBrush="#E6E6E6" BorderThickness="0 0 0 1" Padding="5">
+ <DockPanel>
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <StackPanel Margin="5 0 0 0">
+ <TextBlock Text="{Binding Title}" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"></TextBlock>
+ <TextBlock Text="{Binding Comment,TargetNullValue='Comment',FallbackValue='Comment'}" Foreground="Gray" FontSize="10"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+
+ <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
+ <Button Background="#FF8282" BorderBrush="#FF8282" Padding="0" Width="90" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DeclineCommand}" CommandParameter="{Binding}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Kind="Close" />
+ <TextBlock Margin="10 0 0 0" FontSize="11" VerticalAlignment="Center">DECLINE</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Background="#91D66D" BorderBrush="#91D66D" Padding="0" Width="90" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ApproveCommand}" CommandParameter="{Binding}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Kind="Check" />
+ <TextBlock Margin="10 0 0 0" FontSize="11" VerticalAlignment="Center">APPROVE</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </DockPanel>
+ </Border>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+
+ <Grid Grid.Row="2">
+ <Border BorderBrush="#FFA5A5" BorderThickness="0 1 0 0" Margin="5">
+ <DockPanel>
+ <DockPanel Margin="0 10 0 0" DockPanel.Dock="Top">
+ <materialDesign:PackIcon Kind="ChartTimeline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center" FontSize="16">Steps To Reproduce</TextBlock>
+ </DockPanel>
+
+ <Grid>
+ <TextBox Margin="5 10 10 10" Style="{x:Null}" BorderThickness="0" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Text="{Binding ElementName=list,Path=SelectedItem.StepsToReproduce}" IsReadOnly="True"></TextBox>
+ </Grid>
+ </DockPanel>
+ </Border>
+ </Grid>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs
new file mode 100644
index 000000000..7825bf587
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.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.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for ResolvedBugsView.xaml
+ /// </summary>
+ public partial class ResolvedIssuesView : UserControl
+ {
+ public ResolvedIssuesView()
+ {
+ InitializeComponent();
+ }
+ }
+}