(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; ctrl.view = 'list'; ctrl.moveIdx = null; ctrl.categoryToEdit = null; ctrl.categoryDefinitions = null; ctrl.categoryDefinitions = await crmApi4("ContactCategoryDefinition", 'get', { orderBy: { label: 'ASC' }, withLabels: true }); $scope.$digest(); ctrl.edit = idx => { if (idx === -1) { // New item. // Create a random dark colour let [r, g, b] = [Math.random(), Math.random(), Math.random()], min = Math.min(r, g, b), range = Math.max(r, g, b) - min, conv = (x) => ('0' + Math.ceil((x-min)/range * 128).toString(16)).replace(/^.*(..)$/, '$1'); // Create a blank ctrl.categoryToEdit = { idx: ctrl.categoryDefinitions.length, label: '', search_type: 'search', search_data: { saved_search_id: null }, color: '#' + [r, g, b].map(conv).join(''), icon: '', description: '', }; } else { ctrl.categoryToEdit = Object.assign({idx}, JSON.parse(JSON.stringify(ctrl.categoryDefinitions[idx]))); } ctrl.view = 'edit'; }; ctrl.moveTo = idx => { let item = ctrl.categoryDefinitions.splice(ctrl.moveIdx, 1)[0]; if (idx > ctrl.moveIdx) { idx--; } ctrl.categoryDefinitions.splice(idx, 0, item); ctrl.moveIdx = null; }; ctrl.deleteCategory = idx => { if (!confirm(ts( 'Confirm deleting category ‘%1’. You will lose history related to this category. Sure?', {1: ctrl.categoryDefinitions[idx].label} ))) { return; } ctrl.categoryDefinitions[idx].deleted = true; ctrl.categoryToEdit = null; ctrl.view = 'list'; }; ctrl.updateEditedThing = () => { // @todo validate, e.g. if (!ctrl.categoryToEdit.label) { alert("No name"); return; } const search_data = ctrl.categoryToEdit.search_data; console.log("search_data", search_data); if (ctrl.categoryToEdit.search_type === 'group') { // Only store what we need. const {group_id} = search_data; console.log("group_id", group_id, search_data); ctrl.categoryToEdit.search_data = {group_id}; } else if (ctrl.categoryToEdit.search_type === 'search') { const {saved_search_id} = search_data; ctrl.categoryToEdit.search_data = {saved_search_id}; } const edited = ctrl.categoryToEdit; const idx = edited.idx; delete(edited.idx); ctrl.categoryDefinitions[idx] = edited; ctrl.categoryToEdit = null; ctrl.view = 'list'; console.log("done editing"); } // We need to ensure the search_data object contains the fields required for the selected search_type ctrl.fixSearchData = () => { const search_data = ctrl.categoryToEdit.search_data; if (ctrl.categoryToEdit.search_type === 'group') { if (!('group_id' in search_data)) { search_data.group_id = null; } } else if (ctrl.categoryToEdit.search_type === 'search') { if (!('saved_search_id' in search_data)) { search_data.saved_search_id = null; } } }; ctrl.save = async () => { if (!confirm(ts("Confirm saving changes to categories? Note that categories will not be fully applied until tomorrow."))) { return; } }; // 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._);