Add WPFUi to prevent stuck state

Add Range to TournamentService
Use DataTable to export CSV
DataTable can be ordered on Total
This commit is contained in:
2019-05-31 23:34:34 +02:00
parent 3d73071925
commit 21713fed69
7 changed files with 227 additions and 114 deletions

View File

@@ -21,13 +21,19 @@ namespace LaDOSE.Api.Controllers
_service = service;
}
[HttpGet("GetTournaments")]
public async Task<List<TournamentDTO>> GetChallonges()
//This may be a get , but i dont know what the RFC State for Get request with Body
//As i don't like to populate GET request with body this will be a post (and i think
//it will be easier to proxy.
[HttpPost("GetTournaments")]
public async Task<List<TournamentDTO>> GetChallonges([FromBody] TimeRangeDTO dto)
{
var tournaments = await _service.GetTournaments(DateTime.Now.AddMonths(-2), null);
if (dto.To.HasValue | dto.From.HasValue)
{
var tournaments = await _service.GetTournaments(dto.From, dto.To);
return AutoMapper.Mapper.Map<List<TournamentDTO>>(tournaments);
}
return null;
}

View File

@@ -0,0 +1,10 @@
using System;
namespace LaDOSE.DTO
{
public class TimeRangeDTO
{
public DateTime? From { get; set; }
public DateTime? To { get; set; }
}
}

View File

@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace LaDOSE.DesktopApp.Utils
{
@@ -14,5 +17,30 @@ namespace LaDOSE.DesktopApp.Utils
Application.Current.Dispatcher.BeginInvoke(action);
}
public static void Await(Action function,string message=null)
{
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
Task tsk = Task.Factory.StartNew(new Action(function));
tsk.ContinueWith(t =>
{
Application.Current.Dispatcher.Invoke(() =>
System.Windows.Input.Mouse.OverrideCursor = null);
MessageBox.Show(t.Exception.InnerException.Message);
},
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
tsk.ContinueWith(task =>
{
if (!string.IsNullOrEmpty(message))
MessageBox.Show(message);
Application.Current.Dispatcher.Invoke(() =>
System.Windows.Input.Mouse.OverrideCursor = null);
});
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using System.Windows.Forms;
using LaDOSE.DesktopApp.Utils;
@@ -22,12 +23,44 @@ namespace LaDOSE.DesktopApp.ViewModels
private RestService RestService { get; set; }
public TournamentResultViewModel(RestService restService)
#region Properties
private String _selectRegex;
public String SelectRegex
{
this.RestService = restService;
_selectedTournaments = new ObservableCollection<TournamentDTO>();
Tournaments = new List<TournamentDTO>();
get { return _selectRegex; }
set
{
_selectRegex = value;
NotifyOfPropertyChange(() => SelectRegex);
}
}
private DateTime _from;
public DateTime From
{
get { return _from; }
set
{
_from = value;
NotifyOfPropertyChange(() => From);
}
}
private DateTime _to;
public DateTime To
{
get { return _to; }
set
{
_to = value;
NotifyOfPropertyChange(() => To);
}
}
private TournamentsResultDTO _results;
public List<TournamentDTO> Tournaments { get; set; }
@@ -96,18 +129,36 @@ namespace LaDOSE.DesktopApp.ViewModels
}
}
#endregion
public TournamentResultViewModel(RestService restService)
{
this.RestService = restService;
_selectedTournaments = new ObservableCollection<TournamentDTO>();
Tournaments = new List<TournamentDTO>();
}
protected override void OnInitialize()
{
this.To=DateTime.Now;
this.From = DateTime.Now.AddMonths(-1);
this.SelectRegex = "Ranking";
LoadTournaments();
base.OnInitialize();
}
public void LoadTournaments()
{
var tournamentDtos = this.RestService.GetTournaments().ToList();
WpfUtil.Await(() =>
{
var tournamentDtos = this.RestService
.GetTournaments(new TimeRangeDTO() {From = this.From, To = this.To}).ToList();
this.Tournaments = tournamentDtos;
NotifyOfPropertyChange("Tournaments");
});
}
public DataTable GridDataTable
@@ -121,11 +172,35 @@ namespace LaDOSE.DesktopApp.ViewModels
}
public void Select()
{
WpfUtil.Await(() =>
{
var tournamentsIds = SelectedTournaments.Select(e => e.Id).ToList();
var resultsDto = this.RestService.GetResults(tournamentsIds);
this.Results = resultsDto;
ComputeDataGrid();
});
}
public void SelectYear()
{
this.To = DateTime.Now;
this.From = new DateTime(DateTime.Now.Year,1,1);
}
public void SelectMonth()
{
this.To = DateTime.Now;
this.From = DateTime.Now.AddMonths(-1);
}
public void SelectRegexp()
{
var selectedTournaments = this.Tournaments.Where(e => Regex.IsMatch(e.Name, this.SelectRegex)).ToList();
this.SelectedTournaments.Clear();
if(selectedTournaments.Count>0)
selectedTournaments.ForEach(e=>this.SelectedTournaments.AddUI(e));
}
private void ComputeDataGrid()
@@ -138,7 +213,7 @@ namespace LaDOSE.DesktopApp.ViewModels
DataTable grid = new DataTable();
grid.Columns.Add("Players");
Results.Games.ForEach(e => grid.Columns.Add(e.Name.Replace('.',' ')));
grid.Columns.Add("Total");
grid.Columns.Add("Total").DataType = typeof(Int32);
for (int i = 0; i < resultsParticipents.Count; i++)
@@ -157,7 +232,7 @@ namespace LaDOSE.DesktopApp.ViewModels
if (dictionary.ContainsKey(resultsGame.Id))
{
int points = dictionary[resultsGame.Id];
dataRow[resultsGame.Name.Replace('.', ' ')] = points.ToString();
dataRow[resultsGame.Name.Replace('.', ' ')] = points;
total += points;
}
@@ -165,9 +240,10 @@ namespace LaDOSE.DesktopApp.ViewModels
dataRow[resultsGame.Name.Replace('.', ' ')] = null;
}
dataRow["Total"] = total.ToString();
dataRow["Total"] = total;
}
grid.DefaultView.Sort = "Total DESC";
this.GridDataTable = grid;
}
@@ -182,72 +258,33 @@ namespace LaDOSE.DesktopApp.ViewModels
private void ExportToCSV()
{
if (this.GridDataTable != null)
{
SaveFileDialog sfDialog = new SaveFileDialog()
{
AddExtension = true
};
if (sfDialog.ShowDialog() == true)
{
var resultsParticipents = this.Results.Participents.OrderBy(e => e.Name).ToList();
var computed = ResultsToDataDictionary(resultsParticipents);
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = this.GridDataTable.Columns.Cast<DataColumn>()
.Select(column => column.ColumnName);
sb.AppendLine(string.Join(";", columnNames));
sb.AppendLine(Results.Games.Aggregate("Player;", (current, t) => current + (t.Name + ";")));
for (int i = 0; i < resultsParticipents.Count; i++)
foreach (DataRow row in this.GridDataTable.Rows)
{
var entry = "";
var resultsParticipent = resultsParticipents[i];
entry = resultsParticipent.Name + ";";
var gameDtos = Results.Games.Distinct().ToList();
for (int j = 0; j < gameDtos.Count; j++)
{
var resultsGame = Results.Games[j];
var dictionary = computed[resultsParticipent.Name];
entry += dictionary.ContainsKey(resultsGame.Id)
? dictionary[resultsGame.Id].ToString() + ";"
: ";";
//EXCEL IS A BITCH
IEnumerable<string> fields = row.ItemArray.Select(field =>
string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
sb.AppendLine(string.Join(";", fields));
}
sb.AppendLine(entry);
}
//string[][] resultCsv = new string[resultsParticipents.Count + 1][];
//resultCsv[0] = new string[Results.Games.Count + 1];
//resultCsv[0][0] = "Player";
//for (int j = 0; j < Results.Games.Count; j++)
//{
// resultCsv[0][j + 1] = Results.Games[j].Name;
//}
//for (int i = 0; i < resultsParticipents.Count; i++)
//{
// resultCsv[i + 1] = new string[Results.Games.Count + 1];
// var resultsParticipent = resultsParticipents[i];
// resultCsv[i + 1][0] = resultsParticipent.Name;
// for (int j = 0; j < Results.Games.Count; j++)
// {
// var resultsGame = Results.Games[j];
// var dictionary = computed[resultsParticipent.Name];
// if (dictionary.ContainsKey(resultsGame.Id))
// {
// var i1 = dictionary[resultsGame.Id];
// resultCsv[i + 1][j + 1] = i1.ToString();
// }
// }
//}
//Save
File.WriteAllText(sfDialog.FileName, sb.ToString());
}
}
}
private Dictionary<string, Dictionary<int, int>> ResultsToDataDictionary(
List<ParticipentDTO> resultsParticipents)

View File

@@ -122,17 +122,7 @@ namespace LaDOSE.DesktopApp.ViewModels
public void UpdateDb()
{
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
var tsk = Task.Factory.StartNew(new Action(()=>this.RestService.RefreshDb()));
tsk.ContinueWith(t =>
{
MessageBox.Show(t.Exception.InnerException.Message);
},
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
MessageBox.Show("Database updated");
WpfUtil.Await(()=>this.RestService.RefreshDb(), "Updated");
}
public void Generate()

View File

@@ -13,6 +13,7 @@
d:DesignHeight="450" d:DesignWidth="800">
<Grid Row="2" Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="2*" />
@@ -20,9 +21,51 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" x:Name="LoadTournaments">Update</Button>
<ListView Grid.Row="1" ItemsSource="{Binding Tournaments}" x:Name="TournamentList" Margin="0,0,0,5"
IsTextSearchEnabled="True" TextSearch.TextPath="Name" behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedTournaments}"
<StackPanel Orientation="Horizontal">
<Label> Date : </Label>
<StackPanel Orientation="Horizontal" Width="200">
<DatePicker SelectedDate="{Binding From}" Width="100">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox" Foreground="White"
Text="{Binding Path=SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}},StringFormat=d}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
<DatePicker SelectedDate="{Binding To}" Width="100">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox" Foreground="White"
Text="{Binding Path=SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}},StringFormat=d}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
</StackPanel>
<Label>Usefull :</Label>
<Button x:Name="SelectMonth">Month</Button>
<Button x:Name="SelectYear">Year</Button>
<Label>Select :</Label>
<TextBox Width="200" Text="{Binding SelectRegex}"></TextBox>
<Button x:Name="SelectRegexp">Select</Button>
</StackPanel>
<Button Grid.Row="1" x:Name="LoadTournaments">Update</Button>
<ListView Grid.Row="2" ItemsSource="{Binding Tournaments}" x:Name="TournamentList" Margin="0,0,0,5"
IsTextSearchEnabled="True" TextSearch.TextPath="Name"
behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedTournaments}"
SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
@@ -37,7 +80,7 @@
</ListView.ItemTemplate>
</ListView>
<Grid Row="2">
<Grid Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -59,7 +102,8 @@
</StackPanel>
<ListView Grid.Row="2" ItemsSource="{Binding Results.Games}" Margin="5,5,5,5"
IsTextSearchEnabled="True" TextSearch.TextPath="Name" SelectedItem="{Binding SelectedGame, UpdateSourceTrigger=PropertyChanged}">
IsTextSearchEnabled="True" TextSearch.TextPath="Name"
SelectedItem="{Binding SelectedGame, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
@@ -89,16 +133,15 @@
<TabControl Grid.Row="2" Grid.Column="2">
<TabItem Header="Result">
<DataGrid ItemsSource="{Binding GridDataTable}" AutoGenerateColumns="True" CanUserAddRows="False" CanUserDeleteRows="False">
</DataGrid>
<DataGrid ItemsSource="{Binding GridDataTable}" AutoGenerateColumns="True" CanUserAddRows="False"
CanUserDeleteRows="False" />
</TabItem>
<TabItem Header="By Game">
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
<TextBlock> Total :</TextBlock>
<TextBlock Text="{Binding SelectedGameResult.Count,UpdateSourceTrigger=PropertyChanged}"></TextBlock>
<TextBlock Text="{Binding SelectedGameResult.Count,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<ListView ItemsSource="{Binding SelectedGameResult}" Margin="5,5,5,5"
IsTextSearchEnabled="True" TextSearch.TextPath="Name" DockPanel.Dock="Top">
@@ -117,7 +160,7 @@
</TabItem>
</TabControl>
<Button Grid.Row="3" Grid.ColumnSpan="3" x:Name="Export">Export</Button>
<Button Grid.Row="4" Grid.ColumnSpan="3" x:Name="Export">Export</Button>
</Grid>
</Grid>

View File

@@ -252,12 +252,11 @@ namespace LaDOSE.REST
#region Tournaments
public List<TournamentDTO> GetTournaments()
public List<TournamentDTO> GetTournaments(TimeRangeDTO timeRange)
{
CheckToken();
var restRequest = new RestRequest("/api/Tournament/GetTournaments", Method.GET);
var restResponse = Client.Get<List<TournamentDTO>>(restRequest);
return restResponse.Data;
List<TournamentDTO> tournamentDtos = Post<TimeRangeDTO, List<TournamentDTO>>("/api/Tournament/GetTournaments",timeRange);
return tournamentDtos;
}
public TournamentsResultDTO GetResults(List<int> ids)