Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
D004
@bappajubcse05
true
I can use factory pattern and go to the corresponding repository as from EntityViewProcessorAdapter I can get the entity name and try to create a JPA specification:
Steven Gentens
@sgentens
each of those searches is done on the database itself though, so that would also have quite an impact on performance
D004
@bappajubcse05

public final class EntitySpecification {
private EntitySpecification() {

}
public static Specification<?> searchRecords(String searchText) {
    return (root, criteria, builder) -> builder.or(
            root.getModel()
                .getDeclaredSingularAttributes()
                .stream()
                //.filter(a -> (a.getJavaType().getSimpleName().equalsIgnoreCase("string")))
                .map(a -> builder.like(root.<String>get(a.getName()).as(String.class), searchText))
                .toArray(Predicate[] :: new)
    );
}

private static String getLikeWrap(Attribute attribute, String searchText) {
    //if (attribute.getJavaType().getSimpleName().equalsIgnoreCase("String")) {
        return "%" + searchText + "%";
    //}
    //return searchText;
}

}

but querybuilder doesn't support like operation on numeric filed
field*

In the EntityViewProcessorAdapter:
Steven Gentens
@sgentens
I'm not sure as to whether that's possible without a custom implementation to filter the items on properties that are not strings themselves. I'm also not sure whether the above example would actually apply any filtering at all because the items for the SortableTableBuilder are fetched pretty early (see SortableTableRenderingViewProcessor)
No, you're correct, your processor should overwrite the items attribute if it comes after the AbstractEntityFetchingViewProcessor, but it would always perform a query twice
D004
@bappajubcse05
what do you suggest me..
Currently I am blocked by this one and pagination (adding a dropdown which will allow the user to chose the no. of records he/she wants to see per page)
It would be helpful if I get your help to implement these
Steven Gentens
@sgentens
To do client-side filtering like the datatables, it would probably be easiest to implement https://datatables.net/
You'll then simply fetch all records and the component should take care of filtering
If you'd like to do serverside filtering, the best option would probably be to provide an additional property on your entities, which contains the string representation of all your fields
then you've got a single string field on which you can execute a like query (aka, perform a full-text search on a single column which holds all the data)
Steven Gentens
@sgentens
I've written a small sample configuration that renders a datatable:
@Configuration
public class ExampleConfiguration implements EntityConfigurer
{
    @Override
    public void configure( EntitiesConfigurationBuilder entities ) {
        entities.withType( SimpleEntity.class )
                .listView(
                        lvb -> lvb.viewProcessor( new TableRenderingViewProcessor() )
                                  .pageSize( PageableExtensionViewProcessor.DEFAULT_MAX_PAGE_SIZE )
                );
    }

    class TableRenderingViewProcessor extends EntityViewProcessorAdapter
    {
        @Override
        protected void registerWebResources( EntityViewRequest entityViewRequest, EntityView entityView, WebResourceRegistry webResourceRegistry ) {
            webResourceRegistry.addWithKey( WebResource.CSS, "datatable-css", "//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css",
                                            WebResource.EXTERNAL );
            webResourceRegistry.addWithKey( WebResource.JAVASCRIPT_PAGE_END, "datatable-js", "//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js",
                                            WebResource.EXTERNAL );
            webResourceRegistry.addWithKey( WebResource.JAVASCRIPT_PAGE_END, "datatable-js-activation",
                                            "/static/demo/js/configure-datatables.js", WebResource.VIEWS );
        }

        @Override
        protected void render( EntityViewRequest entityViewRequest,
                               EntityView entityView,
                               ContainerViewElementBuilderSupport<?, ?> containerBuilder,
                               ViewElementBuilderMap builderMap,
                               ViewElementBuilderContext builderContext ) {
            if ( builderMap.containsKey( TABLE_BUILDER ) ) {
                builderMap.get( TABLE_BUILDER, SortableTableBuilder.class )
                          .noSorting();
            }
        }

        @Override
        protected void postRender( EntityViewRequest entityViewRequest,
                                   EntityView entityView,
                                   ContainerViewElement container,
                                   ViewElementBuilderContext builderContext ) {
            ContainerViewElementUtils.find( container, "itemsTable-table", TableViewElement.class )
                                     .ifPresent( table -> table.setHtmlId( "myTable" ) );
        }
    }
}
the configure-datatables.js file simply contains the snippet found on datatables.net, being:
$(document).ready( function () {
    $('#myTable').DataTable();
} );
Steven Gentens
@sgentens
this will however have an impact on performance depending on how many items you are fetching
to apply the above for each entity, you could simply apply the configuration on all EntityConfigurations by using EntitiesConfigurationBuilder#all
D004
@bappajubcse05
@sgentens Thank you. It worked.
How can I customise EntityOverviewController?
I tried with this one-

@AdminWebController
@RequestMapping("/")
public class HomeController {

@RequestMapping("/entities")
public String renderPage( @ModelAttribute PageContentStructure page) {
    System.out.println("Hey! I am here....");
    return PageContentStructure.TEMPLATE;
}

}

but it is throwing exception -
ava.lang.IllegalStateException: Ambiguous mapping. Cannot map 'homeController' method
public java.lang.String com.bt.demo.application.controller.HomeController.renderPage(com.foreach.across.modules.adminweb.ui.PageContentStructure)
to {[/adminUI/entities],custom=[[]]}: There is already 'entityOverviewController' bean method
public java.lang.String com.foreach.across.modules.entity.controllers.admin.EntityOverviewController.listAllEntityTypes() mapped.
D004
@bappajubcse05
and include the list of entities here
Arne Vandamme
@arne-vandamme
actually if you want to replace the dashboard, you can simply write a new controller on a separate path, and then redirect to that controller by setting the adminWebModule.dashboard property (see https://across-docs.foreach.be/across-site/production/admin-web-module/3.0.1/configuration-properties.html)
for example if you controller uses GetMapping(“/mydashboard”) you put /mydashboard as the property value
D004
@bappajubcse05
Hello. Whenever I create an record for any entity, after saving it, the screen is redirected to Update view. How can I redirect to list view once it is saved?
D004
@bappajubcse05
Could you please let me know whether it can be done?
Steven Gentens
@sgentens
When saving an entity, a redirectUrl is set for the current entityView which will then forward you to the update view. This is done inSaveEntityViewProcessor#doPost.
to redirect to the list view, you could add an additional viewprocessor to the class, which sets a the redirectUrl to the listview.
To redirect to the listview of the current entity type, you can fetch the EntityViewLinkBuilder on the EntityViewContext which can be found via the EntityViewRequest
D004
@bappajubcse05
Thanks @sgentens
D004
@bappajubcse05

Hello,

Each across page is including some third party resources (js and css) like below and every time those resources are getting loaded from their server (urls)

Is there any way to stop that (by storing a local copy and load the local copies)?

Steven Gentens
@sgentens
Usually, in a non-development environment these are cached by the browser, the fact that they are constantly fetched is most likely due to devtools being active

Should you want to replace those resources, you can replace the WebResourcePackages that register those resources. The ones you've mentioned are registered by various modules:

  • toaster: see AdminWebResources in AdminWebModule
  • jquery/bootstrap: see BootstrapUiConfiguration in BootstrapUiModule

WebResources and WebResourcePackages are registered to and handled by the WebResourceRegistry, which uses a WebResourcePackageManager

Steven Gentens
@sgentens
You can use either of those to override the WebResourcePackages that register those files.
Steven Gentens
@sgentens

Usually, in a non-development environment these are cached by the browser, the fact that they are constantly fetched is most likely due to devtools being active

Apologies, the above statement was incorrect, opening your browsers development tools allow you to bypass the browser cache, which would result in those files being fetched from the server. (For example, the "Disable cache" setting in the Network tab of the chrome developer tools)

Emmanuel Nyachoke
@enyachoke
Hi guys I just found across framework at am finding my way around. One question though do I need recompile my project to install a module or is there a way to load the module at runtime
slyoldfox
@slyoldfox
Heya @enyachoke, adding a module at runtime is not really possible at the moment (like OSGi does). What is it you are trying to achieve?
Emmanuel Nyachoke
@enyachoke
Yeah thats' kinda what I was hoping for.
slyoldfox
@slyoldfox
The reason this isn't really part of Across at this moment, is that is hasn't been an issue for us. The idea is more to have functional, reusable modules. Reusable for different projects and customers, than to have modules which can plugin at runtime. The runtime loading/unloading is a tricky thing technically because you need to take into account the inter-module dependencies, reinject beans where needed and so on. You need to manage the classpath and classloaders, ... and so on :-)
slyoldfox
@slyoldfox
@enyachoke hope we can still assist you with other matters concerning Across!
Emmanuel Nyachoke
@enyachoke
Thanks @slyoldfox this is still impressive.
Valentín
@valentinlineiro
Hey guys, first I wanted to congratulate you for the hard work and excellent idea. I'm evaluating Across to implement a modular monolithic architecture, and I wonder if you plan to support Spring Boot 2 / Spring Framework 5 any soon
slyoldfox
@slyoldfox
@valentinlineiro Sorry for the late reply, we have been side-tracked on other projects for a while. It is on our roadmap, and will probably become Across Platform 4.0.0 (based on Spring Boot 2.1 and Spring Framework 5.1, maybe a Spring Boot 2.2 depending how fast things evolve).