From 8c5bb56dd5ff32e24c90edad65dc2625547a0368 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 30 Jun 2021 16:49:05 -0400 Subject: [PATCH] APIv4 Explorer - Show joins for write actions It recently became possible in APIv4 to use joins during write operations; now that feature is advertised in the Explorer. --- ang/api4Explorer/Explorer.js | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/ang/api4Explorer/Explorer.js b/ang/api4Explorer/Explorer.js index 50e7935657..c51793b3a2 100644 --- a/ang/api4Explorer/Explorer.js +++ b/ang/api4Explorer/Explorer.js @@ -122,12 +122,15 @@ } // Replaces contents of fieldList array with current fields formatted for select2 - function getFieldList(fieldList, action, addPseudoconstant) { + function getFieldList(fieldList, action, addPseudoconstant, addWriteJoins) { var fieldInfo = _.cloneDeep(_.findWhere(getEntity().actions, {name: action}).fields); fieldList.length = 0; if (addPseudoconstant) { addPseudoconstants(fieldInfo, addPseudoconstant); } + if (addWriteJoins) { + addWriteJoinFields(fieldInfo); + } formatForSelect2(fieldInfo, fieldList, 'name', ['description', 'required', 'default_value']); } @@ -194,6 +197,19 @@ }); } + // Adds join fields for create actions + // Note: this function transforms a raw list a-la getFields; not a select2-formatted list + function addWriteJoinFields(fieldList) { + _.eachRight(fieldList, function(field, pos) { + var fkNameField = field.fk_entity && getField('name', field.fk_entity, $scope.action); + if (fkNameField) { + var newField = _.cloneDeep(fkNameField); + newField.name = field.name + '.' + newField.name; + fieldList.splice(pos, 0, newField); + } + }); + } + $scope.help = function(title, content) { if (!content) { $scope.helpTitle = helpTitle; @@ -263,12 +279,13 @@ $scope.fieldList = function(param) { return function() { var fields = []; - getFieldList(fields, $scope.action === 'getFields' ? ($scope.params.action || 'get') : $scope.action, ['name']); + getFieldList(fields, $scope.action === 'getFields' ? ($scope.params.action || 'get') : $scope.action, ['name'], true); // Disable fields that are already in use _.each($scope.params[param] || [], function(val) { - var usedField = val[0].replace(':name', ''); + var usedField = val[0].replace(/[:.]name/, ''); (_.findWhere(fields, {id: usedField}) || {}).disabled = true; (_.findWhere(fields, {id: usedField + ':name'}) || {}).disabled = true; + (_.findWhere(fields, {id: usedField + '.name'}) || {}).disabled = true; }); return {results: fields}; }; @@ -1194,7 +1211,8 @@ $el.removeClass('loading').crmSelect2({data: options, multiple: multi}); }); } else if (field.fk_entity) { - $el.crmEntityRef({entity: field.fk_entity, select:{multiple: multi}, static: field.fk_entity === 'Contact' ? ['user_contact_id'] : []}); + var apiParams = field.id_field ? {id_field: field.id_field} : {}; + $el.crmEntityRef({entity: field.fk_entity, api: apiParams, select: {multiple: multi}, static: field.fk_entity === 'Contact' ? ['user_contact_id'] : []}); } else if (dataType === 'Boolean') { $el.attr('placeholder', ts('- select -')).crmSelect2({allowClear: false, multiple: multi, placeholder: ts('- select -'), data: [ {id: 'true', text: ts('Yes')}, @@ -1374,10 +1392,15 @@ var suffix = fieldName.split(':')[1]; fieldName = fieldName.split(':')[0]; var fieldNames = fieldName.split('.'); - var field = get(entity, fieldNames); + var field = _.cloneDeep(get(entity, fieldNames)); if (field && suffix) { field.pseudoconstant = suffix; } + // When joining to a 'name' field, value fields should render an appropriate entityRef + if (field && field.type === 'Field' && field.name === 'name' && _.includes(fieldName, '.')) { + field.fk_entity = field.entity; + field.id_field = 'name'; + } return field; function get(entity, fieldNames) { -- 2.25.1