Activities of "Leonardo.Willrich"

Hi mladen,

Please, don't prioritize that! I have a workaround and I end up adding one more component to the layout anyway to show a modal message. I'll close this thread, I appreciate your help and explanation.

Thank you for you answer liangshiwei.

I've overriden the code as per documentation. I just affraid getting issues when updating the framework. It would be awesome having a callback function to onInitialize where we can create instances and hook up that to the main application.

Hi mladen.macanovic,

Thank you for your answer. I got your point and I am rewriting the razor part as well.

I've tried your suggestion with MainHeader component, only inheriting the class part, but that doesn't work, see below:

Code:

using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.MainHeader;
using Volo.Abp.DependencyInjection;

namespace TVD_Holdings_Ltd.AvalancheOCP.Blazor.Components.Layout
{
    [ExposeServices(typeof(MainHeader))]
    [Dependency(ReplaceServices = true)]
    public class MainHeaderExtension : MainHeader
    {
        protected override async Task OnInitializedAsync()
        {
            Console.WriteLine("MainHeader Init");
        }
    }
}

Error:

My only concern overriding the .razor and .razor.cs is updating the framework and getting conflit or missing some changes due to overriden files.

Answer

Updating my existing Blazor project, it updates Volo packages but not Blazorise package, so, it becames incompatible:

Error: Severity Code Description Project File Line Suppression State Error NU1605 Detected package downgrade: Blazorise.Components from 0.9.3.3 to 0.9.3-preview6. Reference the package directly from the project to select a different version. TVD_Holdings_Ltd.AvalancheOCP.Blazor -> Volo.Abp.LanguageManagement.Blazor 4.3.0-rc.1 -> Volo.Abp.AspNetCore.Components.Web.Theming 4.3.0-rc.1 -> Volo.Abp.BlazoriseUI 4.3.0-rc.1 -> Blazorise.Components (>= 0.9.3.3) TVD_Holdings_Ltd.AvalancheOCP.Blazor -> Blazorise.Components (>= 0.9.3-preview6) TVD_Holdings_Ltd.AvalancheOCP.Blazor D:\Source\AvalancheOCPLatest\src\TVD_Holdings_Ltd.AvalancheOCP.Blazor\TVD_Holdings_Ltd.AvalancheOCP.Blazor.csproj 1

Answer

Error creating a new Blazor project:

Parameters:

@alper, that is a great solution, but it doesn't work 100%. I've been using a similar solution for my AspNetZero projects, but with just one difference.

Issue: When there is a aggregation/association with another class and there is a .Include() in the query, it will not find the field by that string because the right string should be "objectname.field", for example:

Student { public int Id {get; set;} public string Name {get; set;} public int GenderId {get; set;} public virtual Gender Gender {get; set;} }

Gender { public int Id {get; set;} public string Name {get; set;} }

Then, the query will be:

Student.Include(x => x.Gender).OrderBy("Gender.Name");

But, when the fields comes from the grid in the filter, it will come only "Name" or "GenderName", it will depends on my Dto class.

To sort that out in AspNetZero using JQuery DataGrid, there is a property called "Data". When I set that property, it is passed as parameter when filtering. For example:

var dataTable = _$assetFlagTable.DataTable({
            scrollY: "calc(100vh - 505px)",
            scrollCollapse: false,
            paging: true,
            serverSide: true,
            processing: true,
            listAction: {
                ajaxFunction: _assetFlagService.getAll,
                inputFilter: function () {
                    return {
                        filter: $('#AssetFlagTableFilter').val(),
                        nameFilter: $('#NameFilterId').val(),
                        actionFilter: $('#ActionFilterId').val(),
                        flagTypeFilter: $('#FlagTypeFilterId').val(),
                        isActiveFilter: getFilterIsActive()
                    };
                }
            },
            columnDefs: [
                {
                    width: 120,
                    targets: 0,
                    data: null,
                    orderable: false,
                    autoWidth: false,
                    defaultContent: '',
                    rowAction: {
                        cssClass: 'btn btn-brand dropdown-toggle',
                        text: '<i class="fa fa-cog"></i> ' + app.localize('Actions') + ' <span class="caret"></span>',
                        items: [
                            {
                                text: app.localize('View'),
                                action: function (data) {

                                    console.log('View AssetFlag', data);

                                    _viewAseetFlagModal.open({ data: data.record });
                                }
                            },
                            {
                                text: app.localize('Edit'),
                                visible: function () {
                                    return _permissions.edit;
                                },
                                action: function (data) {

                                    console.log('Edit AssetFlag', data);

                                    _createOrEditModal.open({ id: data.record.assetFlag.id });
                                }
                            },
                            {
                                text: app.localize('Delete'),
                                visible: function () {
                                    return _permissions.delete;
                                },
                                action: function (data) {
                                    deleteAssetFlag(data.record.assetFlag);
                                }
                            }]
                    }
                },
                {
                    targets: 1,
                    data: "assetFlag.flagName",  // -->> HERE is the property to be used in the OrderBy method in the back-end.
                    name: "flagName",
                    render: function (data, type, row) {
                        return data.length > 100 ? data.substr(0, 100) + '…' : data;
                    }
                },
                {
                    targets: 2,
                    data: "assetFlag.flagAction",
                    name: "flagAction",
                    render: function (data, type, row) {
                        return data.length > 100 ? data.substr(0, 100) + '…' : data;
                    }
                },
                {
                    targets: 3,
                    data: "assetFlag.flagType",
                    name: "flagType",
                    render: function (data, type, row) {
                        return data.length > 100 ? data.substr(0, 100) + '…' : data;
                    }
                },
                {
                    targets: 4,
                    data: "assetFlag.isActive",
                    name: "isActive",
                    render: function (check) {
                        if (check) {
                            return '<div class="text-center"><i class="fa fa-check-circle m--font-success" title="True"></i></div>';
                        }
                        return '<div class="text-center"><i class="fa fa-times-circle" title="False"></i></div>';
                    }
                }
            ]
        });

My back-end function to populate the grid:

public async Task<PagedResultDto<GetAssetFlagForView>> GetAll(GetAllAssetFlagsInput input)
        {
            try
            {
                var filteredAssetFlag = _assetFlagRepository.GetAll()
                            .WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => e.FlagName.Contains(input.Filter) || e.FlagAction.Contains(input.Filter))
                            .WhereIf(!string.IsNullOrWhiteSpace(input.NameFilter), e => e.FlagName.Contains(input.NameFilter))
                            .WhereIf(!string.IsNullOrWhiteSpace(input.ActionFilter), e => e.FlagAction.Contains(input.ActionFilter))
                            .WhereIf(!string.IsNullOrWhiteSpace(input.FlagTypeFilter), e => e.FlagType.Contains(input.FlagTypeFilter))
                            .WhereIf(input.IsActiveFilter.HasValue, e => e.IsActive == input.IsActiveFilter.Value);
                filteredAssetFlag = filteredAssetFlag.OrderBy(input.Sorting ?? "flagname asc");
                var query = (from o in filteredAssetFlag
                             select new GetAssetFlagForView()
                             {
                                 AssetFlag = ObjectMapper.Map<AssetFlagDto>(o)
                             });

                var totalCount = await query.CountAsync();

                var AssetFlag = await query
                    .PageBy(input)
                    .ToListAsync();

                return new PagedResultDto<GetAssetFlagForView>(
                    totalCount,
                    AssetFlag
                );
            }catch(Exception ex)
            {
                throw ex;
            }
        }

That works perfectly, using the Abp extension and DataGrid with the property Data for each column.

That is great. Thank you for sharing that.

Hi Enisn, I appreciated your answer, but, I could not create an instance for CurrentTenant in the MenuContributor class. Dependency Injection doesn't work on that class and I have no idea how I could create a new instance to check the current TenantId.

Anyway, it seems to be answered by @alper, the right thing is defining the scope in the PermissionDefinitionClass.

Hi Alper.

I haven't found a solution so far. Temporarily, I changed my grid to client-side operations, so, it wlll peform all operation on client side (filter, group, sort).

Hi mladen.macanovic, I did the test again changing the string for the method nameof, but that haven't changing nothing. I think the problem is when parsing the object DataSourceRequest into Json for the method. The method by itself is not called. I guess it would be easier to be reproduced.

Here is my class OutageReportDto:

public class OutageReportDto : AuditedEntityDto<int>, IMultiTenant
    {
        public Guid? TenantId { get; set; }
        public int SupplyNetworkId { get; set; }
        public string SupplyNetworkName { get; set; }
        public DateTime RecordedTime { get; set; }
        public string Location { get; set; }
        
        public string Suburb { get; set; }
        public int CauseId { get; set; }
        public string CauseName { get; set; }
        public string ContactPhoneNumber { get; set; }
        public double LatitudeReporter { get; set; }
        public double LongitudeReporter { get; set; }
        public double LatitudeLocator { get; set; }
        public double LongitudeLocator { get; set; }
        public DateTime? NotifiedTime { get; set; }
        public new DateTime CreationTime { get; set; }
    }

Notice, if I change the grid to Client-Side filter, where I just call a service method with no parameters to return a complete List<OutageReporterDto>, it works fine. So, I don't think that there's an issue with my grid or my Dto class. The problem is only when calling the service method with a parameter type DataSourceRequest and there is a Filter item in this object. If there is no filter items the method works fine.

Hi Alper,

So, I need to set the menu scope (Tenant / Host) in the PermissionDefinitionProvider and then it will reflect the menu as well, is that right?

Showing 121 to 130 of 145 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13