First attempt at Find Contributions replacement
authorAidan Saunders <aidan.saunders@squiffle.uk>
Thu, 6 Jul 2023 06:55:34 +0000 (07:55 +0100)
committerAidan Saunders <aidan.saunders@squiffle.uk>
Tue, 18 Jul 2023 09:19:21 +0000 (10:19 +0100)
ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.html [new file with mode: 0644]
ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.json [new file with mode: 0644]
ext/civicrm_admin_ui/managed/SavedSearch_Find_Contributions.mgd.php [new file with mode: 0644]

diff --git a/ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.html b/ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.html
new file mode 100644 (file)
index 0000000..6bdd270
--- /dev/null
@@ -0,0 +1,45 @@
+<div af-fieldset="">
+  <div class="af-container af-layout-inline af-collapsible" af-title="Contact Filters">
+    <af-field name="Contribution_Contact_contact_id_01.display_name" />
+    <af-field name="Contribution_Contact_contact_id_01.tags" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="Contribution_Contact_contact_id_01.groups" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="Contribution_Contact_contact_id_01.contact_type" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="Contribution_Contact_contact_id_01.is_deleted" defn="{required: false, label: 'Search in Trash (deleted contacts)'}" />
+  </div>
+  <div class="af-container af-layout-inline af-collapsible" af-title="Common Filters">
+    <af-field name="receive_date" defn="{input_type: 'Select', search_range: true, options: [{id: '{}', label: 'Choose Date Range'}, {id: 'this.day', label: 'Today'}, {id: 'this.week', label: 'This week'}, {id: 'this.month', label: 'This calendar month'}, {id: 'this.quarter', label: 'This quarter'}, {id: 'this.fiscal_year', label: 'This fiscal year'}, {id: 'this.year', label: 'This calendar year'}, {id: 'previous.day', label: 'Yesterday'}, {id: 'previous.week', label: 'Previous week'}, {id: 'previous.month', label: 'Previous calendar month'}, {id: 'previous.quarter', label: 'Previous quarter'}, {id: 'previous.fiscal_year', label: 'Previous fiscal year'}, {id: 'previous.year', label: 'Previous calendar year'}, {id: 'ending.week', label: 'Last 7 days including today'}, {id: 'ending_30.day', label: 'Last 30 days including today'}, {id: 'ending_60.day', label: 'Last 60 days including today'}, {id: 'ending_90.day', label: 'Last 90 days including today'}, {id: 'ending.year', label: 'Last 12 months including today'}, {id: 'ending_2.year', label: 'Last 2 years including today'}, {id: 'ending_3.year', label: 'Last 3 years including today'}, {id: 'starting.day', label: 'Tomorrow'}, {id: 'next.week', label: 'Next week'}, {id: 'next.month', label: 'Next calendar month'}, {id: 'next.quarter', label: 'Next quarter'}, {id: 'next.fiscal_year', label: 'Next fiscal year'}, {id: 'next.year', label: 'Next calendar year'}, {id: 'starting.week', label: 'Next 7 days including today'}, {id: 'starting.month', label: 'Next 30 days including today'}, {id: 'starting_2.month', label: 'Next 60 days including today'}, {id: 'starting.quarter', label: 'Next 90 days including today'}, {id: 'starting.year', label: 'Next 12 months including today'}, {id: 'current.week', label: 'Current week to-date'}, {id: 'current.month', label: 'Current calendar month to-date'}, {id: 'current.quarter', label: 'Current quarter to-date'}, {id: 'current.year', label: 'Current calendar year to-date'}, {id: 'earlier.day', label: 'To end of yesterday'}, {id: 'earlier.week', label: 'To end of previous week'}, {id: 'earlier.month', label: 'To end of previous calendar month'}, {id: 'earlier.quarter', label: 'To end of previous quarter'}, {id: 'earlier.year', label: 'To end of previous calendar year'}, {id: 'greater.day', label: 'From start of current day'}, {id: 'greater.week', label: 'From start of current week'}, {id: 'greater.month', label: 'From start of current calendar month'}, {id: 'greater.quarter', label: 'From start of current quarter'}, {id: 'greater.year', label: 'From start of current calendar year'}, {id: 'less.week', label: 'To end of current week'}, {id: 'less.month', label: 'To end of current calendar month'}, {id: 'less.quarter', label: 'To end of current quarter'}, {id: 'less.year', label: 'To end of current calendar year'}, {id: 'previous_2.day', label: 'Previous 2 days'}, {id: 'previous_2.week', label: 'Previous 2 weeks'}, {id: 'previous_2.month', label: 'Previous 2 calendar months'}, {id: 'previous_2.quarter', label: 'Previous 2 quarters'}, {id: 'previous_2.year', label: 'Previous 2 calendar years'}, {id: 'previous_2.fiscal_year', label: 'Previous 2 fiscal years'}, {id: 'previous_before.day', label: 'Day prior to yesterday'}, {id: 'previous_before.week', label: 'Week prior to previous week'}, {id: 'previous_before.month', label: 'Month prior to previous calendar month'}, {id: 'previous_before.quarter', label: 'Quarter prior to previous quarter'}, {id: 'previous_before.year', label: 'Year prior to previous calendar year'}, {id: 'previous_before.fiscal_year', label: 'Fiscal year prior to previous fiscal year'}, {id: 'greater_previous.week', label: 'From end of previous week'}, {id: 'greater_previous.month', label: 'From end of previous calendar month'}, {id: 'greater_previous.quarter', label: 'From end of previous quarter'}, {id: 'greater_previous.year', label: 'From end of previous calendar year'}], input_attrs: {}}" />
+    <af-field name="total_amount" defn="{required: false, input_attrs: {}, input_type: 'Number', search_range: true, label: 'Total Amount (min, max)'}" />
+    <af-field name="contribution_status_id" defn="{input_attrs: {multiple: true}, afform_default: ['1']}" />
+    <af-field name="currency" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="financial_type_id" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="contribution_page_id" defn="{input_attrs: {multiple: true}}" />
+    <af-field name="source" />
+    <af-field name="id" defn="{required: false, input_attrs: {}}" />
+  </div>
+  <div class="af-container af-layout-inline af-collapsible af-collapsed" af-title="Yes/No">
+    <legend class="af-text">Dev note: these should all be Yes/No radios.&nbsp; See https://lab.civicrm.org/dev/core/-/issues/4415</legend>
+    <af-field name="thankyou_date" defn="{input_type: 'Select', options: [{id: 'this.day', label: 'Today'}, {id: 'this.week', label: 'This week'}, {id: 'this.month', label: 'This calendar month'}, {id: 'this.quarter', label: 'This quarter'}, {id: 'this.fiscal_year', label: 'This fiscal year'}, {id: 'this.year', label: 'This calendar year'}, {id: 'previous.day', label: 'Yesterday'}, {id: 'previous.week', label: 'Previous week'}, {id: 'previous.month', label: 'Previous calendar month'}, {id: 'previous.quarter', label: 'Previous quarter'}, {id: 'previous.fiscal_year', label: 'Previous fiscal year'}, {id: 'previous.year', label: 'Previous calendar year'}, {id: 'ending.week', label: 'Last 7 days including today'}, {id: 'ending_30.day', label: 'Last 30 days including today'}, {id: 'ending_60.day', label: 'Last 60 days including today'}, {id: 'ending_90.day', label: 'Last 90 days including today'}, {id: 'ending.year', label: 'Last 12 months including today'}, {id: 'ending_2.year', label: 'Last 2 years including today'}, {id: 'ending_3.year', label: 'Last 3 years including today'}, {id: 'starting.day', label: 'Tomorrow'}, {id: 'next.week', label: 'Next week'}, {id: 'next.month', label: 'Next calendar month'}, {id: 'next.quarter', label: 'Next quarter'}, {id: 'next.fiscal_year', label: 'Next fiscal year'}, {id: 'next.year', label: 'Next calendar year'}, {id: 'starting.week', label: 'Next 7 days including today'}, {id: 'starting.month', label: 'Next 30 days including today'}, {id: 'starting_2.month', label: 'Next 60 days including today'}, {id: 'starting.quarter', label: 'Next 90 days including today'}, {id: 'starting.year', label: 'Next 12 months including today'}, {id: 'current.week', label: 'Current week to-date'}, {id: 'current.month', label: 'Current calendar month to-date'}, {id: 'current.quarter', label: 'Current quarter to-date'}, {id: 'current.year', label: 'Current calendar year to-date'}, {id: 'earlier.day', label: 'To end of yesterday'}, {id: 'earlier.week', label: 'To end of previous week'}, {id: 'earlier.month', label: 'To end of previous calendar month'}, {id: 'earlier.quarter', label: 'To end of previous quarter'}, {id: 'earlier.year', label: 'To end of previous calendar year'}, {id: 'greater.day', label: 'From start of current day'}, {id: 'greater.week', label: 'From start of current week'}, {id: 'greater.month', label: 'From start of current calendar month'}, {id: 'greater.quarter', label: 'From start of current quarter'}, {id: 'greater.year', label: 'From start of current calendar year'}, {id: 'less.week', label: 'To end of current week'}, {id: 'less.month', label: 'To end of current calendar month'}, {id: 'less.quarter', label: 'To end of current quarter'}, {id: 'less.year', label: 'To end of current calendar year'}, {id: 'previous_2.day', label: 'Previous 2 days'}, {id: 'previous_2.week', label: 'Previous 2 weeks'}, {id: 'previous_2.month', label: 'Previous 2 calendar months'}, {id: 'previous_2.quarter', label: 'Previous 2 quarters'}, {id: 'previous_2.year', label: 'Previous 2 calendar years'}, {id: 'previous_2.fiscal_year', label: 'Previous 2 fiscal years'}, {id: 'previous_before.day', label: 'Day prior to yesterday'}, {id: 'previous_before.week', label: 'Week prior to previous week'}, {id: 'previous_before.month', label: 'Month prior to previous calendar month'}, {id: 'previous_before.quarter', label: 'Quarter prior to previous quarter'}, {id: 'previous_before.year', label: 'Year prior to previous calendar year'}, {id: 'previous_before.fiscal_year', label: 'Fiscal year prior to previous fiscal year'}, {id: 'greater_previous.week', label: 'From end of previous week'}, {id: 'greater_previous.month', label: 'From end of previous calendar month'}, {id: 'greater_previous.quarter', label: 'From end of previous quarter'}, {id: 'greater_previous.year', label: 'From end of previous calendar year'}], input_attrs: {}, label: 'Thank-you Sent?'}" />
+    <af-field name="receipt_date" defn="{input_type: 'Select', options: [{id: 'this.day', label: 'Today'}, {id: 'this.week', label: 'This week'}, {id: 'this.month', label: 'This calendar month'}, {id: 'this.quarter', label: 'This quarter'}, {id: 'this.fiscal_year', label: 'This fiscal year'}, {id: 'this.year', label: 'This calendar year'}, {id: 'previous.day', label: 'Yesterday'}, {id: 'previous.week', label: 'Previous week'}, {id: 'previous.month', label: 'Previous calendar month'}, {id: 'previous.quarter', label: 'Previous quarter'}, {id: 'previous.fiscal_year', label: 'Previous fiscal year'}, {id: 'previous.year', label: 'Previous calendar year'}, {id: 'ending.week', label: 'Last 7 days including today'}, {id: 'ending_30.day', label: 'Last 30 days including today'}, {id: 'ending_60.day', label: 'Last 60 days including today'}, {id: 'ending_90.day', label: 'Last 90 days including today'}, {id: 'ending.year', label: 'Last 12 months including today'}, {id: 'ending_2.year', label: 'Last 2 years including today'}, {id: 'ending_3.year', label: 'Last 3 years including today'}, {id: 'starting.day', label: 'Tomorrow'}, {id: 'next.week', label: 'Next week'}, {id: 'next.month', label: 'Next calendar month'}, {id: 'next.quarter', label: 'Next quarter'}, {id: 'next.fiscal_year', label: 'Next fiscal year'}, {id: 'next.year', label: 'Next calendar year'}, {id: 'starting.week', label: 'Next 7 days including today'}, {id: 'starting.month', label: 'Next 30 days including today'}, {id: 'starting_2.month', label: 'Next 60 days including today'}, {id: 'starting.quarter', label: 'Next 90 days including today'}, {id: 'starting.year', label: 'Next 12 months including today'}, {id: 'current.week', label: 'Current week to-date'}, {id: 'current.month', label: 'Current calendar month to-date'}, {id: 'current.quarter', label: 'Current quarter to-date'}, {id: 'current.year', label: 'Current calendar year to-date'}, {id: 'earlier.day', label: 'To end of yesterday'}, {id: 'earlier.week', label: 'To end of previous week'}, {id: 'earlier.month', label: 'To end of previous calendar month'}, {id: 'earlier.quarter', label: 'To end of previous quarter'}, {id: 'earlier.year', label: 'To end of previous calendar year'}, {id: 'greater.day', label: 'From start of current day'}, {id: 'greater.week', label: 'From start of current week'}, {id: 'greater.month', label: 'From start of current calendar month'}, {id: 'greater.quarter', label: 'From start of current quarter'}, {id: 'greater.year', label: 'From start of current calendar year'}, {id: 'less.week', label: 'To end of current week'}, {id: 'less.month', label: 'To end of current calendar month'}, {id: 'less.quarter', label: 'To end of current quarter'}, {id: 'less.year', label: 'To end of current calendar year'}, {id: 'previous_2.day', label: 'Previous 2 days'}, {id: 'previous_2.week', label: 'Previous 2 weeks'}, {id: 'previous_2.month', label: 'Previous 2 calendar months'}, {id: 'previous_2.quarter', label: 'Previous 2 quarters'}, {id: 'previous_2.year', label: 'Previous 2 calendar years'}, {id: 'previous_2.fiscal_year', label: 'Previous 2 fiscal years'}, {id: 'previous_before.day', label: 'Day prior to yesterday'}, {id: 'previous_before.week', label: 'Week prior to previous week'}, {id: 'previous_before.month', label: 'Month prior to previous calendar month'}, {id: 'previous_before.quarter', label: 'Quarter prior to previous quarter'}, {id: 'previous_before.year', label: 'Year prior to previous calendar year'}, {id: 'previous_before.fiscal_year', label: 'Fiscal year prior to previous fiscal year'}, {id: 'greater_previous.week', label: 'From end of previous week'}, {id: 'greater_previous.month', label: 'From end of previous calendar month'}, {id: 'greater_previous.quarter', label: 'From end of previous quarter'}, {id: 'greater_previous.year', label: 'From end of previous calendar year'}], input_attrs: {}, label: 'Receipt Sent?'}" />
+    <af-field name="is_pay_later" defn="{required: false, input_type: 'Radio', label: 'Contribution is Pay Later?'}" />
+    <af-field name="is_test" defn="{input_type: 'Radio', required: false, afform_default: '0', label: 'Contribution is a Test?'}" />
+    <af-field name="is_template" defn="{required: false, input_type: 'Radio', afform_default: '0', label: 'Contribution is Template?'}" />
+    <af-field name="contribution_recur_id" defn="{label: 'Contribution is Recurring?', input_attrs: {}}" />
+  </div>
+  <div class="af-container af-layout-inline af-collapsible af-collapsed" af-title="Less Common Filters">
+    <af-field name="invoice_number" defn="{search_operator: 'IS EMPTY', input_attrs: {}, input_type: 'Number'}" />
+    <af-field name="trxn_id" />
+    <af-field name="cancel_date" defn="{input_type: 'Select', search_range: true, options: [{id: '{}', label: 'Choose Date Range'}, {id: 'this.day', label: 'Today'}, {id: 'this.week', label: 'This week'}, {id: 'this.month', label: 'This calendar month'}, {id: 'this.quarter', label: 'This quarter'}, {id: 'this.fiscal_year', label: 'This fiscal year'}, {id: 'this.year', label: 'This calendar year'}, {id: 'previous.day', label: 'Yesterday'}, {id: 'previous.week', label: 'Previous week'}, {id: 'previous.month', label: 'Previous calendar month'}, {id: 'previous.quarter', label: 'Previous quarter'}, {id: 'previous.fiscal_year', label: 'Previous fiscal year'}, {id: 'previous.year', label: 'Previous calendar year'}, {id: 'ending.week', label: 'Last 7 days including today'}, {id: 'ending_30.day', label: 'Last 30 days including today'}, {id: 'ending_60.day', label: 'Last 60 days including today'}, {id: 'ending_90.day', label: 'Last 90 days including today'}, {id: 'ending.year', label: 'Last 12 months including today'}, {id: 'ending_2.year', label: 'Last 2 years including today'}, {id: 'ending_3.year', label: 'Last 3 years including today'}, {id: 'starting.day', label: 'Tomorrow'}, {id: 'next.week', label: 'Next week'}, {id: 'next.month', label: 'Next calendar month'}, {id: 'next.quarter', label: 'Next quarter'}, {id: 'next.fiscal_year', label: 'Next fiscal year'}, {id: 'next.year', label: 'Next calendar year'}, {id: 'starting.week', label: 'Next 7 days including today'}, {id: 'starting.month', label: 'Next 30 days including today'}, {id: 'starting_2.month', label: 'Next 60 days including today'}, {id: 'starting.quarter', label: 'Next 90 days including today'}, {id: 'starting.year', label: 'Next 12 months including today'}, {id: 'current.week', label: 'Current week to-date'}, {id: 'current.month', label: 'Current calendar month to-date'}, {id: 'current.quarter', label: 'Current quarter to-date'}, {id: 'current.year', label: 'Current calendar year to-date'}, {id: 'earlier.day', label: 'To end of yesterday'}, {id: 'earlier.week', label: 'To end of previous week'}, {id: 'earlier.month', label: 'To end of previous calendar month'}, {id: 'earlier.quarter', label: 'To end of previous quarter'}, {id: 'earlier.year', label: 'To end of previous calendar year'}, {id: 'greater.day', label: 'From start of current day'}, {id: 'greater.week', label: 'From start of current week'}, {id: 'greater.month', label: 'From start of current calendar month'}, {id: 'greater.quarter', label: 'From start of current quarter'}, {id: 'greater.year', label: 'From start of current calendar year'}, {id: 'less.week', label: 'To end of current week'}, {id: 'less.month', label: 'To end of current calendar month'}, {id: 'less.quarter', label: 'To end of current quarter'}, {id: 'less.year', label: 'To end of current calendar year'}, {id: 'previous_2.day', label: 'Previous 2 days'}, {id: 'previous_2.week', label: 'Previous 2 weeks'}, {id: 'previous_2.month', label: 'Previous 2 calendar months'}, {id: 'previous_2.quarter', label: 'Previous 2 quarters'}, {id: 'previous_2.year', label: 'Previous 2 calendar years'}, {id: 'previous_2.fiscal_year', label: 'Previous 2 fiscal years'}, {id: 'previous_before.day', label: 'Day prior to yesterday'}, {id: 'previous_before.week', label: 'Week prior to previous week'}, {id: 'previous_before.month', label: 'Month prior to previous calendar month'}, {id: 'previous_before.quarter', label: 'Quarter prior to previous quarter'}, {id: 'previous_before.year', label: 'Year prior to previous calendar year'}, {id: 'previous_before.fiscal_year', label: 'Fiscal year prior to previous fiscal year'}, {id: 'greater_previous.week', label: 'From end of previous week'}, {id: 'greater_previous.month', label: 'From end of previous calendar month'}, {id: 'greater_previous.quarter', label: 'From end of previous quarter'}, {id: 'greater_previous.year', label: 'From end of previous calendar year'}], input_attrs: {}, afform_default: '{}'}" />
+    <af-field name="cancel_reason" />
+    <af-field name="payment_instrument_id" defn="{input_attrs: {multiple: true}}" />
+  </div>
+  <div class="af-container af-collapsible af-layout-inline af-collapsed" af-title="Soft Credit">
+    <legend class="af-text">Dev note:&nbsp; several options currently - need to understand soft credits better! &nbsp;</legend>
+    <af-field name="Contribution_ContributionSoft_contribution_id_01.id" />
+  </div>
+  <div class="af-container af-collapsible af-layout-inline af-collapsed" af-title="PCP">
+    <legend class="af-text">Dev note: want this as page name select. &nbsp; Does anyone use PCP's???</legend>
+    <af-field name="Contribution_ContributionSoft_contribution_id_01_ContributionSoft_PCP_pcp_id_01.id" />
+    <af-field name="Contribution_ContributionSoft_contribution_id_01_ContributionSoft_PCP_pcp_id_01.is_honor_roll" defn="{label: 'Honor Roll?'}" />
+  </div>
+  <crm-search-display-table search-name="Find_Contributions_2" display-name="Find_Contributions_Table_1"></crm-search-display-table>
+</div>
diff --git a/ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.json b/ext/civicrm_admin_ui/ang/afsearchFindContributions.aff.json
new file mode 100644 (file)
index 0000000..e7cbe62
--- /dev/null
@@ -0,0 +1,19 @@
+{
+    "type": "search",
+    "requires": [],
+    "entity_type": null,
+    "join_entity": null,
+    "title": "Find Contributions",
+    "description": "The original searches for Contributions but also can show just soft credits and recurring contributions.  Maybe recur is better as a separate search?  And soft credits?",
+    "is_dashlet": false,
+    "is_public": false,
+    "is_token": false,
+    "contact_summary": null,
+    "summary_contact_type": null,
+    "icon": "fa-list-alt",
+    "server_route": "civicrm/sk/contrib",
+    "permission": "access CiviCRM",
+    "redirect": null,
+    "create_submission": false,
+    "navigation": null
+}
diff --git a/ext/civicrm_admin_ui/managed/SavedSearch_Find_Contributions.mgd.php b/ext/civicrm_admin_ui/managed/SavedSearch_Find_Contributions.mgd.php
new file mode 100644 (file)
index 0000000..d080bb8
--- /dev/null
@@ -0,0 +1,242 @@
+<?php
+
+use CRM_CivicrmAdminUi_ExtensionUtil as E;
+
+return [
+  [
+    'name' => 'SavedSearch_Find_Contributions_2',
+    'entity' => 'SavedSearch',
+    'cleanup' => 'always',
+    'update' => 'unmodified',
+    'params' => [
+      'version' => 4,
+      'values' => [
+        'name' => 'Find_Contributions_2',
+        'label' => E::ts('Find Contributions'),
+        'form_values' => NULL,
+        'mapping_id' => NULL,
+        'search_custom_id' => NULL,
+        'api_entity' => 'Contribution',
+        'api_params' => [
+          'version' => 4,
+          'select' => [
+            'Contribution_Contact_contact_id_01.display_name',
+            'total_amount',
+            'financial_type_id:label',
+            'source',
+            'receive_date',
+            'thankyou_date',
+            'contribution_status_id:label',
+          ],
+          'orderBy' => [],
+          'where' => [],
+          'groupBy' => [],
+          'join' => [
+            [
+              'Contact AS Contribution_Contact_contact_id_01',
+              'INNER',
+              [
+                'contact_id',
+                '=',
+                'Contribution_Contact_contact_id_01.id',
+              ],
+            ],
+            [
+              'ContributionSoft AS Contribution_ContributionSoft_contribution_id_01',
+              'LEFT',
+              [
+                'id',
+                '=',
+                'Contribution_ContributionSoft_contribution_id_01.contribution_id',
+              ],
+            ],
+            [
+              'PCP AS Contribution_ContributionSoft_contribution_id_01_ContributionSoft_PCP_pcp_id_01',
+              'LEFT',
+              [
+                'Contribution_ContributionSoft_contribution_id_01.pcp_id',
+                '=',
+                'Contribution_ContributionSoft_contribution_id_01_ContributionSoft_PCP_pcp_id_01.id',
+              ],
+            ],
+          ],
+          'having' => [],
+        ],
+        'expires_date' => NULL,
+        'description' => NULL,
+      ],
+      'match' => [
+        'name',
+      ],
+    ],
+  ],
+  [
+    'name' => 'SavedSearch_Find_Contributions_2_SearchDisplay_Find_Contributions_Table_1',
+    'entity' => 'SearchDisplay',
+    'cleanup' => 'always',
+    'update' => 'unmodified',
+    'params' => [
+      'version' => 4,
+      'values' => [
+        'name' => 'Find_Contributions_Table_1',
+        'label' => E::ts('Find Contributions Table 1'),
+        'saved_search_id.name' => 'Find_Contributions_2',
+        'type' => 'table',
+        'settings' => [
+          'description' => NULL,
+          'sort' => [],
+          'limit' => 50,
+          'pager' => [],
+          'placeholder' => 5,
+          'columns' => [
+            [
+              'type' => 'field',
+              'key' => 'Contribution_Contact_contact_id_01.display_name',
+              'dataType' => 'String',
+              'label' => E::ts('Name'),
+              'sortable' => TRUE,
+              'link' => [
+                'path' => '',
+                'entity' => 'Contact',
+                'action' => 'view',
+                'join' => 'Contribution_Contact_contact_id_01',
+                'target' => '_blank',
+              ],
+              'title' => E::ts('View Contact'),
+              'icons' => [
+                [
+                  'field' => 'Contribution_Contact_contact_id_01.contact_type:icon',
+                  'side' => 'left',
+                ],
+              ],
+            ],
+            [
+              'type' => 'field',
+              'key' => 'total_amount',
+              'dataType' => 'Money',
+              'label' => E::ts('Amount'),
+              'sortable' => TRUE,
+            ],
+            [
+              'type' => 'field',
+              'key' => 'financial_type_id:label',
+              'dataType' => 'Integer',
+              'label' => E::ts('Type'),
+              'sortable' => TRUE,
+            ],
+            [
+              'type' => 'field',
+              'key' => 'source',
+              'dataType' => 'String',
+              'label' => E::ts('Contribution Source'),
+              'sortable' => TRUE,
+            ],
+            [
+              'type' => 'field',
+              'key' => 'receive_date',
+              'dataType' => 'Timestamp',
+              'label' => E::ts('Contribution Date'),
+              'sortable' => TRUE,
+            ],
+            [
+              'type' => 'field',
+              'key' => 'thankyou_date',
+              'dataType' => 'Timestamp',
+              'label' => E::ts('Thank-you Sent'),
+              'sortable' => TRUE,
+            ],
+            [
+              'type' => 'field',
+              'key' => 'contribution_status_id:label',
+              'dataType' => 'Integer',
+              'label' => E::ts('Status'),
+              'sortable' => TRUE,
+            ],
+            [
+              'size' => 'btn-xs',
+              'links' => [
+                [
+                  'entity' => 'Contribution',
+                  'action' => 'view',
+                  'join' => '',
+                  'target' => 'crm-popup',
+                  'icon' => 'fa-external-link',
+                  'text' => E::ts('View'),
+                  'style' => 'default',
+                  'path' => '',
+                  'condition' => [],
+                ],
+                [
+                  'entity' => 'Contribution',
+                  'action' => 'update',
+                  'join' => '',
+                  'target' => 'crm-popup',
+                  'icon' => 'fa-pencil',
+                  'text' => E::ts('Update'),
+                  'style' => 'default',
+                  'path' => '',
+                  'condition' => [],
+                ],
+              ],
+              'type' => 'buttons',
+              'alignment' => 'text-right',
+            ],
+            [
+              'text' => '',
+              'style' => 'default',
+              'size' => 'btn-xs',
+              'icon' => 'fa-bars',
+              'links' => [
+                [
+                  'entity' => '',
+                  'action' => '',
+                  'join' => '',
+                  'target' => '',
+                  'icon' => 'fa-external-link',
+                  'text' => E::ts('Send Letter'),
+                  'style' => 'default',
+                  'path' => 'civicrm/contribute/task?reset=1&task_item=letter&id=[id]',
+                  'condition' => [],
+                ],
+                [
+                  'entity' => '',
+                  'action' => '',
+                  'join' => '',
+                  'target' => '',
+                  'icon' => 'fa-external-link',
+                  'text' => E::ts('Send Receipt'),
+                  'style' => 'default',
+                  'path' => 'civicrm/contribute/task?reset=1&task_item=receipt&id=[id]',
+                  'condition' => [],
+                ],
+                [
+                  'entity' => 'Contribution',
+                  'action' => 'delete',
+                  'join' => '',
+                  'target' => 'crm-popup',
+                  'icon' => 'fa-trash',
+                  'text' => E::ts('Delete'),
+                  'style' => 'danger',
+                  'path' => '',
+                  'condition' => [],
+                ],
+              ],
+              'type' => 'menu',
+              'alignment' => 'text-right',
+            ],
+          ],
+          'actions' => TRUE,
+          'classes' => [
+            'table',
+            'table-striped',
+          ],
+        ],
+        'acl_bypass' => FALSE,
+      ],
+      'match' => [
+        'name',
+        'saved_search_id',
+      ],
+    ],
+  ],
+];