(function(angular, $, _) { // Declare a list of dependencies. angular.module("crmContactcats", CRM.angRequires("crmContactcats")); angular.module("crmContactcats").component("crmContactCategorySettings", { templateUrl: "~/crmContactcats/crmContactCategorySettings.html", bindings: { // things listed here become properties on the controller using // values from attributes. @ means a fixed string is passed // e.g. // token: '@', // & is special. In the child, call ctrl.onMyAction with an // Object whose keys provide parameter names for the code in the parent. // onMyAction: '&', // '<' means one-way binding (parent»child) and I think is what you are // supposed to use for components. // v: '<' }, controller: function($scope, $timeout, crmApi4, $document) { var ts = ($scope.ts = CRM.ts(null)), ctrl = this; // this.$onInit gets run after the this controller is called, and after the bindings have been applied. this.$onInit = async function() { ctrl.saved = false; const various = await crmApi4({ settings: ["Setting", "get", { select: ["contact_categories"] }, 0], groups: [ "Group", "get", { where: [ ["is_active", "=", 1], ["is_hidden", "=", 0] ], orderBy: { name: "ASC" } } ], cats: [ "OptionValue", "get", { select: ["value", "label"], where: [["option_group_id:name", "=", "contact_categories"]] } ] }); ctrl.catmap = []; if (!various.settings.value || !various.settings.value.groupIDs) { various.settings.value = { groupIDs: ["0"], updateAfter: 0 }; } various.settings.value.groupIDs.forEach(groupID => { let cat = various.cats.find(c => c.value == groupID); ctrl.catmap.push({ groupID, name: cat ? cat.label : "" }); }); console.log({ various, catmap: ctrl.catmap }); ctrl.groups = various.groups; ctrl.nameKeydown = (keyEvt, idx) => { if (keyEvt.key === "ArrowUp" || keyEvt.key === "ArrowDown") { keyEvt.preventDefault(); keyEvt.stopPropagation(); if ( keyEvt.key === "ArrowUp" && idx > 0 && idx < ctrl.catmap.length - 1 ) { ctrl.catmap.splice(idx, 0, ...ctrl.catmap.splice(idx - 1, 1)); console.log("up", { keyEvt }); $timeout(() => keyEvt.target.focus(), 10); } else if ( keyEvt.key === "ArrowDown" && idx < ctrl.catmap.length - 2 ) { ctrl.catmap.splice(idx + 1, 0, ...ctrl.catmap.splice(idx, 1)); console.log( "down", ctrl.catmap.map(e => e.name) ); } } }; $scope.$digest(); ctrl.deleteRow = idx => { ctrl.catmap.splice(idx, 1); }; ctrl.getGroupsFor = idx => { let groupsInUse = ctrl.catmap.map(c => c.groupID); groupsInUse.splice(idx, 1); return ctrl.groups.filter( g => !groupsInUse.includes(g.id.toString()) ); }; ctrl.save = async () => { console.log("save", ctrl.catmap); // reconstruct everything. const optValsRecords = []; ctrl.catmap.forEach(r => { if (!r.name || r.groupID === "") { return; } // Do we have an option value for this group ID? let c = various.cats.find(cat => cat.value == r.groupID); if (c) { if (c.label != r.name) { optValsRecords.push({ id: c.id, label: r.name }); } } else { optValsRecords.push({ label: r.name, value: r.groupID, "option_group_id:name": "contact_categories" }); } }); console.log("optionValue updates", optValsRecords, ctrl.catmap); const updates = { saveSetting: [ "Setting", "set", { values: { contact_categories: { groupIDs: ctrl.catmap.map(i => i.groupID), updateAfter: 0 } } } ] }; if (optValsRecords.length) { updates.saveOptions = [ "OptionValue", "save", { records: optValsRecords } ]; } await crmApi4(updates); console.log("saved", updates); ctrl.saved = true; $scope.$digest(); }; }; // this.$onChange = function(changes) { // // changes is object keyed by name what '<' binding changed in // // the parent (e.g. 'v'), and value is another obj with keys // // something like previous, new, ...?... // }; } }); })(angular, CRM.$, CRM._);