Those use cases show what is up to the application developer responsibility (on diagrams, it is the controller actor), what is done automatically by the framework (light blue rectangle).

Displaying a form and saving an object

Two actions are involved, using 2 services:

Diagram
Figure 1. Sequence Diagram Rendering Form and Process Object
Code Sample: Form + Save Workflow
def userForm(User user) {                           (1)
    user ?= new User()                              (2)

    UiFormSpecifier f = new UiFormSpecifier()       (3)
    f.ui user, {
        hiddenField user.subsidiary_
        hiddenField user.origin_
        section "User", {
            field user.username_
            field user.firstName_
            field user.lastName_
            ajaxField user.manager_, this.&selectUserM2O as MC
            field user.trigram_
            field user.password_
        }
        section "Coords", {
            field user.businessUnit_
            field user.job_
            field user.directPhone_
            field user.additionalPhone_
            field user.mail_
            field user.mainSubsidiary_
            field user.allowedSubsidiaries_
        }
        // [. . .]
        formAction this.&saveUser as MC, user.id    (4)
    }

    taackUiService.show new UiBlockSpecifier().ui { (5)
        modal {
            form "User Form", f, BlockSpec.Width.MAX
        }
    }
}

@Transactional
@Secured("ROLE_ADMIN")                              (6)
def saveUser() {                                    (7)
    taackSaveService.saveThenRedirectOrRenderErrors(User, this.&listUser) (8)
}
1 Action displaying the form
2 Create the object if object is null
3 Create the form
4 Form button that send the form data to the saveUser action
5 show the form
6 Secure the save action
7 Action that will save the object
8 Call to taackSaveService, here if the object is valid, user is redirected to listUsers action.

Display a table with sortable columns, inline actions, and a filter

Only one action is necessary to manage pagination, filtering and sorting:

Diagram
Figure 2. Sequence Diagram Managing Action on a Table to process a list of objects
Code Sample Filter and table
def index() {                                                   (1)
    User cu = authenticatedUser as User

    UiFilterSpecifier f = buildUserTableFilter cu               (2)
    UiTableSpecifier t = buildUserTable f                       (3)

    UiBlockSpecifier b = new UiBlockSpecifier()                 (4)
    b.ui {
        tableFilter "Filter", f, "Users", t, BlockSpec.Width.MAX, {
            action ActionIcon.CREATE, this.&userForm as MC      (5)
        }
    }

    taackUiService.show(b, buildMenu())                         (6)
}
1 Action that display a list of objects
2 Build the filter, here the filter takes the current connected user as parameter, because we want to be able to list user team.
3 Build the table
4 Build the block containing the table and the filter
5 Add an action to create a new user
6 Show the block
We exceptionally pass the filter to the buildTable for building the query and avoiding filter hacking

Display a modal then close it and refresh part of current content

Diagram
Figure 3. Sequence Diagram Managing Action on a Table to process a list of objects
Code Sample to close modal and refresh current page
taackSaveService.saveThenDisplayBlockOrRenderErrors(EngineeringChangeRequest,   (1)
new UiBlockSpecifier().ui {                                                     (2)
    closeModalAndUpdateBlock {                                                  (3)
        show "Projects", buildShowProjects(ecr), BlockSpec.Width.MAX, {
            action
                ActionIcon.ADD,
                Ecr2Controller.&projectsForm as MC,
                [id: ecr.id, ajaxBlockId: ajaxBlockId]
        }
    }
})
1 After an action implying to save an object is called into a modal, you can close the modal and refresh page elements in one action
2 saveThenDisplayBlockOrRenderErrors take a UiBlockSpecifier as parameter
3 closeModalAndUpdateBlock will first close the last opened modal and then apply the modification
4 Here, the block with the name contained in ajaxBlockId will be updated

TODO

  • Updating a portion of a page

  • Show some object with an editable field

  • Show a graph

  • Export a table in CSV

  • Rendering a block in a PDF

  • Rendering a block in a Mail

  • …​