import React from 'react'; import ReactDOM from 'react-dom'; import _ from 'lodash'; import {getUrlParameters} from '../constants'; import {SelectFieldSearchInput} from '../../contacts/components/Form'; import {gettext} from 'core/utils'; class LinkFunction { scope: any; elem: any; orgField: any; contacts: any; $location: any; constructor(contacts, $location, scope, elem) { this.scope = scope; this.elem = elem; this.orgField = document.getElementById('org-field'); this.contacts = contacts; this.$location = $location; this.scope.searchItems = this.search.bind(this); this.scope.clear = this.clear.bind(this); this.setQueryString = this.setQueryString.bind(this); this.scope.toggle = {all: true}; this.scope.keyPressed = this.keyPressed.bind(this); this.scope.searchField = this.searchField.bind(this); this.scope.isSearchDifferent = this.isSearchDifferent.bind(this); this.handleOnChange = this.handleOnChange.bind(this); this.init(); this.scope.$on('$locationChangeSuccess', () => { if (this.scope.query !== this.$location.search().q || this.scope.isSearchDifferent()) { this.init(); } }); this.scope.$on('$destroy', () => { elem.off(); ReactDOM.unmountComponentAtNode(this.orgField); }); } /* * init function to setup the directive initial state and called by $locationChangeSuccess event */ init() { var params = this.$location.search(); this.scope.query = params.q; this.scope.flags = false; let meta = {}; _.forEach(getUrlParameters(), (value, key) => { if (_.get(params, key)) { meta[key] = params[key]; } }); this.scope.meta = meta; this.scope.filteredList = {}; if (!params.organisation) { this.scope.filteredList['organisation'] = []; } this.renderSearchField('organisation', true); this.scope.selectedItem = ''; } isSearchDifferent() { let params = this.$location.search(); return _.some(_.keys(getUrlParameters()), (key) => _.get(this.scope.meta, key) !== _.get(params, key)); } handleOnChange(field, value) { this.scope.meta[field] = value; this.renderSearchField(field, false); } renderSearchField(field, initValue?) { let fieldElement; let fieldLabel; let querySearch = false; switch (field) { case 'organisation': fieldElement = this.orgField; fieldLabel = gettext('Organisation'); querySearch = true; break; } ReactDOM.render( this.scope.searchField(field, searchText))} dataList={this.scope.filteredList[field]} initValue={initValue} /> , fieldElement, ); } /** * @ngdoc method * @name sdContactsSearchPanel#setQueryString * @description function to set query string. */ setQueryString() { let pattern = /[()]/g; let params = this.$location.search(); const booleanToBinaryString = function(bool) { return Number(bool).toString(); }; _.forEach(this.scope.meta, (val, key) => { let v = val; if (typeof val === 'boolean') { v = booleanToBinaryString(val); } if (typeof val === 'string') { v = val.replace(pattern, ''); } if (v) { this.$location.search(key, val); } else if (_.get(params, key)) { this.$location.search(key, null); } }); this.$location.search('q', this.scope.query || null); } /** * @ngdoc method * @name sdContactsSearchPanel#search * @description function to perform search. */ search() { this.setQueryString(); } /* * Get search input from field while typed and query the text input. */ searchField(field, text) { if (text) { this.contacts.queryField(field, text).then((items) => { this.scope.filteredList[field] = _.map(items._items, field); this.scope.meta[field] = text; this.renderSearchField(field); }); } } keyPressed(event) { const ENTER = 13; if (event.keyCode === ENTER) { this.search(); event.preventDefault(); } } /** * @ngdoc method * @name sdContactsSearchPanel#clear * @description clear all search and refresh the results. */ clear() { const fields = [..._.keys(getUrlParameters()), 'q']; this.$location.search(_.omit(this.$location.search(), fields)); this.scope.$broadcast('tag:removed'); } } /** * @ngdoc directive * @module superdesk.apps.contacts * @name sdContactsSearchPanel * @requires https://docs.angularjs.org/api/ng/service/$location $location * @description sd-contacts-search-panel operates the search panel that appears * to the left of the contacts search page */ export function ContactsSearchPanelDirective(contacts, $location) { return { template: require('scripts/apps/contacts/views/search-panel.html'), link: (scope, elem) => new LinkFunction(contacts, $location, scope, elem), }; } ContactsSearchPanelDirective.$inject = ['contacts', '$location'];