"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.entityCtrl = exports.nestedassign = exports.entitiesCtrl = exports.fileread = exports.jsonText = exports.copytext = exports.userdata = exports.translate = exports.ngtype = exports.textarea = exports.whenScrolled = exports.formatBytes = exports.timetoo = exports.timesince = exports.api = void 0;
const angular = require("angular");
const openflow_api_1 = require("@openiap/openflow-api");
class api {
    constructor($rootScope, $location, WebSocketClientService) {
        this.$rootScope = $rootScope;
        this.$location = $location;
        this.WebSocketClientService = WebSocketClientService;
    }
}
exports.api = api;
api.$inject = ["$rootScope", "$location", "WebSocketClientService"];
function _timeSince(timeStamp) {
    const now = new Date(), secondsPast = (now.getTime() - timeStamp.getTime()) / 1000;
    if (secondsPast < 60) {
        return parseInt(secondsPast.toString()) + 's';
    }
    if (secondsPast < 3600) {
        return parseInt((secondsPast / 60).toString()) + 'm';
    }
    if (secondsPast <= 86400) {
        return parseInt((secondsPast / 3600).toString()) + 'h';
    }
    if (secondsPast > 86400) {
        let day = timeStamp.getDate();
        let month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
        let year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear();
        return day + " " + month + year;
    }
}
function _timeToo(timeStamp) {
    const now = new Date();
    let secondsPast = (now.getTime() - timeStamp.getTime()) / 1000;
    var suffix = "";
    if (secondsPast > 0)
        suffix = " ago";
    if (secondsPast < 0)
        secondsPast *= -1;
    if (secondsPast < 60) {
        return parseInt(secondsPast.toString()) + 's' + suffix;
    }
    if (secondsPast < 3600) {
        return parseInt((secondsPast / 60).toString()) + 'm' + suffix;
    }
    if (secondsPast <= 86400) {
        return parseInt((secondsPast / 3600).toString()) + 'h' + suffix;
    }
    if (secondsPast > 86400) {
        let day = timeStamp.getDate();
        let month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
        let year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear();
        return day + " " + month + year;
    }
}
// @ts-ignore
class timesince {
    constructor($location, $timeout) {
        this.$location = $location;
        this.$timeout = $timeout;
        // restrict = 'E';
        this.require = 'ngModel';
        this.replace = true;
        this.link = (scope, element, attr, ngModelCtrl) => {
            scope.$watch(() => {
                if (ngModelCtrl.$viewValue === null || ngModelCtrl.$viewValue === undefined) {
                    return;
                }
                const timeStamp = ngModelCtrl.$viewValue;
                element.text(_timeSince(new Date(timeStamp)));
            });
        };
    }
    static factory() {
        const directive = ($location, $timeout) => new timesince($location, $timeout);
        directive.$inject = ['$location', '$timeout'];
        return directive;
    }
}
exports.timesince = timesince;
// @ts-ignore
class timetoo {
    constructor($location, $timeout) {
        this.$location = $location;
        this.$timeout = $timeout;
        // restrict = 'E';
        this.require = 'ngModel';
        this.replace = true;
        this.link = (scope, element, attr, ngModelCtrl) => {
            scope.$watch(() => {
                if (ngModelCtrl.$viewValue === null || ngModelCtrl.$viewValue === undefined) {
                    return;
                }
                const timeStamp = ngModelCtrl.$viewValue;
                element.text(_timeToo(new Date(timeStamp)));
            });
        };
    }
    static factory() {
        const directive = ($location, $timeout) => new timetoo($location, $timeout);
        directive.$inject = ['$location', '$timeout'];
        return directive;
    }
}
exports.timetoo = timetoo;
// @ts-ignore
class formatBytes {
    constructor($location, $timeout) {
        this.$location = $location;
        this.$timeout = $timeout;
        // restrict = 'E';
        this.require = 'ngModel';
        this.replace = true;
        this.link = (scope, element, attr, ngModelCtrl) => {
            scope.$watch(() => {
                if (ngModelCtrl.$viewValue === null || ngModelCtrl.$viewValue === undefined) {
                    return;
                }
                const size = ngModelCtrl.$viewValue;
                const decimal = parseInt(attr.decimal || 1);
                try {
                    element.text(this.formatBytes(size, decimal));
                }
                catch (error) {
                    console.error(error);
                }
            });
        };
    }
    formatBytes(bytes, decimals = 1) {
        if (bytes === 0)
            return '0 Bytes';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }
    static factory() {
        const directive = ($location, $timeout) => new formatBytes($location, $timeout);
        directive.$inject = ['$location', '$timeout'];
        return directive;
    }
}
exports.formatBytes = formatBytes;
// @ts-ignore
class whenScrolled {
    constructor($rootScope, $window, $timeout) {
        this.$rootScope = $rootScope;
        this.$window = $window;
        this.$timeout = $timeout;
        this.link = (scope, elem, attrs, ngModelCtrl) => {
            var checkWhenEnabled, handler, scrollDistance, scrollEnabled;
            // var $window = angular.element(this.$window);
            scrollDistance = 1;
            if (attrs.whenScrolledDistance != null) {
                scope.$watch(attrs.whenScrolledDistance, (value) => {
                    return scrollDistance = parseInt(value, 10);
                });
            }
            scrollEnabled = true;
            checkWhenEnabled = false;
            if (attrs.whenScrolledDisabled != null) {
                scope.$watch(attrs.whenScrolledDisabled, (value) => {
                    scrollEnabled = !value;
                    if (scrollEnabled && checkWhenEnabled) {
                        checkWhenEnabled = false;
                        return handler();
                    }
                });
            }
            handler = (e) => {
                var ele = elem[0].getBoundingClientRect();
                var scrollTop = window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0);
                var elementBottom, remaining, shouldScroll, windowBottom;
                windowBottom = window.innerHeight + scrollTop;
                elementBottom = ele.top + ele.height;
                remaining = elementBottom - windowBottom;
                shouldScroll = remaining <= this.$window.innerHeight * scrollDistance;
                if (shouldScroll && scrollEnabled && ele.height > 300) {
                    if (this.$rootScope.$$phase) {
                        return scope.$eval(attrs.whenScrolled);
                    }
                    else {
                        return scope.$apply(attrs.whenScrolled);
                    }
                }
                else if (shouldScroll) {
                    return checkWhenEnabled = true;
                }
            };
            var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel"; //FF doesn't recognize mousewheel as of FF3.x
            var doc = document;
            if (doc.attachEvent)
                doc.attachEvent("on" + mousewheelevt, handler);
            else if (document.addEventListener) //WC3 browsers
                document.addEventListener(mousewheelevt, handler, false);
            // angular.element(this.$window).on('scroll', handler);
            scope.$on('$destroy', () => {
                var doc = document;
                if (doc.detachEvent)
                    doc.detachEvent("on" + mousewheelevt, handler);
                else if (document.removeEventListener) //WC3 browsers
                    document.removeEventListener(mousewheelevt, handler, false);
                // return this.$window.off('scroll', handler);
            });
            return this.$timeout((() => {
                if (attrs.whenScrolledImmediateCheck) {
                    if (scope.$eval(attrs.whenScrolledImmediateCheck)) {
                        return handler();
                    }
                }
                else {
                    return handler();
                }
            }));
        };
    }
    static factory() {
        const directive = ($rootScope, $window, $timeout) => new whenScrolled($rootScope, $window, $timeout);
        directive.$inject = ['$rootScope', '$window', '$timeout'];
        return directive;
    }
}
exports.whenScrolled = whenScrolled;
class textarea {
    constructor($location, $timeout) {
        this.$location = $location;
        this.$timeout = $timeout;
        // restrict = 'E';
        // require = 'ngModel';
        this.replace = true;
        this.link = (scope, element, attr, ngModelCtrl) => {
            if (!element.hasClass("autogrow")) {
                // no autogrow for you today
                return;
            }
            // get possible minimum height style
            const minHeight = parseInt(window.getComputedStyle(element[0]).getPropertyValue("min-height")) || 0;
            // prevent newlines in textbox
            // element.on("keydown", function (evt) {
            //     if (evt.which === 13) {
            //         evt.preventDefault();
            //     }
            // });
            element.on("input", function (evt) {
                const contentHeight2 = this.scrollHeight;
                const firstrun = element.attr("firstrun");
                if (contentHeight2 > 1000) {
                    if (firstrun === null || firstrun === undefined) {
                        element.attr("firstrun", "false");
                    }
                    else {
                        return;
                    }
                }
                {
                    element.css({
                        paddingTop: 0,
                        height: 0,
                        minHeight: 0
                    });
                    const contentHeight = this.scrollHeight;
                    const borderHeight = this.offsetHeight;
                    element.css({
                        paddingTop: ~~Math.max(0, minHeight - contentHeight) / 2 + "px",
                        minHeight: null,
                        height: contentHeight + borderHeight + "px" // because we're using border-box
                    });
                }
            });
            // watch model changes from the outside to adjust height
            scope.$watch(attr.ngModel, trigger);
            // set initial size
            trigger();
            function trigger() {
                setTimeout(element.triggerHandler.bind(element, "input"), 1);
            }
        };
    }
    static factory() {
        const directive = ($location, $timeout) => new textarea($location, $timeout);
        directive.$inject = ['$location', '$timeout'];
        return directive;
    }
}
exports.textarea = textarea;
class ngtype {
    constructor($location, $timeout) {
        this.$location = $location;
        this.$timeout = $timeout;
        this.restrict = 'A';
        this.require = '?ngModel';
        this.link = (scope, element, attr, ngModelCtrl) => {
            if (openflow_api_1.NoderedUtil.IsNullUndefinded(ngModelCtrl)) {
                return;
            }
            var mytype = "";
            scope.$watch((newValue) => {
                if (ngModelCtrl.$viewValue === null || ngModelCtrl.$viewValue === undefined) {
                    return;
                }
                if (typeof ngModelCtrl.$modelValue === 'number') {
                    mytype = "number";
                    element.attr("type", "number");
                }
                else if (typeof ngModelCtrl.$modelValue === 'boolean') {
                    mytype = "boolean";
                    element.attr("type", "checkbox");
                }
            });
            var toModelb = function (value) {
                if (mytype == "text") {
                    return value;
                }
                else if (mytype == "boolean") {
                    if (String(value).toLowerCase() == "true") {
                        value = true;
                        return true;
                    }
                    {
                        value = false;
                        return false;
                    }
                }
                else if (mytype == "number") {
                    if (value === "" || value === null || value === undefined)
                        return value;
                    return parseInt(value);
                }
                return value;
            };
            var toViewb = function (value) {
                if (mytype == "") {
                    if (typeof value === 'number') {
                        mytype = "number";
                        element.attr("type", "number");
                    }
                    else if (typeof value === 'boolean') {
                        mytype = "boolean";
                        element.attr("type", "checkbox");
                    }
                    else if (value != null && value != undefined && typeof value === 'string') {
                        mytype = "text";
                        element.attr("type", "text");
                    }
                }
                if (mytype == "text") {
                    return value;
                }
                else if (mytype == "boolean") {
                    if (String(value).toLowerCase() == "true") {
                        value = true;
                        return true;
                    }
                    {
                        value = false;
                        return false;
                    }
                }
                else if (mytype == "number") {
                    if (value === "" || value === null || value === undefined)
                        return value;
                    return parseInt(value);
                }
                return value;
            };
            ngModelCtrl.$formatters.push(toViewb);
            ngModelCtrl.$parsers.push(toModelb);
        };
    }
    static factory() {
        const directive = ($location, $timeout) => new ngtype($location, $timeout);
        directive.$inject = ['$location', '$timeout'];
        return directive;
    }
}
exports.ngtype = ngtype;
async function getString(locale, lib, key) {
    return new Promise((resolve) => {
        try {
            if (locale === null || locale === undefined) {
                return;
            }
            locale.ready(lib).then(function () {
                const value = locale.getString(lib + "." + key);
                if (value !== null && value !== undefined && value !== "") {
                    resolve(value);
                }
                else {
                    resolve(key);
                }
            });
        }
        catch (error) {
        }
    });
}
const global_translate_notfound = [];
class translate {
    constructor($location, $timeout, locale) {
        this.$location = $location;
        this.$timeout = $timeout;
        this.locale = locale;
        this.require = '?ngModel';
        this.replace = true;
        this.link = (scope, element, attr, ngModelCtrl) => {
            const calculateValue = (value) => {
                try {
                    if (value === null || value === undefined || value === "")
                        return value;
                    const lib = (attr.lib ? attr.lib : "common");
                    if ((value.toString()).startsWith(lib + ".")) {
                        return;
                    }
                    const key = (lib + "." + value).toLowerCase();
                    let result = this.locale.getString(key);
                    if (result.startsWith(lib + ".")) {
                        result = result.slice((lib + ".").length);
                    }
                    // const result = await getString(this.locale, lib, value);
                    if (result == "%%KEY_NOT_FOUND%%" || result == "") {
                        if (global_translate_notfound.indexOf(lib + "." + value) === -1) {
                            global_translate_notfound.push(lib + "." + value);
                            console.debug("KEY_NOT_FOUND " + lib + "." + value);
                        }
                        result = value;
                    }
                    return result;
                }
                catch (error) {
                    console.error(error);
                    return "error";
                }
            };
            const lib = (attr.lib ? attr.lib : "common");
            this.locale.ready(lib).then(() => {
                let value = null;
                if (ngModelCtrl !== null) {
                    ngModelCtrl.$formatters.push(function (value) {
                        return calculateValue(value);
                    });
                }
                else {
                    const hashCode = (s) => {
                        return s.split("").reduce(function (a, b) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
                    };
                    if (attr.value !== null && attr.value !== undefined && element[0].tagName !== "OPTION") {
                        value = calculateValue(attr.value);
                        attr.$set('value', value);
                    }
                    else {
                        value = element.text();
                        if (value !== null || value !== undefined) {
                            const result = calculateValue(value);
                            element.text(result);
                        }
                    }
                }
            });
        };
    }
    static factory() {
        const directive = ($location, $timeout, locale) => new translate($location, $timeout, locale);
        directive.$inject = ['$location', '$timeout', 'locale'];
        return directive;
    }
}
exports.translate = translate;
class userdata {
    constructor() {
        this.data = {};
    }
}
exports.userdata = userdata;
// implements ng.IDirective
class copytext {
    constructor($location, $timeout, locale) {
        this.$location = $location;
        this.$timeout = $timeout;
        this.locale = locale;
        this.restrict = 'A';
        this.require = '?ngModel';
        this.link = (scope, element, attr, ngModelCtrl) => {
            console.debug("copytext", element);
            if (!ngModelCtrl)
                return;
            element.attr('unselectable', 'on');
            element.on('mousedown', function (e, eventData) {
                /* istanbul ignore else: this is for catching the jqLite testing*/
                if (eventData)
                    angular.extend(e, eventData);
                // this prevents focusout from firing on the editor when clicking toolbar buttons
                e.preventDefault();
                console.debug("Prevent mousedown");
                return false;
            });
        };
    }
    static factory() {
        const directive = ($location, $timeout, locale) => new copytext($location, $timeout, locale);
        directive.$inject = ['$location', '$timeout', 'locale'];
        return directive;
    }
}
exports.copytext = copytext;
// implements ng.IDirective
class jsonText {
    constructor($location, $timeout, locale) {
        this.$location = $location;
        this.$timeout = $timeout;
        this.locale = locale;
        this.restrict = 'A';
        this.require = '?ngModel';
        this.link = (scope, element, attr, ngModelCtrl) => {
            function into(input) {
                return JSON.parse(input);
            }
            function out(data) {
                return JSON.stringify(data, null, 2);
            }
            ngModelCtrl.$parsers.push(into);
            ngModelCtrl.$formatters.push(out);
        };
    }
    static factory() {
        const directive = ($location, $timeout, locale) => new jsonText($location, $timeout, locale);
        directive.$inject = ['$location', '$timeout', 'locale'];
        return directive;
    }
}
exports.jsonText = jsonText;
// implements ng.IDirective
class fileread {
    constructor($location, $timeout, locale) {
        this.$location = $location;
        this.$timeout = $timeout;
        this.locale = locale;
        this.restrict = 'A';
        this.require = '?ngModel';
        this.link = (scope, element, attr, ngModelCtrl) => {
            if (!ngModelCtrl)
                return;
            ngModelCtrl.$render = function () { };
            element.bind('change', function (changeEvent) {
                const reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        const base64result = loadEvent.target.result.split(',')[1];
                        ngModelCtrl.$setViewValue(base64result);
                        scope.filename = changeEvent.target.files[0].name;
                        scope.type = changeEvent.target.files[0].type;
                    });
                };
                if (changeEvent.target.files != null && changeEvent.target.files.length > 0) {
                    reader.readAsDataURL(changeEvent.target.files[0]);
                }
            }); //change
        };
    }
    static factory() {
        const directive = ($location, $timeout, locale) => new fileread($location, $timeout, locale);
        directive.$inject = ['$location', '$timeout', 'locale'];
        return directive;
    }
}
exports.fileread = fileread;
class entitiesCtrl {
    constructor($rootScope, $scope, $location, $routeParams, $interval, WebSocketClientService, api, userdata) {
        this.$rootScope = $rootScope;
        this.$scope = $scope;
        this.$location = $location;
        this.$routeParams = $routeParams;
        this.$interval = $interval;
        this.WebSocketClientService = WebSocketClientService;
        this.api = api;
        this.userdata = userdata;
        this.loading = false;
        this.basequery = {};
        this.baseprojection = {};
        this.collection = "entities";
        this.models = [];
        this.orderby = {};
        this.autorefresh = false;
        this.autorefreshinterval = 30 * 1000;
        this.pagesize = 50;
        this.autorefreshpromise = null;
        this.preloadData = null;
        this.postloadData = null;
        this.searchstring = "";
        this.lastsearchstring = "";
        this.searchfields = ["name"];
        this.basequeryas = null;
        this.errormessage = "";
        this.skipcustomerfilter = false;
        this.page = 0;
        this.controldown = false;
        this.shiftdown = false;
        this._onKeyDown = this.onKeyDown.bind(this);
        this._onKeyUp = this.onKeyUp.bind(this);
        document.addEventListener('keydown', this._onKeyDown);
        document.addEventListener('keyup', this._onKeyUp);
        $scope.$on('$destroy', () => {
            document.removeEventListener('keydown', this._onKeyDown);
            document.removeEventListener('keyup', this._onKeyUp);
        });
        if (this.userdata.data != null && this.userdata.data) {
            if (this.userdata.data.basequery != null) {
                this.basequery = this.userdata.data.basequery;
                delete this.userdata.data.basequery;
            }
            if (this.userdata.data.searchstring != null) {
                this.searchstring = this.userdata.data.searchstring;
                this.$rootScope.$broadcast("setsearch", this.searchstring);
                delete this.userdata.data.searchstring;
            }
            if (this.userdata.data.basequeryas != null) {
                this.basequeryas = this.userdata.data.basequeryas;
                delete this.userdata.data.basequeryas;
            }
        }
        this.$scope.$on('search', (event, data) => {
            this.searchstring = data;
            this.loadData();
        });
    }
    onKeyDown(e) {
        if ((e.code == 'ControlLeft' || e.code == 'ControlRight') && !this.controldown) {
            this.controldown = true;
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
        if ((e.code == 'ShiftLeft' || e.code == 'ShiftRight') && !this.shiftdown) {
            this.shiftdown = true;
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
    }
    onKeyUp(e) {
        if ((e.code == 'ControlLeft' || e.code == 'ControlRight') && this.controldown) {
            this.controldown = false;
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
        if ((e.code == 'ShiftLeft' || e.code == 'ShiftRight') && this.shiftdown) {
            this.shiftdown = false;
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
    }
    static parseJson(txt, reviver, context) {
        context = context || 20;
        try {
            return JSON.parse(txt, reviver);
        }
        catch (e) {
            if (typeof txt !== "string") {
                const isEmptyArray = Array.isArray(txt) && txt.length === 0;
                const errorMessage = "Cannot parse " +
                    (isEmptyArray ? "an empty array" : String(txt));
                throw new TypeError(errorMessage);
            }
            const syntaxErr = e.message.match(/^Unexpected token.*position\s+(\d+)/i);
            const errIdx = syntaxErr
                ? +syntaxErr[1]
                : e.message.match(/^Unexpected end of JSON.*/i)
                    ? txt.length - 1
                    : null;
            if (errIdx != null) {
                const start = errIdx <= context
                    ? 0
                    : errIdx - context;
                const end = errIdx + context >= txt.length
                    ? txt.length
                    : errIdx + context;
                e.message += ` while parsing near "${start === 0 ? "" : "..."}${txt.slice(start, end)}${end === txt.length ? "" : "..."}"`;
            }
            else {
                e.message += ` while parsing "${txt.slice(0, context * 2)}"`;
            }
            throw e;
        }
    }
    async loadData() {
        try {
            if (this.loading == true) {
                console.debug("allready loading data, exit");
                return;
            }
            this.$rootScope.$broadcast("setsearch", this.searchstring);
            this.errormessage = "";
            this.loading = true;
            if (this.preloadData != null) {
                this.preloadData();
            }
            let query = Object.assign({}, this.basequery);
            let exactquery = null;
            let basequeryas = this.basequeryas;
            // if (this.collection == "users" && (this.basequery._type == "user" || this.basequery._type == "role") && !this.skipcustomerfilter && this.WebSocketClientService.multi_tenant) {
            //     // if (!NoderedUtil.IsNullUndefinded(this.WebSocketClientService.customer) && !this.skipcustomerfilter) {
            //     //     basequeryas = this.WebSocketClientService.customer._id;
            //     // }
            //     if (this.WebSocketClientService.customer && !NoderedUtil.IsNullEmpty(this.WebSocketClientService.customer._id)) {
            //         query["customerid"] = this.WebSocketClientService.customer._id;
            //     }
            // }
            if (this.WebSocketClientService.multi_tenant && !openflow_api_1.NoderedUtil.IsNullUndefinded(this.WebSocketClientService.customer) && !this.skipcustomerfilter) {
                basequeryas = this.WebSocketClientService.customer._id;
            }
            let orderby = this.orderby;
            if (this.lastsearchstring !== this.searchstring) {
                this.models = [];
                this.orderby = null;
            }
            this.lastsearchstring = this.searchstring;
            if (this.searchstring !== "" && this.searchstring != null) {
                if (this.searchstring.indexOf("{") == 0) {
                    if (this.searchstring.lastIndexOf("}") == (this.searchstring.length - 1)) {
                        try {
                            query = entitiesCtrl.parseJson(this.searchstring, null, null);
                        }
                        catch (error) {
                            this.errormessage = error.message ? error.message : error;
                        }
                    }
                }
                else {
                    let finalor = [];
                    const finalexactor = [];
                    for (let i = 0; i < this.searchfields.length; i++) {
                        let newq = {};
                        const newexactq = {};
                        // exact match case sensitive
                        // newq[this.searchfields[i]] = this.searchstring;
                        // exact match case insensitive
                        newexactq[this.searchfields[i]] = new RegExp(["^", this.searchstring, "$"].join(""), "i");
                        // newexactq[this.searchfields[i]] = new RegExp(["^", this.searchstring].join(""), "i");
                        // exact match string contains
                        newq[this.searchfields[i]] = new RegExp([this.searchstring.substring(1)].join(""), "i");
                        finalor.push(newq);
                        finalexactor.push(newexactq);
                    }
                    var hastextindex = false;
                    if (this.WebSocketClientService.collections_with_text_index.indexOf(this.collection) > -1) {
                        hastextindex = true;
                    }
                    if (!this.searchstring.startsWith(".") && hastextindex) {
                        finalor = [{ $text: { $search: this.searchstring.toLowerCase() } }];
                        console.debug("text search using ", this.searchstring.toLowerCase());
                    }
                    if (Object.keys(query).length == 0) {
                        query = { $or: finalor.concat() };
                        exactquery = { $or: finalexactor.concat() };
                    }
                    else {
                        query = { $and: [query, { $or: finalor.concat() }] };
                        exactquery = { $and: [query, { $or: finalexactor.concat() }] };
                    }
                    if (!this.searchstring.startsWith(".") && hastextindex) {
                        exactquery = { "_searchnames": this.searchstring.toLowerCase() };
                    }
                }
            }
            if (this.WebSocketClientService.collections_with_text_index.indexOf(this.collection) == -1) {
                if (openflow_api_1.NoderedUtil.IsNullUndefinded(this.orderby) || Object.keys(this.orderby).length == 0) {
                    orderby = { _created: -1 };
                }
            }
            else {
                if (openflow_api_1.NoderedUtil.IsNullUndefinded(this.orderby) || Object.keys(this.orderby).length == 0) {
                    orderby = { _created: -1 };
                }
                if (!openflow_api_1.NoderedUtil.IsNullEmpty(this.searchstring) && !this.searchstring.startsWith(".")) {
                    // Remove order by when using text index
                    orderby = null;
                }
            }
            if (this.page == 0) {
                this.models = await openflow_api_1.NoderedUtil.Query({ collectionname: this.collection, query, projection: this.baseprojection, orderby, top: this.pagesize, queryas: basequeryas });
            }
            else {
                var temp = await openflow_api_1.NoderedUtil.Query({ collectionname: this.collection, query, projection: this.baseprojection, orderby, top: this.pagesize, skip: this.pagesize * this.page, queryas: basequeryas });
                this.models = this.models.concat(temp);
            }
            if (exactquery != null && this.page == 0 && this.collection != "audit") {
                var temp = await openflow_api_1.NoderedUtil.Query({ collectionname: this.collection, query: exactquery, projection: this.baseprojection, orderby, top: 1, queryas: basequeryas });
                if (temp.length > 0) {
                    this.models = this.models.filter(x => x._id != temp[0]._id);
                    this.models = temp.concat(this.models);
                }
            }
            this.loading = false;
            if (this.autorefresh) {
                if (this.models.length >= this.pagesize || this.page > 0) {
                    // console.warn("Disabling auto refresh, result has more than pagesize entries");
                }
                else {
                    if (this.autorefreshpromise == null && this.searchstring === "") {
                        this.autorefreshpromise = this.$interval(() => {
                            this.loadData();
                        }, this.autorefreshinterval);
                        this.$scope.$on('$destroy', () => {
                            this.$interval.cancel(this.autorefreshpromise);
                        });
                    }
                }
            }
            if (this.postloadData != null) {
                this.postloadData();
            }
            else {
                if (!this.$scope.$$phase) {
                    this.$scope.$apply();
                }
            }
        }
        catch (error) {
            this.loading = false;
            this.errormessage = JSON.stringify(error);
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
    }
    more() {
        if (this.loading == true) {
            console.debug("allready loading data, exit");
            return;
        }
        if (this.models.length < (this.pagesize - 15)) {
            console.debug("Seems there are no more data, exit");
            return;
        }
        this.page++;
        this.loadData();
    }
    ToggleOrder(field) {
        if (this.orderby == null)
            this.orderby = {};
        if (this.orderby[field] == undefined) {
            this.orderby = {};
        }
        if (this.orderby[field] == -1) {
            this.orderby[field] = 1;
        }
        else {
            this.orderby[field] = -1;
        }
        if (field === '_type') {
            this.orderby["type"] = this.orderby[field];
        }
        this.page = 0;
        this.loadData();
    }
    async DeleteOne(model) {
        this.loading = true;
        this.errormessage = "";
        if (!this.$scope.$$phase) {
            this.$scope.$apply();
        }
        try {
            let recursive = false;
            if (this.collection == "users" && (model._type == "user" || model._type == "customer")) {
                if (this.shiftdown == true) {
                    if (confirm("Confirm you want to HARD delete " + model.name + "\nWill delete all associated data") == true) {
                        recursive = true;
                    }
                    else {
                        event.preventDefault();
                        return;
                    }
                }
            }
            await openflow_api_1.NoderedUtil.DeleteOne({ collectionname: this.collection, id: model._id, recursive });
            var oldcount = this.models.length;
            this.models = this.models.filter(function (m) { return m._id !== model._id; });
            if (this.models.length < oldcount && oldcount < 5) {
                this.loading = false;
                this.loadData();
            }
        }
        catch (error) {
            this.errormessage = error.message ? error.message : error;
        }
        this.loading = false;
        if (!this.$scope.$$phase) {
            this.$scope.$apply();
        }
    }
    async Search() {
        await this.loadData();
    }
}
exports.entitiesCtrl = entitiesCtrl;
entitiesCtrl.$inject = [
    "$rootScope",
    "$scope",
    "$location",
    "$routeParams",
    "$interval",
    "WebSocketClientService",
    "api",
    "userdata"
];
function nestedassign(target, source) {
    if (source === null || source === undefined)
        return null;
    const keys = Object.keys(source);
    for (let i = 0; i < keys.length; i++) {
        const sourcekey = keys[i];
        if (Object.keys(source).find(targetkey => targetkey === sourcekey) !== undefined &&
            Object.keys(source).find(targetkey => targetkey === sourcekey) !== null
            && typeof source === "object" && typeof source[sourcekey] === "object") {
            target[sourcekey] = nestedassign(target[sourcekey], source[sourcekey]);
        }
        else {
            target[sourcekey] = source[sourcekey];
        }
    }
    return target;
}
exports.nestedassign = nestedassign;
class entityCtrl {
    constructor($rootScope, $scope, $location, $routeParams, $interval, WebSocketClientService, api, userdata) {
        this.$rootScope = $rootScope;
        this.$scope = $scope;
        this.$location = $location;
        this.$routeParams = $routeParams;
        this.$interval = $interval;
        this.WebSocketClientService = WebSocketClientService;
        this.api = api;
        this.userdata = userdata;
        this.loading = false;
        this.basequery = {};
        this.baseprojection = {};
        this.collection = "entities";
        this.model = null;
        this.id = null;
        this.keys = [];
        this.autorefresh = false;
        this.autorefreshinterval = 30 * 1000;
        this.autorefreshpromise = null;
        this.preloadData = null;
        this.postloadData = null;
        this.errormessage = "";
        this.id = $routeParams.id;
        this.basequery = { _id: this.id };
    }
    async loadData() {
        try {
            if (this.loading == true) {
                console.debug("allready loading data, exit");
                return;
            }
            this.errormessage = "";
            let updated = false;
            this.loading = true;
            if (this.preloadData != null) {
                this.preloadData();
            }
            const result = await openflow_api_1.NoderedUtil.Query({ collectionname: this.collection, query: this.basequery, projection: this.baseprojection, top: 1 });
            if (result.length > 0) {
                if (this.model == null) {
                    this.model = result[0];
                    updated = true;
                }
                else {
                    if (!angular.equals(this.model, result[0])) {
                        this.model = result[0];
                        updated = true;
                    }
                }
            }
            if (updated) {
                this.keys = Object.keys(this.model);
                for (let i = this.keys.length - 1; i >= 0; i--) {
                    if (this.keys[i].startsWith('_'))
                        this.keys.splice(i, 1);
                }
            }
            this.loading = false;
            if (this.postloadData != null) {
                this.postloadData();
            }
            else {
                if (!this.$scope.$$phase) {
                    this.$scope.$apply();
                }
            }
            if (this.autorefresh) {
                if (this.autorefreshpromise == null) {
                    this.autorefreshpromise = this.$interval(() => {
                        this.loadData();
                    }, this.autorefreshinterval);
                    this.$scope.$on('$destroy', () => {
                        this.$interval.cancel(this.autorefreshpromise);
                    });
                }
            }
        }
        catch (error) {
            this.loading = false;
            this.errormessage = JSON.stringify(error);
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }
    }
}
exports.entityCtrl = entityCtrl;
entityCtrl.$inject = [
    "$rootScope",
    "$scope",
    "$location",
    "$routeParams",
    "$interval",
    "WebSocketClientService",
    "api",
    "userdata"
];
//# sourceMappingURL=CommonControllers.js.map