SearchKit: two displays on dashboard using similar search incorrectly share Total value -- variable leakage?
Overview
Following text posted here: https://chat.civicrm.org/civicrm/pl/qp6ssaudj3875qroobpkkciiao
For SearchKit Table Display, it looks like the Totals in the footer is not unique to the individual display.
In other words, if you have two membership summary displays and select Show Totals in Footer
then put both of them on your dashboard, they'll show the same total for whichever table was refreshed last.
Reproduction steps
- Create two membership summary displays in SearchKit that are enabled to be displayed on the dashboard.
- On the dashboard, drag both of them to display.
- Notice the total will be the same for both.
- Refresh the one with the wrong total.
- Notice that both totals change to that updated total.
SearchKit with form and display for Active Memberships
[
[
"SavedSearch",
"save",
{
"records": [
{
"name": "Current_Active_Members",
"label": "Current Active Members Summary",
"form_values": null,
"mapping_id": null,
"search_custom_id": null,
"api_entity": "Membership",
"api_params": {
"version": 4,
"select": [
"membership_type_id:label",
"COUNT(id) AS COUNT_id",
"GROUP_CONCAT(DISTINCT status_id:label) AS GROUP_CONCAT_status_id_label"
],
"orderBy": [],
"where": [
[
"status_id:name",
"IN",
[
"New",
"Grace",
"Current"
]
],
[
"Membership_Contact_contact_id_01.is_deleted",
"=",
false
]
],
"groupBy": [
"membership_type_id"
],
"join": [
[
"Contact AS Membership_Contact_contact_id_01",
"LEFT",
[
"contact_id",
"=",
"Membership_Contact_contact_id_01.id"
],
[
"Membership_Contact_contact_id_01.is_deleted",
"=",
false
]
]
],
"having": []
},
"expires_date": null,
"description": "Display current active members. With new, grace, current."
}
],
"match": [
"name"
]
}
],
[
"SearchDisplay",
"save",
{
"records": [
{
"name": "Current_Active_Members_Table_1",
"label": "Current Active Members Table 1",
"saved_search_id.name": "Current_Active_Members",
"type": "table",
"settings": {
"description": "Display current active members summary. With new, grace, current.",
"sort": [],
"limit": 50,
"pager": [],
"placeholder": 5,
"columns": [
{
"type": "field",
"key": "membership_type_id:label",
"dataType": "Integer",
"label": "Membership Type",
"sortable": true,
"tally": {
"fn": null
}
},
{
"type": "field",
"key": "COUNT_id",
"dataType": "Integer",
"label": "Count",
"sortable": true,
"tally": {
"fn": "SUM"
}
},
{
"type": "field",
"key": "GROUP_CONCAT_status_id_label",
"dataType": "Integer",
"label": "(List) Status",
"sortable": true,
"tally": {
"fn": null
}
}
],
"actions": false,
"classes": [
"table",
"table-striped"
],
"headerCount": false,
"tally": {
"label": "Total"
}
},
"acl_bypass": false
}
],
"match": [
"name",
"saved_search_id"
]
}
],
[
"Afform",
"save",
{
"records": [
{
"name": "afsearchMembersCurrentActiveTable",
"requires": [],
"title": "Members: Current Active Summary",
"description": "Display current active members. With new, grace, current.",
"is_dashlet": true,
"is_public": false,
"is_token": false,
"permission": "access CiviCRM",
"type": "search",
"entity_type": null,
"join_entity": null,
"contact_summary": null,
"summary_contact_type": null,
"icon": "fa-list-alt",
"server_route": "civicrm/member/summary-current",
"redirect": null,
"create_submission": false,
"navigation": {
"parent": "Membership Reports",
"label": "Members: Current Active Summary",
"weight": 9
},
"layout": "<div af-fieldset=\"\">\n <crm-search-display-table search-name=\"Current_Active_Members\" display-name=\"Current_Active_Members_Table_1\"></crm-search-display-table>\n</div>\n"
}
]
}
]
]
SearchKit with form and display for Not Active Memberships
[
[
"SavedSearch",
"save",
{
"records": [
{
"name": "Not_Active_Members",
"label": "Members: Not Active (Pending, Expired, Deceased)",
"form_values": null,
"mapping_id": null,
"search_custom_id": null,
"api_entity": "Membership",
"api_params": {
"version": 4,
"select": [
"membership_type_id:label",
"COUNT(id) AS COUNT_id",
"GROUP_CONCAT(DISTINCT status_id:label) AS GROUP_CONCAT_status_id_label"
],
"orderBy": [],
"where": [
[
"status_id:name",
"NOT IN",
[
"New",
"Grace",
"Current"
]
],
[
"Membership_Contact_contact_id_01.is_deleted",
"=",
false
]
],
"groupBy": [
"membership_type_id"
],
"join": [
[
"Contact AS Membership_Contact_contact_id_01",
"LEFT",
[
"contact_id",
"=",
"Membership_Contact_contact_id_01.id"
]
]
],
"having": []
},
"expires_date": null,
"description": "Members that do not have a membership status of New, Grace, or Current. Includes at least Pending, Expired, Deceased."
}
],
"match": [
"name"
]
}
],
[
"SearchDisplay",
"save",
{
"records": [
{
"name": "Not_Active_Members_Table_1",
"label": "Not Active Members Table 1",
"saved_search_id.name": "Not_Active_Members",
"type": "table",
"settings": {
"description": "Members: Not Active (Pending, Expired, Deceased)",
"sort": [],
"limit": 50,
"pager": [],
"placeholder": 5,
"columns": [
{
"type": "field",
"key": "membership_type_id:label",
"dataType": "Integer",
"label": "Membership Type",
"sortable": true,
"tally": {
"fn": null
}
},
{
"type": "field",
"key": "COUNT_id",
"dataType": "Integer",
"label": "Count",
"sortable": true,
"tally": {
"fn": "SUM"
}
},
{
"type": "field",
"key": "GROUP_CONCAT_status_id_label",
"dataType": "Integer",
"label": "(List) Status",
"sortable": true,
"tally": {
"fn": null
}
}
],
"actions": false,
"classes": [
"table",
"table-striped"
],
"tally": {
"label": "Total"
}
},
"acl_bypass": false
}
],
"match": [
"name",
"saved_search_id"
]
}
],
[
"Afform",
"save",
{
"records": [
{
"name": "afsearchMembersNotActivePendingExpiredDeceased",
"requires": [],
"title": "Members: Not Active (Pending, Expired, Deceased)",
"description": "",
"is_dashlet": true,
"is_public": false,
"is_token": false,
"permission": "access CiviCRM",
"type": "search",
"entity_type": null,
"join_entity": null,
"contact_summary": null,
"summary_contact_type": null,
"icon": "fa-list-alt",
"server_route": "civicrm/member/summary-notactive",
"redirect": null,
"create_submission": false,
"navigation": {
"parent": "Membership Reports",
"label": "Members: Not Active (Pending, Expired, Deceased)",
"weight": 10
},
"layout": "<div af-fieldset=\"\">\n <crm-search-display-table search-name=\"Not_Active_Members\" display-name=\"Not_Active_Members_Table_1\"></crm-search-display-table>\n</div>\n"
}
]
}
]
]
Current behaviour
Total incorrect for one of the displays, showing the same value for both. Seems like the variable name may not be unique between the two SearchKit displays. Described above.
Expected behaviour
Total should be correct value.
Environment information
- Browser: Safari 16.5 (16615.2.9.11.6, 16615)
- CiviCRM: 5.61.2
- PHP: 8.0.28
- CMS: WordPress 6.2.2
- Database: MariaDB 10.6
- Web Server: Apache 2.4.57 / Nginx 1.21.3
Comments
Apologies for the long code sections for the exported SearchKit settings. @colemanw asked to be tagged during the SearchKit meeting, today.