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
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:01a6344ef3d86c080e4362dafa008d13)
* (GenCodeChecksum:222d053743f68a2678d92b8a75b46316)
*/
use CRM_Contactcats_ExtensionUtil as E;
@ -40,6 +40,15 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
*/
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
* (SQL type: int unsigned)
@ -97,12 +106,34 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
'entity' => 'ContactCategory',
'bao' => 'CRM_Contactcats_DAO_ContactCategory',
'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',
'html' => [
'type' => 'EntityRef',
'label' => E::ts("Contact"),
],
'readonly' => TRUE,
'add' => NULL,
],
'category' => [
@ -192,7 +223,16 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
* @return array
*/
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;
}

View file

@ -54,13 +54,13 @@ class Sync extends \Civi\Api4\Generic\AbstractAction {
Civi::log()->debug('', ['=' => 'pop']);
}
Civi::log()->debug('Resetting table', ['=' => 'timed']);
Civi::log()->debug('Resetting table', ['=' => 'start,timed']);
// clear out temp space.
CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = 0;")->free();
// ensure we have all our contacts covered.
CRM_Core_DAO::executeQuery(<<<SQL
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
SQL)->free();
Civi::log()->debug('', ['=' => 'pop']);

View file

@ -1,18 +1,22 @@
/* Add any CSS rules for Angular module "crmContactcats" */
crm-contact-category-settings ol {
padding:0;
padding: 0;
}
crm-contact-category-settings ol li {
display: flex;
padding:0.5em 0;
padding: 0.5em 0;
align-items: flex-end;
gap: 1em;
}
crm-contact-category-settings li label {
display: block;
}
crm-contact-category-settings .name-input-wrapper {
flex: 0 1 29ch;
}
crm-contact-category-settings .hint {
display:none;
display: none;
}
crm-contact-category-settings .name-input-wrapper:focus-within .hint {
display:block;
display: block;
}

View file

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

View file

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

View file

@ -35,9 +35,11 @@ SET FOREIGN_KEY_CHECKS=1;
-- *******************************************************/
CREATE TABLE `civicrm_contact_category` (
`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,
`next_category` int unsigned NOT NULL DEFAULT 0,
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;

View file

@ -13,16 +13,26 @@
<required>true</required>
<comment>Unique ID, corresponds to contact id</comment>
<html>
<type>EntityRef</type>
<label>Contact</label>
<type>Number</type>
</html>
</field>
<primaryKey>
<name>id</name>
<autoincrement>true</autoincrement>
</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>
<name>id</name>
<name>contact_id</name>
<table>civicrm_contact</table>
<key>id</key>
<onDelete>CASCADE</onDelete>
@ -30,7 +40,7 @@
<field>
<name>category</name>
<type>int unsigned</type>
<type>int unsigned</type>
<required>true</required>
<default>0</default>
<pseudoconstant>
@ -40,10 +50,14 @@
<type>Select</type>
</html>
</field>
<index>
<name>index_category</name>
<fieldName>category</fieldName>
</index>
<field>
<name>next_category</name>
<type>int unsigned</type>
<type>int unsigned</type>
<required>true</required>
<default>0</default>
<pseudoconstant>