diff --git a/TIAMSharedUI/Pages/User/MyServiceProviders.razor b/TIAMSharedUI/Pages/User/MyServiceProviders.razor
index 87e89e70..d3ecd46e 100644
--- a/TIAMSharedUI/Pages/User/MyServiceProviders.razor
+++ b/TIAMSharedUI/Pages/User/MyServiceProviders.razor
@@ -82,7 +82,8 @@
-
+
+
@{
@@ -147,19 +148,13 @@
}
- protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- if (firstRender)
- await _gridCompany.StartEditRowAsync(0);
- }
-
void Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e)
{
if (e.IsNew)
{
var newEmployee = (Company)e.EditModel;
newEmployee.Name = "John";
- newEmployee.OwnerId = Guid.NewGuid();
+ newEmployee.AffiliateId = Guid.NewGuid();
}
}
diff --git a/TIAMSharedUI/Pages/User/SysAdmins/AddressDetailGridComponent.razor b/TIAMSharedUI/Pages/User/SysAdmins/AddressDetailGridComponent.razor
index 68cfa3c5..3a092984 100644
--- a/TIAMSharedUI/Pages/User/SysAdmins/AddressDetailGridComponent.razor
+++ b/TIAMSharedUI/Pages/User/SysAdmins/AddressDetailGridComponent.razor
@@ -26,9 +26,9 @@
DataSource="DataSource"
Logger="_logger"
SignalRClient="AdminSignalRClient"
- OnEditModelSaving="DataItemSaving"
- OnDataItemDeleting="DataItemDeleting"
- OnDataItemChanged="DataItemChanged"
+ OnGridEditModelSaving="DataItemSaving"
+ OnGridItemDeleting="DataItemDeleting"
+ OnGridItemChanged="DataItemChanged"
PageSize="5"
AutoExpandAllGroupRows="true"
KeyboardNavigationEnabled="KeyboardNavigationEnabled"
diff --git a/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor b/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor
index 8cb19deb..2a5d97ec 100644
--- a/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor
+++ b/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor
@@ -17,6 +17,8 @@
@using AyCode.Core.Extensions
@using AyCode.Core.Consts
@using AyCode.Core
+@using AyCode.Core.Helpers
+@using TIAM.Entities.Emails
@layout AdminLayout
@inject IEnumerable LogWriters
@inject IStringLocalizer localizer
@@ -89,10 +91,10 @@
Logger="_logger"
SignalRClient="AdminSignalRClient"
OnDataSourceChanged="DataSourceChanged"
- OnDataItemChanging="DataSourceItemChanging"
- OnDataItemChanged="DataSourceItemChanged"
- OnDataItemDeleting="DataItemDeleting"
- OnEditModelSaving="DataItemSaving"
+ OnGridItemChanging="DataSourceItemChanging"
+ OnGridItemChanged="DataSourceItemChanged"
+ OnGridItemDeleting="DataItemDeleting"
+ OnGridEditModelSaving="DataItemSaving"
CustomizeElement="Grid_CustomizeElement"
CustomizeEditModel="Grid_CustomizeEditModel"
@@ -163,7 +165,18 @@
-
+
+
+ @System.Text.RegularExpressions.Regex.Replace((displayTextContext.Value as string)!, "<(.|\n)*?>", string.Empty)
+
+
+
+ @{
+ var value = ((EmailMessage)editTextContext.EditModel).Text;
+
+ }
+
+
diff --git a/TIAMSharedUI/Pages/User/SysAdmins/TransferToDriverGridComponent.razor b/TIAMSharedUI/Pages/User/SysAdmins/TransferToDriverGridComponent.razor
index 83b676ac..9744e98a 100644
--- a/TIAMSharedUI/Pages/User/SysAdmins/TransferToDriverGridComponent.razor
+++ b/TIAMSharedUI/Pages/User/SysAdmins/TransferToDriverGridComponent.razor
@@ -21,9 +21,9 @@
DataSource="ParentData.TransferToDrivers"
Logger="_logger"
SignalRClient="AdminSignalRClient"
- OnEditModelSaving="DataItemSaving"
- OnDataItemDeleting="DataItemDeleting"
- OnDataItemChanged="DataItemChanged"
+ OnGridEditModelSaving="DataItemSaving"
+ OnGridItemDeleting="DataItemDeleting"
+ OnGridItemChanged="DataItemChanged"
PageSize="5"
AutoExpandAllGroupRows="true"
KeyboardNavigationEnabled="KeyboardNavigationEnabled"
diff --git a/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs b/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs
index 0fc18741..545fddc3 100644
--- a/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs
+++ b/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs
@@ -1,4 +1,5 @@
using System.ComponentModel;
+using System.Data.Common;
using AyCode.Core;
using AyCode.Core.Enums;
using AyCode.Core.Extensions;
@@ -8,8 +9,10 @@ using AyCode.Interfaces.Entities;
using AyCode.Services.SignalRs;
using AyCode.Utils.Extensions;
using DevExpress.Blazor;
+using DevExpress.Blazor.Internal;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
+using TIAM.Services;
using TIAMWebApp.Shared.Application.Services;
using TIAMWebApp.Shared.Application.Utility;
@@ -41,7 +44,8 @@ namespace TIAMSharedUI.Shared.Components.Grids
public class TiamGrid : DxGrid where TDataItem : class, IId
{
protected bool IsFirstInitializeParameters;
- private IList _dataSource = null!;
+ private SignalRDataSource _dataSource = null!;
+ private IList _dataSourceParam = [];
private string _gridLogName;
public TiamGrid() : base()
@@ -60,14 +64,17 @@ namespace TIAMSharedUI.Shared.Components.Grids
[Parameter] public int RemoveMessageTag { get; set; }
protected new EventCallback DataItemDeleting { get; set; }
- [Parameter] public EventCallback OnDataItemDeleting { get; set; }
+ [Parameter] public EventCallback OnGridItemDeleting { get; set; }
protected new EventCallback EditModelSaving { get; set; }
- [Parameter] public EventCallback OnEditModelSaving { get; set; }
+ [Parameter] public EventCallback OnGridEditModelSaving { get; set; }
[Parameter] public EventCallback> OnDataSourceChanged { get; set; }
- [Parameter] public EventCallback> OnDataItemChanging { get; set; }
- [Parameter] public EventCallback> OnDataItemChanged { get; set; }
+ [Parameter] public EventCallback> OnGridItemChanging { get; set; }
+ ///
+ /// After server response!
+ ///
+ [Parameter] public EventCallback> OnGridItemChanged { get; set; }
[Parameter]
[DefaultValue(null)]
@@ -86,26 +93,65 @@ namespace TIAMSharedUI.Shared.Components.Grids
}
set
{
- if (value == null) throw new ArgumentNullException(nameof(value));
+ if (value == null) return;
+ _dataSourceParam = value;
- var equals = Equals(_dataSource, value);
+ //bool equals;
- _dataSource = value;
- Data = _dataSource;
+ //if ((equals = Equals(_dataSource, value)) == false)
+ //{
+ // if (value is SignalRDataSource dataSource)
+ // _dataSource = dataSource;
+ // else
+ // {
+ // var crudTags = new SignalRCrudTags(GetAllMessageTag, SignalRTags.None, AddMessageTag, UpdateMessageTag, RemoveMessageTag);
+ // _dataSource = new SignalRDataSource(value, SignalRClient, crudTags, ContextId);
+ // }
+ //}
- if (!equals) OnDataSourceChanged.InvokeAsync(_dataSource);
+ //Data = _dataSource;
+ //if (!equals) OnDataSourceChanged.InvokeAsync(_dataSource);
}
}
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
{
if (Logger == null)
throw new NullReferenceException($"[{GetType().Name}] Logger == null");
if (SignalRClient == null)
+ {
Logger.Error($"[{GetType().Name}] SignalRClient == null");
+ throw new NullReferenceException($"[{GetType().Name}] SignalRClient == null");
+ }
- base.OnInitialized();
+ var crudTags = new SignalRCrudTags(GetAllMessageTag, SignalRTags.None, AddMessageTag, UpdateMessageTag, RemoveMessageTag);
+ _dataSource = new SignalRDataSource(SignalRClient, crudTags, ContextId);
+
+ Data = _dataSource;
+
+ _dataSource.OnDataSourceLoaded += OnDataSourceLoaded;
+ _dataSource.OnDataSourceItemChanged += OnDataSourceItemChanged;
+
+ await base.OnInitializedAsync();
+ }
+
+ private Task OnDataSourceItemChanged(ItemChangedEventArgs args)
+ {
+ if (args.TrackingState is TrackingState.GetAll or TrackingState.None) return Task.CompletedTask;
+
+ Logger.Info($"{_gridLogName} OnItemLoaded; trackingState: {args.TrackingState}");
+
+ var changedEventArgs = new GridDataItemChangedEventArgs(this, args.Item, args.TrackingState);
+ return OnGridItemChanged.InvokeAsync(changedEventArgs);
+ }
+
+ private Task OnDataSourceLoaded()
+ {
+ Logger.Info($"{_gridLogName} OnDataSourceLoaded");
+
+ Reload();
+ return OnDataSourceChanged.InvokeAsync(_dataSource);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
@@ -114,9 +160,8 @@ namespace TIAMSharedUI.Shared.Components.Grids
if (firstRender)
{
- if (_dataSource == null || _dataSource.Count == 0) RefreshDataSourceAsync().Forget();
-
- //AutoFitColumnWidths();
+ if (_dataSourceParam.Count > 0) await _dataSource.LoadDataSource(_dataSourceParam);
+ else _dataSource.LoadDataSourceAsync(true).Forget();
}
}
@@ -131,21 +176,29 @@ namespace TIAMSharedUI.Shared.Components.Grids
public Task RemoveDataItem(Guid id) => RemoveDataItem(id, RemoveMessageTag);
- public Task RemoveDataItem(Guid id, int messageTag)
+ public async Task RemoveDataItem(Guid id, int messageTag)
{
var dataItem = _dataSource.FirstOrDefault(x => x.Id == id);
+ if (dataItem != null)
+ {
+ _dataSource.Remove(dataItem);
+ await _dataSource.SaveChanges();
+ //await RemoveDataItem(dataItem);
+ }
- return dataItem == null ? Task.CompletedTask : RemoveDataItem(dataItem);
+ await InvokeAsync(StateHasChanged);
}
private async Task OnItemSaving(GridEditModelSavingEventArgs e)
{
var dataItem = (e.EditModel as TDataItem)!;
+ if (e.IsNew && dataItem.Id.IsNullOrEmpty()) dataItem.Id = Guid.NewGuid();
+
var logText = e.IsNew ? "add" : "update";
Logger.Info($"{_gridLogName} OnItemSaving {logText}; Id: {dataItem.Id}");
- await OnEditModelSaving.InvokeAsync(e);
+ await OnGridEditModelSaving.InvokeAsync(e);
if (e.Cancel)
{
@@ -153,15 +206,31 @@ namespace TIAMSharedUI.Shared.Components.Grids
return;
}
- if (e.IsNew) await AddDataItem(dataItem);
- else await UpdateDataItem(dataItem);
+ if (!e.IsNew) _dataSource.SetTrackingStateToUpdate(dataItem);
+ else
+ {
+ if (dataItem.Id.IsNullOrEmpty()) dataItem.Id = Guid.NewGuid();
+ _dataSource.Add(dataItem);
+ }
+
+ try
+ {
+ var unsavedItems = await _dataSource.SaveChanges();
+
+ if (unsavedItems.Count > 0)
+ Logger.Error($"OnItemSaving->TrySaveChanges error! unsavedCount: {unsavedItems.Count}");
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"{_gridLogName} OnItemSaving", ex);
+ }
}
private async Task OnItemDeleting(GridDataItemDeletingEventArgs e)
{
Logger.Info($"{_gridLogName} OnItemDeleting");
- await OnDataItemDeleting.InvokeAsync(e);
+ await OnGridItemDeleting.InvokeAsync(e);
if (e.Cancel)
{
@@ -170,32 +239,19 @@ namespace TIAMSharedUI.Shared.Components.Grids
}
var dataItem = (e.DataItem as TDataItem)!;
- await RemoveDataItem(dataItem);
- }
+ _dataSource.Remove(dataItem);
- public virtual Task RefreshDataSourceAsync()
- {
- if (GetAllMessageTag == 0) return Task.CompletedTask;
-
- Logger.Info($"{_gridLogName} RefreshDataSourceAsync called");
-
- return SignalRClient.GetAllAsync>(GetAllMessageTag, ContextId, response =>
- {
- if (response.Status == SignalResponseStatus.Error)
- return;
-
- BeginUpdate();
- DataSource = response.ResponseData ?? [];
- EndUpdate();
-
- InvokeAsync(StateHasChanged).Forget();
- });
+ var unsavedItems = await _dataSource.SaveChanges();
+ if (unsavedItems.Count > 0)
+ Logger.Error($"OnItemDeleting->TrySaveChanges error! unsavedCount: {unsavedItems.Count}");
}
protected virtual async Task PostDataToServerAsync(TDataItem dataItem, int messageTag, TrackingState trackingState)
{
+ return;
+
var changingEventArgs = new GridDataItemChangingEventArgs(this, dataItem, trackingState);
- await OnDataItemChanging.InvokeAsync(changingEventArgs);
+ await OnGridItemChanging.InvokeAsync(changingEventArgs);
if (changingEventArgs.IsCanceled)
{
@@ -211,21 +267,21 @@ namespace TIAMSharedUI.Shared.Components.Grids
_dataSource.UpdateCollection(dataItem, trackingState == TrackingState.Remove); //egyből látszódik a változás a grid-ben, nem csak a callback lefutásakor! felhasználóbarátabb... - J.
- SignalRClient.PostDataAsync(messageTag, dataItem, async response =>
- {
- if (response.Status != SignalResponseStatus.Success || response.ResponseData == null)
- {
- RefreshDataSourceAsync().Forget();
- return;
- }
+ //SignalRClient.PostDataAsync(messageTag, dataItem, async response =>
+ //{
+ // if (response.Status != SignalResponseStatus.Success || response.ResponseData == null)
+ // {
+ // RefreshDataSourceAsync().Forget();
+ // return;
+ // }
- _dataSource.UpdateCollection(response.ResponseData, trackingState == TrackingState.Remove);
+ // _dataSource.UpdateCollection(response.ResponseData, trackingState == TrackingState.Remove);
- var changedEventArgs = new GridDataItemChangedEventArgs(this, response.ResponseData, trackingState);
- await OnDataItemChanged.InvokeAsync(changedEventArgs);
+ // var changedEventArgs = new GridDataItemChangedEventArgs(this, response.ResponseData, trackingState);
+ // await OnDataItemChanged.InvokeAsync(changedEventArgs);
- InvokeAsync(StateHasChanged).Forget();
- }).Forget();
+ // InvokeAsync(StateHasChanged).Forget();
+ //}).Forget();
//transfer = await devAdminSignalClient.PostDataAsync(SignalRTags.UpdateTransferAsync, transfer);
}
@@ -250,6 +306,7 @@ namespace TIAMSharedUI.Shared.Components.Grids
{
base.DataItemDeleting = EventCallback.Factory.Create(this, OnItemDeleting);
base.EditModelSaving = EventCallback.Factory.Create(this, OnItemSaving);
+
CustomizeElement += OnCustomizeElement;
//ShowFilterRow = true;
diff --git a/TIAMWebApp/Shared/Utility/SignalRDataSource.cs b/TIAMWebApp/Shared/Utility/SignalRDataSource.cs
index 19b2c826..1a6ce0d3 100644
--- a/TIAMWebApp/Shared/Utility/SignalRDataSource.cs
+++ b/TIAMWebApp/Shared/Utility/SignalRDataSource.cs
@@ -7,6 +7,7 @@ using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using AyCode.Core.Enums;
using AyCode.Core.Extensions;
+using AyCode.Core.Helpers;
using AyCode.Core.Interfaces;
using AyCode.Services.SignalRs;
using TIAM.Services;
@@ -18,7 +19,7 @@ namespace TIAMWebApp.Shared.Application.Utility
{
public TrackingState TrackingState { get; internal set; } = trackingState;
public T CurrentValue { get; internal set; } = currentValue;
- public T? OriginalValue { get; init; } = originalValue; //originalValue == null ? null : TrackingItemHelpers.Clone(originalValue);
+ public T? OriginalValue { get; init; } = originalValue;
internal TrackingItem UpdateItem(TrackingState trackingState, T newValue)
{
@@ -32,7 +33,7 @@ namespace TIAMWebApp.Shared.Application.Utility
}
- public class ChangeTracking where T : class, IId
+ public class ChangeTracking /*: IEnumerable>*/ where T : class, IId
{
private readonly List> _trackingItems = []; //TODO: Dictionary... - J.
@@ -58,7 +59,7 @@ namespace TIAMWebApp.Shared.Application.Utility
}
if (originalValue != null && Equals(newValue, originalValue))
- originalValue = TrackingItemHelpers.ReflectionClone(originalValue);
+ originalValue = TrackingItemHelpers.JsonClone(originalValue);
trackingItem = new TrackingItem(trackingState, newValue, originalValue);
_trackingItems.Add(trackingItem);
@@ -77,6 +78,16 @@ namespace TIAMWebApp.Shared.Application.Utility
}
internal void Remove(TrackingItem trackingItem) => _trackingItems.Remove(trackingItem);
+
+ //public IEnumerator> GetEnumerator()
+ //{
+ // return _trackingItems.GetEnumerator();
+ //}
+
+ //IEnumerator IEnumerable.GetEnumerator()
+ //{
+ // return GetEnumerator();
+ //}
}
@@ -91,17 +102,18 @@ namespace TIAMWebApp.Shared.Application.Utility
protected readonly ChangeTracking TrackingItems = new();
protected readonly Guid? ContextId;
- protected readonly AcSignalRClientBase SignalRClient;
+ public AcSignalRClientBase SignalRClient;
protected readonly SignalRCrudTags SignalRCrudTags;
- public SignalRDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, Guid? contextId = null, bool autoLoadDataSource = true)
+ public Func, Task>? OnDataSourceItemChanged;
+ public Func? OnDataSourceLoaded;
+
+ public SignalRDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, Guid? contextId = null)
{
ContextId = contextId;
SignalRCrudTags = signalRCrudTags;
SignalRClient = signalRClient;
-
- if (autoLoadDataSource) LoadDataSource(false);
}
public bool IsSynchronized => true;
@@ -113,38 +125,79 @@ namespace TIAMWebApp.Shared.Application.Utility
///
///
///
- public void LoadDataSource(bool clearChangeTracking = true)
+ public async Task LoadDataSource(bool clearChangeTracking = true)
{
if (SignalRCrudTags.GetAllMessageTag == SignalRTags.None) throw new ArgumentException($"SignalRCrudTags.GetAllMessageTag == SignalRTags.None");
- lock (_syncRoot)
- {
- var resultList = SignalRClient.GetAllAsync>(SignalRCrudTags.GetAllMessageTag, ContextId).GetAwaiter().GetResult() ?? throw new NullReferenceException();
+ var resultList = (await SignalRClient.GetAllAsync>(SignalRCrudTags.GetAllMessageTag, ContextId)) ?? throw new NullReferenceException();
- Clear(clearChangeTracking);
- InnerList.AddRange(resultList);
- }
+ LoadDataSource(resultList);
}
- public T? LoadItem(Guid id)
+ public Task LoadDataSourceAsync(bool clearChangeTracking = true)
+ {
+ if (SignalRCrudTags.GetAllMessageTag == SignalRTags.None) throw new ArgumentException($"SignalRCrudTags.GetAllMessageTag == SignalRTags.None");
+
+ return SignalRClient.GetAllAsync>(SignalRCrudTags.GetAllMessageTag, ContextId, result=>
+ {
+ if (result.Status != SignalResponseStatus.Success || result.ResponseData == null)
+ throw new NullReferenceException($"result.Status != SignalResponseStatus.Success || result.ResponseData == null; Status: {SignalResponseStatus.Success}");
+
+ LoadDataSource(result.ResponseData);
+ });
+ }
+
+ public async Task LoadDataSource(IList fromSource, bool clearChangeTracking = true)
+ {
+ Monitor.Enter(_syncRoot);
+
+ try
+ {
+ Clear(clearChangeTracking);
+
+ foreach (var item in fromSource)
+ {
+ InnerList.Add(item);
+
+ var eventArgs = new ItemChangedEventArgs(item, TrackingState.GetAll);
+ if (OnDataSourceItemChanged != null) await OnDataSourceItemChanged.Invoke(eventArgs);
+ }
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
+ if (OnDataSourceLoaded != null) await OnDataSourceLoaded.Invoke();
+ }
+
+ public async Task LoadItem(Guid id)
{
if (SignalRCrudTags.GetItemMessageTag == SignalRTags.None) throw new ArgumentException($"SignalRCrudTags.GetItemMessageTag == SignalRTags.None");
T? resultitem = null;
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
- resultitem = SignalRClient.GetByIdAsync(SignalRCrudTags.GetItemMessageTag, id).GetAwaiter().GetResult();
+ resultitem = await SignalRClient.GetByIdAsync(SignalRCrudTags.GetItemMessageTag, id);
if (resultitem == null) return null;
if (TryGetIndex(id, out var index)) InnerList[index] = resultitem;
else InnerList.Add(resultitem);
+
+ var eventArgs = new ItemChangedEventArgs(resultitem, TrackingState.Get);
+ if (OnDataSourceItemChanged != null) await OnDataSourceItemChanged.Invoke(eventArgs);
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
}
return resultitem;
}
-
///
/// set: UpdateMessageTag
///
@@ -157,17 +210,28 @@ namespace TIAMWebApp.Shared.Application.Utility
{
if ((uint)index >= (uint)Count) throw new ArgumentOutOfRangeException(nameof(index));
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
return InnerList[index];
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
set
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
Update(index, value);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
}
@@ -180,13 +244,20 @@ namespace TIAMWebApp.Shared.Application.Utility
{
if (newValue.Id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(newValue), @"Add->newValue.Id.IsNullOrEmpty()");
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
if (Contains(newValue))
throw new ArgumentException($@"It already contains this Id! Id: {newValue.Id}", nameof(newValue));
UnsafeAdd(newValue);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -198,12 +269,19 @@ namespace TIAMWebApp.Shared.Application.Utility
{
if (newValue.Id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(newValue), @"AddOrUpdate->newValue.Id.IsNullOrEmpty()");
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
var index = IndexOf(newValue);
return index > -1 ? Update(index, newValue) : UnsafeAdd(newValue);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
//public void AddRange(IEnumerable collection)
@@ -233,7 +311,9 @@ namespace TIAMWebApp.Shared.Application.Utility
{
if (newValue.Id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(newValue), @"Insert->newValue.Id.IsNullOrEmpty()");
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
if (Contains(newValue))
throw new ArgumentException($@"It already contains this Id! Id: {newValue.Id}", nameof(newValue));
@@ -241,6 +321,11 @@ namespace TIAMWebApp.Shared.Application.Utility
TrackingItems.AddTrackingItem(TrackingState.Add, newValue);
InnerList.Insert(index, newValue);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -264,7 +349,9 @@ namespace TIAMWebApp.Shared.Application.Utility
if (newValue.Id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(newValue), @"Update->newValue.Id.IsNullOrEmpty()");
if ((uint)index >= (uint)Count) throw new ArgumentOutOfRangeException(nameof(index));
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
var currentItem = InnerList[index];
@@ -276,6 +363,11 @@ namespace TIAMWebApp.Shared.Application.Utility
return newValue;
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -285,7 +377,9 @@ namespace TIAMWebApp.Shared.Application.Utility
///
public bool Remove(T item)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
var index = IndexOf(item);
@@ -294,6 +388,11 @@ namespace TIAMWebApp.Shared.Application.Utility
RemoveAt(index);
return true;
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -304,10 +403,17 @@ namespace TIAMWebApp.Shared.Application.Utility
///
public bool TryRemove(Guid id, out T? item)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
return TryGetValue(id, out item) && Remove(item);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -319,7 +425,9 @@ namespace TIAMWebApp.Shared.Application.Utility
///
public void RemoveAt(int index)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
var currentItem = InnerList[index];
if (currentItem.Id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(currentItem), $@"RemoveAt->item.Id.IsNullOrEmpty(); index: {index}");
@@ -327,6 +435,11 @@ namespace TIAMWebApp.Shared.Application.Utility
TrackingItems.AddTrackingItem(TrackingState.Remove, currentItem, currentItem);
InnerList.RemoveAt(index);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -335,21 +448,39 @@ namespace TIAMWebApp.Shared.Application.Utility
///
public List> GetTrackingItems()
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
+ {
return TrackingItems.ToList();
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
public void SetTrackingStateToUpdate(T item)
{
- if (TrackingItems.TryGetTrackingItem(item.Id, out var trackingItem))
+ Monitor.Enter(_syncRoot);
+
+ try
{
- if (trackingItem.TrackingState != TrackingState.Add)
- trackingItem.TrackingState = TrackingState.Update;
+ if (TrackingItems.TryGetTrackingItem(item.Id, out var trackingItem))
+ {
+ if (trackingItem.TrackingState != TrackingState.Add)
+ trackingItem.TrackingState = TrackingState.Update;
- return;
+ return;
+ }
+
+ if (!TryGetValue(item.Id, out var originalItem)) return;
+ TrackingItems.AddTrackingItem(TrackingState.Update, item, originalItem);
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
}
-
- TrackingItems.AddTrackingItem(TrackingState.Update, item, item);
}
///
@@ -360,33 +491,49 @@ namespace TIAMWebApp.Shared.Application.Utility
///
public bool TryGetTrackingItem(Guid id, [NotNullWhen(true)] out TrackingItem? trackingItem)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
+ {
return TrackingItems.TryGetTrackingItem(id, out trackingItem);
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
///
///
/// Unsaved items
- public bool SaveChanges(out List> unsavedItems)
+ public async Task>> SaveChanges()
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+
+ try
{
foreach (var trackingItem in TrackingItems.ToList())
{
try
{
- SaveTrackingItemUnsafe(trackingItem);
+ //throw new Exception();
+ await SaveTrackingItemUnsafe(trackingItem);
}
- catch
+ catch(Exception ex)
{
- // ignored
+ TryRollbackItem(trackingItem.CurrentValue.Id, out _);
}
}
- unsavedItems = TrackingItems.ToList();
- return unsavedItems.Count == 0;
+ return TrackingItems.ToList();
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
///
@@ -395,34 +542,55 @@ namespace TIAMWebApp.Shared.Application.Utility
///
///
///
- public bool TrySaveItem(Guid id, [NotNullWhen(true)] out T? resultItem)
+ public async Task SaveItem(Guid id)
{
- resultItem = null;
+ Monitor.Enter(_syncRoot);
- if (TryGetTrackingItem(id, out var trackingItem))
- resultItem = SaveTrackingItemUnsafe(trackingItem);
+ try
+ {
+ T? resultItem = null;
- return resultItem != null;
+ if (TryGetTrackingItem(id, out var trackingItem))
+ resultItem = await SaveTrackingItemUnsafe(trackingItem);
+
+ return resultItem;
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
- public bool TrySaveItem(Guid id, TrackingState trackingState, [NotNullWhen(true)] out T? resultItem)
- => TryGetValue(id, out resultItem) && TrySaveItem(resultItem, trackingState, out resultItem);
-
- public bool TrySaveItem(T item, TrackingState trackingState, [NotNullWhen(true)] out T? resultItem)
+ public async Task SaveItem(Guid id, TrackingState trackingState)
{
- resultItem = SaveItemUnsafe(item, trackingState);
- return resultItem != null;
+ Monitor.Enter(_syncRoot);
+
+ try
+ {
+ T? resultItem = null;
+
+ if (TryGetValue(id, out var item))
+ resultItem = await SaveItem(item, trackingState);
+
+ return resultItem;
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
- protected T? SaveTrackingItemUnsafe(TrackingItem trackingItem)
+ public Task SaveItem(T item, TrackingState trackingState) => SaveItemUnsafe(item, trackingState);
+
+ protected Task SaveTrackingItemUnsafe(TrackingItem trackingItem)
=> SaveItemUnsafe(trackingItem.CurrentValue, trackingItem.TrackingState);
- protected T? SaveItemUnsafe(T item, TrackingState trackingState)
+ protected async Task SaveItemUnsafe(T item, TrackingState trackingState)
{
var messageTag = SignalRCrudTags.GetMessageTagByTrackingState(trackingState);
if (messageTag == SignalRTags.None) return null; //throw new ArgumentException($"messageTag == SignalRTags.None");
- var result = SignalRClient.PostDataAsync(messageTag, item).GetAwaiter().GetResult();
+ var result = await SignalRClient.PostDataAsync(messageTag, item);
if (result == null) return null; //throw new NullReferenceException($"result == null");
if (TryGetTrackingItem(item.Id, out var trackingItem))
@@ -431,6 +599,9 @@ namespace TIAMWebApp.Shared.Application.Utility
if (TryGetIndex(result.Id, out var index))
InnerList[index] = result;
+ var eventArgs = new ItemChangedEventArgs(result, trackingState);
+ if (OnDataSourceItemChanged != null) await OnDataSourceItemChanged.Invoke(eventArgs);
+
return result;
}
@@ -449,7 +620,8 @@ namespace TIAMWebApp.Shared.Application.Utility
public bool TryRollbackItem(Guid id, out T? originalValue)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
if (TryGetTrackingItem(id, out var trackingItem))
{
@@ -462,22 +634,40 @@ namespace TIAMWebApp.Shared.Application.Utility
originalValue = null;
return false;
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
public void Rollback()
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
foreach (var trackingItem in TrackingItems.ToList())
RollbackItemUnsafe(trackingItem);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
public int Count
{
get
{
- lock (_syncRoot) return InnerList.Count;
+ Monitor.Enter(_syncRoot);
+ try
+ {
+ return InnerList.Count;
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
}
@@ -485,17 +675,30 @@ namespace TIAMWebApp.Shared.Application.Utility
public void Clear(bool clearChangeTracking)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
if (clearChangeTracking) TrackingItems.Clear();
InnerList.Clear();
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
public int IndexOf(Guid id)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
+ {
return InnerList.FindIndex(x => x.Id == id);
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
public int IndexOf(T item) => IndexOf(item.Id);
@@ -505,22 +708,37 @@ namespace TIAMWebApp.Shared.Application.Utility
public bool TryGetValue(Guid id, [NotNullWhen(true)] out T? item)
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
item = InnerList.FirstOrDefault(x => x.Id == id);
return item != null;
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
}
public void CopyTo(T[] array) => CopyTo(array, 0);
public void CopyTo(T[] array, int arrayIndex)
{
- lock (_syncRoot) InnerList.CopyTo(array, arrayIndex);
+ Monitor.Enter(_syncRoot);
+ try
+ {
+ InnerList.CopyTo(array, arrayIndex);
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
public int BinarySearch(int index, int count, T item, IComparer? comparer)
{
+ throw new NotImplementedException($"BinarySearch");
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
if (count < 0)
@@ -528,8 +746,15 @@ namespace TIAMWebApp.Shared.Application.Utility
if (Count - index < count)
throw new ArgumentException("Invalid length");
- lock (_syncRoot)
- return InnerList.BinarySearch(index, count, item, comparer);
+ //Monitor.Enter(_syncRoot);
+ //try
+ //{
+ // return InnerList.BinarySearch(index, count, item, comparer);
+ //}
+ //finally
+ //{
+ // Monitor.Exit(_syncRoot);
+ //}
}
public int BinarySearch(T item) => BinarySearch(0, Count, item, null);
@@ -537,8 +762,17 @@ namespace TIAMWebApp.Shared.Application.Utility
public IEnumerator GetEnumerator()
{
- lock (_syncRoot)
- return InnerList.ToList().GetEnumerator();
+ Monitor.Enter(_syncRoot);
+ try
+ {
+ //return InnerList.ToList().GetEnumerator();
+ return InnerList.GetEnumerator();
+ }
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
public ReadOnlyCollection AsReadOnly() => new(this);
@@ -618,11 +852,17 @@ namespace TIAMWebApp.Shared.Application.Utility
try
{
- lock (_syncRoot)
+ Monitor.Enter(_syncRoot);
+ try
{
//TODO: _list.ToArray() - ez nem az igazi... - J.
Array.Copy(InnerList.ToArray(), 0, array!, arrayIndex, InnerList.Count);
}
+ finally
+ {
+ Monitor.Exit(_syncRoot);
+ }
+
}
catch (ArrayTypeMismatchException)
{
@@ -638,4 +878,16 @@ namespace TIAMWebApp.Shared.Application.Utility
#endregion IList, ICollection
}
+
+ public class ItemChangedEventArgs where T : IId
+ {
+ internal ItemChangedEventArgs(T item, TrackingState trackingState)
+ {
+ Item = item;
+ TrackingState = trackingState;
+ }
+
+ public T Item { get; }
+ public TrackingState TrackingState { get; }
+ }
}
diff --git a/TIAMWebApp/Shared/Utility/SignalRDataSourceAsync.cs b/TIAMWebApp/Shared/Utility/SignalRDataSourceAsync.cs
index e6361fa2..d435cb51 100644
--- a/TIAMWebApp/Shared/Utility/SignalRDataSourceAsync.cs
+++ b/TIAMWebApp/Shared/Utility/SignalRDataSourceAsync.cs
@@ -16,7 +16,7 @@ public class SignalRDataSourceAsync : SignalRDataSource where T : class, I
public Action>? OnDataSourceLoaded;
public SignalRDataSourceAsync(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, Guid? contextId = null, Action>? onDataSourceLoaded = null, bool autoLoadDataSource = false)
- : base(signalRClient, signalRCrudTags, contextId, false)
+ : base(signalRClient, signalRCrudTags, contextId)
{
OnDataSourceLoaded = onDataSourceLoaded;
@@ -27,34 +27,34 @@ public class SignalRDataSourceAsync : SignalRDataSource where T : class, I
{
if (SignalRCrudTags.GetAllMessageTag == SignalRTags.None) throw new ArgumentException($"_signalRCrudTags.GetAllMessageTag == SignalRTags.None;");
- Monitor.Exit(SyncRoot); //Exception test - J.
+ //Monitor.Exit(SyncRoot); //Exception test - J.
- Monitor.Enter(SyncRoot);
- try
- {
- SignalRClient.GetAllAsync>(SignalRCrudTags.GetAllMessageTag, ContextId, response =>
- {
- try
- {
- if (response.Status == SignalResponseStatus.Error) throw new Exception($"LoadDataSourceAsync; response.Status == SignalResponseStatus.Error");
- if (response.ResponseData == null) throw new NullReferenceException($"response.ResponseData == null");
+ //Monitor.Enter(SyncRoot);
+ //try
+ //{
+ // SignalRClient.GetAllAsync>(SignalRCrudTags.GetAllMessageTag, ContextId, response =>
+ // {
+ // try
+ // {
+ // if (response.Status == SignalResponseStatus.Error) throw new Exception($"LoadDataSourceAsync; response.Status == SignalResponseStatus.Error");
+ // if (response.ResponseData == null) throw new NullReferenceException($"response.ResponseData == null");
- Clear(clearChangeTracking);
- InnerList.AddRange(response.ResponseData);
- }
- finally
- {
- Monitor.Exit(SyncRoot);
- }
+ // Clear(clearChangeTracking);
+ // InnerList.AddRange(response.ResponseData);
+ // }
+ // finally
+ // {
+ // Monitor.Exit(SyncRoot);
+ // }
- OnDataSourceLoaded?.Invoke(this);
- }).Forget();
- }
- catch (Exception)
- {
- Monitor.Exit(SyncRoot);
- throw;
- }
+ // OnDataSourceLoaded?.Invoke(this);
+ // }).Forget();
+ //}
+ //catch (Exception)
+ //{
+ // Monitor.Exit(SyncRoot);
+ // throw;
+ //}
}
@@ -101,17 +101,4 @@ public class SignalRDataSourceAsync : SignalRDataSource where T : class, I
// return Task.CompletedTask;
//}
-
- public class ItemChangedEventArgs where T : IId
- {
- internal ItemChangedEventArgs(T item, TrackingState trackingState)
- {
- Item = item;
- TrackingState = trackingState;
- }
-
- public T Item { get; }
- public TrackingState TrackingState { get; }
- }
-
}
\ No newline at end of file