The AI basically reiterated what I said. I don't have a _Host.cshtml in a Blazor Web App project and the .AddBlazorise is already done by Volo.Abp.BlazoriseUI. AddBootstrapProviders() and AddFontAwesomeIcons() are not done, but wouldn't they be done if BlazoriseUI needed them?
Please answer again to my original questions.
I want to create a minimal Blazor Web App project (with the purpose of testing a module's UI components). I have already created something that works and uses the module's test projects to set up the back-end ("module" means a DDD Web App module created from ABP Studio)
My server project has the following packages: Volo.Abp.AspNetCore.Mvc.UI.Bundling Volo.Abp.AspNetCore.Serilog Volo.Abp.Autofac Volo.Abp.AspNetCore.Components.Web Volo.Abp.AspNetCore.Components.Web.Theming Volo.Abp.AutoMapper as well as any other packages that the test projects and the source projects of the module have.
In order to test components that use basic services like IBlockUiService and INotificationService, I discovered that I need to add some bundles (js and css) to the minimal project. However, the documentation is unclear on what is needed to be included. At first I thought that I should just include the npm package "@abp/core". This did not work as apparently the abp.ui.block function in abp.js is not the same as what the IBlockUiService expects.
So I searched for any bundles that should be included in App.razor to make the basic ABP functionality work. Sadly, the documentation only mentions that the themes have global bundles and I do not have a theme in my minimal project. By searching ABP's project templates, I discovered the BlazorStandardBundles and BlazorWebAssemblyStandardBundles. If I include the BlazorStandardBundles in my App.razor, IBlockUiService at least works. INotificationService probably expects Blazorise to be initialized?
So, my questions are:
Given that ABP promotes a modular solution, it seems logical that each module should handle its own dependencies and initializations since the modules are supposed to be able to be added/removed to/from a solution without much change to the solution. Ideally, the only change when adding/removing a module, would be to add the project/package reference and add the AbpModule of the module's project to the DependsOnAttribute of the solution's projects.
However, the ABP project templates for the solutions indicate that the main application project is responsible for initializing or managing many dependencies of the UI layer.
I want to build a Blazor WebApp application with many modules. Each module is responsible for a business domain and has its own models, logic and UI. Modules may depend on other modules (no circular dependencies obviously). Now I need to implement some components in one of the modules.
What I want: I want to open the module solution, implement the UI component and use a test UI project to see the component and test it. I want the project that implements the UI component to contain and initialize any 3rd party library it may use to develop the component.
Problems:
The <div/> does not have any significance. The body of any page is rendered inside the <RouterTabs/> component. Unfortunately, <RouterTabs/> does not support layout sections inside it. It just renders the page's body.
Rewriting the LeptonX source code or providing a custom layout would not help as the ABP pages expect any layout used to contain a Toolbar section. I could rewrite all the ABP pages to place their toolbar inside their body, but I would like to avoid that.
Besides that, the RouterTabs component expects an attribute in each page to provide the name of the page. The ABP pages do not have this attribute and thus the RouterTabs component uses their type name as the name.
Do you have an alternate suggestion to RouterTabs or a workaround to the above problems?
I have already overriden the layout file and replaced the @Body with the <Div Class="layout"><RouterTabs /></div> as described in the Blazorise documentation.
The RouterTabs component captures the navigation of the pages and renders the page components into tabs.
The problem is that the Toolbar is not part of the Body of each page, and thus it is not rendered inside the tab.
Also, RouterTabs get the type of each page and place its name in the tab name.
I'm not sure the AI answer makes sense.
Context:
I am developing a Blazor Web App using the LeptonX theme with a side-menu layout. I have implemented a dynamic tab navigation system using Blazorise RouterTabs, by following the Blazorise documentation and customizing the layout as mentioned in the LeptonX documentation. My issue is similar to #9473
Problems:
Request:
I am seeking a recommended approach or solution to implement a dynamic tab navigation system in a Blazor Web App that:
Has there been any progress since those issues reported by the AI above? Or are we stuck with dealing with the warnings?
Context: I use ABP Suite to create and modify the entities of a module. I use it for the initial creation and the modifications that no doubt follow closely behind while the entities settle on a structure. After that, I plan to modify the entities manually with the more custom code when needed (and the custom code cannot be placed in the .Extended files) and stop using ABP Suite for those Entities (and module) from that point on.
Problems:
The problem I'm facing is that even for the basic entities, the code produced contains warnings related to the nullability of fields/properties/parameters. When the EntityFramework project contains the <Nullable>enable</Nullable> , then the query generated by ABP Suite for public virtual async Task<EntityWithNavigationProperties> GetWithNavigationPropertiesAsync(Guid id, CancellationToken cancellationToken = default) generates warnings regarding the assignment of possible null values (through the use of FirstOrDefault()) when populating the navigation properties. That's because the navigation properties are not marked as nullable when the foreign key is nullable. Also, when the foreign key is required, the use of FirstOrDefault() indicates that the query may produce no results, even though the database ensures that through the use of a foreign key constraint and a non-null column, the navigation property will always contain a value. Other warnings arise from the use of WhereIf(condition, expression) where the analyzer cannot determine that when the condition is false, the expression is not evaluated.
When the EntityFramework project contains <Nullable>disable</Nullable>, then the above warnings go away, but new warnings arrive. Specifically the use of string? in the parameters of filtering methods.
Solutions:
This leaves me with no option to deal with the warnings by switching the nullability context.
I thought of modifying the ABP Suite templates to add ? to the navigation types when the foreign key is nullable and using First() instead of FirstOrDefault() when it is not, but I do not know the name of the condition to use to check for that, or even if such a condition exists.
My current decision is to ignore the warnings for a short while while the entities are being changed and then fixing the warnings after a short amount of time. Then, whenever I use ABP Suite again to modify the entities, I need to not commit code that will make the warnings re-appear.
I would like not having to deal with those warnings every time I use the Suite. Is there any recommendation?
This is a theoretical question.
Sample problem: Let's assume I have modules/domains named Customers/Appointments/Finances. The Customers module is supposed to work independently of the others, with its own UI, entities, DTOs, DbContext. The Appointments and Finances modules have a dependency on the Customers module as their entities are connected to the Customers.
Let's say I have the need to conditionally show some extra information in the Customers list (grid), which can be obtained from the Appointments (next appointment date) and the Finances (last payment date) modules. This information should be shown conditionally when the modules for Appointments and/or Finances are setup and have registered their services. Otherwise, this information should not be shown.
Current way of thinking: I understand that the Customers module can gather injected services that add extra information to the customer list and have the Appointments and Finances modules implement such services. However, in order to prevent one call to the database per customer in the list per module providing extra information, I need a way to perform a join along with the customer query or use the customer query in the other modules to perform the join there (making it 3 queries).
To do one query with joins (using EF Core), I injected the entity information from each module to the Customer module's DbContext (to perform the joins between entities), I created a model that holds the Customer entity and an IEnumerable<object> of joined information, modified the getList query to project the customer list to that model and passed the query to multiple injected services that added their joins and placed each joined entity into that IEnumerable<object> of the container model.
To pass that from the Application layer to the UI layer, I would need to create an equivalent DTO (instead of the CustomerDTO, a CustomerWithExtraInfoDTO).
Generalized problem: However, at this point, I began thinking that a DTO with a list of unknown objects attached to it kind of defeats the purpose of a known data transfer interface. Also, while I succeeded in injecting services that perform a simple join with the main entity, what if I need those services to filter the customer list or connect the extra information through other logic?
So, the main problem is how to ensure that the Customers module can stay pure without being contaminated with entities or logic from subsequently developed modules, while still being extensible enough to have other modules inject logic and information (in an efficient way when it comes to queries)?
I am already searching for best practices in revelant docs (such as DDD books), but I thought I'd ask here as well believing that this issue must be common enough and maybe the ABP framework provides something for such purposes.