Fluent Commerce Logo
Sign In

Fluent Store Dashboard: new dashboard tile based on fulfilment expiry time

How-to Guide
Extend

Author:

Randy Chan

Changed on:

16 Apr 2025

Key Points

  • A guide to extend Fluent STORE UI capabilities to allow the store users to have a better visibility on the fulfilments by expiry time.
  • The use case where the store staff would like to see number of fulfilments for the next 2 hours so that they can plan their pick and pack process accordingly. 
  • One of the solutions is by using OOTB component and manifest to display the fulfilments number based on the expiry time.  Hence, there are no custom rules nor custom component is required for this solution.
  • Here are the steps to archive the outcome:
    • Create a new screen in fluent Store
    • Create dashboard tiles

Steps

Step arrow right iconCreate a new screen in Fluent Store

Create a new setting for the new empty screen:

Name: fc.mystique.manifest.store.fragment.store_dashboard

Context: ACCOUNT

Context ID: 0

Value Type: JSON

JSON Value:

1{
2    "manifestVersion": "2.0",
3    "routes": [
4        {
5            "type": "page",
6            "path": "store_dashboard",
7            "component": "fc.page",
8            "nav": {
9                "label": "Store Dashboard",
10                "icon": "store"
11            },
12            "props": {
13                "title": "Store Dashboard"
14            },
15            "descendants": []
16        }
17    ]
18}

Language: json

Name: fc.mystique.manifest.store.fragment.store_dashboard JSON Value

Description:

fc.mystique.manifest.store.fragment.store_dashboard JSON Value

Then add the new setting to the fc.mystique.manifest.store

1{
2    "type": "reference",
3    "settingName": "fc.mystique.manifest.store.fragment.store_dashboard"
4},

Language: json

Name: fc.mystique.manifest.store

Description:

[Warning: empty required content area]
No alt provided

Refresh the store screen and you should able to see the new Store Dashboard page:

No alt providedNo alt provided

Step arrow right iconCreate dashboard tiles

This step is to create 4 dashboard tiles where:

  • Tile 1:  display the number of (AWAITING_WAVE) fulfilments with the expiry Time is less than 30 mins.
  • Tile 2: display the number of (AWAITING_WAVE) fulfilments with the expiry Time is between 30 and 60 mins.
  • Tile 3: display the number of (AWAITING_WAVE) fulfilments with the expiry Time is between 60 and 120 mins.
  • Tile 4: display the number of (AWAITING_WAVE) fulfilments assigned to this location.
Tile 1: Fulfilment expiring less than 30 mins

Parameter

Configuration

Data Source

`fulfilment_expired30Mins:fulfilment`
 query

Filters

  • `activeLocation.ref`
     of the current Location
  • `status`
     set to 
    `AWAITING_WAVE`
  • `ExpiryTime from:Now, to:+30mins`

Min Threshold

0

Max Threshold

0

link

awaiting-pick page has a default filter of location and status. Hence we only need to provide the fulfilments_expiryTime:

`#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}`

1{
2    "manifestVersion": "2.0",
3    "routes": [
4        {
5            "type": "page",
6            "path": "store_dashboard",
7            "component": "fc.page",
8            "nav": {
9                "label": "Store Dashboard",
10                "icon": "store"
11            },
12            "props": {
13                "title": "Store Dashboard"
14            },
15            "data": {
16                "query": "query ($ordersAwaitingPickFromLocationRef: String!, $ordersAwaitingPickStatus: [String]!,  $fulfilmentExpiryNow:DateTime!, $fulfilmentExpiry30mins:DateTime!) {  fulfilment_expired30Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiryNow, to:$fulfilmentExpiry30mins}) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  }  }",
17                "variables": {
18                    "ordersAwaitingPickFromLocationRef": "{{activeLocation.ref}}",
19                    "ordersAwaitingPickStatus": [
20                        "AWAITING_WAVE"
21                    ],
22                    "fulfilmentExpiryNow": "{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
23                    "fulfilmentExpiry30mins": "{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
24                }
25            },
26            "descendants": [
27                {
28                    "component": "fc.dashboard.threshold",
29                    "dataSource": "fulfilment_expired30Mins",
30                    "props": {
31                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired30Mins.title",
32                        "subTitle": "Expiring in 30 mins",
33                        "value": "{{edges.length}}",
34                        "thresholdLow": 0,
35                        "thresholdHigh": 0,
36                        "width": "third",
37                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
38                    }
39                }
40            ]
41        }
42    ]
43}

Language: json

Name: fc.mystique.manifest.store.fragment.store_dashboard with 1 dashboard tile

Description:

[Warning: empty required content area]

Update the language setting:

1"fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired30Mins.title": "ORDER AWAITING PICK EXPIRING in 30 mins",
2"fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired60Mins.title": "ORDER AWAITING PICK EXPIRING in 60 mins",
3"fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired120Mins.title": "ORDER AWAITING PICK EXPIRING in 2 hours",   
4

Language: json

Name: Add value in language setting: LANGUAGE_EN-AU

Description:

[Warning: empty required content area]
No alt provided

Refresh the Fluent Store screen:

No alt provided
Tile 2: Fulfilment expiring between 30 and 60 mins

Parameter

Configuration

Data Source

`fulfilment_expired60Mins:fulfilment`
 query

Filters

  • `activeLocation.ref`
     of the current Location
  • `status`
     set to 
    `AWAITING_WAVE`
  • `ExpiryTime from:+30mins, to:+60mins`

Min Threshold

1

Max Threshold

10

link

awaiting-pick page has a default filter of location and status. Hence we only need to provide the fulfilments_expiryTime:

`#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}`

1
2// 1. In the query section:
3//
4// 1.a Add a new parameter:
5, $fulfilmentExpiry60mins:DateTime!
6
7// 1.b add a new subquery:
8fulfilment_expired60Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiry30mins, to:$fulfilmentExpiry60mins }) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  }
9
10// 2. In the variables section:
11//
12,
13"fulfilmentExpiry60mins": "{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
14
15// 3. In the descendants section:
16,
17    {
18        "component": "fc.dashboard.threshold",
19        "dataSource": "fulfilment_expired60Mins",
20        "props": {
21            "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired60Mins.title",
22            "subTitle": "Expiring in 60 mins",
23            "value": "{{edges.length}}",
24            "thresholdLow": 1,
25            "thresholdHigh": 10,
26            "width": "third",
27            "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
28        }
29    } 
30

Language: json

Name: Extend the fc.mystique.manifest.store.fragment.store_dashboard for tile 2:

Description:

[Warning: empty required content area]
1{
2    "manifestVersion": "2.0",
3    "routes": [
4        {
5            "type": "page",
6            "path": "store_dashboard",
7            "component": "fc.page",
8            "nav": {
9                "label": "Store Dashboard",
10                "icon": "store"
11            },
12            "props": {
13                "title": "Store Dashboard"
14            },
15            "data": {
16                "query": "query ($ordersAwaitingPickFromLocationRef: String!, $ordersAwaitingPickStatus: [String]!,  $fulfilmentExpiryNow:DateTime!, $fulfilmentExpiry30mins:DateTime!, $fulfilmentExpiry60mins:DateTime!) {  fulfilment_expired30Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiryNow, to:$fulfilmentExpiry30mins}) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  } \n fulfilment_expired60Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiry30mins, to:$fulfilmentExpiry60mins }) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  } }",
17                "variables": {
18                    "ordersAwaitingPickFromLocationRef": "{{activeLocation.ref}}",
19                    "ordersAwaitingPickStatus": [
20                        "AWAITING_WAVE"
21                    ],
22                    "fulfilmentExpiryNow": "{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
23                    "fulfilmentExpiry30mins": "{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
24                    "fulfilmentExpiry60mins": "{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
25                }
26            },
27            "descendants": [
28                {
29                    "component": "fc.dashboard.threshold",
30                    "dataSource": "fulfilment_expired30Mins",
31                    "props": {
32                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired30Mins.title",
33                        "subTitle": "Expiring in 30 mins",
34                        "value": "{{edges.length}}",
35                        "thresholdLow": 0,
36                        "thresholdHigh": 0,
37                        "width": "third",
38                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
39                    }
40                },
41                {
42                    "component": "fc.dashboard.threshold",
43                    "dataSource": "fulfilment_expired60Mins",
44                    "props": {
45                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired60Mins.title",
46                        "subTitle": "Expiring in 60 mins",
47                        "value": "{{edges.length}}",
48                        "thresholdLow": 1,
49                        "thresholdHigh": 10,
50                        "width": "third",
51                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
52                    }
53                }                
54            ]
55        }
56    ]
57}

Language: json

Name: Extend the fc.mystique.manifest.store.fragment.store_dashboard with 2 dashboard tiles

Description:

[Warning: empty required content area]

Refresh the Fluent Store:

No alt provided

Follow the same pattern as above for tile 3 (with expiryTime from:60mins and to:120mins) and for tile 4 expiryTime parameter does not require:

1{
2    "manifestVersion": "2.0",
3    "routes": [
4        {
5            "type": "page",
6            "path": "store_dashboard",
7            "component": "fc.page",
8            "nav": {
9                "label": "Store Dashboard",
10                "icon": "store"
11            },
12            "props": {
13                "title": "Store Dashboard"
14            },
15            "data": {
16                "query": "query ($ordersAwaitingPickFromLocationRef: String!, $ordersAwaitingPickStatus: [String]!,  $fulfilmentExpiryNow:DateTime!, $fulfilmentExpiry30mins:DateTime!, $fulfilmentExpiry60mins:DateTime!, $fulfilmentExpiry120mins:DateTime!) {  fulfilment_expired30Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiryNow, to:$fulfilmentExpiry30mins}) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  } \n fulfilment_expired60Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiry30mins, to:$fulfilmentExpiry60mins }) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  } \n fulfilment_expired120Mins:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus, expiryTime:{from:$fulfilmentExpiry60mins, to:$fulfilmentExpiry120mins }) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  }\n fulfilment_awaitingwave:fulfilments(fromLocation: {ref: $ordersAwaitingPickFromLocationRef}, status: $ordersAwaitingPickStatus) {    edges {      node {        id        ref        order {          ref          totalPrice          customer {            firstName            lastName          }        }        expiryTime        deliveryType      }    }  } \n }",
17                "variables": {
18                    "ordersAwaitingPickFromLocationRef": "{{activeLocation.ref}}",
19                    "ordersAwaitingPickStatus": [
20                        "AWAITING_WAVE"
21                    ],
22                    "fulfilmentExpiryNow": "{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
23                    "fulfilmentExpiry30mins": "{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
24                    "fulfilmentExpiry60mins": "{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}",
25                    "fulfilmentExpiry120mins": "{{dateStringFormatter (dateAdd minute=120) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
26                }
27            },
28            "descendants": [
29                {
30                    "component": "fc.dashboard.threshold",
31                    "dataSource": "fulfilment_expired30Mins",
32                    "props": {
33                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired30Mins.title",
34                        "subTitle": "Expiring in 30 mins",
35                        "value": "{{edges.length}}",
36                        "thresholdLow": 0,
37                        "thresholdHigh": 0,
38                        "width": "third",
39                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd day=0) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
40                    }
41                },
42                {
43                    "component": "fc.dashboard.threshold",
44                    "dataSource": "fulfilment_expired60Mins",
45                    "props": {
46                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired60Mins.title",
47                        "subTitle": "Expiring in 60 mins",
48                        "value": "{{edges.length}}",
49                        "thresholdLow": 1,
50                        "thresholdHigh": 10,
51                        "width": "third",
52                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd minute=30) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
53                    }
54                },
55                {
56                    "component": "fc.dashboard.threshold",
57                    "dataSource": "fulfilment_expired120Mins",
58                    "props": {
59                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPickExpired120Mins.title",
60                        "subTitle": "Expiring in 120 mins",
61                        "value": "{{edges.length}}",
62                        "thresholdLow": 1,
63                        "thresholdHigh": 10,
64                        "width": "third",
65                        "link": "#/waves/list/awaiting-pick?fulfilments_expiryTime={\"from\":\"{{dateStringFormatter (dateAdd minute=60) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\",\"to\":\"{{dateStringFormatter (dateAdd minute=120) 'YYYY-MM-DD[T]HH:mm:ss.SSS' true}}Z\"}"
66                    }
67                },
68                {
69                    "component": "fc.dashboard.threshold",
70                    "dataSource": "fulfilment_awaitingwave",
71                    "props": {
72                        "label": "i18n:fc.sf.ui.waves.detail.dashboard.ordersAwaitingPick.title",
73                        "subTitle": "subTile text1",
74                        "value": "{{edges.length}}",
75                        "thresholdLow": 1,
76                        "thresholdHigh": 10,
77                        "width": "third"
78                    }
79                }
80            ]
81        }
82    ]
83}

Language: json

Name: fc.mystique.manifest.store.fragment.store_dashboard with 4 dashboard tiles

Description:

[Warning: empty required content area]
No alt provided