Can the My Assignments widget be filtered? Or can I create a webreport that mimics node list widgets

The context: We have a perspective for employees that are part of our Health and Safety team. In that perspective, we use the My Assignments widget to get access to workflow steps that might be assigned to the employee. However, My Assignments shows all assignments, including tasks.

I have a request to have the My Assignments widget only show Workflow Steps for specific workflow maps. As far as I know, the widget can't be customized to do so.

So I have created a webreport that lists all the current active workflow tasks for the employee, filtered to only the workflow types that are related to the Health and Safety Team. However, the webreport widget doesn't have the same Search and Expand icons that Node List Widgets or My Assignments widgets have. That got me wondering on how the My Assignments widget works exactly. It looks like a Node List widget, but workflow steps are not Nodes in Content Server.

Is there a way to customize the My Assignments widget? Is there a way to create a Node List widget for workflow steps?

Comments

  • Hi David,

    Assignments use a different data model to the nodes in the NodesList and the other node list widgets like Favorites and Recently Accessed so you won't be able to reliably create a list of assignments using the WebReports Nodes List widget.

    The search and expand are different just because the My Assignments widget switched to use a newer mechanism to show the search and expand buttons on hover and the expand launches a new Perspective rather than a modal. This should be changed at some point for the NodesList but it's dependent on a few other pieces of work before the change can be made.

    Regards
    Ian
  • Ferdinand Prantl
    edited September 10, 2020 #3
    Both MyAssignments widgets (list and table) call /api/v2/members/assignments. If you find a way to hook in, or to the underlying InboxItem subsystem in OScript, you will save a lot of work. But I do not know, if it is feasible.

    If you find some way how to do it easily in Classic UI, you can open the Classic UI page from Smart UI.

    When looking at Smart UI, this is the subject of your customisation:
    1. collection retrieving the assignments
    2. small tile widget showing a list of assignments
    3. large table widget showing assignments
    4. perspective showing the table widget on the URL /myassignments
    You need only to filter the collection of assignments, otherwise the widgets are fine.
    However, there is no easy way to hook into the collection and achieve a minimum customisation. (The existing way to hook into the collection is implementing a server adaptor, which could add some filtering parameters. But server adaptors are available for adapting Smart UI to a specific product platform like CS, Documentum etc. You cannot use it to modify the behaviour of the CS Smart UI application today.)

    There is no way to hook into the existing widget or supply it some parameters. When you create your own widgets, trying to reuse as much of the original code, you will end up replacing all four parts above.
    1. inherit FilteredAssignmentsCollection from MyAssignmentsCollection and override parse to filter out what you need, create FilteredAssignmentsCollectionFactory for it
    2. inherit FilteredAssignmentsView from MyAssignmentsView and pass options.collection to the parent constructor to make it use your data
    3. inherit FilteredAssignmentsTableView from MyAssignmentsTableView and pass options.collection to the parent constructor to make it use your data
    4. create perspective context plugin for the scope "filtered-assignments", which will navigate to a perspective showing the new widget, and perspective router for the URL "/filtered-assignments"
    Sample implementation of the public modules:

    src/models/filtered.assignments/filtered.assignments.js:
    <div>FilteredAssignmentsCollection = MyAssignmentsCollection.extend({
      parse: function (response, options) {
        var assignments = MyAssignmentsCollection.prototype.parse.call(this, response, options);
        return assignments.filter(...);
      }
    });</div><div></div>
    src/widgets/filtered.assignments/filtered.assignments.view.js:
    <div>FilteredAssignmentsView = MyAssignmentsView.extends({
      constructor: function FilteredAssignmentsView(options) {
        options.collection = options.context.getCollection(FilteredAssignmentsCollectionFactory);
        MyAssignmentsView.call(this, options);
      }
    });</div><div></div>
    src/widgets/filtered.assignments.table/filtered.assignments.table.view.js:
    <div>FilteredAssignmentsTableView = MyAssignmentsTableView.extends({
      constructor: function FilteredAssignmentsTableView(options) {
        options.collection = options.context.getCollection(FilteredAssignmentsCollectionFactory);
        MyAssignmentsTableView.call(this, options);
      }
    });</div><div></div>
    src/plugins/filtered.assignments.context.plugin/filtered.assignments.context.plugin.js:
    <div>FilteredAssignmentsPerspectiveContextPlugin = PerspectiveContextPlugin.extend({
      constructor: function FilteredAssignmentsPerspectiveContextPlugin(options) {
        PerspectiveContextPlugin.call(this, options);
        this.applicationScope = this.context
            .getModel('applicationScope')
            .on('change', this._openFilteredAssignments, this);
      },
      _openFilteredAssignments: function () {
        if (this.applicationScope.id !== 'filtered-assignments') {
          this.applicationScope.set('id', 'filtered-assignments');
          this.context.loadPerspective('json!myext/plugins/filtered.assignments.context.plugin/impl/filtered.assignments.json');
        }
      }
    });</div><div></div>
    src/plugins/filtered.assignments.context.plugin/impl/filtered.assignments.json:
    <div>{
      "type": "left-center-right",
      "options": {
        "center": { "type": "myext/widgets/filtered.assignments.table" }
      }
    }</div><div></div>
    src/routers/filtered.assignments.router/filtered.assignments.router.js:
    <div>var FilteredAssignmentsPerspectiveRouter = PerspectiveRouter.extend({
      routes: { 'filtered-assignments': '_openFilteredAssignments' },
      constructor: function FilteredAssignmentsPerspectiveRouter(options) {
        PerspectiveRouter.call(this, options);
        this.applicationScope = this.context.getModel('applicationScope');
        this.listenTo(this.applicationScope, 'change', this._updateUrl);
      },
      _openFilteredAssignments: function () {
        this.applicationScope.set('id', 'filtered-assignments');
      },
      _updateUrl: function () {
        if (this.applicationScope.id === 'filtered-assignments') {
          document.title = 'Filtered Assignments';
          this.navigate('filtered-assignments');
        }
      }
    });</div><div></div>
    src/myext-extensions.json:
    <div>"csui/models/widget/widget.collection": {
      "widgets": {
        "myext": [
          "myext/widgets/filtered.assignments",
          "myext/widgets/filtered.assignments.table"
        ]
      }
    },
    "csui/utils/contexts/perspective/perspective.context": {
      "extensions": {
        "myext": ["myext/plugins/filtered.assignments.context.plugin/filtered.assignments.context.plugin"]
      }
    },
    "csui/pages/start/perspective.routing": {
      "extensions": {
        "myext": ["myext/routers/filtered.assignments.router/filtered.assignments.router"]
      }
    },
    ....
    </div>
  • Has there been any delivered options or updates on this topic? We would like to configure My Assignments to show assigned to user, not a group. Is this possible?