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 Microsoft.AspNetCore.Components; using TIAMWebApp.Shared.Application.Services; using TIAMWebApp.Shared.Application.Utility; namespace TIAMSharedUI.Shared.Components.Grids { public class TiamGrid : DxGrid where TDataItem : class, IEntityGuid { private bool _initialParametersSet; 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; } [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() { base.OnInitialized(); } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) RefreshDataSourceAsync().Forget(); } 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 OnDataSourceItemChanged { get; set; } 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; } PostDataToServerAsync(dataItem, e.IsNew ? AddMessageTag : UpdateMessageTag).Forget(); //await transferDataService.CreateTransfer((TransferWizardModel)e.EditModel); //transfer = await transferDataService.UpdateTransferAsync(transfer); } 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)!; PostDataToServerAsync(dataItem, RemoveMessageTag, true).Forget(); } public Task RefreshDataSourceAsync() { Logger.Info($"{_gridLogName} UpdateAllDataAsync called"); return SignalRClient.GetAllAsync>(GetAllMessageTag, response => { if (response.Status == SignalResponseStatus.Error) return; BeginUpdate(); DataSource = response.ResponseData ?? []; EndUpdate(); InvokeAsync(StateHasChanged).Forget(); }); } private Task PostDataToServerAsync(TDataItem transfer, int messageTag, bool isDelete = false) { Logger.Info($"{_gridLogName} PostDataToServerAsync called; transferId " + transfer.Id); RefreshDataSourceItem(transfer, isDelete, false); //egyből látszódik a változás a grid-ben, nem csak a callback lefutásakor! felhasználóbarátabb... - J. return SignalRClient.PostDataAsync(messageTag, transfer, repsonse => { if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null) { RefreshDataSourceAsync().Forget(); return; } RefreshDataSourceItem(repsonse.ResponseData, isDelete); InvokeAsync(StateHasChanged).Forget(); }); //transfer = await devAdminSignalClient.PostDataAsync(SignalRTags.UpdateTransferAsync, transfer); } public Task RefreshDataSourceItem(TDataItem dataItem, bool isDelete, bool invokeItemChanged = true) { 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 invokeItemChanged ? OnDataSourceItemChanged.InvokeAsync(dataItem) : Task.CompletedTask; } protected override Task SetParametersAsyncCore(ParameterView parameters) { if (!_initialParametersSet) { base.DataItemDeleting = EventCallback.Factory.Create(this, OnItemDeleting); base.EditModelSaving = EventCallback.Factory.Create(this, OnItemSaving); //ShowFilterRow = true; //PageSize = 4; //ShowGroupPanel = true; //AllowSort = false; _initialParametersSet = true; } return base.SetParametersAsyncCore(parameters); } protected override void OnParametersSet() { base.OnParametersSet(); if (GridName.IsNullOrWhiteSpace()) GridName = $"{typeof(TDataItem).Name}Grid"; _gridLogName = $"[{GridName}]"; } } }