public/components/punters/punters.js (109 lines of code) (raw):

import puntersTemplate from './punters.html'; /** * Created by cfinch on 09/01/2015. */ function punters ($rootScope) { /** * Filter one array based on another * @param list Array to be filtered * @param shouldNotContain Items the array should not contain * @returns {*} */ function filterList(list, shouldNotContain) { if (list && list.filter) { return list.filter((item) => { return shouldNotContain.indexOf(item) === -1; }); } else { return list; } } return { restrict: 'E', template: puntersTemplate, scope: { stub: '=', indrawer: '=' }, link: function ($scope, $elem) { var field = $elem[0].querySelector('.punters__autocomplete-field'), input = $elem[0].querySelector('.punters__text-input'), $input = angular.element(input); $scope.searchText = ""; $scope.selectedIndex = 0; $scope.tokens = []; $scope.foundUsers = []; /** * Emulate focus and blur styles from inputs on div container for autocomplete */ (function emulateInputFocusBehaviour () { $input.on('focus', () => { field.classList.add('punters__autocomplete-field--focus'); }); $input.on('blur', () => { field.classList.remove('punters__autocomplete-field--focus'); }); })(); /** * Reset the autocomplete list for when it should be emptied */ function resetAutocomplete () { $scope.foundUsers = []; // Reset search $scope.selectedIndex = 0; // reset selected token } $scope.addToken = function (userEmail, dontSendEvent) { if ($scope.tokens.length === 0) { // artificial limit to 1 token for time being $scope.tokens.push(userEmail); $scope.foundUsers = filterList($scope.foundUsers, $scope.tokens); // Update model $scope.stub.assigneeEmail = userEmail; $scope.stub.assignee = userEmail?.substring(0,128); // TODO can we get rid of this field all together $scope.searchText = ""; // clear input when token is added resetAutocomplete(); if (!dontSendEvent) { $rootScope.$emit('punters.punterSelected'); } } }; // On load, pre-fill a token if someone already assigned if ($scope.stub.assigneeEmail) { $scope.addToken($scope.stub.assigneeEmail, true); } $scope.removeToken = function ($index, dontSendEvent) { $scope.tokens.splice($index, 1); // Update model $scope.stub.assigneeEmail = ''; $scope.stub.assignee = ''; if (!dontSendEvent) { $rootScope.$emit('punters.punterSelected'); } }; /** * Listen to key events on the input for searching, navigating, selecting and deleting items * @param $event keyDown event from Angular */ $scope.keyDown = function ($event) { switch ($event.keyCode) { case 40: // Down $event.preventDefault(); if($scope.selectedIndex < $scope.foundUsers.length) { $scope.selectedIndex++; } break; case 38: // Up $event.preventDefault(); if($scope.selectedIndex > 0) { $scope.selectedIndex--; } break; case 13: // Enter $event.preventDefault(); if ($scope.foundUsers.length && $scope.foundUsers[$scope.selectedIndex]) { $scope.addToken($scope.foundUsers[$scope.selectedIndex]); } break; } }; $scope.searchForUsers = function() { const searchText = $scope.searchText.trim(); if (searchText && searchText.length > 0) { fetch(`/api/people?prefix=${encodeURI(searchText)}`).then(_ => _.json()).then((data) => { if (data && data.length > 0) { $scope.foundUsers = data; //FIXME figure out why it takes so long to render this new `foundUsers` list if ($scope.selectedIndex > $scope.foundUsers.length - 1) { $scope.selectedIndex = $scope.foundUsers.length - 1; } } }); } else { // TODO check if we need to clear $scope.tokens resetAutocomplete(); } }; $scope.assignToMe = function () { input.focus(); $scope.searchText = ""; resetAutocomplete(); $scope.addToken(_wfConfig.user.email); }; } }; } export { punters }