From f87f9c743031b2da841c3ac5740a1c2ae06bbfe7 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 15 Feb 2017 22:33:03 -0500 Subject: [PATCH] CRM-20034 - Expose OR grouping to api explorer --- templates/CRM/Admin/Page/APIExplorer.js | 48 +++++++++++++++-- templates/CRM/Admin/Page/APIExplorer.tpl | 67 +++++++++++++++++++++++- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/templates/CRM/Admin/Page/APIExplorer.js b/templates/CRM/Admin/Page/APIExplorer.js index 3bca15f509..9ce6482920 100644 --- a/templates/CRM/Admin/Page/APIExplorer.js +++ b/templates/CRM/Admin/Page/APIExplorer.js @@ -20,8 +20,7 @@ docCodeTpl = _.template($('#doc-code-tpl').html()), joinTpl = _.template($('#join-tpl').html()), - // The following apis do not support the syntax for joins - // FIXME: the solution is to convert these apis to use _civicrm_api3_basic_get + // The following apis do not use Api3SelectQuery so do not support advanced features like joins or OR NO_JOINS = ['Contact', 'Contribution', 'Pledge', 'Participant'], // These types of entityRef don't require any input to open @@ -660,6 +659,7 @@ } }); if (entity && action) { + handleAndOr(); formatQuery(); } } @@ -879,7 +879,7 @@ */ function renderJoinSelector() { $('#api-join').hide(); - if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle'], action)) { + if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle', 'getcount'], action)) { var joinable = {}; (function recurse(fields, joinable, prefix, depth, entities) { _.each(fields, function(field) { @@ -938,6 +938,40 @@ } } + function handleAndOr() { + if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle', 'getcount'], action)) { + var or = []; + $('tr.api-param-row').each(function() { + if ($(this).next().is('tr.api-param-row') && $('input.api-param-name', this).val()) { + $('.api-and-or', this).show(); + } else { + $(this).removeClass('or').find('.api-and-or').hide(); + } + }); + $('tr.api-param-row.or').each(function() { + var val = $(this).next().find('input.api-param-name').val(); + if (val) { + if ($(this).prev().is('.or')) { + or[or.length - 1].push(val); + } else { + or.push([$('input.api-param-name', this).val(), val]); + } + } + }); + if (or.length) { + params.options = params.options || {}; + params.options.or = or; + } + } else { + $('.api-and-or').hide(); + } + } + + function toggleAndOr() { + $(this).closest('tr').toggleClass('or'); + buildParams(); + } + $(document).ready(function() { // Set up tabs - bind active tab to document hash because... it's cool? document.location.hash = document.location.hash || 'explorer'; @@ -996,7 +1030,13 @@ $(this).closest('tr').remove(); buildParams(); }) - .on('change', 'select.api-chain-entity', getChainedAction); + .on('click', '.api-and-or > span', toggleAndOr) + .on('change', 'select.api-chain-entity', getChainedAction) + .on('sortupdate', buildParams) + .sortable({ + handle: '.api-sort-handle', + items: '.api-chain-row, .api-param-row' + }); $('#api-join').on('change', 'input', onSelectJoin); $('#example-entity').on('change', getExamples); $('#example-action').on('change', getExample); diff --git a/templates/CRM/Admin/Page/APIExplorer.tpl b/templates/CRM/Admin/Page/APIExplorer.tpl index fea4a10bcd..df992f8827 100644 --- a/templates/CRM/Admin/Page/APIExplorer.tpl +++ b/templates/CRM/Admin/Page/APIExplorer.tpl @@ -50,6 +50,9 @@ margin-top: 1em; overflow: auto; } + #api-params tr td { + padding-top: 13px; + } #api-params-table th:first-child, #api-params-table td:first-child { width: 35%; @@ -69,6 +72,61 @@ #api-params-table th:first-child + th + th { width: 65% } + #api-params .api-sort-handle { + margin-right: 10px; + cursor: move; + } + #api-params tr td > .crm-i, + #api-params tr td > a .crm-i { + color: lightgrey; + } + #api-params tr:hover td > .crm-i, + #api-params tr:hover td > a .crm-i { + color: grey; + } + #api-params .api-and-or { + margin-left: 1.2em; + font-size: .8em; + position: relative; + top: 5px; + width: 10em; + margin-bottom: -9px; + } + #api-params .api-and-or > span { + padding: 0 1em; + background: white; + cursor: pointer; + } + #api-params .api-or, + #api-params tr.or .api-and { + color: lightgrey; + } + #api-params tr.or .api-or { + color: inherit; + } + #api-params .api-and-or .crm-i { + transform: rotate(180deg); + } + #api-params tr.or .api-and-or .crm-i { + transform: initial; + } + #api-params .api-and-or:hover .crm-i { + color: #2786c2; + } + #api-params tr.or { + border-top: 3px solid lightgrey; + border-left: 3px solid lightgrey; + border-right: 3px solid lightgrey; + } + #api-params tr.or + tr { + border-left: 3px solid lightgrey; + border-right: 3px solid lightgrey; + border-bottom: 3px solid lightgrey; + } + #api-params tr.or + tr.or { + border-top: none; + border-bottom: none; + } #api-generated td:first-child { width: 60px; } @@ -303,7 +361,11 @@ {strip}