Fluent Store Dashboard: new dashboard tile based on fulfilment expiry time
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
Prerequisites
Steps
Create 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]
Refresh the store screen and you should able to see the new Store Dashboard page:


Create 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 |
|
Filters |
|
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:
|
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]
Refresh the Fluent Store screen:

Tile 2: Fulfilment expiring between 30 and 60 mins
Parameter | Configuration |
Data Source |
|
Filters |
|
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:
|
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:

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]