Git Product home page Git Product logo

cuba-example-declarative-comments's Introduction

license

CUBA Platform Example - Declarative Comments

CUBA example that shows how to use the declarative-controllers application component.

Customers and Products should be commentable

Let's say you want to add a generic "comments-feature" on entities (in our case you can comment on "Customer" as well as "Product") and you already got everything setup on the entity layer. This example shows how to use the declarative-controllers app component to create a UI where for every controller it should be possible to just declare that this entity should be commentable as well.

For every commentable Entity, there should be a "comments" button in the browse screen:

Screenshot products browser

Clicking on the comments for a particular entity, should open a dialog with a list of comments that are associated to this entity:

Screenshot product comments

Using the @Commentable Annotation

This application component brings not only a way of dealing with the inheritance problem. It also makes it possible to, instead of programmatically define that certain features should be used, activate these generic features in a declarative way through the Usage of Annotations.

The ProductBrowse looks with the declarative definition of the Comments feature:

@Commentable(listComponent = "productsTable")
public class ProductBrowse extends AnnotatableAbstractLookup {
}

The CustomerBrowse looks like this:

@Commentable(listComponent = "productsTable")
public class CustomerBrowse extends AnnotatableAbstractLookup {
}

Defining Annotations

The application component allows two kinds of Annotations. A class-based Annotation and a field-based Annotation. Field based annotations are useful if you want to enhance a particular Component on the page.

Class-based Annotation: @Commentable

  1. Create the Commentable Annotation in your web module like this:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Commentable {
    String listComponent() default "";
    String buttonId() default "commentBtn";
    String buttonsPanel() default "buttonsPanel";
}

In this case we need the parameter for the list component it should act on. Additionally it is possible to define what button should be used. If the button is not available, it will be created (this is sometimes interesting, when you explicitly define where the button should be placed).

  1. Create the CommentableBrowseAnnotationExecutor spring bean (in the web module) that implements BrowseAnnotationExecutor which contains the logic that sholuld get injected into the controllers:
@Component
class CommentableBrowseAnnotationExecutor implements BrowseAnnotationExecutor<Commentable> {

    @Inject
    ButtonsPanelHelper buttonsPanelHelper


    @Override
    void init(Commentable annotation, Window.Lookup browse, Map<String, Object> params) {
        ListComponent listComponent = browse.getComponent(annotation.listComponent()) as ListComponent
        def action = new CommentsButtonAction(listComponent)
        listComponent.addAction(action)
        if (annotation.buttonsPanel()) {
            ButtonsPanel buttonsPanel = browse.getComponent(annotation.buttonsPanel()) as ButtonsPanel
            Button dokumentButton = buttonsPanelHelper.createButton(annotation.buttonId(), buttonsPanel, [])
            dokumentButton.action = action
        }
    }

    @Override
    boolean supports(Annotation annotation) {
        annotation instanceof Commentable
    }


    @Override
    void ready(Commentable annotation, Window.Lookup browse, Map<String, Object> params) {

    }
}

The supports defines that the Executor should support the Commentable annotation. In this case we only need the init hook method of the browse screen, to add our button.

When the buttons gets clicked it will invoke a CommentsButtonAction which is just the regular CUBA action programming model:

class CommentsButtonAction extends ItemTrackingAction implements Action.HasOpenType {

    WindowManager.OpenType openType

    static final String ACTION_ID = 'commentsAction'


    CommentsButtonAction(ListComponent target) {
        this(ACTION_ID, target)
    }

    CommentsButtonAction(String id, ListComponent target) {
        super(target, id)
        icon = 'font-icon:COMMENTS_O'
        caption = ''
    }

    @Override
    void actionPerform(Component component) {
        def entity = target.singleSelected
        target.frame.openWindow(
                'dbcedc_Comment.browse',
                WindowManager.OpenType.DIALOG,
                [
                        entityId: entity.id,
                        entityClass: entity.metaClass.name,
                        entityInstanceName: entity.instanceName,
                ]
        )
    }

}

Field-based Annotation: @IconCommentedEntities

There is an example of a field based annotation: @IconCommentedEntities. This annotation can be applied to Table components and adds a icon provider to the table. It will display an icon for entities that already have commentes associated with it.

  1. create a Annotation called IconCommentedEntities:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface IconCommentedEntities {
    String icon() default "font-icon:COMMENTING_O";
}
  1. Create the IconCommentedEntitiesFieldAnnotationBrowseExecutor spring bean (in the web module) that implements BrowseFieldAnnotationExecutor which contains the logic that sholuld get injected into the controllers:
@Component
class IconCommentedEntitiesFieldAnnotationBrowseExecutor implements BrowseFieldAnnotationExecutor<IconCommentedEntities, Table> {

    @Inject
    CommentEntityService commentEntityService

    @Override
    boolean supports(Annotation annotation) {
        return annotation instanceof IconCommentedEntities
    }

    @Override
    void init(IconCommentedEntities annotation, Window.Lookup browse, Table target, Map<String, Object> params) {

        target.iconProvider = new ListComponent.IconProvider<Entity>() {
            @Override
            String getItemIcon(Entity entity) {
                boolean hasComments = commentEntityService.hasComments(entity)
                hasComments ? annotation.icon() : ''
            }
        }
    }

    @Override
    void ready(IconCommentedEntities annotation, Window.Lookup browse, Table target, Map<String, Object> params) {

    }
}
  1. Use the annotation for a particular Component in your controller. Here's the example of the CustomerBrowse screens:
@Commentable(listComponent = 'customersTable')
class CustomerBrowse extends AnnotatableAbstractLookup {

    @IconCommentedEntities(icon = 'font-icon:COMMENTING')
    @Inject
    Table<Customer> customersTable
}

Screenshot customer comments via field annotation

cuba-example-declarative-comments's People

Contributors

bresche avatar mariodavid avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

mariodavid

cuba-example-declarative-comments's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.