Overriding work queue cards

A built-in work queue is based on a business object, such as Inventory or Shipment. You can override work queue cards for built-in work queues by using an API.

A built-in work queue might not always have work items that are associated with every row of the table. Instead, some rows might have business object information only until a work item is created through an action on that row, such as through user assignment or status change.

Built-in work queue use case

The information that is needed for the work item is in the businessObject field. For the standard work queue, to make a change to a specific work queue, you can use subscription overrides so that all users of a tenant see those changes to that specific work queue. Because all work queues use the same layout templates and card definitions, you must add the logical name of the work queue as a prefix to all your subscription override properties.

The following example shows a query that fetches the work queue definition from the Intelligence Suite database.

Query

query WorkQueueDefinition($tenantId: String, $workQueueId: String, $sortBy: String = "priority", $sortOrder: SortOrder = DESC) {
  workQueues: businessObjects(simpleFilter: {type: WorkQueueDefinition, tenantId: $tenantId}, advancedFilter: {EQUALS: [{SELECT: "id", type: STRING}, {VALUE: $workQueueId, type: STRING}]}, hint: {viewId: "graph"}, cursorParams: {first: 50, sort: {fieldPath: $sortBy, order: $sortOrder}}) {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      cursor
      object {
        ... on WorkQueueDefinition {
          id
          logicalName
          name
          priority
          description
          simpleFilter
          advancedFilter
          hint
          primaryBusinessObjectTypes
          defaultFieldsForSelect
          defaultCursorParams
        }
      }
    }
  }
}
Query variables

{
 "tenantId": "<TENANT_ID>",
 "workQueueId": "<WORK_QUEUE_ID>",
  "sortOrder": "DESC"
}
Response
{
  "data": {
    "workQueues": {
      "totalCount": 1,
      "pageInfo": {
        "hasNextPage": false,
        "endCursor": "MjI4MDY4ODM="
      },
      "edges": [
        {
          "cursor": "MjI4MDY4ODM=",
          "object": {
            "id": "d4c364f3-6ad0-4a19-b96f-e31fba636f53",
            "logicalName": "inventoryApproachingOutOfStockCopy1",
            "name": "Inventory approaching out of stock - copy",
            "priority": 100,
            "description": "Inventory with a minimal amount of remaining stock.",
            "simpleFilter": "{\"type\":\"Inventory\"}",
            "advancedFilter": "{\"AND\":[{\"GREATER_THAN\":[{\"SELECT\":\"quantityBelowLowerThreshold\",\"type\":\"FLOAT\"},{\"VALUE\":\"0\",\"type\":\"FLOAT\"}]},{\"GREATER_THAN\":[{\"SELECT\":\"quantity\",\"type\":\"FLOAT\"},{\"VALUE\":\"0\",\"type\":\"FLOAT\"}]},{\"EQUALS\":[{\"SELECT\":\"inventoryType\",\"type\":\"STRING\"},{\"VALUE\":\"PRODUCT\",\"type\":\"STRING\"}]}]}",
            "hint": "{\"viewId\":\"graph\"}",
            "primaryBusinessObjectTypes": [
              "Inventory"
            ],
            "defaultFieldsForSelect": [
              "Inventory.product.partNumber",
              "Inventory.product.name",
              "WorkItem.status",
              "WorkItem.userAssigned",
              "Inventory.location.locationIdentifier",
              "Inventory.location.locationName",
              "Inventory.quantity",
              "Inventory.quantityUnits",
              "Inventory.quantityBelowLowerThreshold",
              "Inventory.quantityLowerThreshold",
              "Inventory.product.category.name",
              "Inventory.plannerCode",
              "Inventory.product.plannerCode",
              "WorkItem.updateReceived"
            ],
            "defaultCursorParams": "{\"first\":20,\"sort\":[{\"fieldPath\":\"quantityBelowLowerThreshold\",\"order\":\"DESC\"}]}"
          }
        }
      ]
    }
  }
}
Note: Any properties in the tenant-specific subscription override any ones with a matching name in the all-tenants version. If you are making a change to the work queue, consult the all-tenants subscription first to see whether you need to make a merge. If you are changing only one work queue and not another, you do not need to copy the other work queues because the same subscription file holds overrides for all work queues, which are distinguished by a preceding logical name.

For example, an entry in the subscriptionConfig might be the following code snippet:

{
  "name": "inventoryApproachingOutOfStockCopy1.columns[0].cell.label",
  "value": "{{ Test }}"
},

The code snippet shows that the inventoryApproachingOutOfStockCopy1 work queue has an override for the property columns[0].cell.label on this card's widget definition.

The following diagram shows the order in which overrides are applied. The subscription overrides from all tenants are automatically included for specific tenants. However, since tenant-specific overrides take precedence, if duplicate properties are identified, then the tenant-specific value is used.

Diagram illustrating override order

Overriding cards on the Work items tabs page

Some work queues are not associated with a business object. For work queues that are associated with work items only, you must make changes to work with your generalized work queues layout templates. For example,
  • OPEN_WORK_ITEMS_LAYOUT_TEMPLATE for the open tab on the tabs page,
  • CLOSED_WORK_ITEMS_LAYOUT_TEMPLATE for the closed tab,
  • WORK_ITEM_DETAILS_LAYOUT_TEMPLATE for the resolutions page.

Overriding the open tab on Work queue items tabs page

The widget definition for the open tab is OPEN_WORK_QUEUE_ITEMS_V2. A subscription for OPEN_WORK_QUEUE_ITEMS_subscription.json is needed for your tenant ID.

  1. Create a tenant-specific subscription for card if none exists.

    1. To get all subscriptions, make the following GET API call.
      URL
      GET {{API_URL}}/api/v1/wms/subscriptions?tenantId=<MY_TENANT_ID>
      Method GET
    2. To create a subscription, make the following POST API call.
      URL
      POST _/api/v1/wms/subscriptions/subscribe_
      Method GET
      Body
      
      {
        "widgetDefinitionId": "OPEN_WORK_QUEUE_ITEMS_V2",
        "state": "ACTIVE",
        "tenantId":"<TENANT_ID>",
        "subscriptionConfig": [
      ...any configs for other work queues that was in the all-tenants subscription config that we want to override
      ...and our configurations, outlined below
      ]
      
    3. Create a subscription now with no overrides for the current definition and take note of the subscription ID. Then, you can later make a PUT API call to the following location: /api/v1/wms/subscriptions/<SUBSCRIPTION_ID>
    4. If you want to change a value of a column without overriding a transformation, access all regular nonwork item fields with the business object type in front of the attribute.

      For example, if you want to access the first global identifier and the work queue is of type "Product", you can add the following parameters to subscriptionConfig,

      
           {
                  "name": "inventoryApproachingOutOfStockCopy1.columns[1].cell.label",
                  "value": "{{ Inventory.globalIdentifiers[0].value }}"
            },
      Note: For any attribute that is overwritten to enable sorting, you must confirm that the attribute is sortable in Intelligence Suite by running the query with that attribute as sortBy first. If there is an error or if the items are not sorted afterward, then Intelligence Suite must be consulted to see whether sorting can be enabled on that particular column.
  2. Overwrite the name of the first column.

    The work queue is based on a business object, and the column headers and values are based on the work queue's defaultFieldsForSelect and the data comes from the business object data. Any part of the table can be overwritten.

    {
      "name": "inventoryApproachingOutOfStockCopy1.columns[0].header.label",
      "value": "Test"
    }
    

    To hide a column entirely, set the hidden property to true. For example, the preceding changes need to be made for each tab's widget definition's subscriptions, both Open and Closed. The following ids are the ID of the widget definitions for each tab:

    • Open - OPEN_WORK_QUEUE_ITEMS_V2.
    • Closed - CLOSED_WORK_QUEUE_ITEMS_V2

    If you want to confirm, see the URL to take the layout template ID. Get the template with a GET request to /api/v1/wms/layout_templates/<layout_template_id>. Under widgets, you can see the widgetDefinitionId of each card on the page.

Overriding cards on the Work item Resolutions page

Similarly, the work item resolution page can be customized with subscription overrides by adding tenant-level subscriptions to any card that needs customization.

Hiding a card on the resolutions page

To hide a card on the resolutions page, a subscription configuration that sets the enabled property of cards to false is needed. For example, if you want to hide the research assistant card, the following subscription suffices:


{
  "id": "RESEARCH_ASSISTANT_subscription",
  "tenantId": "<TENANT_ID>",
  "widgetDefinitionId": "RESEARCH_ASSISTANT",
  "offeringId": "SCO",
  "state": "ACTIVE",
  "subscriptionConfig": [
    {
      "name": "inventoryApproachingOutOfStockCopy1.enabled",
      "value": "false"
    }
  ]
}

Because it is the only card within that accordion section, disabling the research assistant hides the entire accordion section.

Changing the layout template that is shown in Additional Details

The layout template that is rendered in the Additional Details section of the work item resolution page is by default the detail page of the associated business object of that work queue. For example, a work queue of type inventory renders the Inventory detail page there. To use a different page, complete following steps:

  1. Get the layout template ID of page that you want to use.
  2. Override the WORK_ITEM_ADDITIONAL_DETAILS_IFRAME widget property for your tenant ID with the iframe path of the layout template ID and the iframe query parameterss of the parameters that the layout template needs.

Example

For a tenant ID, the additional details iframe loads the SEVERE_WEATHER_DETAILS_LAYOUT_TEMPLATE instead of the default one for the business object.


POST {{API_URL}}/api/v1/wms/subscriptions/subscribe

{
    "tenantId": "<TENANT_ID>",
    "widgetDefinitionId": "WORK_ITEM_ADDITIONAL_DETAILS_IFRAME",
    "state": "ACTIVE",
    "subscriptionConfig": [
        {
            "name": "emergencyMaterialPlanning.iframe.path",
            "value": "/template/SEVERE_WEATHER_DETAILS_LAYOUT_TEMPLATE"
        },
        {
            "name": "emergencyMaterialPlanning.iframe.queryParams",
            "value": "weatherId={{ businessObjectId }}&disabledLayoutFeatures=ivAssistantEnabled,timestampEnabled"
        }
    ]
}
Changing the labels on the work item header card

To change a label on the work item header widget, a few subscription overrides need to be added and the path for which attributes must be shown must be clear. For example, if the product ID label must be changed to "Test" so that it shows Test, instead of the product ID in the header at the top of the page, then change the WORK_ITEM_DETAILS_BUSINESS_OBJECT_PROCESSOR 's transformation and make sure that you include any other attributes with certain labels that you want to include and the defaultFieldsForSelect in WORK_ITEM_HEADER.

WORK_ITEM_HEADER override
        {
            "name": "inventoryApproachingOutOfStockCopy1.defaultFieldsForSelect",
            "value": "[\"test\", \"productName\", \"status\", \"userAssigned\", \"locationID\", \"locationName\", \"quantity\", \"quantityUnits\"]"
        }
WORK_ITEM_DETAILS_BUSINESS_OBJECT_PROCESSOR override

You do not need to explicitly include quantity and quantityUnits for the value to appear correctly because those paths are identical to the labels Inventory.quantity and Inventory.quantityUnits. For values such as locationID, no Inventory.locationID is applicable so you must include it in this transformation for the mapping to work:

              {
            "name": "inventoryApproachingOutOfStockCopy1.transformation",
            "value": "{\"errors\":\"{{#? this.errors}}\", \"pageInfo\":\"{{this.data.businessObjectItem.pageInfo}}\", \"totalCount\":\"{{this.data.businessObjectItem.totalCount}}\", \"results\":{\"{{#each this.data.businessObjectItem.edges}}\": { \"{{ #merge }}\": [ \"{{this.object}}\", {\"test\": \"{{this.object.product.partNumber}}\", \"locationID\": \"{{this.object.location.locationIdentifier}}\", \"locationName\": \"{{this.object.location.locationName}}\",\"productName\": \"{{this.object.product.name}}\"}]}}}"
        }