source : listsList.js

(function (angular) {
    'use strict';
    /**
     * @memberof spApp
     * @ngdoc directive
     * @name listsList
     * @description
     *   Table of selectable species-lists
     */
    angular.module('lists-list-directive', ['lists-service', 'map-service'])
        .directive('listsList', ['$http', '$timeout', 'ListsService', 'MapService', 'LayoutService',
            function ($http, $timeout, ListsService, MapService, LayoutService) {
                return {
                    templateUrl: '/spApp/listsList.htm',
                    scope: {
                        _custom: "&onCustom"
                    },
                    link: function (scope, element, attrs) {
                        scope.items = [];
                        scope.searchLists = '';
                        scope.pageSize = 20;
                        scope.page = 1;
                        scope.total = '';
                        scope.sortType = '';
                        scope.sortReverse = false;
                        scope.lastSearch = scope.searchLists + scope.sortType + scope.sortReverse;
                        scope.isLoading = true;
                        scope.setItems = function (data) {
                            let newItems = [];
                            if (data.length) {
                                for (var i = 0; i < data.length; i++) {
                                    newItems.push({
                                        dataResourceUid: data[i].dataResourceUid || data[i].id,
                                        listName: data[i].listName,
                                        lastUpdated: data[i].lastUpdated,
                                        itemCount: data[i].itemCount,
                                        fullName: data[i].fullName,
                                        isAuthoritative:data[i].isAuthoritative,
                                        selected: false
                                    })
                                }
                            } else if (data.dataResourceUid) {
                                newItems.push({
                                    dataResourceUid: data.dataResourceUid || data.id,
                                    listName: data.listName,
                                    lastUpdated: data.lastUpdated,
                                    itemCount: data.itemCount,
                                    fullName: data.fullName,
                                    selected: false
                                });
                            }
                            scope.items = newItems;
                        };
                        scope.appendItems = function (data) {
                            if (data.length) {
                                for (var i = 0; i < data.length; i++) {
                                    scope.items.push({
                                        dataResourceUid: data[i].dataResourceUid,
                                        listName: data[i].listName,
                                        lastUpdated: data[i].lastUpdated,
                                        itemCount: data[i].itemCount,
                                        fullName: data[i].fullName,
                                        isAuthoritative:data[i].isAuthoritative,
                                        selected: false
                                    })
                                }
                            } else if (data.dataResourceUid) {
                                scope.items.push({
                                    dataResourceUid: data.dataResourceUid,
                                    listName: data.listName,
                                    lastUpdated: data.lastUpdated,
                                    itemCount: data.itemCount,
                                    fullName: data.fullName,
                                    selected: false
                                });
                            }
                        };
                        scope.addToMap = function () {
                            MapService.add(scope.selection);
                        };
                        scope.fetchLists = function () {
                            let thisSearch = scope.searchLists + scope.sortType + scope.sortReverse;
                            if (scope.lastSearch !== thisSearch) {
                                scope.items = [];
                                scope.page = 1;
                                scope.lastSearch = thisSearch;
                            }
                            scope.isLoading = true;
                            ListsService.list(scope.searchLists, scope.pageSize, (scope.page - 1) * scope.pageSize, scope.sortType, scope.sortReverse ? "asc" : "desc").then(function (data) {
                                scope.total = data.listCount;
                                scope.setItems(data.lists);
                                // if there was another search running this may already be false
                                scope.isLoading = false;
                            });
                        }
                        scope.fetchMore = function () {
                            scope.page += 1;
                            scope.lastSearch = scope.searchLists + scope.sortType + scope.sortReverse;
                            scope.isLoading = true;
                            ListsService.list(scope.searchLists, scope.pageSize, (scope.page - 1) * scope.pageSize, scope.sortType, scope.sortReverse ? "asc" : "desc").then(function (data) {
                                scope.appendItems(data.lists);
                                // if there was another search running this may already be false
                                scope.isLoading = false;
                            });
                        }
                        scope.searchAgain = function () {
                            scope.page = 1;
                            scope.isLoading = true;
                            scope.items = [];
                            scope.fetchLists();
                        }
                        scope.searchListsTimeout;
                        scope.$watchGroup(['searchLists', 'sortType', 'sortReverse'], function () {
                            if (scope.searchListsTimeout) {
                                $timeout.cancel(scope.searchListsTimeout);
                            }
                            scope.searchListsTimeout = $timeout(function () {
                                scope.fetchLists();
                            }, 300); // 300ms debounce
                        }, true);
                        scope.selection = {};
                        scope.getItem = function (dataResourceUid) {
                            for (var i = 0; i < scope.items.length; i++) {
                                if (scope.items[i].dataResourceUid === dataResourceUid) {
                                    return scope.items[i];
                                }
                            }
                        };
                        scope.itemUrl = function (item) {
                            return ListsService.urlUi() + item.dataResourceUid
                        };
                        scope.add = function (item) {
                            var found = scope.getItem(!item.dataResourceUid ? item : item.dataResourceUid);
                            if (found && found.dataResourceUid && !found.selected) {
                                found.selected = true;
                                scope.selection = found;
                                //If the list is authoritative, Biocache builds index against species_list_uid (over night)
                                //We should use q=species_list_uid:drxxxx
                                if (found.isAuthoritative) {
                                    scope._custom()({
                                        q: ["species_list_uid:" + found.dataResourceUid],
                                        name: found.listName,
                                        species_list: found.dataResourceUid
                                    })
                                } else {
                                    if (found.dataResourceUid.startsWith("dr")) {
                                        // public list
                                        scope._custom()({
                                            // list not indexed, can be very slow (minutes)
                                            q: ["species_list:" + found.dataResourceUid],
                                            name: found.listName,
                                            species_list: found.dataResourceUid
                                        })
                                    } else {
                                        // private list, first 200 names only
                                        ListsService.getItemsQ(found.dataResourceUid).then(function (data) {
                                            var items = data.split(" OR ");
                                            var query = data;
                                            var limit = 200;
                                            if (items.length > limit ) {
                                                alert("Note: only the first 200 names will be used when when adding species to the map (for user-uploaded and private checklists)");
                                                query = items.slice(0,limit).join(" OR ") +")";
                                            }
                                            scope._custom()({
                                                q: [query],
                                                name: found.listName,
                                                species_list: found.dataResourceUid
                                            })
                                        })
                                    }
                                }
                            }
                        };
                        scope.removeAll = function () {
                            for (var i = 0; i < scope.items.length; i++) {
                                scope.items[i].selected = false
                            }
                        };
                        scope.remove = function (item) {
                            var found = scope.getLayer(!item.dataResourceUid ? item : item.dataResourceUid);
                            found.selected = false;
                            scope.selection = {}
                        };
                        scope.select = function (item) {
                            scope.removeAll();
                            scope.add(item)
                        }
                    }
                }
            }])
}(angular));