Basic implementation of updating which shop is active.

This commit is contained in:
Patrick Fic
2020-01-20 12:28:08 -08:00
parent 73a2cb4fcb
commit bc5cb13113
9 changed files with 299 additions and 12 deletions

View File

@@ -251,6 +251,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Models\Bodyshop.cs" />
<Compile Include="Models\DTO_Base.cs" />
<Compile Include="Models\DTO_QueueItem.cs" />
<Compile Include="Models\Monitor.cs" />
@@ -264,6 +265,7 @@
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Utils\ApplicationExceptionHandler.cs" />
<Compile Include="Utils\AppMetaData.cs" />
<Compile Include="Utils\Auth.cs" />
<Compile Include="Utils\BaseModel.cs" />
@@ -278,6 +280,7 @@
</Compile>
<Compile Include="Utils\Growls\Notification.cs" />
<Compile Include="Utils\JobProcessingQueue.cs" />
<Compile Include="Utils\JsonConverter.cs" />
<Compile Include="Utils\LoginHelpers.cs" />
<Compile Include="Utils\RelayCommand.cs" />
<Compile Include="Utils\TrayIcon.cs" />

View File

@@ -0,0 +1,52 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BodyshopUploader.Models
{
[JsonConverter(typeof(Utils.JsonPathConverter))]
public class Bodyshop : DTO_Base
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public Bodyshop()
{
}
private string id;
[JsonProperty("id")]
public string Id
{
get { return id; }
set { SetProperty(ref id, value); }
}
private string _shopname;
[JsonProperty("shopname")]
public string ShopName
{
get { return _shopname; }
set { SetProperty(ref _shopname, value); }
}
private string _associationId;
[JsonProperty("associations[0].id")]
public string AssociationId
{
get { return _associationId; }
set { SetProperty(ref _associationId, value); }
}
private bool _associationActive;
[JsonProperty("associations[0].active")]
public bool AssociationActive
{
get { return _associationActive; }
set { SetProperty(ref _associationActive, value); }
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BodyshopUploader.Utils
{
public static class ApplicationExceptionHandler
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public static void InitExceptionHandlers()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
//do something with the file contents
}
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
logger.Fatal((e.ExceptionObject as Exception), "Unhandled generic exception.");
}
}
}

View File

@@ -79,8 +79,6 @@ namespace BodyshopUploader.Utils
private static void DecodeQueueItemJob(DTO_QueueItem item)
{
//Process the job.
logger.Info("Should process the job here. {0}", item.FilePath);
item.Job = Utils.Decoder.EstimateDecoder.CIECAEstimateImport.DecodeEstimate(item.FilePath);
}

View File

@@ -0,0 +1,57 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace BodyshopUploader.Utils
{
class JsonPathConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
object targetObj = Activator.CreateInstance(objectType);
foreach (PropertyInfo prop in objectType.GetProperties()
.Where(p => p.CanRead && p.CanWrite))
{
JsonPropertyAttribute att = prop.GetCustomAttributes(true)
.OfType<JsonPropertyAttribute>()
.FirstOrDefault();
string jsonPath = (att != null ? att.PropertyName : prop.Name);
JToken token = jo.SelectToken(jsonPath);
if (token != null && token.Type != JTokenType.Null)
{
object value = token.ToObject(prop.PropertyType, serializer);
prop.SetValue(targetObj, value, null);
}
}
return targetObj;
}
public override bool CanConvert(Type objectType)
{
// CanConvert is not called when [JsonConverter] attribute is used
return false;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}

View File

@@ -2,9 +2,11 @@
using BodyshopUploader.Utils.Growls;
using GraphQL.Client;
using GraphQL.Common.Request;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -18,9 +20,38 @@ namespace BodyshopUploader.ViewModels
public MainViewModel()
{
logger.Trace("Main VM constructed.");
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_InitVm;
bw.WorkerReportsProgress = true;
bw.ProgressChanged += Bw_ProgressChanged;
bw.RunWorkerCompleted += Bw_RunWorkerCompleted;
bw.RunWorkerAsync();
Growler = new GrowlNotification(this);
Utils.JobProcessingQueue.SetGrowler(Growler);
}
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
((BackgroundWorker)sender).Dispose();
//Progress = 0;
logger.Trace("BW Completed.");
}
private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Progress = e.ProgressPercentage;
}
private void bw_InitVm(object sender, DoWorkEventArgs e)
{
BackgroundWorker _callingThread = sender as BackgroundWorker;
_callingThread.ReportProgress(1);
//Restore list of paths, convert to monitor object.
List<string> listOfPaths = Properties.Settings.Default.MonitoringPaths;
if (listOfPaths == null) listOfPaths = new List<string>();
@@ -29,9 +60,19 @@ namespace BodyshopUploader.ViewModels
MonitoringPaths.Add(new Models.Monitor() { FilePath = p });
}
MonitoringPaths.CollectionChanged += MonitoringPathsChanged;
logger.Trace("Main VM Created.");
_callingThread.ReportProgress(30);
//Cannot use await.
LoadBodyshopData().Wait(); ;
_callingThread.ReportProgress(80);
logger.Debug("VM Init Complete");
_callingThread.ReportProgress(100);
}
private void MonitoringPathsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
logger.Warn("TODO: Change monitoring lifecycles for folder watchers.");
@@ -83,6 +124,84 @@ namespace BodyshopUploader.ViewModels
}
}
public async Task LoadBodyshopData()
{
var r = new GraphQLRequest
{
Query = @"query QUERY_BODYSHOPS {
bodyshops {
shopname
id
associations {
id
active
}
}
}"
};
using (var g = Utils.GraphQL.CreateGQLClient())
{
logger.Trace("Firing GQL Query: {0}", r.ToString());
var graphQLResponse = await g.PostAsync(r);
if (graphQLResponse.Errors == null)
{
logger.Trace("GQL Response: {0}", graphQLResponse.Data.bodyshops);
var p = graphQLResponse.Data.bodyshops;
ShopData = graphQLResponse.Data.bodyshops.ToObject<ObservableCollection<Bodyshop>>();
}
else
{
logger.Error("Error querying bodyshop data.");
}
}
}
public async Task SetActiveBodyshop(Bodyshop b)
{
foreach (var s in ShopData)
{
if (s.Id == ActiveShop.Id) s.AssociationActive = true;
else s.AssociationActive = false;
var r = new GraphQLRequest
{
Query = @"
mutation UPDATE_ASSOCIATION($assocId: uuid, $assocActive: Boolean) {
update_associations(where: {id: {_eq: $assocId}}, _set: {active: $assocActive}) {
returning {
id
active
}
}
}
",
Variables = new
{
assocId = s.AssociationId,
assocActive = s.AssociationActive
}
};
using (var g = Utils.GraphQL.CreateGQLClient())
{
logger.Trace("Firing GQL Query: {0}", r.ToString());
var graphQLResponse = await g.PostAsync(r);
if (graphQLResponse.Errors == null)
{
logger.Trace("GQL Response: {0}", graphQLResponse.Data);
}
else
{
logger.Error("Error mutating data.");
}
}
}
}
public async Task TestGql()
{
Notification _n = new Notification()
@@ -98,20 +217,18 @@ namespace BodyshopUploader.ViewModels
var r = new GraphQLRequest
{
Query = @"
query {
jobs {
query QUERY_BODYSHOPS {
bodyshops {
shopname
id
est_number
ro_number
}
}
"
}"
};
using (var g = Utils.GraphQL.CreateGQLClient())
{
var graphQLResponse = await g.PostAsync(r);
logger.Info(graphQLResponse.Data.jobs);
logger.Info("GQL Response: {0}", graphQLResponse.Data.bodyshops);
}
}
}

View File

@@ -19,5 +19,27 @@ namespace BodyshopUploader.ViewModels
get { return _monitoringPaths; }
set { SetProperty(ref _monitoringPaths, value); }
}
private ObservableCollection<Bodyshop> _shopData;
public ObservableCollection<Bodyshop> ShopData
{
get { return _shopData; }
set { SetProperty(ref _shopData, value); }
}
private int _progress;
public int Progress
{
get { return _progress; }
set { SetProperty(ref _progress, value); }
}
private Bodyshop _activeShop;
public Bodyshop ActiveShop
{
get { return _activeShop; }
set { SetProperty(ref _activeShop, value); SetActiveBodyshop(value); }
}
}
}

View File

@@ -23,6 +23,7 @@ namespace BodyshopUploader.Views
public Login()
{
InitializeComponent();
Utils.ApplicationExceptionHandler.InitExceptionHandlers();
}
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{

View File

@@ -67,6 +67,16 @@
</Button>
<StackPanel DockPanel.Dock="Right">
<ComboBox ItemsSource="{Binding ShopData}"
SelectedItem="{Binding ActiveShop}"
DisplayMemberPath="ShopName">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
<Button Command="{Binding StartFolderMonitorsCommand}"
Content="{x:Static p:Resources.Label_StartAllMonitors}" />
<Button Command="{Binding StopFolderMonitorsCommand}"
@@ -74,6 +84,9 @@
</StackPanel>
<ProgressBar DockPanel.Dock="Bottom"
Value="{Binding Progress}" />
<DataGrid ItemsSource="{Binding MonitoringPaths}"
AutoGenerateColumns="False"
CanUserAddRows="False">