using System.ComponentModel; using AyCode.Core.Helpers; using AyCode.Interfaces.Entities; using AyCode.Services.SignalRs; using AyCode.Utils.Extensions; using DevExpress.Blazor; using DevExpress.Blazor.Internal; using DevExpress.Blazor.Navigation.Internal; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; using TIAMWebApp.Shared.Application.Services; using TIAMWebApp.Shared.Application.Utility; namespace TIAMSharedUI.Shared.Components.Grids { public class TiamGrid : DxGrid where TDataItem : class, IEntityGuid { protected bool IsFirstInitializeParameters; private IList? _dataSource; private string _gridLogName; public TiamGrid() : base() { } [Parameter] public LoggerClient Logger { get; set; } [Parameter] public string GridName { get; set; } [Parameter] public AcSignalRClientBase SignalRClient { get; set; } [Parameter] public int GetAllMessageTag { get; set; } [Parameter] public int GetItemMessageTag { get; set; } [Parameter] public int AddMessageTag { get; set; } [Parameter] public int UpdateMessageTag { get; set; } [Parameter] public int RemoveMessageTag { get; set; } protected new EventCallback DataItemDeleting { get; set; } [Parameter] public EventCallback OnDataItemDeleting{ get; set; } protected new EventCallback EditModelSaving { get; set; } [Parameter] public EventCallback OnDataItemSaving { get; set; } [Parameter] public EventCallback> OnDataSourceChanged { get; set; } [Parameter] public EventCallback OnDataItemChanging { get; set; } [Parameter] public EventCallback OnDataItemChanged { get; set; } [Parameter] [DefaultValue(null)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "BL0007:Component parameters should be auto properties", Justification = "")] public IList? DataSource { get { if (_dataSource == null && Data != null) { Logger.Error($"{_gridLogName} Use the DataSource parameter instead of Data!"); throw new NullReferenceException($"{_gridLogName} Use the DataSource parameter instead of Data!"); } return _dataSource; } set { _dataSource = value; Data = _dataSource; OnDataSourceChanged.InvokeAsync(_dataSource); } } protected override void OnInitialized() { if (Logger == null) throw new NullReferenceException($"[{GetType().Name}] Logger == null"); if (SignalRClient == null) Logger.Error($"[{GetType().Name}] SignalRClient == null"); base.OnInitialized(); } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender && DataSource == null) RefreshDataSourceAsync().Forget(); } public Task AddDataItem(TDataItem dataItem) => PostDataToServerAsync(dataItem, AddMessageTag); public Task UpdateDataItem(TDataItem dataItem) => PostDataToServerAsync(dataItem, UpdateMessageTag); public Task RemoveDataItem(TDataItem dataItem) => PostDataToServerAsync(dataItem, RemoveMessageTag); public Task RemoveDataItem(Guid id) { var dataItem = _dataSource.FirstOrDefault(x => x.Id == id); return dataItem == null ? Task.CompletedTask : RemoveDataItem(dataItem); } private async Task OnItemSaving(GridEditModelSavingEventArgs e) { var dataItem = (e.EditModel as TDataItem)!; var logText = e.IsNew ? "add" : "update"; Logger.Info($"{_gridLogName} OnItemSaving {logText}; Id: {dataItem.Id}"); await OnDataItemSaving.InvokeAsync(e); if (e.Cancel) { Logger.Debug($"{_gridLogName} OnItemSaving {logText} canceled; Id: {dataItem.Id}"); return; } if (e.IsNew) await AddDataItem(dataItem); else await UpdateDataItem(dataItem); } private async Task OnItemDeleting(GridDataItemDeletingEventArgs e) { Logger.Info($"{_gridLogName} OnItemDeleting"); await OnDataItemDeleting.InvokeAsync(e); if (e.Cancel) { Logger.Debug($"{_gridLogName} OnItemDeleting canceled"); return; } var dataItem = (e.DataItem as TDataItem)!; await RemoveDataItem(dataItem); } public virtual Task RefreshDataSourceAsync() { if (GetAllMessageTag == 0) return Task.CompletedTask; Logger.Info($"{_gridLogName} UpdateAllDataAsync called"); return SignalRClient.GetAllAsync>(GetAllMessageTag, response => { if (response.Status == SignalResponseStatus.Error) return; BeginUpdate(); DataSource = response.ResponseData ?? []; EndUpdate(); InvokeAsync(StateHasChanged).Forget(); }); } protected virtual async Task PostDataToServerAsync(TDataItem dataItem, int messageTag, bool isDelete = false) { await OnDataItemChanging.InvokeAsync(dataItem); if (messageTag == 0) return; Logger.Info($"{_gridLogName} PostDataToServerAsync called; transferId " + dataItem.Id); if (dataItem.Id.IsNullOrEmpty()) dataItem.Id = Guid.NewGuid(); RefreshDataItem(dataItem, isDelete); //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 repsonse => { if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null || !RefreshDataItem(repsonse.ResponseData, isDelete)) { RefreshDataSourceAsync().Forget(); return; } await OnDataItemChanged.InvokeAsync(dataItem); InvokeAsync(StateHasChanged).Forget(); }).Forget(); //transfer = await devAdminSignalClient.PostDataAsync(SignalRTags.UpdateTransferAsync, transfer); } protected virtual bool RefreshDataItem(TDataItem dataItem, bool isDelete) { if (dataItem.Id.IsNullOrEmpty()) { Logger.Error($"{_gridLogName} dataItem.Id.IsNullOrEmpty()"); return false; } var transferIndex = _dataSource.FindIndex(x => x.Id == dataItem.Id); if (isDelete && transferIndex > -1) _dataSource.RemoveAt(transferIndex); else { if (transferIndex > -1) _dataSource[transferIndex] = dataItem; else _dataSource.Add(dataItem); } return true; } protected override Task SetParametersAsyncCore(ParameterView parameters) { if (!IsFirstInitializeParameters) { base.DataItemDeleting = EventCallback.Factory.Create(this, OnItemDeleting); base.EditModelSaving = EventCallback.Factory.Create(this, OnItemSaving); //ShowFilterRow = true; //PageSize = 4; //ShowGroupPanel = true; //AllowSort = false; IsFirstInitializeParameters = true; } return base.SetParametersAsyncCore(parameters); } protected override void OnParametersSet() { base.OnParametersSet(); if (GridName.IsNullOrWhiteSpace()) GridName = $"{typeof(TDataItem).Name}Grid"; _gridLogName = $"[{GridName}]"; } } }