superdesk/superdesk-client-core

View on GitHub
scripts/apps/contacts/services/ContactsService.ts

Summary

Maintainability
B
4 hrs
Test Coverage
import {get, find} from 'lodash';

import {FILTER_FIELDS, getUrlParameters} from '../constants';
import {gettext} from 'core/utils';

import {replaceUrls} from '../helpers';
import {IContact, IContactsService} from '../Contacts';

const DEFAULT_PAGE_SIZE = 50;

/**
 * @ngdoc service
 * @module superdesk.apps.contacts
 * @name sdContactsSearch
 * @requires api
 * @requires https://docs.angularjs.org/api/ng/service/$location $location
 * @requires sort
 * @requires search
 * @description Handles retrieval of data from contacts api
 */
export class ContactsService implements IContactsService {
    api: any;
    $location: any;
    sort: any;
    sortOptions: any;
    search: any;
    twitterPattern: any;
    privacyOptions: any;
    statusOptions: any;
    metadata: any;

    constructor(api, $location, sort, search, metadata) {
        this.api = api;
        this.$location = $location;
        this.sort = sort;
        this.sortOptions = [
            {field: 'last_name.keyword', label: gettext('Person (Last Name)'), defaultDir: 'asc'},
            {field: 'organisation.keyword', label: gettext('Organisation'), defaultDir: 'asc'},
            {field: '_created', label: gettext('Created')},
            {field: '_updated', label: gettext('Updated')},
        ];
        this.search = search;

        this.metadata = metadata;
        this.metadata.initialize();

        this.toggleStatus = this.toggleStatus.bind(this);
        this.togglePublic = this.togglePublic.bind(this);
        this.save = this.save.bind(this);
        this.convertForClient = this.convertForClient.bind(this);

        this.twitterPattern = /^@([A-Za-z0-9_]{1,15}$)/;
        this.privacyOptions = [
            {name: gettext('All'), value: null},
            {name: gettext('Public'), value: 'true'},
            {name: gettext('Private'), value: 'false'},
        ];
        this.statusOptions = [
            {name: gettext('All'), value: null},
            {name: gettext('Active'), value: 'true'},
            {name: gettext('Inactive'), value: 'false'},
        ];
    }

    /**
     * @ngdoc method
     * @name contacts#getCriteria
     * @public
     * @description Get the search criteria for given params.
     * @param {object} param $location.search object
     * @return {object}
     */
    getCriteria(param) {
        let criteria: any = {};
        let params = param || this.$location.search();
        let sort = this.sort.getSort(this.sortOptions);
        let filters = [];

        criteria.max_results = DEFAULT_PAGE_SIZE;
        criteria.sort = this.sort.formatSort(sort.field, sort.dir);
        criteria.page = 1;
        criteria.all = false; // to get all contacts

        let queryParams = params.q ? [params.q] : [];

        angular.forEach(getUrlParameters(), (val, key) => {
            if (params[key]) {
                queryParams.push(`${key}:(${params[key]})`);
            }
        });

        if (queryParams.length) {
            criteria.q = queryParams.join(' ');
            criteria.default_operator = 'AND';
        }

        Object.keys(FILTER_FIELDS).forEach((key) => {
            let paramName = FILTER_FIELDS[key];

            if (angular.isDefined(params[paramName])) {
                filters.push({term: {[paramName]: params[paramName]}});
            }
        });

        if (filters.length) {
            criteria.filter = JSON.stringify({and: filters});
        }

        return criteria;
    }

    /**
     * @ngdoc method
     * @name contacts#query
     * @public
     * @description Calls contacts api and performs the query.
     * @param {object} param parameters to query
     * @return {promise}
     */
    query(param) {
        return this.metadata.initialize()
            .then(() => this.api('contacts').query(param))
            .then((data) => {
                get(data, '_items', []).forEach(this.convertForClient);

                return data;
            });
    }

    /**
      * @ngdoc method
      * @name contacts#queryField
      * @param {string} name of field in contacts collection
      * @param {string} search text to query with in given field
      * @returns {Promise}
      * @public
      * @description Requests a list of fields value suggestions from the server e.g.,
      * in case of organisation field returns organisations suggestions if resolved.
      */
    queryField(field, text) {
        switch (field) {
        case 'organisation':
            return this.metadata.initialize()
                .then(() => this.api.get(`contacts/organisations?q=${text}`))
                .then((data) => {
                    get(data, '_items', []).forEach(this.convertForClient);

                    return data;
                });
        }
    }

    /* Contact Form */

    /**
     * Toggle contact status
     */
    toggleStatus(contact, active) {
        return this.api.save('contacts', {is_active: active});
    }

    togglePublic(contact, isPublic) {
        return this.api.save('contacts', {public: isPublic});
    }

    save(contact, updates) {
        return this.api.save('contacts', contact, updates)
            .then(this.convertForClient);
    }

    convertForClient(response: IContact) {
        if (!response) {
            return response;
        }

        return replaceUrls(response);
    }
}

ContactsService.$inject = ['api', '$location', 'sort', 'search', 'metadata'];