kalpdev.1 / Level phonetool amazon

// ==UserScript==
// @name            Level phonetool amazon
// @downloadURL https://openuserjs.org/install/kalpdev.1/Level_phonetool_amazon.user.js
// @updateURL https://openuserjs.org/meta/kalpdev.1/Level_phonetool_amazon.meta.js
// @namespace       http://amazon.com
// @description     Adds job level & time to all direct reports and manager in the org chart on the new phonetool page
// @match           https://phonetool.amazon.com/people/*
// @match           https://phonetool.amazon.com/users/*
// @grant           GM_xmlhttpRequest
// @grant           GM_setValue
// @grant           GM_getValue
// @grant           GM_addStyle
// @grant           GM_getResourceText
// @grant           GM_getResourceURL
// @grant           unsafeWindow
// @require         https://internal-cdn.amazon.com/btk.amazon.com/ajax/libs/jquery/2.1.4/jquery-2.1.4.min.js
// @version         2.0
// @license MIT
// ==/UserScript==

(function() {

    var urls = (function() {
        var prefix = 'https://improvement-ninjas.amazon.com/GreaseMonkey/jobdata/';
        var suffix = {level:'get_level.cgi', infor:'get_num_years.cgi' };

        return {
            get:function(what) {
                return(prefix + suffix[what]);
            }
        };
    })();

    if (GM_getValue("localCache") === null || GM_getValue("localCache") === undefined) {
        GM_setValue("localCache", {});
    }

    var localCache = {
        /**
         * timeout for cache in millis
         * @type {number}
         */
        timeout: 21600000, // 6 hour cache
        /** 
         * @type {{_: number, data: {}}}
         **/
        data: GM_getValue("localCache"),
        remove: function (url) {
            delete localCache.data[url];
            GM_setValue("localCache", localCache.data);
        },
        exist: function (url) {
            return !!GM_getValue("localCache")[url] && ((new Date().getTime() - GM_getValue("localCache")[url]._) < localCache.timeout);
        },
        get: function (url) {
            console.log('Getting in cache for url' + url);
            return GM_getValue("localCache")[url].data;
        },
        set: function (url, cachedData, callback) {
            localCache.remove(url);
            localCache.data[url] = {
                _: new Date().getTime(),
                data: cachedData
            };
            GM_setValue("localCache", localCache.data);
            if ($.isFunction(callback)) callback(cachedData);
        }
    };

    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        if (options.cache) {
            var complete = originalOptions.complete || $.noop,
                url = originalOptions.url + "?login=" + originalOptions.data.login;
            //remove jQuery cache as we have our own localCache
            options.cache = false;
            options.beforeSend = function () {
                if (localCache.exist(url)) {
                    complete(localCache.get(url));
                    return false;
                }
                return true;
            };
            options.complete = function (data, textStatus) {
                localCache.set(url, data, complete);
            };
        }
    });

    var sortRow = function() {
        var $people = $('div.org-chart-row'),
        margin = $people.last().css('padding-left'),
        parent = $people.parent(),
        $directs = $people.filter(function () {
            return $(this).css('padding-left') === margin;
        }),
        lastIndex = $directs.length - 1;

        $directs.sort(function (a, b) {
            let aLevel = $(a).data('level');
            let bLevel = $(b).data('level');
            var scalar = 10000000,
                aRank = scalar * (aLevel > 90 ? 0 : aLevel) + $(a).data('total'),
                bRank = scalar * (bLevel > 90 ? 0 : bLevel) + $(b).data('total');
            return bRank - aRank;
        });


        var titleRow = parent.find('.title');

        $directs.each(function (i) {
            var isLeaf = $(this).find('.level').attr('class').match(/level\s(\w*)(\-bottom)?/)[1],
                isLast = i === lastIndex,
                newClass = 'level ' + isLeaf + (isLast ? '-bottom' : '');

            $(this).find('.level').attr('class', newClass);
        }).detach().insertBefore(titleRow);
    };

    var getBuildingInfoOfEmployee = function(xhr) {
        var responseArray = xhr.responseJSON.results;
        var employeeBuildingMap = {};
        for (const response of responseArray) {
            employeeBuildingMap[response.id] = response.user.building;
        }
        return employeeBuildingMap;
    };

    unsafeWindow.$(document).ajaxSuccess(function(e, xhr, settings) {
        if (settings.url.indexOf('/setup_org_chart.json') > -1) {
            var userRow = $('div.org-chart-row');
            var allPromises = [];
            var employeeBuildingMap = getBuildingInfoOfEmployee(xhr);

            userRow.each(function(i) {
                var orgChartRow = $(this);
                var node = $('div.user-information:first', this);
                var empId = $('a:first', node).attr('href');
                if (!empId) return;
                empId = empId.split('/')[2];
                var data = {login:empId};

                if ($("#directEmpJobInfoLoginId_" + empId).length <= 0) {
                    node.append($('<span>',{id:'directEmpJobInfoLoginId_' + empId, class:'direct-reports-number'}).text('Login: ' + empId));
                }
                if ($("#directEmpJobInfoLevel_" + empId).length <= 0) {
                    node.append($('<span>',{id:'directEmpJobInfoLevel_' + empId, class:'direct-reports-number'}).text(' - Level: loading'));
                }
                if ($("#directEmpJobInfoTime_" + empId).length <= 0) {
                    node.append($('<span>',{id:'directEmpJobInfoTime_' + empId, class:'direct-reports-number'}).text(' - Here For: loading'));
                }
                if ($("#directEmpJobInfoBuilding_" + empId).length <=0) {
                    node.append($('<span>',{id:'directEmpJobInfoBuilding_' + empId, class:'direct-reports-number'}).text(' - Building: ' + employeeBuildingMap[empId]));

                }

                //get and append level
                var $levelPromise = $.ajax({url: urls.get('level'),
                        method: "GET",
                        data: data,
                        xhrFields: {
                            withCredentials: true
                        },
                        cache: true,
                        complete: function(response) {
                               var value = response.responseText.replace(/\s+$/,'');
                               orgChartRow.data("level", value);
                               $('#directEmpJobInfoLevel_' + data.login).text(' - Level: ' + value);
                          }
                });

                //get and append time
                var $timePromise = $.ajax({url: urls.get('infor'),
                        method: "GET",
                        data: data,
                        xhrFields: {
                            withCredentials: true
                        },
                        cache: true,
                        complete: function(response) {
                            var resp = response.responseText
                            var time = resp.trim();
                            var value = resp.replace(/\s+$/,''),
                            years = value.match(/(\d*)\syear/) ? +value.match(/(\d*)\syear/)[1] : 0,
                            months = value.match(/(\d*)\smonth/) ? +value.match(/(\d*)\smonth/)[1] : 0,
                            days = value.match(/(\d*)\sday/) ? +value.match(/(\d*)\sday/)[1] : 0;

                            orgChartRow.data({
                                years: years,
                                months: months,
                                days: days,
                                total: 365 * years + 31 * months + days
                                });
                                $('#directEmpJobInfoTime_' + data.login).text(' - Here For: ' + time);
                        }
                });
                allPromises.push($levelPromise, $timePromise);
            });
            Promise.allSettled(allPromises).then(([result]) => {
                sortRow();
            });
        }
    });
})();