New 16.2.10 Content Server Smart UI Advanced Workshop

This is a 4-5 days’ Workshop covering the additional Parts of the SDK, the xECM, Webreports, Workflow etc. Modules. Here, some of the more advanced concepts are discussed, like how to make Widgets configurable in the Perspective Manager.

Also, there are overviews of D3 (Graphic Package) and Alpaca (Forms Package) inside the SDK. The complete Training is configurable.

See the complete Agenda here

New smartUI Workshop Basic for 16.2.10

This is an overview of the Content Server part in the SDK. At the end, simple Widgets based on the standard demo widget can be build and set up in the Content Server. This Workshop in available in various lengths to allow a different depth of Understanding. See the complete 5 days Agenda on the next pages. The 1 day and 2 days workshops are subsets of the complete 5 days workshop-

1 Day Content Server Smart UI Workshop Basic

Suited for Managers to get a technical overview of the SDK (Content Server Part) and what’s to do with it. First held at the Enterprise World Vienna 2019.

2 Days Content Server Smart UI Workshop Basic

Suited for technical Team Leaders or Consultants to get a technical overview of the SDK (Content Server Part) and what’s to do with it. Gets more in-depth as the 1-day workshop with more exercises. Forst held at the Enterprise World Toronto 2019.

5 Days Content Server Smart UI Workshop Basic

This is the complete training, covering all areas (JS Patterns, REST, SDK Infrastructure, SDK, Exercises) in the SDK (Content Server Part)

See the complete 5 days Agenda here

New: We are offering custom widget development. Interested? Send an e-mail at merz at ebit-company.de stating the purpose of the widget and requesting an offering

New Trainings for smartUI and Content Server 16.2.10

Content Server 16.2.10 gave us a lot of new Features, which require a new Traininigs.

Therefore there is a Workshop Line of smartUI Trainings and a new Practical Series.

Workshop Line: The two Workshops Content Server SmartUI Workshop Basic and Contnent Server smartUI Workshop advanced have been extended to 16.2.10. As always this Workshops give the explanation, what and why is going on in der SDK

  • Content Server Smart UI Workshop Basic
  • Content Server Smart UI Workshop Advanced

The Practical Series include a complete Implementation of Widgets, REST Services and Contnent Server based Applications in the form of Business Workspaces. So this part is more a Workshop for the practical usage of smartUI. As the content of the Workshop Line is required in the Practical Series, a knowledge comparable to this Workshop Line is recommended for attending the practical Series.

  • Practical Series I: Strategies to “widgedize” an existing Content Server module and to add functionality in an existing widget.
  • Practical Series II: Building an EVENT Management System in the Content Server using a graphical smartUI Dashboard and Connected Workspaces

New: We are offering custom widget development. Interested? Send an e-mail at merz at ebit-company.de stating the purpose of the widget and requesting an offering

New in 16.2.10: New Favorites, MyAssignments and RecentAccessed Widgets

New in the actual Content Server Release 16.2.10 are redesigned Favorites, My Assignments and Recently Accessed Widgets.

All three widgets can now be expanded from an Icon located at the upper right. And the expanded view is no longer a popup Window, its a separate view, giving you much more space to display. Also, there are node Commands available at the entries

Lets start from with the Recently Accessed widget:

The new Recently Accessed Main View
with the new menu

Here we see, that the expanded view has been moved to the upper right. And direct node commands are available from the menu

The expanded view of the recently accessed widget
The new expanded view of the recently Accessed Widget

To leave the expanded view, simply click on the Arrow at the upper left.

Next, we have a new Favorites Widget

Favorites Widget
The new Favorites Widget

By hovering over the entries, there are new node commands available (here for the business workspace). Also the expand Icon moved to the top right.

Favorites Expanded View
Favorites Expanded View

This is an example of the Favorites expanded view.

The next is the MyAssignments Widget

The MyAssignments Widget
The MyAssignments Widget

and the expanded view is

MyAssignments Widget expanded
The MyAssignments Widget

Interesting, isn’t it?

New: We are offering custom widget development. Interested? Send an e-mail at merz at ebit-company.de stating the purpose of the widget and requesting an offering

smartUI SDK additional Libraries

There are a few additional libraries in smartUI, which are distributed in any content server installation. Therefore its not necessary, to instatt the libraries, just use them. We discuss several libraries also in the smartUI base and advanced trainings.

These are

  • alpacca.js
    A library to develop and use JSON based forms. Supported by Content Server RESTS calls
  • ally.js
    simplify certain accessibility features, functions and behaviors.
  • bililite.js
    Cross-Browser Text Ranges and Selection
  • ckeditor.js
    Configurable javascript RTF Editor
  • d3.js
    Data driven documents. A highly interactive library to draw interactive SVG graphics. Used to visualize data. The OpenText distribution contains
  • d3-selection
  • d3-array
  • d3-scale
  • d3-shape
  • d3-axis
  • d3-collection
  • d3-transition
  • d3-interpolate
  • d3-format
  • hammer.js
    Gestures in Webapps
  • less.js
    dynamic stylesheet language
  • moment.js
    Date Arithmetic in JS. Very useful with d3.
  • numeral.js
    Formatting and manipulating numbers
  • text.js
    AMD/Loader Plugin for loading text resources
  • jqueryui.js
    Includes:
    widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js,
    jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js,
    widgets/selectable.js, widgets/sortable.js, widgets/mouse.js, effect.js,
    effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js,
    effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js

Whats new in the Workflow Area of Content Server 16.2.9?

There are seveeral new things implemented in the Workflow area of Content Server 16.2.9.

First think of a very simple workflow defined like this.

a very simple Workflow as example
A really simple workflow

Lets set the name of our workflow to “Test Work Flow 16.2.9”. Lets initiate it.

Stop Action in smartUI

If configured on a landing page, the workflow tracking widget shows our workflow, once initiated like this

The Workflow Tracking Widget
The workflow tracking widget

If you click on the extension button on the lower right of the workflow tracking widget, then there will be a list of all workflows belonging to or initiated by this person will open.

A workflow list with only one workflow.

If you click on the status of a workflow (here we have only one workflow to click onto), the details of this workflow instance opens

Details of the Test Work Flow 16.2.9

Here you see a graphical overview of the current step along with all steps of the workflow. This instance of the workflow an be stopped by pressing the “Stop” Button.

Open the Workflow Map from smartUI

A new Edit Action has been added to allow the edit of a Workflow Map

The new edit action for workflow maps

This will open the Workflow Map Editor in the legacy gui

A simple Workflow
A really simple Workflow

Copying or Moving Workflow Attachments in smart UI

Workflow Attachments can now be moved of copied within the Workflow Attachment Panel

New in 16.2.9: Custom View Search Form as side panel

In 16.2.9, there is a nice thing added to smartUI:

Custom View Search Form

First, a custom view search form has to be configured in the legacy gui, something like this:

A Custom View Search configured fpr a folder
A Custom View Search configured in the legacy gui

When switched to the smartUI, a doubleclick on the stored Search “Product Search” starts the Custom View Search

Search not started
Search started

Then the Search Panel appears on the left. Clicking on the “Search” Button will start the search. A click on the icon in the upper right will switch between the standard form and the tabular form of the search results.

Search results in standard list form
Tabular Form
Search Results in tabular form

Nice, isn’t it?

SmartUI expandable Tiles at Work

Wondered, how expandable Tiles work in smartUI?

The base Widget is a simple Tile:

Reiners Expandable Tile Entries
Expandable Tile Entries

Pressing the Expand Button (lower right) shows a different view with more details as a list:

Expanded Tile Entries
Expanded Tile Entries

Implementation:

For simplicity sake, all require.js setups are omitted. The complete javascript would run on a simple html page without connecting to Server.

First, we need a collection and a model. The model does have 3 attributes, name, desc, adv. 30 Models are filled automatically in the collection.

     var  ItemModel = Backbone.Model.extend({
              defaults: {
                  id: null,
                  name: 'Unnamed',
                  desc: 'Unnamed',
                  adv: 'Unnamed'
              }
          }),

      ItemCollection = Backbone.Collection.extend({
              model: ItemModel,
              initialize: function (models, options) {
                  this._items = _.times(30, function (index) {
                          ++index;
                          return {
                              id: index,
                              name: 'Item Entry No.' + index,
                              desc: 'the ' + index + 'th. Description',
                              adv: 'the adv attribute of the ' + index + '-Description Model'
                          };
                      });
                  this.makeFetchable(options)
                  .makeClientSideBrowsable(options);
              },
              sync: function (method, collection, options) {
                  if (method !== 'read') {
                      throw new Error('Only fetching the collection is supported.');
                  }
                  console.log('Getting', collection._items.length, 'items');
                  var deferred = $.Deferred();
                  setTimeout(function () {
                      var response = _.clone(collection._items);
                      if (!options) {
                          options = {};
                      }
                      if (options.success) {
                          options.success(response, options);
                      }
                      collection.trigger('sync', collection, response, options);
                      deferred.resolve(response);
                  }, 250);
                  return deferred.promise();
              }
          }),

Second, we need two views, a base view and an expanded view.

The base view with its template is:

      ListItemView = Marionette.ItemView.extend({
              className: 'binf-list-group-item',
              template: Handlebars.compile($('#list-item-template').html())
          }),
 
script id="list-item-template" type="text/x-handlebars-template"
  {{name}} 
/script

<> around the script tags are omitted

The extended view with its template is

ListFieldItemView = Marionette.ItemView.extend({

                  className: 'binf-list-group-item',

                  template: Handlebars.compile($('#list-item-template1').html()),

                  initialize: function () {

                      this.listenTo(this.collection, 'sync', this.render);

                      this.collection.fetch();

                  },

                  serializeData: function () {

                      if (!this.model && !this.collection) {

                          return {};

                      }
                   var args = [this.model || this.collection];
                  if (arguments.length) {
                      args.push.apply(args, arguments);
                  }

                  if (this.model) {
                      return this.serializeModel.apply(this, args);
                  } else {
                      return {
                          items: this.serializeCollection.apply(this, args)
                      };
                  }
              },
          }), 
script id="list-item-template1" type="text/x-handlebars-template"
   {{#each items}}
      p class="items"a href=#{{name}}  ----     {{desc}}---{{adv}}/a/p
  {{/each}}
/script

<> brackets around the html and script tags are omitted

The serialize function is used to make the collection renderable with handlebars.js. This and item-template1 will render to this expanded view:

We also need one base view, referencing our two views, one as contentview and one as expandedView. We add the Behavior Expanding with the options with our collection set. And of course, with several title and icon options set.

     ListTileView = TileView.extend({
              icon: 'header-openfolder',
              title: 'Reiners expandable Tile Entries',
              contentView: ListView,
              contentViewOptions: function () {
                  return {
                      collection: this.items
                  };
              },
              childEvents: {
                  'click .items': 'onClickItem'
              },
              onClickItem: function (target) {
                  this.trigger('click:item');
                  this.triggerMethod('execute:defaultAction', target.model);
                  alert("Clicked on item '" + target.model.attributes.name + "'");
              },
              behaviors: {

                  Expanding: {
                      behaviorClass: ExpandingBehavior,
                      expandedView: ListFieldItemView,
                      expandedViewOptions: function () {
                          return {
                              collection: this.contentView.collection
                          };
                      },
                      titleBarIcon: 'title-assignments',
                      dialogTitle: 'Reiners Special Tile expanded Details',
                      expandIconTitle: 'Reiners Expand Button',
                      dialogTitleIconRight: "icon-tileCollapse"
                  }
              },
              constructor: function (options) {
                  ListTileView.__super__.constructor.apply(this, arguments);
                  this.items = new ItemCollection(undefined, {
                          top: 30
                      });
                     // options.items = this.items;
              },
              onShow: function () {
                  this.items.fetch();
              }
          });

Initialize it and show it at the el #tile. Then you are done

      var
      // Create instances of the views to show on the page
      tileView = new ListTileView(),

      // Create helpers to show the views on the page

      tileRegion = new Marionette.Region({
              el: "#tile"
          });

      tileRegion.show(tileView);

Easy, isn’t it?

The complete html file containing the javascript demo code can be downloaded here

How to “widgedize” an existing CS Module

Lets discuss the strategies on how to “widgedize” an existing legacy GUI based module to support smartUI.

As we are discussing smartUI, we do only discuss the client side, the things to do on the server side are only drawn.

Ok, let’s start:

To keep the example easy, we use the Barcode Module, which is part of the core Content Server and is providing a very easy service.

  • Allows to mark a folder and to enter a filename and will print out the coversheet at the right
  • Used to be the designator of a document to be scanned with Enterprise Scan. The document wll be scanned and stored under the folder (defined by the path) and the name (defined by the Document name) in the Content Server.
  • Base for a Scan-Workflow
  • The Barcode module gives this as result
The Barcode result
Result of the Barcode Module Execution

This gives a Barcode ID, the Document Name and the Content Server Path. This sheet can be prited and scanned using Enterprise Scan. Then the next scanned document will be stored in the Content Server with that name and that path.

First, we have to do some investigations.

Investigate the GUI

  • Invoked by clicking on „Print Barcode“ at the container node menu
  • Will ask for the name of the scanned document and output the cover sheet for the scan order
Barcode Node Menu
Is available at the Node menu in the legacy gui
Then the Name of the document can be entered

Investigate the module

  • •Next, the module is interrogated for
    • Data Storage
    • Request handler
    • Internal processing
  • This can be done with the help of CSIDE
    • Use the Module-Tab and DONT(!) unlock the module or import.

Results

Obviously the module uses a table with this format

The barcode table format in SQL

With a unique index on the barcodeid. This is the number which is printed as barcode.

There is also one REST command existing. This REST command /api/v2/barcodes/{barcodeid} is obviously used by the Enterprise Scan to store the doc in the Content Server. It gives this JSON answers:

To be implemented

Server Side (Not part of this example)

  • Rest Services
    • To get the next unique number
    • To store the Barcode ID, Document name, the Path, the User and the Date in the barcode table

Client Side

  • New Barcode Widget
    • To select the parent container
    • To query for Document Name
    • To process all dates
    • To print the cover sheet locally
    • To be used as a small widget under connected workspaces

Client Side Development

  • Copy the base demo widget to a new folder under [yourprojDir]/src/widgets with a new name (p.ex.barcode)
  • Rename all references from the base demo widget to the new name (using wingrep etc)
  • Rename all files to the new widget name
  • Use the test\index.html to verify that all in the copying procedure was successful.
  • At this point the new widget should display the same output as the base widget
  • Add a Nodepicker to get the parent node
  • Use fiddler to search for the REST commands used by the nodepicker
  • Use postman to get the REST answers against an existing CS
  • Setup the REST mock up to test without the need to install the widget (text\index.html)
  • Put the output of the nodepicker to a text field to avoid typos
The Nodepicker Control
The Nodepicker Start Button in our Widget
  • Add a document name input field with a label of „Document name“
The Document name Input field

Next, you can add a „Process Barcode“ button, because everything is gathered. The User Name is in the Context, the Date is today. Process Barcode should (not part of this exercise) report the next sequence number from the table, store all data in the table and render

  • Add a display field for the cover sheet. First with dummy data, then with the actual data filled in. Ensure that the actual user is requested by using the base model.
  • Add a Print-Button
  • Add some Print Functionality using browser printer capabilities

The complete widget would look like

The complete barcode Widget in preliminary layout

ToDo if the Widget is correct

  • Implement the REST Services in the server
  • Add the REST client functionality in the widget
  • Add the REST calls in the mockup
  • Add the barcode widget in the project-name-extensions.json
  • Add the widget and the widgets manifest to the bundles file
  • Grunt
  • Copy the resulting files to the support dir of your carrier module
  • Test it
Adding the barcode widget in xxxxx-extensions.json
Adding the barcode widget in the bundles file

And you have added smartUI support to the barcode module and any Enterprise Scan workflows.

Easy, isn’t it?