Add redundant contact_id field for search kit/form builder; add index on category field...

This commit is contained in:
Rich Lott / Artful Robot 2024-02-28 17:18:46 +00:00
parent 9fee48603b
commit 7b611c343f
7 changed files with 113 additions and 29 deletions

View file

@ -6,7 +6,7 @@
* *
* Generated from contactcats/xml/schema/CRM/Contactcats/ContactCategory.xml * Generated from contactcats/xml/schema/CRM/Contactcats/ContactCategory.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen * DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:01a6344ef3d86c080e4362dafa008d13) * (GenCodeChecksum:222d053743f68a2678d92b8a75b46316)
*/ */
use CRM_Contactcats_ExtensionUtil as E; use CRM_Contactcats_ExtensionUtil as E;
@ -40,6 +40,15 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
*/ */
public $id; public $id;
/**
* Same as id but for FormBuilder
*
* @var int|string
* (SQL type: int unsigned)
* Note that values will be retrieved from the database as a string.
*/
public $contact_id;
/** /**
* @var int|string * @var int|string
* (SQL type: int unsigned) * (SQL type: int unsigned)
@ -97,12 +106,34 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
'entity' => 'ContactCategory', 'entity' => 'ContactCategory',
'bao' => 'CRM_Contactcats_DAO_ContactCategory', 'bao' => 'CRM_Contactcats_DAO_ContactCategory',
'localizable' => 0, 'localizable' => 0,
'html' => [
'type' => 'Number',
],
'readonly' => TRUE,
'add' => NULL,
],
'contact_id' => [
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => E::ts('Contact ID'),
'description' => E::ts('Same as id but for FormBuilder'),
'required' => TRUE,
'usage' => [
'import' => FALSE,
'export' => FALSE,
'duplicate_matching' => FALSE,
'token' => FALSE,
],
'where' => 'civicrm_contact_category.contact_id',
'table_name' => 'civicrm_contact_category',
'entity' => 'ContactCategory',
'bao' => 'CRM_Contactcats_DAO_ContactCategory',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKClassName' => 'CRM_Contact_DAO_Contact',
'html' => [ 'html' => [
'type' => 'EntityRef', 'type' => 'EntityRef',
'label' => E::ts("Contact"), 'label' => E::ts("Contact"),
], ],
'readonly' => TRUE,
'add' => NULL, 'add' => NULL,
], ],
'category' => [ 'category' => [
@ -192,7 +223,16 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
* @return array * @return array
*/ */
public static function indices($localize = TRUE) { public static function indices($localize = TRUE) {
$indices = []; $indices = [
'index_category' => [
'name' => 'index_category',
'field' => [
0 => 'category',
],
'localizable' => FALSE,
'sig' => 'civicrm_contact_category::0::category',
],
];
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices; return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
} }

View file

@ -54,13 +54,13 @@ class Sync extends \Civi\Api4\Generic\AbstractAction {
Civi::log()->debug('', ['=' => 'pop']); Civi::log()->debug('', ['=' => 'pop']);
} }
Civi::log()->debug('Resetting table', ['=' => 'timed']); Civi::log()->debug('Resetting table', ['=' => 'start,timed']);
// clear out temp space. // clear out temp space.
CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = 0;")->free(); CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = 0;")->free();
// ensure we have all our contacts covered. // ensure we have all our contacts covered.
CRM_Core_DAO::executeQuery(<<<SQL CRM_Core_DAO::executeQuery(<<<SQL
INSERT IGNORE INTO civicrm_contact_category INSERT IGNORE INTO civicrm_contact_category
SELECT id, 0 as category, 0 next_category SELECT id, id contact_id, 0 as category, 0 next_category
FROM civicrm_contact FROM civicrm_contact
SQL)->free(); SQL)->free();
Civi::log()->debug('', ['=' => 'pop']); Civi::log()->debug('', ['=' => 'pop']);

View file

@ -5,8 +5,12 @@ crm-contact-category-settings ol {
crm-contact-category-settings ol li { crm-contact-category-settings ol li {
display: flex; display: flex;
padding: 0.5em 0; padding: 0.5em 0;
align-items: flex-end;
gap: 1em; gap: 1em;
} }
crm-contact-category-settings li label {
display: block;
}
crm-contact-category-settings .name-input-wrapper { crm-contact-category-settings .name-input-wrapper {
flex: 0 1 29ch; flex: 0 1 29ch;
} }

View file

@ -2,34 +2,57 @@
Loading... Loading...
</div> </div>
<form ng-if="$ctrl.catmap" crm-ui-id-scope> <form ng-if="$ctrl.catmap" crm-ui-id-scope>
<button ng-click="$ctrl.catmap.unshift({groupID: '', name:''})"><i class="crm-i fa-plus"></i> Add category</button> <button ng-click="$ctrl.catmap.unshift({groupID: '', name:''})">
<i class="crm-i fa-plus"></i> Add category
</button>
<ol class="crm-catmap"> <ol class="crm-catmap">
<li ng-repeat="(idx, row) in $ctrl.catmap"> <li ng-repeat="(idx, row) in $ctrl.catmap">
<select ng-if="row.groupID === '' || row.groupID > 0" <div class="group-input-wrapper">
crm-ui-select="{placeholder:'Select group',allowClear:false}" ng-model="$ctrl.catmap[idx].groupID" <label crm-ui-for="group{{idx}}">Group</label>
style="width: 18rem"> <select
<option ng-repeat="(grpIdx, grp) in $ctrl.getGroupsFor(idx)" value="{{grp.id}}">{{grp.title}}</option> crm-ui-id="group{{idx}}"
ng-if="row.groupID === '' || row.groupID > 0"
crm-ui-select="{placeholder:'Select group',allowClear:false}"
ng-model="$ctrl.catmap[idx].groupID"
style="width: 18rem"
>
<option
ng-repeat="(grpIdx, grp) in $ctrl.getGroupsFor(idx)"
value="{{grp.id}}"
>{{grp.title}}</option
>
</select> </select>
<div ng-if="row.groupID !== '' && row.groupID == 0" style="width: 18rem;display: inline-block;"> </div>
<div
ng-if="row.groupID !== '' && row.groupID == 0"
style="width: 18rem;display: inline-block;"
>
Default Default
</div> </div>
<div class=name-input-wrapper> <div class="name-input-wrapper">
<label crm-ui-for="name{{idx}}">Label</label> <label crm-ui-for="name{{idx}}">Label</label>
<input crm-ui-id="name{{idx}}" type=text ng-model="$ctrl.catmap[idx].name" <input
ng-keydown="$ctrl.nameKeydown($event, idx)" /> crm-ui-id="name{{idx}}"
type="text"
ng-model="$ctrl.catmap[idx].name"
ng-keydown="$ctrl.nameKeydown($event, idx)"
/>
<div class="hint description"> <div class="hint description">
{{ts('Use the Up/Down arrow keys to re-order')}} {{ts('Use the Up/Down arrow keys to re-order')}}
</div> </div>
</div> </div>
<div> <div>
<button ng-click="$ctrl.deleteRow(idx)"><i class="fa-trash crm-i"></i> Delete</button> <button ng-click="$ctrl.deleteRow(idx)">
<i class="fa-trash crm-i"></i> Delete
</button>
</div> </div>
</li> </li>
</ol> </ol>
<p> <p>
<button ng-click="$ctrl.save()"><i class="crm-i fa-save"></i> Save</button> <button ng-click="$ctrl.save()"><i class="crm-i fa-save"></i> Save</button>
</p> </p>
<div ng-if="$ctrl.saved" class="help">Categories saved. Contacts will be updated shortly (when the next Scheduled <div ng-if="$ctrl.saved" class="help">
Job run Categories saved. Contacts will be updated shortly (when the next Scheduled
happens).</div> Job run happens).
</div>
</form> </form>

View file

@ -19,6 +19,7 @@ return [
'name', 'name',
'label', 'label',
'description', 'description',
'weight',
], ],
], ],
'match' => [ 'match' => [

View file

@ -35,9 +35,11 @@ SET FOREIGN_KEY_CHECKS=1;
-- *******************************************************/ -- *******************************************************/
CREATE TABLE `civicrm_contact_category` ( CREATE TABLE `civicrm_contact_category` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID, corresponds to contact id', `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID, corresponds to contact id',
`contact_id` int unsigned NOT NULL COMMENT 'Same as id but for FormBuilder',
`category` int unsigned NOT NULL DEFAULT 0, `category` int unsigned NOT NULL DEFAULT 0,
`next_category` int unsigned NOT NULL DEFAULT 0, `next_category` int unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
CONSTRAINT FK_civicrm_contact_category_id FOREIGN KEY (`id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE INDEX `index_category`(category),
CONSTRAINT FK_civicrm_contact_category_contact_id FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE
) )
ENGINE=InnoDB; ENGINE=InnoDB;

View file

@ -13,16 +13,26 @@
<required>true</required> <required>true</required>
<comment>Unique ID, corresponds to contact id</comment> <comment>Unique ID, corresponds to contact id</comment>
<html> <html>
<type>EntityRef</type> <type>Number</type>
<label>Contact</label>
</html> </html>
</field> </field>
<primaryKey> <primaryKey>
<name>id</name> <name>id</name>
<autoincrement>true</autoincrement> <autoincrement>true</autoincrement>
</primaryKey> </primaryKey>
<field>
<name>contact_id</name>
<type>int unsigned</type>
<required>true</required>
<comment>Same as id but for FormBuilder</comment>
<html>
<type>EntityRef</type>
<label>Contact</label>
</html>
</field>
<foreignKey> <foreignKey>
<name>id</name> <name>contact_id</name>
<table>civicrm_contact</table> <table>civicrm_contact</table>
<key>id</key> <key>id</key>
<onDelete>CASCADE</onDelete> <onDelete>CASCADE</onDelete>
@ -40,6 +50,10 @@
<type>Select</type> <type>Select</type>
</html> </html>
</field> </field>
<index>
<name>index_category</name>
<fieldName>category</fieldName>
</index>
<field> <field>
<name>next_category</name> <name>next_category</name>