Fluent Commerce Logo
Docs
Sign In

Admin Console Overview

Essential knowledge

Author:

Fluent Commerce

Changed on:

6 Mar 2024

Overview

The Fluent Admin Console is a web browser-based portal, for retail business users, that provides the interface to manage orders, product availability, inventory and order fulfillment. The Admin Console is used by businesses and administrators to access a large range of functionality provided by the following Fluent Commerce apps:

  • Distributed Order Management
  • Global Inventory
  • Product Availability

Each app provides out-of-the-box capabilities that are accessed by the Fluent Admin Console.

By default, the Admin Console displays content in English. However, v4.44 release onwards, the Fluent platform provides support for multiple languages. For more information on languages and localization and configuring other languages, click here. The console should be used on tablets and computers that have an active internet connection and a supported web browser.


Key points

  • Fluent Admin Console Overview
  • Console Dashboard Overview
  • Configure the Console Dashboard to Identify and Display Missed SLAs

Console Dashboard

Browser Support

The following browsers have been tested:

  • Safari
  • Chrome
  • Firefox

Overview

The Console Dashboard is an exception management tool that displays information of entities (orders, fulfilments, etc.) that have not moved to the desired state as configured in the workflow. The Console Dashboard is completely configurable and is powered and configured by the Mystique manifest. The Dashboard component is configured to display real-time data coming from a GraphQL query. This component is grid-based and allows users to define a number of cards per row as an integer parameter from the manifest. For example, numOfCols. Each row of the grid has a configurable title and can have any number of cards defined in the manifest. The width (%) of each column is defined as 100 divided by numOfCols("tilesPerRow").

The image below displays an example of the Console Dashboard being configured using the Dashboard component to display orders and fulfillments that have missed specific SLA time periods.

No alt provided
  • The number of tiles is configurable within the Dashboard component using the tilesPerRow variable.
  • The max count displayed on the tile is fetched from the defaultPaginationVariables. The default value is set to 1000 for orders, fulfillments, and waves. This means that the maximum count displayed is 1000 even if the result is more than 1000.
  • The colour on the tiles will change as per the configuration in each tile. The default values are thresholdLow = 0 and thresholdHigh =10.
    • If count = thresholdLow, then tile colour -> White.
    • If count > thresholdLow and <= thresholdHigh, then tile colour -> Orange.
    • If count > thresholdHigh, then tile colour -> Red.

In the above diagram, two orders are in the AWAITING_COLLECTION state with an ORANGE rating. This means that these 2 orders have not exceeded the configured SLA (RED).

Configure the Console Dashboard to Identify and Display Missed SLAs

The Console Dashboard can be configured to display an order that has not moved within an SLA (service level agreement) time period to the (next) state defined in the workflow. This can be achieved by using GraphQL based queries for entities and getting a count of which entities (orders, fulfillments, etc) are not meeting there SLA and moving to the (configured) state. By configuring the console dashboard to identify missed SLAs, the dashboard can help operational/ support teams identify and rectify delays occurring in the order life cycle that may affect customers.

The Console Dashboard is powered by a dashboard component. This grid-based component containing cards provides the flexibility of allowing users to define the number of cards per row as an integer parameter from the manifest (e.g. numOfCols). Each row of the gird has a configurable title and can have any number of cards defined in the manifest with the width (%) of each column defined as 100 divided by numOfCols(tilesPerRow).

Step 1 - Create and Configure the Dashboard Page
  • Open the Mystique Console Manifest.
  • Create and configure the Dashboard page by editing/updating the existing mystique Page component. The example below shows how this can be done. The Dashboard page is the page/screen that displays the Dashboard (when selected from the menu).
1       {
2                   "menu": "Insights",
3                   "icon": "highlight",
4                   "routes": [
5                       {
6                           "path": "dashboard",
7                           "component": "shared.components.material.DynamicPage",
8                           "menuLabel": "SLA Dashboard",
9                           "menuIcon": "library_books",
10                           "params": {
11                               "graphql": {
12                                   "query": "query ($type_Ord: [String!], $NUS_Ord1: DateTime!, $NUS_Ord2: DateTime!, $NUS_Ff1: DateTime!) { ordersCreated: orders(status: \"CREATED\", type: $type_Ord, updatedOn: {to: $NUS_Ord1}) { pageInfo{ hasNextPage } edges { node { id } } } ordersBooked: orders(status: \"BOOKED\", type: $type_Ord, updatedOn: {to: $NUS_Ord2}) { pageInfo{ hasNextPage } edges { node { id } } } fulfilmentsCreated: fulfilments(status: \"PICK&PACK\", updatedOn: {to: $NUS_Ff1}) { pageInfo{ hasNextPage } edges { node { id } } }  ",
13                                   "variables": {
14                                       "NUS_Ord1": "{{dateStringFormatter (dateAdd minutes=-10) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'}}",
15                                       "NUS_Ord2": "{{dateStringFormatter (dateAdd day=-1) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'}}",
16                                       "NUS_Ff1": "{{dateStringFormatter (dateAdd day=-1) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'}}"
17
18                                   }
19                               },
20                           "defaultPaginationVariables": {
21                               "orders_first": 100,
22                               "fulfilments_first": 100,
23
24                           },
25                           "title": "SLA Dashboard - Updated on: {{dateStringFormatter (dateAdd)}}",
26                           "layouts": [
27                               {
28                                   "component": "shared.components.material.DynamicDashboard",
29                                   "params": {
30                                       "title": "Orders",
31                                       "tilesPerRow": 2,
32                                       "tiles": [
33                                           {
34                                               "title": "AWAITING CONFIRMATION",
35                                               "sla": "(> 10 min)",
36                                               "displayTemplate": "{{ ordersCreated.edges.length }}",
37                                               "thresholdLow": 0,
38                                               "thresholdHigh": 10,
39                                               "link_template": "#/orders1day?status[]=PENDING_PAYMENT"
40                                           },
41
42                                           {
43                                               "title": "AWAITING PICK",
44                                               "sla": "(> 1 day)",
45                                               "displayTemplate": "{{ ordersBooked.edges.length }}",
46                                               "thresholdLow": 0,
47                                               "thresholdHigh": 30,
48                                               "link_template": "#/orders1day?status[]=IN_PROGRESS"
49                                           }
50
51                                       ]
52                                   }
53                               },
54                               {
55                                   "component": "shared.components.material.DynamicDashboard",
56                                   "params": {
57                                       "title": "Fulfilments",
58                                       "tilesPerRow": 1,
59                                       "tiles": [
60
61                                           {
62                                               "title": "AWAITING CONFIRMATION",
63                                               "sla": "(> 1 day)",
64                                               "displayTemplate": "{{ fulfilmentsAssigned.edges.length }}",
65                                               "thresholdLow": 0,
66                                               "thresholdHigh": 8,
67                                               "link_template": "#/fulfilments1day?status[]=PICK&PACK"
68                                           }
69                                       ]
70                                   }
71                               }
72                           ]
73                       }
74                   },

Language: json

Name: Example

Description:

[Warning: empty required content area]

In the above example, the Dashboard screen has been configured under the Insights module and will display 2 Order and 1 Fulfilment statuses.

  • Tile1: Dashboard to check if an order is waiting for a payment service to confirm that the order can move to the next Status (Booked). A high number of orders on this tile can be indicative of integration services not working.
  • Tile2: Order in BOOKED status for more than 1 day. A high number of orders in this tile can be indicative of a store not processing allocated orders. This can be investigated further to identify whether the issue is a store or allocation based
  • Tile3: Dashboard to check if any fulfilment in the status of PICK & PACK is later than (more than) 1 day. The higher the number of orders currently stuck in this status can be indicative of a store not being able to book consignments for articles. This can be due to carrier integration services not working.
Step 2 - Add Queries to the Dashboard Page

Mystique currently only allows queries at the page level, so once the Dashboard page has been created and configured, the next step is to add a GQL query at the page level. The GQL query should be configured to extract the entity statuses, states, date ranges, etc that can be used to identify whether the entity has missed an SLA.

For all entities and their statuses, you need to configure tiles. In the above example (code block), three tiles need to be displayed. To do this, a query with fragments and a variable for each fragment.

In the fragment, it is recommended to form the query for an entity with an easily recognizable and distinguishable name as this name will be used in the tile to count the result set.

The default timestamp used in the time range field for GQL query is the user's local timezone; if you want to use UTC timestamp for consistent results across different timezones, use the second manifest snippet with UTC time conversion enabled "true".

Example

1ordersCreated: orders(status: \"CREATED\", type: $type_Ord, updatedOn: {to: $NUS_Ord1}) { pageInfo{ hasNextPage } edges { node { id } } } 
2    $NUS_Ord1-- this variable is the filter condition which will compare and update based on the current time difference if the result is  more than the defined SLA time period.

Language: json

Name: Example

Description:

[Warning: empty required content area]
1"query": "query($type_Ord: [String!], $NUS_Ord1: DateTime){ordersCreated: orders(status: \"CREATED\", type: $type_Ord, updatedOn: {to: $NUS_Ord1}) { pageInfo{ hasNextPage } edges { node { id } } } "
2"Variables": 
3"$NUS_Ord1":"{{dateStringFormatter (dateAdd day=-1) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"

Language: json

Name: Example

Description:

[Warning: empty required content area]
Step 3 - Configure the Dashboard Tiles

Once the Dashboard page and query/queries have been configured, it is time to set identification for the tiles of the Dashboard that display the count of the entities missing the SLA for the given status change. The Dashboard component supports the ability to define multiple rows and tiles per row.

To configure the tiles, continue to add/ edit the Mystique manifest. The following example shows two tiles being created per row with one of the tiles configured as AWAITING CONFIRMATION .

1   "params": {
2               "title": "Orders", //Define the title of the row on Dashboard page
3               "tilesPerRow": 2, // Defines the number of tiles in the dashboard row
4               "tiles": [
5               {
6                  "title": "AWAITING CONFIRMATION",                         // Title for dashboard tile display
7                  "sla": "(> 10 min)",                                     // Shown the SLA on dashboard tile display
8                  "displayTemplate": "{{ ordersCreated.edges.length }}",   // Count the result set to give count to display on dashboard tile
9                  "thresholdLow": 0,                                      // background colour for dashboard tile count 0 will be white
10                  "thresholdHigh": 10,                                    // background colour for dashboard tile count 1-10 will be Orange and more then 10 will be Red
11                  "link_template": "#/orders1day?status[]=PENDING_PAYMENT"// This is to define the click through link for the landing page from this tile
12               },

Language: json

Name: Example

Description:

[Warning: empty required content area]
Step 4 - Set up a Link Page for a Tile

Cards can also be configured (using a link template) to include a click-through link to take users to a detail page that provides more information. The following example shows a dashboard page set up with link pages.

1{
2                       "path": "orders10min",
3                       "component": "shared.components.material.DynamicPage",
4                       "params": {
5                           "graphql": {
6                               "query": "query($ref: [String], $type:[String!], $status: [String], $notUpdatedSince: DateTime!, $notUpdatedFrom: DateTime!) {orders(ref: $ref, status: $status, type:$type, updatedOn: {from: $notUpdatedFrom, to: $notUpdatedSince}){ edges{ node{ id ref retailer{id tradingName} type status workflowRef workflowVersion totalPrice createdOn updatedOn totalTaxPrice customer{id firstName lastName}}}}}",
7                               "variables": {
8                                   "notUpdatedSince": "{{dateStringFormatter (dateAdd minutes=-10) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'}}",
9                                   "notUpdatedFrom": "{{dateStringFormatter (dateAdd day=-5) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'}}"
10                               }
11                           },
12                           "title": "Orders List - SLA: 10 min",
13                           "primaryButtons": [],
14                           "backButtons": [
15                               {
16                                   "path": "dashboard",
17                                   "menuLabel": "Back to Dashboard "
18                               }
19                           ],
20                           "layouts": [
21                               {
22                                   "component": "shared.components.material.DynamicFilter",
23                                   "params": {
24                                       "filterable": {
25                                           "Order ref": "ref",
26                                           "Order Status": "status",
27                                           "Type": "type"
28                                       },
29                                       "label": "Filter orders on ref, status, type"
30                                   }
31                               },
32                               {
33                                   "component": "shared.components.material.DynamicList",
34                                   "params": {
35                                       "defaultPageSize": 10,
36                                       "dataSource": "orders",
37                                       "attributes": [
38                                           {
39                                               "label": "Order Ref",
40                                               "template": "{{node.ref}}",
41                                               "link_template": "#/orders/{{node.id}}"
42                                           },
43                                           {
44                                               "label": "Status",
45                                               "template": "{{node.status}}"
46                                           },
47                                           {
48                                               "label": "Last Update",
49                                               "template": "{{node.updatedOn}}"
50                                           },
51                                           {
52                                               "label": "Order Type",
53                                               "template": "{{node.type}}"
54                                           },
55                                           {
56                                               "label": "Customer",
57                                               "template": "{{node.customer.firstName}} {{node.customer.lastName}}"
58                                           },
59                                           {
60                                               "label": "Order Value",
61                                               "template": "{{node.totalPrice}}"
62                                           },
63                                           {
64                                               "label": "Retailer Name",
65                                               "template": "{{node.retailer.tradingName}}"
66                                           }
67                                       ]
68                                   }
69                               }
70                           ]
71                       }
72                   },

Language: json

Name: Example

Description:

[Warning: empty required content area]
Fluent Commerce

Fluent Commerce